Merge pull request #1085 from umap-project/prettierjs
Apply PrettierJS to the whole codebase
This commit is contained in:
commit
db2da8f407
18 changed files with 8789 additions and 7615 deletions
6
.prettierrc.yaml
Normal file
6
.prettierrc.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
trailingComma: "es5"
|
||||
tabWidth: 2
|
||||
semi: false
|
||||
singleQuote: true
|
||||
printWidth: 88
|
||||
quoteProps: "consistent"
|
6
Makefile
6
Makefile
|
@ -52,3 +52,9 @@ tx_push:
|
|||
tx push -s
|
||||
tx_pull:
|
||||
tx pull
|
||||
|
||||
jsdir = umap/static/umap/js/
|
||||
filepath = "${jsdir}*.js"
|
||||
pretty: ## Apply PrettierJS to all JS files (or specified `filepath`)
|
||||
./node_modules/prettier/bin-prettier.js --write ${filepath}
|
||||
|
||||
|
|
22
package-lock.json
generated
22
package-lock.json
generated
|
@ -40,6 +40,7 @@
|
|||
"mocha-phantomjs": "^4.0.1",
|
||||
"optimist": "~0.4.0",
|
||||
"phantomjs": "^1.9.18",
|
||||
"prettier": "^2.8.8",
|
||||
"sinon": "^1.10.3",
|
||||
"uglify-js": "~3.17.4"
|
||||
}
|
||||
|
@ -1920,6 +1921,21 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin-prettier.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
|
@ -4071,6 +4087,12 @@
|
|||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"prettier": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz",
|
||||
"integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
"mocha-phantomjs": "^4.0.1",
|
||||
"optimist": "~0.4.0",
|
||||
"phantomjs": "^1.9.18",
|
||||
"prettier": "^2.8.8",
|
||||
"sinon": "^1.10.3",
|
||||
"uglify-js": "~3.17.4"
|
||||
},
|
||||
|
|
|
@ -1,314 +1,341 @@
|
|||
L.U.AutoComplete = L.Class.extend({
|
||||
options: {
|
||||
placeholder: 'Start typing...',
|
||||
emptyMessage: 'No result',
|
||||
allowFree: true,
|
||||
minChar: 2,
|
||||
maxResults: 5,
|
||||
},
|
||||
|
||||
options: {
|
||||
placeholder: 'Start typing...',
|
||||
emptyMessage: 'No result',
|
||||
allowFree: true,
|
||||
minChar: 2,
|
||||
maxResults: 5
|
||||
},
|
||||
CACHE: '',
|
||||
RESULTS: [],
|
||||
|
||||
CACHE: '',
|
||||
RESULTS: [],
|
||||
|
||||
initialize: function (el, options) {
|
||||
this.el = el;
|
||||
var ui = new L.U.UI(document.querySelector('header'));
|
||||
this.xhr = new L.U.Xhr(ui);
|
||||
L.setOptions(this, options);
|
||||
var CURRENT = null;
|
||||
try {
|
||||
Object.defineProperty(this, 'CURRENT', {
|
||||
get: function () {
|
||||
return CURRENT;
|
||||
},
|
||||
set: function (index) {
|
||||
if (typeof index === 'object') {
|
||||
index = this.resultToIndex(index);
|
||||
}
|
||||
CURRENT = index;
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// Hello IE8
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
createInput: function () {
|
||||
this.input = L.DomUtil.element('input', {
|
||||
type: 'text',
|
||||
placeholder: this.options.placeholder,
|
||||
autocomplete: 'off',
|
||||
className: this.options.className
|
||||
}, this.el);
|
||||
L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this);
|
||||
L.DomEvent.on(this.input, 'keyup', this.onKeyUp, this);
|
||||
L.DomEvent.on(this.input, 'blur', this.onBlur, this);
|
||||
},
|
||||
|
||||
createContainer: function () {
|
||||
this.container = L.DomUtil.element('ul', {className: 'umap-autocomplete'}, document.body);
|
||||
},
|
||||
|
||||
resizeContainer: function()
|
||||
{
|
||||
var l = this.getLeft(this.input);
|
||||
var t = this.getTop(this.input) + this.input.offsetHeight;
|
||||
this.container.style.left = l + 'px';
|
||||
this.container.style.top = t + 'px';
|
||||
var width = this.options.width ? this.options.width : this.input.offsetWidth - 2;
|
||||
this.container.style.width = width + 'px';
|
||||
},
|
||||
|
||||
|
||||
onKeyDown: function (e) {
|
||||
switch (e.keyCode) {
|
||||
case L.U.Keys.TAB:
|
||||
if(this.CURRENT !== null) this.setChoice();
|
||||
L.DomEvent.stop(e);
|
||||
break;
|
||||
case L.U.Keys.ENTER:
|
||||
L.DomEvent.stop(e);
|
||||
this.setChoice();
|
||||
break;
|
||||
case L.U.Keys.ESC:
|
||||
L.DomEvent.stop(e);
|
||||
this.hide();
|
||||
break;
|
||||
case L.U.Keys.DOWN:
|
||||
if(this.RESULTS.length > 0) {
|
||||
if(this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) { // what if one result?
|
||||
this.CURRENT++;
|
||||
this.highlight();
|
||||
}
|
||||
else if(this.CURRENT === null) {
|
||||
this.CURRENT = 0;
|
||||
this.highlight();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case L.U.Keys.UP:
|
||||
if(this.CURRENT !== null) {
|
||||
L.DomEvent.stop(e);
|
||||
}
|
||||
if(this.RESULTS.length > 0) {
|
||||
if(this.CURRENT > 0) {
|
||||
this.CURRENT--;
|
||||
this.highlight();
|
||||
}
|
||||
else if(this.CURRENT === 0) {
|
||||
this.CURRENT = null;
|
||||
this.highlight();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp: function (e) {
|
||||
var special = [
|
||||
L.U.Keys.TAB,
|
||||
L.U.Keys.ENTER,
|
||||
L.U.Keys.LEFT,
|
||||
L.U.Keys.RIGHT,
|
||||
L.U.Keys.DOWN,
|
||||
L.U.Keys.UP,
|
||||
L.U.Keys.APPLE,
|
||||
L.U.Keys.SHIFT,
|
||||
L.U.Keys.ALT,
|
||||
L.U.Keys.CTRL
|
||||
];
|
||||
if (special.indexOf(e.keyCode) === -1)
|
||||
{
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
|
||||
onBlur: function () {
|
||||
var self = this;
|
||||
setTimeout(function () {
|
||||
self.hide();
|
||||
}, 100);
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
this.RESULTS = [];
|
||||
this.CURRENT = null;
|
||||
this.CACHE = '';
|
||||
this.container.innerHTML = '';
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.clear();
|
||||
this.container.style.display = 'none';
|
||||
this.input.value = '';
|
||||
},
|
||||
|
||||
setChoice: function (choice) {
|
||||
choice = choice || this.RESULTS[this.CURRENT];
|
||||
if (choice) {
|
||||
this.input.value = choice.item.label;
|
||||
this.options.on_select(choice);
|
||||
this.displaySelected(choice);
|
||||
this.hide();
|
||||
if (this.options.callback) {
|
||||
L.Util.bind(this.options.callback, this)(choice);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
search: function() {
|
||||
var val = this.input.value;
|
||||
if (val.length < this.options.minChar) {
|
||||
this.clear();
|
||||
return;
|
||||
}
|
||||
if( val + '' === this.CACHE + '') return;
|
||||
else this.CACHE = val;
|
||||
this._do_search(val, function (data) {
|
||||
this.handleResults(data.data);
|
||||
}, this);
|
||||
},
|
||||
|
||||
createResult: function (item) {
|
||||
var el = L.DomUtil.element('li', {}, this.container);
|
||||
el.textContent = item.label;
|
||||
var result = {
|
||||
item: item,
|
||||
el: el
|
||||
};
|
||||
L.DomEvent.on(el, 'mouseover', function () {
|
||||
this.CURRENT = result;
|
||||
this.highlight();
|
||||
}, this);
|
||||
L.DomEvent.on(el, 'mousedown', function () {
|
||||
this.setChoice();
|
||||
}, this);
|
||||
return result;
|
||||
},
|
||||
|
||||
resultToIndex: function (result) {
|
||||
var out = null;
|
||||
this.forEach(this.RESULTS, function (item, index) {
|
||||
if (item.item.value == result.item.value) {
|
||||
out = index;
|
||||
return;
|
||||
}
|
||||
});
|
||||
return out;
|
||||
},
|
||||
|
||||
handleResults: function(data) {
|
||||
var self = this;
|
||||
this.clear();
|
||||
this.container.style.display = 'block';
|
||||
this.resizeContainer();
|
||||
this.forEach(data, function (item) {
|
||||
self.RESULTS.push(self.createResult(item));
|
||||
});
|
||||
this.CURRENT = 0;
|
||||
this.highlight();
|
||||
//TODO manage no results
|
||||
},
|
||||
|
||||
highlight: function () {
|
||||
var self = this;
|
||||
this.forEach(this.RESULTS, function (result, index) {
|
||||
if (index === self.CURRENT) L.DomUtil.addClass(result.el, 'on');
|
||||
else L.DomUtil.removeClass(result.el, 'on');
|
||||
});
|
||||
},
|
||||
|
||||
getLeft: function (el) {
|
||||
var tmp = el.offsetLeft;
|
||||
el = el.offsetParent;
|
||||
while(el) {
|
||||
tmp += el.offsetLeft;
|
||||
el = el.offsetParent;
|
||||
}
|
||||
return tmp;
|
||||
},
|
||||
|
||||
getTop: function (el) {
|
||||
var tmp = el.offsetTop;
|
||||
el = el.offsetParent;
|
||||
while(el) {
|
||||
tmp += el.offsetTop;
|
||||
el = el.offsetParent;
|
||||
}
|
||||
return tmp;
|
||||
},
|
||||
|
||||
forEach: function (els, callback) {
|
||||
Array.prototype.forEach.call(els, callback);
|
||||
initialize: function (el, options) {
|
||||
this.el = el
|
||||
var ui = new L.U.UI(document.querySelector('header'))
|
||||
this.xhr = new L.U.Xhr(ui)
|
||||
L.setOptions(this, options)
|
||||
var CURRENT = null
|
||||
try {
|
||||
Object.defineProperty(this, 'CURRENT', {
|
||||
get: function () {
|
||||
return CURRENT
|
||||
},
|
||||
set: function (index) {
|
||||
if (typeof index === 'object') {
|
||||
index = this.resultToIndex(index)
|
||||
}
|
||||
CURRENT = index
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Hello IE8
|
||||
}
|
||||
return this
|
||||
},
|
||||
|
||||
});
|
||||
createInput: function () {
|
||||
this.input = L.DomUtil.element(
|
||||
'input',
|
||||
{
|
||||
type: 'text',
|
||||
placeholder: this.options.placeholder,
|
||||
autocomplete: 'off',
|
||||
className: this.options.className,
|
||||
},
|
||||
this.el
|
||||
)
|
||||
L.DomEvent.on(this.input, 'keydown', this.onKeyDown, this)
|
||||
L.DomEvent.on(this.input, 'keyup', this.onKeyUp, this)
|
||||
L.DomEvent.on(this.input, 'blur', this.onBlur, this)
|
||||
},
|
||||
|
||||
createContainer: function () {
|
||||
this.container = L.DomUtil.element(
|
||||
'ul',
|
||||
{ className: 'umap-autocomplete' },
|
||||
document.body
|
||||
)
|
||||
},
|
||||
|
||||
resizeContainer: function () {
|
||||
var l = this.getLeft(this.input)
|
||||
var t = this.getTop(this.input) + this.input.offsetHeight
|
||||
this.container.style.left = l + 'px'
|
||||
this.container.style.top = t + 'px'
|
||||
var width = this.options.width ? this.options.width : this.input.offsetWidth - 2
|
||||
this.container.style.width = width + 'px'
|
||||
},
|
||||
|
||||
onKeyDown: function (e) {
|
||||
switch (e.keyCode) {
|
||||
case L.U.Keys.TAB:
|
||||
if (this.CURRENT !== null) this.setChoice()
|
||||
L.DomEvent.stop(e)
|
||||
break
|
||||
case L.U.Keys.ENTER:
|
||||
L.DomEvent.stop(e)
|
||||
this.setChoice()
|
||||
break
|
||||
case L.U.Keys.ESC:
|
||||
L.DomEvent.stop(e)
|
||||
this.hide()
|
||||
break
|
||||
case L.U.Keys.DOWN:
|
||||
if (this.RESULTS.length > 0) {
|
||||
if (this.CURRENT !== null && this.CURRENT < this.RESULTS.length - 1) {
|
||||
// what if one result?
|
||||
this.CURRENT++
|
||||
this.highlight()
|
||||
} else if (this.CURRENT === null) {
|
||||
this.CURRENT = 0
|
||||
this.highlight()
|
||||
}
|
||||
}
|
||||
break
|
||||
case L.U.Keys.UP:
|
||||
if (this.CURRENT !== null) {
|
||||
L.DomEvent.stop(e)
|
||||
}
|
||||
if (this.RESULTS.length > 0) {
|
||||
if (this.CURRENT > 0) {
|
||||
this.CURRENT--
|
||||
this.highlight()
|
||||
} else if (this.CURRENT === 0) {
|
||||
this.CURRENT = null
|
||||
this.highlight()
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
},
|
||||
|
||||
onKeyUp: function (e) {
|
||||
var special = [
|
||||
L.U.Keys.TAB,
|
||||
L.U.Keys.ENTER,
|
||||
L.U.Keys.LEFT,
|
||||
L.U.Keys.RIGHT,
|
||||
L.U.Keys.DOWN,
|
||||
L.U.Keys.UP,
|
||||
L.U.Keys.APPLE,
|
||||
L.U.Keys.SHIFT,
|
||||
L.U.Keys.ALT,
|
||||
L.U.Keys.CTRL,
|
||||
]
|
||||
if (special.indexOf(e.keyCode) === -1) {
|
||||
this.search()
|
||||
}
|
||||
},
|
||||
|
||||
onBlur: function () {
|
||||
var self = this
|
||||
setTimeout(function () {
|
||||
self.hide()
|
||||
}, 100)
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
this.RESULTS = []
|
||||
this.CURRENT = null
|
||||
this.CACHE = ''
|
||||
this.container.innerHTML = ''
|
||||
},
|
||||
|
||||
hide: function () {
|
||||
this.clear()
|
||||
this.container.style.display = 'none'
|
||||
this.input.value = ''
|
||||
},
|
||||
|
||||
setChoice: function (choice) {
|
||||
choice = choice || this.RESULTS[this.CURRENT]
|
||||
if (choice) {
|
||||
this.input.value = choice.item.label
|
||||
this.options.on_select(choice)
|
||||
this.displaySelected(choice)
|
||||
this.hide()
|
||||
if (this.options.callback) {
|
||||
L.Util.bind(this.options.callback, this)(choice)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
search: function () {
|
||||
var val = this.input.value
|
||||
if (val.length < this.options.minChar) {
|
||||
this.clear()
|
||||
return
|
||||
}
|
||||
if (val + '' === this.CACHE + '') return
|
||||
else this.CACHE = val
|
||||
this._do_search(
|
||||
val,
|
||||
function (data) {
|
||||
this.handleResults(data.data)
|
||||
},
|
||||
this
|
||||
)
|
||||
},
|
||||
|
||||
createResult: function (item) {
|
||||
var el = L.DomUtil.element('li', {}, this.container)
|
||||
el.textContent = item.label
|
||||
var result = {
|
||||
item: item,
|
||||
el: el,
|
||||
}
|
||||
L.DomEvent.on(
|
||||
el,
|
||||
'mouseover',
|
||||
function () {
|
||||
this.CURRENT = result
|
||||
this.highlight()
|
||||
},
|
||||
this
|
||||
)
|
||||
L.DomEvent.on(
|
||||
el,
|
||||
'mousedown',
|
||||
function () {
|
||||
this.setChoice()
|
||||
},
|
||||
this
|
||||
)
|
||||
return result
|
||||
},
|
||||
|
||||
resultToIndex: function (result) {
|
||||
var out = null
|
||||
this.forEach(this.RESULTS, function (item, index) {
|
||||
if (item.item.value == result.item.value) {
|
||||
out = index
|
||||
return
|
||||
}
|
||||
})
|
||||
return out
|
||||
},
|
||||
|
||||
handleResults: function (data) {
|
||||
var self = this
|
||||
this.clear()
|
||||
this.container.style.display = 'block'
|
||||
this.resizeContainer()
|
||||
this.forEach(data, function (item) {
|
||||
self.RESULTS.push(self.createResult(item))
|
||||
})
|
||||
this.CURRENT = 0
|
||||
this.highlight()
|
||||
//TODO manage no results
|
||||
},
|
||||
|
||||
highlight: function () {
|
||||
var self = this
|
||||
this.forEach(this.RESULTS, function (result, index) {
|
||||
if (index === self.CURRENT) L.DomUtil.addClass(result.el, 'on')
|
||||
else L.DomUtil.removeClass(result.el, 'on')
|
||||
})
|
||||
},
|
||||
|
||||
getLeft: function (el) {
|
||||
var tmp = el.offsetLeft
|
||||
el = el.offsetParent
|
||||
while (el) {
|
||||
tmp += el.offsetLeft
|
||||
el = el.offsetParent
|
||||
}
|
||||
return tmp
|
||||
},
|
||||
|
||||
getTop: function (el) {
|
||||
var tmp = el.offsetTop
|
||||
el = el.offsetParent
|
||||
while (el) {
|
||||
tmp += el.offsetTop
|
||||
el = el.offsetParent
|
||||
}
|
||||
return tmp
|
||||
},
|
||||
|
||||
forEach: function (els, callback) {
|
||||
Array.prototype.forEach.call(els, callback)
|
||||
},
|
||||
})
|
||||
|
||||
L.U.AutoComplete.Ajax = L.U.AutoComplete.extend({
|
||||
initialize: function (el, options) {
|
||||
L.U.AutoComplete.prototype.initialize.call(this, el, options)
|
||||
if (!this.el) return this
|
||||
this.createInput()
|
||||
this.createContainer()
|
||||
this.selected_container = this.initSelectedContainer()
|
||||
},
|
||||
|
||||
initialize: function (el, options) {
|
||||
L.U.AutoComplete.prototype.initialize.call(this, el, options);
|
||||
if (!this.el) return this;
|
||||
this.createInput();
|
||||
this.createContainer();
|
||||
this.selected_container = this.initSelectedContainer();
|
||||
},
|
||||
|
||||
optionToResult: function (option) {
|
||||
return {
|
||||
value: option.value,
|
||||
label: option.innerHTML
|
||||
};
|
||||
},
|
||||
|
||||
_do_search: function (val, callback, context) {
|
||||
val = val.toLowerCase();
|
||||
this.xhr.get('/agnocomplete/AutocompleteUser/?q=' + encodeURIComponent(val), {callback: callback, context: context || this});
|
||||
optionToResult: function (option) {
|
||||
return {
|
||||
value: option.value,
|
||||
label: option.innerHTML,
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
_do_search: function (val, callback, context) {
|
||||
val = val.toLowerCase()
|
||||
this.xhr.get('/agnocomplete/AutocompleteUser/?q=' + encodeURIComponent(val), {
|
||||
callback: callback,
|
||||
context: context || this,
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
L.U.AutoComplete.Ajax.SelectMultiple = L.U.AutoComplete.Ajax.extend({
|
||||
initSelectedContainer: function () {
|
||||
return L.DomUtil.after(
|
||||
this.input,
|
||||
L.DomUtil.element('ul', { className: 'umap-multiresult' })
|
||||
)
|
||||
},
|
||||
|
||||
initSelectedContainer: function () {
|
||||
return L.DomUtil.after(this.input, L.DomUtil.element('ul', {className: 'umap-multiresult'}));
|
||||
},
|
||||
|
||||
displaySelected: function (result) {
|
||||
var result_el = L.DomUtil.element('li', {}, this.selected_container);
|
||||
result_el.textContent = result.item.label;
|
||||
var close = L.DomUtil.element('span', {className: 'close'}, result_el);
|
||||
close.textContent = '×';
|
||||
L.DomEvent.on(close, 'click', function () {
|
||||
this.selected_container.removeChild(result_el);
|
||||
this.options.on_unselect(result);
|
||||
}, this);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
displaySelected: function (result) {
|
||||
var result_el = L.DomUtil.element('li', {}, this.selected_container)
|
||||
result_el.textContent = result.item.label
|
||||
var close = L.DomUtil.element('span', { className: 'close' }, result_el)
|
||||
close.textContent = '×'
|
||||
L.DomEvent.on(
|
||||
close,
|
||||
'click',
|
||||
function () {
|
||||
this.selected_container.removeChild(result_el)
|
||||
this.options.on_unselect(result)
|
||||
},
|
||||
this
|
||||
)
|
||||
this.hide()
|
||||
},
|
||||
})
|
||||
|
||||
L.U.AutoComplete.Ajax.Select = L.U.AutoComplete.Ajax.extend({
|
||||
initSelectedContainer: function () {
|
||||
return L.DomUtil.after(
|
||||
this.input,
|
||||
L.DomUtil.element('div', { className: 'umap-singleresult' })
|
||||
)
|
||||
},
|
||||
|
||||
initSelectedContainer: function () {
|
||||
return L.DomUtil.after(this.input, L.DomUtil.element('div', {className: 'umap-singleresult'}));
|
||||
},
|
||||
|
||||
displaySelected: function (result) {
|
||||
var result_el = L.DomUtil.element('div', {}, this.selected_container);
|
||||
result_el.textContent = result.item.label;
|
||||
var close = L.DomUtil.element('span', {className: 'close'}, result_el);
|
||||
close.textContent = '×';
|
||||
this.input.style.display = 'none';
|
||||
L.DomEvent.on(close, 'click', function () {
|
||||
this.selected_container.innerHTML = '';
|
||||
this.input.style.display = 'block';
|
||||
}, this);
|
||||
this.hide();
|
||||
}
|
||||
|
||||
});
|
||||
displaySelected: function (result) {
|
||||
var result_el = L.DomUtil.element('div', {}, this.selected_container)
|
||||
result_el.textContent = result.item.label
|
||||
var close = L.DomUtil.element('span', { className: 'close' }, result_el)
|
||||
close.textContent = '×'
|
||||
this.input.style.display = 'none'
|
||||
L.DomEvent.on(
|
||||
close,
|
||||
'click',
|
||||
function () {
|
||||
this.selected_container.innerHTML = ''
|
||||
this.input.style.display = 'block'
|
||||
},
|
||||
this
|
||||
)
|
||||
this.hide()
|
||||
},
|
||||
})
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,189 +1,199 @@
|
|||
L.U.Icon = L.DivIcon.extend({
|
||||
initialize: function(map, options) {
|
||||
this.map = map;
|
||||
var default_options = {
|
||||
iconSize: null, // Made in css
|
||||
iconUrl: this.map.getDefaultOption('iconUrl'),
|
||||
feature: null
|
||||
};
|
||||
options = L.Util.extend({}, default_options, options);
|
||||
L.Icon.prototype.initialize.call(this, options);
|
||||
this.feature = this.options.feature;
|
||||
if (this.feature && this.feature.isReadOnly()) {
|
||||
this.options.className += ' readonly';
|
||||
}
|
||||
},
|
||||
|
||||
_getIconUrl: function (name) {
|
||||
var url;
|
||||
if(this.feature && this.feature._getIconUrl(name)) url = this.feature._getIconUrl(name);
|
||||
else url = this.options[name + 'Url'];
|
||||
return this.formatUrl(url, this.feature);
|
||||
},
|
||||
|
||||
_getColor: function () {
|
||||
var color;
|
||||
if(this.feature) color = this.feature.getOption('color');
|
||||
else if (this.options.color) color = this.options.color;
|
||||
else color = this.map.getDefaultOption('color');
|
||||
return color;
|
||||
},
|
||||
|
||||
formatUrl: function (url, feature) {
|
||||
return L.Util.greedyTemplate(url || '', feature ? feature.extendedProperties() : {});
|
||||
initialize: function (map, options) {
|
||||
this.map = map
|
||||
var default_options = {
|
||||
iconSize: null, // Made in css
|
||||
iconUrl: this.map.getDefaultOption('iconUrl'),
|
||||
feature: null,
|
||||
}
|
||||
options = L.Util.extend({}, default_options, options)
|
||||
L.Icon.prototype.initialize.call(this, options)
|
||||
this.feature = this.options.feature
|
||||
if (this.feature && this.feature.isReadOnly()) {
|
||||
this.options.className += ' readonly'
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
_getIconUrl: function (name) {
|
||||
var url
|
||||
if (this.feature && this.feature._getIconUrl(name))
|
||||
url = this.feature._getIconUrl(name)
|
||||
else url = this.options[name + 'Url']
|
||||
return this.formatUrl(url, this.feature)
|
||||
},
|
||||
|
||||
_getColor: function () {
|
||||
var color
|
||||
if (this.feature) color = this.feature.getOption('color')
|
||||
else if (this.options.color) color = this.options.color
|
||||
else color = this.map.getDefaultOption('color')
|
||||
return color
|
||||
},
|
||||
|
||||
formatUrl: function (url, feature) {
|
||||
return L.Util.greedyTemplate(url || '', feature ? feature.extendedProperties() : {})
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Icon.Default = L.U.Icon.extend({
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(16, 40),
|
||||
popupAnchor: new L.Point(0, -40),
|
||||
tooltipAnchor: new L.Point(16, -24),
|
||||
className: 'umap-div-icon'
|
||||
},
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(16, 40),
|
||||
popupAnchor: new L.Point(0, -40),
|
||||
tooltipAnchor: new L.Point(16, -24),
|
||||
className: 'umap-div-icon',
|
||||
},
|
||||
|
||||
initialize: function(map, options) {
|
||||
options = L.Util.extend({}, this.default_options, options);
|
||||
L.U.Icon.prototype.initialize.call(this, map, options);
|
||||
},
|
||||
initialize: function (map, options) {
|
||||
options = L.Util.extend({}, this.default_options, options)
|
||||
L.U.Icon.prototype.initialize.call(this, map, options)
|
||||
},
|
||||
|
||||
_setColor: function() {
|
||||
var color = this._getColor();
|
||||
this.elements.container.style.backgroundColor = color;
|
||||
this.elements.arrow.style.borderTopColor = color;
|
||||
},
|
||||
_setColor: function () {
|
||||
var color = this._getColor()
|
||||
this.elements.container.style.backgroundColor = color
|
||||
this.elements.arrow.style.borderTopColor = color
|
||||
},
|
||||
|
||||
createIcon: function() {
|
||||
this.elements = {};
|
||||
this.elements.main = L.DomUtil.create('div');
|
||||
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
||||
var src = this._getIconUrl('icon');
|
||||
if (src) {
|
||||
// An url.
|
||||
if (src.indexOf('http') === 0 || src.indexOf('/') === 0 || src.indexOf('data:image') === 0) {
|
||||
this.elements.img = L.DomUtil.create('img', null, this.elements.container);
|
||||
this.elements.img.src = src;
|
||||
} else {
|
||||
this.elements.span = L.DomUtil.create('span', null, this.elements.container)
|
||||
this.elements.span.textContent = src;
|
||||
}
|
||||
}
|
||||
this._setColor();
|
||||
this._setIconStyles(this.elements.main, 'icon');
|
||||
return this.elements.main;
|
||||
createIcon: function () {
|
||||
this.elements = {}
|
||||
this.elements.main = L.DomUtil.create('div')
|
||||
this.elements.container = L.DomUtil.create(
|
||||
'div',
|
||||
'icon_container',
|
||||
this.elements.main
|
||||
)
|
||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main)
|
||||
var src = this._getIconUrl('icon')
|
||||
if (src) {
|
||||
// An url.
|
||||
if (
|
||||
src.indexOf('http') === 0 ||
|
||||
src.indexOf('/') === 0 ||
|
||||
src.indexOf('data:image') === 0
|
||||
) {
|
||||
this.elements.img = L.DomUtil.create('img', null, this.elements.container)
|
||||
this.elements.img.src = src
|
||||
} else {
|
||||
this.elements.span = L.DomUtil.create('span', null, this.elements.container)
|
||||
this.elements.span.textContent = src
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
this._setColor()
|
||||
this._setIconStyles(this.elements.main, 'icon')
|
||||
return this.elements.main
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Icon.Circle = L.U.Icon.extend({
|
||||
initialize: function(map, options) {
|
||||
var default_options = {
|
||||
iconAnchor: new L.Point(6, 6),
|
||||
popupAnchor: new L.Point(0, -6),
|
||||
tooltipAnchor: new L.Point(6, 0),
|
||||
className: 'umap-circle-icon'
|
||||
};
|
||||
options = L.Util.extend({}, default_options, options);
|
||||
L.U.Icon.prototype.initialize.call(this, map, options);
|
||||
},
|
||||
|
||||
_setColor: function() {
|
||||
this.elements.main.style.backgroundColor = this._getColor();
|
||||
},
|
||||
|
||||
createIcon: function() {
|
||||
this.elements = {};
|
||||
this.elements.main = L.DomUtil.create('div');
|
||||
this.elements.main.innerHTML = ' ';
|
||||
this._setColor();
|
||||
this._setIconStyles(this.elements.main, 'icon');
|
||||
return this.elements.main;
|
||||
initialize: function (map, options) {
|
||||
var default_options = {
|
||||
iconAnchor: new L.Point(6, 6),
|
||||
popupAnchor: new L.Point(0, -6),
|
||||
tooltipAnchor: new L.Point(6, 0),
|
||||
className: 'umap-circle-icon',
|
||||
}
|
||||
options = L.Util.extend({}, default_options, options)
|
||||
L.U.Icon.prototype.initialize.call(this, map, options)
|
||||
},
|
||||
|
||||
});
|
||||
_setColor: function () {
|
||||
this.elements.main.style.backgroundColor = this._getColor()
|
||||
},
|
||||
|
||||
createIcon: function () {
|
||||
this.elements = {}
|
||||
this.elements.main = L.DomUtil.create('div')
|
||||
this.elements.main.innerHTML = ' '
|
||||
this._setColor()
|
||||
this._setIconStyles(this.elements.main, 'icon')
|
||||
return this.elements.main
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Icon.Drop = L.U.Icon.Default.extend({
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(16, 42),
|
||||
popupAnchor: new L.Point(0, -42),
|
||||
tooltipAnchor: new L.Point(16, -24),
|
||||
className: 'umap-drop-icon'
|
||||
}
|
||||
});
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(16, 42),
|
||||
popupAnchor: new L.Point(0, -42),
|
||||
tooltipAnchor: new L.Point(16, -24),
|
||||
className: 'umap-drop-icon',
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Icon.Ball = L.U.Icon.Default.extend({
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(8, 30),
|
||||
popupAnchor: new L.Point(0, -28),
|
||||
tooltipAnchor: new L.Point(8, -23),
|
||||
className: 'umap-ball-icon'
|
||||
},
|
||||
default_options: {
|
||||
iconAnchor: new L.Point(8, 30),
|
||||
popupAnchor: new L.Point(0, -28),
|
||||
tooltipAnchor: new L.Point(8, -23),
|
||||
className: 'umap-ball-icon',
|
||||
},
|
||||
|
||||
createIcon: function() {
|
||||
this.elements = {};
|
||||
this.elements.main = L.DomUtil.create('div');
|
||||
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
||||
this._setColor();
|
||||
this._setIconStyles(this.elements.main, 'icon');
|
||||
return this.elements.main;
|
||||
},
|
||||
createIcon: function () {
|
||||
this.elements = {}
|
||||
this.elements.main = L.DomUtil.create('div')
|
||||
this.elements.container = L.DomUtil.create(
|
||||
'div',
|
||||
'icon_container',
|
||||
this.elements.main
|
||||
)
|
||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main)
|
||||
this._setColor()
|
||||
this._setIconStyles(this.elements.main, 'icon')
|
||||
return this.elements.main
|
||||
},
|
||||
|
||||
_setColor: function() {
|
||||
var color = this._getColor('color'),
|
||||
background;
|
||||
if (L.Browser.ielt9) {
|
||||
background = color;
|
||||
}
|
||||
else if (L.Browser.webkit) {
|
||||
background = '-webkit-gradient( radial, 6 38%, 0, 6 38%, 8, from(white), to(' + color + ') )';
|
||||
}
|
||||
else {
|
||||
background = 'radial-gradient(circle at 6px 38% , white -4px, ' + color + ' 8px) repeat scroll 0 0 transparent';
|
||||
}
|
||||
this.elements.container.style.background = background;
|
||||
_setColor: function () {
|
||||
var color = this._getColor('color'),
|
||||
background
|
||||
if (L.Browser.ielt9) {
|
||||
background = color
|
||||
} else if (L.Browser.webkit) {
|
||||
background =
|
||||
'-webkit-gradient( radial, 6 38%, 0, 6 38%, 8, from(white), to(' + color + ') )'
|
||||
} else {
|
||||
background =
|
||||
'radial-gradient(circle at 6px 38% , white -4px, ' +
|
||||
color +
|
||||
' 8px) repeat scroll 0 0 transparent'
|
||||
}
|
||||
this.elements.container.style.background = background
|
||||
},
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
var _CACHE_COLOR = {};
|
||||
var _CACHE_COLOR = {}
|
||||
L.U.Icon.Cluster = L.DivIcon.extend({
|
||||
options: {
|
||||
iconSize: [40, 40]
|
||||
},
|
||||
options: {
|
||||
iconSize: [40, 40],
|
||||
},
|
||||
|
||||
initialize: function (datalayer, cluster) {
|
||||
this.datalayer = datalayer;
|
||||
this.cluster = cluster;
|
||||
},
|
||||
initialize: function (datalayer, cluster) {
|
||||
this.datalayer = datalayer
|
||||
this.cluster = cluster
|
||||
},
|
||||
|
||||
createIcon: function () {
|
||||
var container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster'),
|
||||
div = L.DomUtil.create('div', '', container),
|
||||
span = L.DomUtil.create('span', '', div),
|
||||
backgroundColor = this.datalayer.getColor();
|
||||
span.textContent = this.cluster.getChildCount();
|
||||
div.style.backgroundColor = backgroundColor;
|
||||
return container;
|
||||
},
|
||||
createIcon: function () {
|
||||
var container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster'),
|
||||
div = L.DomUtil.create('div', '', container),
|
||||
span = L.DomUtil.create('span', '', div),
|
||||
backgroundColor = this.datalayer.getColor()
|
||||
span.textContent = this.cluster.getChildCount()
|
||||
div.style.backgroundColor = backgroundColor
|
||||
return container
|
||||
},
|
||||
|
||||
computeTextColor: function (el) {
|
||||
var color,
|
||||
backgroundColor = this.datalayer.getColor();
|
||||
if (this.datalayer.options.cluster && this.datalayer.options.cluster.textColor) {
|
||||
color = this.datalayer.options.cluster.textColor;
|
||||
}
|
||||
if (!color) {
|
||||
if (typeof _CACHE_COLOR[backgroundColor] === 'undefined') {
|
||||
color = L.DomUtil.TextColorFromBackgroundColor(el);
|
||||
_CACHE_COLOR[backgroundColor] = color;
|
||||
} else {
|
||||
color = _CACHE_COLOR[backgroundColor];
|
||||
}
|
||||
}
|
||||
return color;
|
||||
computeTextColor: function (el) {
|
||||
var color,
|
||||
backgroundColor = this.datalayer.getColor()
|
||||
if (this.datalayer.options.cluster && this.datalayer.options.cluster.textColor) {
|
||||
color = this.datalayer.options.cluster.textColor
|
||||
}
|
||||
|
||||
});
|
||||
if (!color) {
|
||||
if (typeof _CACHE_COLOR[backgroundColor] === 'undefined') {
|
||||
color = L.DomUtil.TextColorFromBackgroundColor(el)
|
||||
_CACHE_COLOR[backgroundColor] = color
|
||||
} else {
|
||||
color = _CACHE_COLOR[backgroundColor]
|
||||
}
|
||||
}
|
||||
return color
|
||||
},
|
||||
})
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,143 +1,196 @@
|
|||
// Dedicated object so we can deal with a separate dirty status, and thus
|
||||
// call the endpoint only when needed, saving one call at each save.
|
||||
L.U.MapPermissions = L.Class.extend({
|
||||
options: {
|
||||
owner: null,
|
||||
editors: [],
|
||||
share_status: null,
|
||||
edit_status: null,
|
||||
},
|
||||
|
||||
options: {
|
||||
owner: null,
|
||||
editors: [],
|
||||
share_status: null,
|
||||
edit_status: null
|
||||
},
|
||||
|
||||
initialize: function (map) {
|
||||
this.setOptions(map.options.permissions);
|
||||
this.map = map;
|
||||
var isDirty = false,
|
||||
self = this;
|
||||
try {
|
||||
Object.defineProperty(this, 'isDirty', {
|
||||
get: function () {
|
||||
return isDirty;
|
||||
},
|
||||
set: function (status) {
|
||||
isDirty = status;
|
||||
if (status) self.map.isDirty = status;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
setOptions: function (options) {
|
||||
this.options = L.Util.setOptions(this, options);
|
||||
},
|
||||
|
||||
isOwner: function () {
|
||||
return this.map.options.user && this.map.options.permissions.owner && this.map.options.user.id == this.map.options.permissions.owner.id;
|
||||
},
|
||||
|
||||
isAnonymousMap: function () {
|
||||
return !this.map.options.permissions.owner;
|
||||
},
|
||||
|
||||
getMap: function () {
|
||||
return this.map;
|
||||
},
|
||||
|
||||
edit: function () {
|
||||
if (!this.map.options.umap_id) return this.map.ui.alert({content: L._('Please save the map first'), level: 'info'});
|
||||
var container = L.DomUtil.create('div', 'permissions-panel'),
|
||||
fields = [],
|
||||
title = L.DomUtil.create('h4', '', container);
|
||||
if (this.isAnonymousMap()) {
|
||||
if (this.options.anonymous_edit_url) {
|
||||
var helpText = L._('Secret edit link is:<br>{link}', {link: this.options.anonymous_edit_url});
|
||||
fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.anonymous_edit_statuses, helpText: helpText}]);
|
||||
}
|
||||
} else {
|
||||
if (this.isOwner()) {
|
||||
fields.push(['options.edit_status', {handler: 'IntSelect', label: L._('Who can edit'), selectOptions: this.map.options.edit_statuses}]);
|
||||
fields.push(['options.share_status', {handler: 'IntSelect', label: L._('Who can view'), selectOptions: this.map.options.share_statuses}]);
|
||||
fields.push(['options.owner', {handler: 'ManageOwner', label: L._("Map's owner")}]);
|
||||
}
|
||||
fields.push(['options.editors', {handler: 'ManageEditors', label: L._("Map's editors")}]);
|
||||
}
|
||||
title.textContent = L._('Update permissions');
|
||||
var builder = new L.U.FormBuilder(this, fields);
|
||||
var form = builder.build();
|
||||
container.appendChild(form);
|
||||
if (this.isAnonymousMap() && this.map.options.user) {
|
||||
// We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
|
||||
// Note: real check is made on the back office anyway.
|
||||
var advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions'));
|
||||
var advancedButtons = L.DomUtil.create('div', 'button-bar', advancedActions);
|
||||
var download = L.DomUtil.create('a', 'button', advancedButtons);
|
||||
download.href = '#';
|
||||
download.textContent = L._('Attach the map to my account');
|
||||
L.DomEvent
|
||||
.on(download, 'click', L.DomEvent.stop)
|
||||
.on(download, 'click', this.attach, this);
|
||||
}
|
||||
this.map.ui.openPanel({data: {html: container}, className: 'dark'});
|
||||
},
|
||||
|
||||
attach: function () {
|
||||
this.map.post(this.getAttachUrl(), {
|
||||
callback: function () {
|
||||
this.options.owner = this.map.options.user;
|
||||
this.map.ui.alert({content: L._("Map has been attached to your account"), level: 'info'});
|
||||
this.map.ui.closePanel();
|
||||
},
|
||||
context: this
|
||||
})
|
||||
},
|
||||
|
||||
save: function () {
|
||||
if (!this.isDirty) return this.map.continueSaving();
|
||||
var formData = new FormData();
|
||||
if (!this.isAnonymousMap() && this.options.editors) {
|
||||
var editors = this.options.editors.map(function (u) {return u.id});
|
||||
for (var i = 0; i < this.options.editors.length; i++) formData.append('editors', this.options.editors[i].id);
|
||||
}
|
||||
if (this.isOwner() || this.isAnonymousMap()) formData.append('edit_status', this.options.edit_status);
|
||||
if (this.isOwner()) {
|
||||
formData.append('owner', this.options.owner && this.options.owner.id);
|
||||
formData.append('share_status', this.options.share_status);
|
||||
}
|
||||
this.map.post(this.getUrl(), {
|
||||
data: formData,
|
||||
context: this,
|
||||
callback: function (data) {
|
||||
this.commit();
|
||||
this.isDirty = false;
|
||||
this.map.continueSaving();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
getUrl: function () {
|
||||
return L.Util.template(this.map.options.urls.map_update_permissions, {'map_id': this.map.options.umap_id});
|
||||
},
|
||||
|
||||
getAttachUrl: function () {
|
||||
return L.Util.template(this.map.options.urls.map_attach_owner, {'map_id': this.map.options.umap_id});
|
||||
},
|
||||
|
||||
addOwnerLink: function (element, container) {
|
||||
if (this.options.owner && this.options.owner.name && this.options.owner.url) {
|
||||
var ownerContainer = L.DomUtil.add(element, 'umap-map-owner', container, ' ' + L._('by') + ' '),
|
||||
owner = L.DomUtil.create('a');
|
||||
owner.href = this.options.owner.url;
|
||||
owner.textContent = this.options.owner.name;
|
||||
ownerContainer.appendChild(owner);
|
||||
}
|
||||
},
|
||||
|
||||
commit: function () {
|
||||
L.Util.extend(this.map.options.permissions, this.options);
|
||||
initialize: function (map) {
|
||||
this.setOptions(map.options.permissions)
|
||||
this.map = map
|
||||
var isDirty = false,
|
||||
self = this
|
||||
try {
|
||||
Object.defineProperty(this, 'isDirty', {
|
||||
get: function () {
|
||||
return isDirty
|
||||
},
|
||||
set: function (status) {
|
||||
isDirty = status
|
||||
if (status) self.map.isDirty = status
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
setOptions: function (options) {
|
||||
this.options = L.Util.setOptions(this, options)
|
||||
},
|
||||
|
||||
isOwner: function () {
|
||||
return (
|
||||
this.map.options.user &&
|
||||
this.map.options.permissions.owner &&
|
||||
this.map.options.user.id == this.map.options.permissions.owner.id
|
||||
)
|
||||
},
|
||||
|
||||
isAnonymousMap: function () {
|
||||
return !this.map.options.permissions.owner
|
||||
},
|
||||
|
||||
getMap: function () {
|
||||
return this.map
|
||||
},
|
||||
|
||||
edit: function () {
|
||||
if (!this.map.options.umap_id)
|
||||
return this.map.ui.alert({
|
||||
content: L._('Please save the map first'),
|
||||
level: 'info',
|
||||
})
|
||||
var container = L.DomUtil.create('div', 'permissions-panel'),
|
||||
fields = [],
|
||||
title = L.DomUtil.create('h4', '', container)
|
||||
if (this.isAnonymousMap()) {
|
||||
if (this.options.anonymous_edit_url) {
|
||||
var helpText = L._('Secret edit link is:<br>{link}', {
|
||||
link: this.options.anonymous_edit_url,
|
||||
})
|
||||
fields.push([
|
||||
'options.edit_status',
|
||||
{
|
||||
handler: 'IntSelect',
|
||||
label: L._('Who can edit'),
|
||||
selectOptions: this.map.options.anonymous_edit_statuses,
|
||||
helpText: helpText,
|
||||
},
|
||||
])
|
||||
}
|
||||
} else {
|
||||
if (this.isOwner()) {
|
||||
fields.push([
|
||||
'options.edit_status',
|
||||
{
|
||||
handler: 'IntSelect',
|
||||
label: L._('Who can edit'),
|
||||
selectOptions: this.map.options.edit_statuses,
|
||||
},
|
||||
])
|
||||
fields.push([
|
||||
'options.share_status',
|
||||
{
|
||||
handler: 'IntSelect',
|
||||
label: L._('Who can view'),
|
||||
selectOptions: this.map.options.share_statuses,
|
||||
},
|
||||
])
|
||||
fields.push([
|
||||
'options.owner',
|
||||
{ handler: 'ManageOwner', label: L._("Map's owner") },
|
||||
])
|
||||
}
|
||||
fields.push([
|
||||
'options.editors',
|
||||
{ handler: 'ManageEditors', label: L._("Map's editors") },
|
||||
])
|
||||
}
|
||||
title.textContent = L._('Update permissions')
|
||||
var builder = new L.U.FormBuilder(this, fields)
|
||||
var form = builder.build()
|
||||
container.appendChild(form)
|
||||
if (this.isAnonymousMap() && this.map.options.user) {
|
||||
// We have a user, and this user has come through here, so they can edit the map, so let's allow to own the map.
|
||||
// Note: real check is made on the back office anyway.
|
||||
var advancedActions = L.DomUtil.createFieldset(container, L._('Advanced actions'))
|
||||
var advancedButtons = L.DomUtil.create('div', 'button-bar', advancedActions)
|
||||
var download = L.DomUtil.create('a', 'button', advancedButtons)
|
||||
download.href = '#'
|
||||
download.textContent = L._('Attach the map to my account')
|
||||
L.DomEvent.on(download, 'click', L.DomEvent.stop).on(
|
||||
download,
|
||||
'click',
|
||||
this.attach,
|
||||
this
|
||||
)
|
||||
}
|
||||
this.map.ui.openPanel({ data: { html: container }, className: 'dark' })
|
||||
},
|
||||
|
||||
attach: function () {
|
||||
this.map.post(this.getAttachUrl(), {
|
||||
callback: function () {
|
||||
this.options.owner = this.map.options.user
|
||||
this.map.ui.alert({
|
||||
content: L._('Map has been attached to your account'),
|
||||
level: 'info',
|
||||
})
|
||||
this.map.ui.closePanel()
|
||||
},
|
||||
context: this,
|
||||
})
|
||||
},
|
||||
|
||||
save: function () {
|
||||
if (!this.isDirty) return this.map.continueSaving()
|
||||
var formData = new FormData()
|
||||
if (!this.isAnonymousMap() && this.options.editors) {
|
||||
var editors = this.options.editors.map(function (u) {
|
||||
return u.id
|
||||
})
|
||||
for (var i = 0; i < this.options.editors.length; i++)
|
||||
formData.append('editors', this.options.editors[i].id)
|
||||
}
|
||||
if (this.isOwner() || this.isAnonymousMap())
|
||||
formData.append('edit_status', this.options.edit_status)
|
||||
if (this.isOwner()) {
|
||||
formData.append('owner', this.options.owner && this.options.owner.id)
|
||||
formData.append('share_status', this.options.share_status)
|
||||
}
|
||||
this.map.post(this.getUrl(), {
|
||||
data: formData,
|
||||
context: this,
|
||||
callback: function (data) {
|
||||
this.commit()
|
||||
this.isDirty = false
|
||||
this.map.continueSaving()
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
getUrl: function () {
|
||||
return L.Util.template(this.map.options.urls.map_update_permissions, {
|
||||
map_id: this.map.options.umap_id,
|
||||
})
|
||||
},
|
||||
|
||||
getAttachUrl: function () {
|
||||
return L.Util.template(this.map.options.urls.map_attach_owner, {
|
||||
map_id: this.map.options.umap_id,
|
||||
})
|
||||
},
|
||||
|
||||
addOwnerLink: function (element, container) {
|
||||
if (this.options.owner && this.options.owner.name && this.options.owner.url) {
|
||||
var ownerContainer = L.DomUtil.add(
|
||||
element,
|
||||
'umap-map-owner',
|
||||
container,
|
||||
' ' + L._('by') + ' '
|
||||
),
|
||||
owner = L.DomUtil.create('a')
|
||||
owner.href = this.options.owner.url
|
||||
owner.textContent = this.options.owner.name
|
||||
ownerContainer.appendChild(owner)
|
||||
}
|
||||
},
|
||||
|
||||
commit: function () {
|
||||
L.Util.extend(this.map.options.permissions, this.options)
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,224 +1,239 @@
|
|||
/* Shapes */
|
||||
|
||||
L.U.Popup = L.Popup.extend({
|
||||
options: {
|
||||
parseTemplate: true,
|
||||
},
|
||||
|
||||
options: {
|
||||
parseTemplate: true
|
||||
},
|
||||
initialize: function (feature) {
|
||||
this.feature = feature
|
||||
this.container = L.DomUtil.create('div', 'umap-popup')
|
||||
this.format()
|
||||
L.Popup.prototype.initialize.call(this, {}, feature)
|
||||
this.setContent(this.container)
|
||||
},
|
||||
|
||||
initialize: function (feature) {
|
||||
this.feature = feature;
|
||||
this.container = L.DomUtil.create('div', 'umap-popup');
|
||||
this.format();
|
||||
L.Popup.prototype.initialize.call(this, {}, feature);
|
||||
this.setContent(this.container);
|
||||
},
|
||||
|
||||
format: function () {
|
||||
var mode = this.feature.getOption('popupTemplate') || 'Default',
|
||||
klass = L.U.PopupTemplate[mode] || L.U.PopupTemplate.Default;
|
||||
this.content = new klass(this.feature, this.container);
|
||||
this.content.render();
|
||||
var els = this.container.querySelectorAll('img,iframe');
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
this.onElementLoaded(els[i]);
|
||||
}
|
||||
if (!els.length && this.container.textContent.replace('\n', '') === '') {
|
||||
this.container.innerHTML = '';
|
||||
L.DomUtil.add('h3', '', this.container, this.feature.getDisplayName());
|
||||
}
|
||||
},
|
||||
|
||||
onElementLoaded: function (el) {
|
||||
L.DomEvent.on(el, 'load', function () {
|
||||
this._updateLayout();
|
||||
this._updatePosition();
|
||||
this._adjustPan();
|
||||
}, this);
|
||||
format: function () {
|
||||
var mode = this.feature.getOption('popupTemplate') || 'Default',
|
||||
klass = L.U.PopupTemplate[mode] || L.U.PopupTemplate.Default
|
||||
this.content = new klass(this.feature, this.container)
|
||||
this.content.render()
|
||||
var els = this.container.querySelectorAll('img,iframe')
|
||||
for (var i = 0; i < els.length; i++) {
|
||||
this.onElementLoaded(els[i])
|
||||
}
|
||||
if (!els.length && this.container.textContent.replace('\n', '') === '') {
|
||||
this.container.innerHTML = ''
|
||||
L.DomUtil.add('h3', '', this.container, this.feature.getDisplayName())
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
onElementLoaded: function (el) {
|
||||
L.DomEvent.on(
|
||||
el,
|
||||
'load',
|
||||
function () {
|
||||
this._updateLayout()
|
||||
this._updatePosition()
|
||||
this._adjustPan()
|
||||
},
|
||||
this
|
||||
)
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Popup.Large = L.U.Popup.extend({
|
||||
options: {
|
||||
maxWidth: 500,
|
||||
className: 'umap-popup-large'
|
||||
}
|
||||
});
|
||||
|
||||
options: {
|
||||
maxWidth: 500,
|
||||
className: 'umap-popup-large',
|
||||
},
|
||||
})
|
||||
|
||||
L.U.Popup.Panel = L.U.Popup.extend({
|
||||
options: {
|
||||
zoomAnimation: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
zoomAnimation: false
|
||||
},
|
||||
allButton: function () {
|
||||
var button = L.DomUtil.create('li', '')
|
||||
L.DomUtil.create('i', 'umap-icon-16 umap-list', button)
|
||||
var label = L.DomUtil.create('span', '', button)
|
||||
label.textContent = label.title = L._('See all')
|
||||
L.DomEvent.on(button, 'click', this.feature.map.openBrowser, this.feature.map)
|
||||
return button
|
||||
},
|
||||
|
||||
allButton: function () {
|
||||
var button = L.DomUtil.create('li', '');
|
||||
L.DomUtil.create('i', 'umap-icon-16 umap-list', button);
|
||||
var label = L.DomUtil.create('span', '', button);
|
||||
label.textContent = label.title = L._('See all');
|
||||
L.DomEvent.on(button, 'click', this.feature.map.openBrowser, this.feature.map);
|
||||
return button;
|
||||
},
|
||||
update: function () {
|
||||
this.feature.map.ui.openPanel({
|
||||
data: { html: this._content },
|
||||
actions: [this.allButton()],
|
||||
})
|
||||
},
|
||||
|
||||
update: function () {
|
||||
this.feature.map.ui.openPanel({data: {html: this._content}, actions: [this.allButton()]});
|
||||
},
|
||||
onRemove: function (map) {
|
||||
map.ui.closePanel()
|
||||
L.U.Popup.prototype.onRemove.call(this, map)
|
||||
},
|
||||
|
||||
onRemove: function (map) {
|
||||
map.ui.closePanel();
|
||||
L.U.Popup.prototype.onRemove.call(this, map);
|
||||
},
|
||||
|
||||
_initLayout: function () {this._container = L.DomUtil.create('span');},
|
||||
_updateLayout: function () {},
|
||||
_updatePosition: function () {},
|
||||
_adjustPan: function () {}
|
||||
|
||||
});
|
||||
L.U.Popup.SimplePanel = L.U.Popup.Panel; // Retrocompat.
|
||||
_initLayout: function () {
|
||||
this._container = L.DomUtil.create('span')
|
||||
},
|
||||
_updateLayout: function () {},
|
||||
_updatePosition: function () {},
|
||||
_adjustPan: function () {},
|
||||
})
|
||||
L.U.Popup.SimplePanel = L.U.Popup.Panel // Retrocompat.
|
||||
|
||||
/* Content templates */
|
||||
|
||||
L.U.PopupTemplate = {};
|
||||
L.U.PopupTemplate = {}
|
||||
|
||||
L.U.PopupTemplate.Default = L.Class.extend({
|
||||
initialize: function (feature, container) {
|
||||
this.feature = feature
|
||||
this.container = container
|
||||
},
|
||||
|
||||
initialize: function (feature, container) {
|
||||
this.feature = feature;
|
||||
this.container = container;
|
||||
},
|
||||
renderTitle: function () {},
|
||||
|
||||
renderTitle: function () {},
|
||||
renderBody: function () {
|
||||
var template = this.feature.getOption('popupContentTemplate'),
|
||||
container = L.DomUtil.create('div', 'umap-popup-container'),
|
||||
content = '',
|
||||
properties,
|
||||
center
|
||||
properties = this.feature.extendedProperties()
|
||||
// Resolve properties inside description
|
||||
properties.description = L.Util.greedyTemplate(
|
||||
this.feature.properties.description || '',
|
||||
properties
|
||||
)
|
||||
content = L.Util.greedyTemplate(template, properties)
|
||||
content = L.Util.toHTML(content)
|
||||
container.innerHTML = content
|
||||
return container
|
||||
},
|
||||
|
||||
renderBody: function () {
|
||||
var template = this.feature.getOption('popupContentTemplate'),
|
||||
container = L.DomUtil.create('div', 'umap-popup-container'),
|
||||
content = '', properties, center;
|
||||
properties = this.feature.extendedProperties();
|
||||
// Resolve properties inside description
|
||||
properties.description = L.Util.greedyTemplate(this.feature.properties.description || '', properties);
|
||||
content = L.Util.greedyTemplate(template, properties);
|
||||
content = L.Util.toHTML(content);
|
||||
container.innerHTML = content;
|
||||
return container;
|
||||
},
|
||||
|
||||
renderFooter: function () {
|
||||
if (this.feature.hasPopupFooter()) {
|
||||
var footerContainer = L.DomUtil.create('div', 'umap-footer-container', this.container),
|
||||
footer = L.DomUtil.create('ul', 'umap-popup-footer', footerContainer),
|
||||
previousLi = L.DomUtil.create('li', 'previous', footer),
|
||||
zoomLi = L.DomUtil.create('li', 'zoom', footer),
|
||||
nextLi = L.DomUtil.create('li', 'next', footer),
|
||||
next = this.feature.getNext(),
|
||||
prev = this.feature.getPrevious();
|
||||
if (next) nextLi.title = L._('Go to «{feature}»', {feature: next.properties.name || L._('next')});
|
||||
if (prev) previousLi.title = L._('Go to «{feature}»', {feature: prev.properties.name || L._('previous')});
|
||||
zoomLi.title = L._('Zoom to this feature');
|
||||
L.DomEvent.on(nextLi, 'click', function () {
|
||||
if (next) next.zoomTo({callback: next.view});
|
||||
});
|
||||
L.DomEvent.on(previousLi, 'click', function () {
|
||||
if (prev) prev.zoomTo({callback: prev.view});
|
||||
});
|
||||
L.DomEvent.on(zoomLi, 'click', function () {
|
||||
this.zoomTo();
|
||||
}, this.feature);
|
||||
}
|
||||
},
|
||||
|
||||
render: function () {
|
||||
var title = this.renderTitle();
|
||||
if (title) this.container.appendChild(title);
|
||||
var body = this.renderBody();
|
||||
if (body) L.DomUtil.add('div', 'umap-popup-content', this.container, body);
|
||||
this.renderFooter();
|
||||
renderFooter: function () {
|
||||
if (this.feature.hasPopupFooter()) {
|
||||
var footerContainer = L.DomUtil.create(
|
||||
'div',
|
||||
'umap-footer-container',
|
||||
this.container
|
||||
),
|
||||
footer = L.DomUtil.create('ul', 'umap-popup-footer', footerContainer),
|
||||
previousLi = L.DomUtil.create('li', 'previous', footer),
|
||||
zoomLi = L.DomUtil.create('li', 'zoom', footer),
|
||||
nextLi = L.DomUtil.create('li', 'next', footer),
|
||||
next = this.feature.getNext(),
|
||||
prev = this.feature.getPrevious()
|
||||
if (next)
|
||||
nextLi.title = L._('Go to «{feature}»', {
|
||||
feature: next.properties.name || L._('next'),
|
||||
})
|
||||
if (prev)
|
||||
previousLi.title = L._('Go to «{feature}»', {
|
||||
feature: prev.properties.name || L._('previous'),
|
||||
})
|
||||
zoomLi.title = L._('Zoom to this feature')
|
||||
L.DomEvent.on(nextLi, 'click', function () {
|
||||
if (next) next.zoomTo({ callback: next.view })
|
||||
})
|
||||
L.DomEvent.on(previousLi, 'click', function () {
|
||||
if (prev) prev.zoomTo({ callback: prev.view })
|
||||
})
|
||||
L.DomEvent.on(
|
||||
zoomLi,
|
||||
'click',
|
||||
function () {
|
||||
this.zoomTo()
|
||||
},
|
||||
this.feature
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
render: function () {
|
||||
var title = this.renderTitle()
|
||||
if (title) this.container.appendChild(title)
|
||||
var body = this.renderBody()
|
||||
if (body) L.DomUtil.add('div', 'umap-popup-content', this.container, body)
|
||||
this.renderFooter()
|
||||
},
|
||||
})
|
||||
|
||||
L.U.PopupTemplate.BaseWithTitle = L.U.PopupTemplate.Default.extend({
|
||||
|
||||
renderTitle: function () {
|
||||
var title;
|
||||
if (this.feature.getDisplayName()) {
|
||||
title = L.DomUtil.create('h3', 'popup-title');
|
||||
title.textContent = this.feature.getDisplayName();
|
||||
}
|
||||
return title;
|
||||
renderTitle: function () {
|
||||
var title
|
||||
if (this.feature.getDisplayName()) {
|
||||
title = L.DomUtil.create('h3', 'popup-title')
|
||||
title.textContent = this.feature.getDisplayName()
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return title
|
||||
},
|
||||
})
|
||||
|
||||
L.U.PopupTemplate.Table = L.U.PopupTemplate.BaseWithTitle.extend({
|
||||
|
||||
formatRow: function (key, value) {
|
||||
if (value.indexOf('http') === 0) {
|
||||
value = '<a href="' + value + '" target="_blank">' + value + '</a>';
|
||||
}
|
||||
return value;
|
||||
},
|
||||
|
||||
addRow: function (container, key, value) {
|
||||
var tr = L.DomUtil.create('tr', '', container);
|
||||
L.DomUtil.add('th', '', tr, key);
|
||||
L.DomUtil.add('td', '', tr, this.formatRow(key, value));
|
||||
},
|
||||
|
||||
renderBody: function () {
|
||||
var table = L.DomUtil.create('table');
|
||||
|
||||
for (var key in this.feature.properties) {
|
||||
if (typeof this.feature.properties[key] === 'object' || key === 'name') continue;
|
||||
// TODO, manage links (url, mailto, wikipedia...)
|
||||
this.addRow(table, key, L.Util.escapeHTML(this.feature.properties[key]).trim());
|
||||
}
|
||||
return table;
|
||||
formatRow: function (key, value) {
|
||||
if (value.indexOf('http') === 0) {
|
||||
value = '<a href="' + value + '" target="_blank">' + value + '</a>'
|
||||
}
|
||||
return value
|
||||
},
|
||||
|
||||
});
|
||||
addRow: function (container, key, value) {
|
||||
var tr = L.DomUtil.create('tr', '', container)
|
||||
L.DomUtil.add('th', '', tr, key)
|
||||
L.DomUtil.add('td', '', tr, this.formatRow(key, value))
|
||||
},
|
||||
|
||||
renderBody: function () {
|
||||
var table = L.DomUtil.create('table')
|
||||
|
||||
for (var key in this.feature.properties) {
|
||||
if (typeof this.feature.properties[key] === 'object' || key === 'name') continue
|
||||
// TODO, manage links (url, mailto, wikipedia...)
|
||||
this.addRow(table, key, L.Util.escapeHTML(this.feature.properties[key]).trim())
|
||||
}
|
||||
return table
|
||||
},
|
||||
})
|
||||
|
||||
L.U.PopupTemplate.GeoRSSImage = L.U.PopupTemplate.BaseWithTitle.extend({
|
||||
options: {
|
||||
minWidth: 300,
|
||||
maxWidth: 500,
|
||||
className: 'umap-popup-large umap-georss-image',
|
||||
},
|
||||
|
||||
options: {
|
||||
minWidth: 300,
|
||||
maxWidth: 500,
|
||||
className: 'umap-popup-large umap-georss-image'
|
||||
},
|
||||
|
||||
renderBody: function () {
|
||||
var container = L.DomUtil.create('a');
|
||||
container.href = this.feature.properties.link;
|
||||
container.target = '_blank';
|
||||
if (this.feature.properties.img) {
|
||||
var img = L.DomUtil.create('img', '', container);
|
||||
img.src = this.feature.properties.img;
|
||||
// Sadly, we are unable to override this from JS the clean way
|
||||
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
|
||||
img.style.maxWidth = this.options.maxWidth + 'px';
|
||||
img.style.maxHeight = this.options.maxWidth + 'px';
|
||||
this.onElementLoaded(img);
|
||||
}
|
||||
return container;
|
||||
renderBody: function () {
|
||||
var container = L.DomUtil.create('a')
|
||||
container.href = this.feature.properties.link
|
||||
container.target = '_blank'
|
||||
if (this.feature.properties.img) {
|
||||
var img = L.DomUtil.create('img', '', container)
|
||||
img.src = this.feature.properties.img
|
||||
// Sadly, we are unable to override this from JS the clean way
|
||||
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
|
||||
img.style.maxWidth = this.options.maxWidth + 'px'
|
||||
img.style.maxHeight = this.options.maxWidth + 'px'
|
||||
this.onElementLoaded(img)
|
||||
}
|
||||
|
||||
});
|
||||
return container
|
||||
},
|
||||
})
|
||||
|
||||
L.U.PopupTemplate.GeoRSSLink = L.U.PopupTemplate.Default.extend({
|
||||
options: {
|
||||
className: 'umap-georss-link',
|
||||
},
|
||||
|
||||
options: {
|
||||
className: 'umap-georss-link'
|
||||
},
|
||||
|
||||
renderBody: function () {
|
||||
var title = this.renderTitle(this),
|
||||
a = L.DomUtil.add('a');
|
||||
a.href = this.feature.properties.link;
|
||||
a.target = '_blank';
|
||||
a.appendChild(title);
|
||||
return a;
|
||||
}
|
||||
});
|
||||
renderBody: function () {
|
||||
var title = this.renderTitle(this),
|
||||
a = L.DomUtil.add('a')
|
||||
a.href = this.feature.properties.link
|
||||
a.target = '_blank'
|
||||
a.appendChild(title)
|
||||
return a
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,164 +1,163 @@
|
|||
L.U.Slideshow = L.Class.extend({
|
||||
statics: {
|
||||
CLASSNAME: 'umap-slideshow-active',
|
||||
},
|
||||
|
||||
statics: {
|
||||
CLASSNAME: 'umap-slideshow-active'
|
||||
},
|
||||
options: {
|
||||
delay: 5000,
|
||||
autoplay: false,
|
||||
},
|
||||
|
||||
options: {
|
||||
delay: 5000,
|
||||
autoplay: false
|
||||
},
|
||||
|
||||
initialize: function (map, options) {
|
||||
this.setOptions(options);
|
||||
this.map = map;
|
||||
this._id = null;
|
||||
var current = null, // current feature
|
||||
self = this;
|
||||
try {
|
||||
Object.defineProperty(this, 'current', {
|
||||
get: function () {
|
||||
if (!current) {
|
||||
var datalayer = this.defaultDatalayer();
|
||||
if (datalayer) current = datalayer.getFeatureByIndex(0);
|
||||
}
|
||||
return current;
|
||||
},
|
||||
set: function (feature) {
|
||||
current = feature;
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
try {
|
||||
Object.defineProperty(this, 'next', {
|
||||
get: function () {
|
||||
if (!current) {
|
||||
return self.current;
|
||||
}
|
||||
return current.getNext();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
if (this.options.autoplay) {
|
||||
this.map.onceDataLoaded(function () {
|
||||
this.play();
|
||||
}, this);
|
||||
}
|
||||
this.map.on('edit:enabled', function () {
|
||||
this.stop();
|
||||
}, this);
|
||||
},
|
||||
|
||||
setOptions: function (options) {
|
||||
L.setOptions(this, options);
|
||||
this.timeSpinner();
|
||||
},
|
||||
|
||||
defaultDatalayer: function () {
|
||||
return this.map.findDataLayer(function (d) { return d.allowBrowse() && d.hasData(); });
|
||||
},
|
||||
|
||||
timeSpinner: function () {
|
||||
var time = parseInt(this.options.delay, 10);
|
||||
if (!time) return;
|
||||
var css = 'rotation ' + time / 1000 + 's infinite linear',
|
||||
spinners = document.querySelectorAll('.umap-slideshow-toolbox .play .spinner');
|
||||
for (var i = 0; i < spinners.length; i++) {
|
||||
spinners[i].style.animation = css;
|
||||
spinners[i].style['-webkit-animation'] = css;
|
||||
spinners[i].style['-moz-animation'] = css;
|
||||
spinners[i].style['-o-animation'] = css;
|
||||
}
|
||||
},
|
||||
|
||||
resetSpinners: function () {
|
||||
// Make that animnation is coordinated with user actions
|
||||
var spinners = document.querySelectorAll('.umap-slideshow-toolbox .play .spinner'),
|
||||
el, newOne;
|
||||
for (var i = 0; i < spinners.length; i++) {
|
||||
el = spinners[i];
|
||||
newOne = el.cloneNode(true);
|
||||
el.parentNode.replaceChild(newOne, el);
|
||||
}
|
||||
},
|
||||
|
||||
play: function () {
|
||||
if (this._id) return;
|
||||
if (this.map.editEnabled || !this.map.options.slideshow.active) return;
|
||||
L.DomUtil.addClass(document.body, L.U.Slideshow.CLASSNAME);
|
||||
this._id = window.setInterval(L.bind(this.loop, this), this.options.delay);
|
||||
this.resetSpinners();
|
||||
this.loop();
|
||||
},
|
||||
|
||||
loop: function () {
|
||||
this.current = this.next;
|
||||
this.step();
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
if (this._id) {
|
||||
L.DomUtil.removeClass(document.body, L.U.Slideshow.CLASSNAME);
|
||||
window.clearInterval(this._id);
|
||||
this._id = null;
|
||||
}
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
this.pause();
|
||||
this.current = null;
|
||||
},
|
||||
|
||||
forward: function () {
|
||||
this.pause();
|
||||
this.current = this.next;
|
||||
this.step();
|
||||
},
|
||||
|
||||
backward: function () {
|
||||
this.pause();
|
||||
if (this.current) this.current = this.current.getPrevious();
|
||||
this.step();
|
||||
},
|
||||
|
||||
step: function () {
|
||||
if(!this.current) return this.stop();
|
||||
this.current.zoomTo({easing: this.options.easing});
|
||||
this.current.view();
|
||||
},
|
||||
|
||||
renderToolbox: function (container) {
|
||||
var box = L.DomUtil.create('ul', 'umap-slideshow-toolbox'),
|
||||
play = L.DomUtil.create('li', 'play', box),
|
||||
stop = L.DomUtil.create('li', 'stop', box),
|
||||
prev = L.DomUtil.create('li', 'prev', box),
|
||||
next = L.DomUtil.create('li', 'next', box);
|
||||
L.DomUtil.create('div', 'spinner', play);
|
||||
play.title = L._('Start slideshow');
|
||||
stop.title = L._('Stop slideshow');
|
||||
next.title = L._('Zoom to the next');
|
||||
prev.title = L._('Zoom to the previous');
|
||||
var toggle = function () {
|
||||
if (this._id) this.pause();
|
||||
else this.play();
|
||||
};
|
||||
L.DomEvent.on(play, 'click', L.DomEvent.stop)
|
||||
.on(play, 'click', toggle, this);
|
||||
L.DomEvent.on(stop, 'click', L.DomEvent.stop)
|
||||
.on(stop, 'click', this.stop, this);
|
||||
L.DomEvent.on(prev, 'click', L.DomEvent.stop)
|
||||
.on(prev, 'click', this.backward, this);
|
||||
L.DomEvent.on(next, 'click', L.DomEvent.stop)
|
||||
.on(next, 'click', this.forward, this);
|
||||
container.appendChild(box);
|
||||
this.timeSpinner();
|
||||
return box;
|
||||
initialize: function (map, options) {
|
||||
this.setOptions(options)
|
||||
this.map = map
|
||||
this._id = null
|
||||
var current = null, // current feature
|
||||
self = this
|
||||
try {
|
||||
Object.defineProperty(this, 'current', {
|
||||
get: function () {
|
||||
if (!current) {
|
||||
var datalayer = this.defaultDatalayer()
|
||||
if (datalayer) current = datalayer.getFeatureByIndex(0)
|
||||
}
|
||||
return current
|
||||
},
|
||||
set: function (feature) {
|
||||
current = feature
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
try {
|
||||
Object.defineProperty(this, 'next', {
|
||||
get: function () {
|
||||
if (!current) {
|
||||
return self.current
|
||||
}
|
||||
return current.getNext()
|
||||
},
|
||||
})
|
||||
} catch (e) {
|
||||
// Certainly IE8, which has a limited version of defineProperty
|
||||
}
|
||||
if (this.options.autoplay) {
|
||||
this.map.onceDataLoaded(function () {
|
||||
this.play()
|
||||
}, this)
|
||||
}
|
||||
this.map.on(
|
||||
'edit:enabled',
|
||||
function () {
|
||||
this.stop()
|
||||
},
|
||||
this
|
||||
)
|
||||
},
|
||||
|
||||
});
|
||||
setOptions: function (options) {
|
||||
L.setOptions(this, options)
|
||||
this.timeSpinner()
|
||||
},
|
||||
|
||||
defaultDatalayer: function () {
|
||||
return this.map.findDataLayer(function (d) {
|
||||
return d.allowBrowse() && d.hasData()
|
||||
})
|
||||
},
|
||||
|
||||
timeSpinner: function () {
|
||||
var time = parseInt(this.options.delay, 10)
|
||||
if (!time) return
|
||||
var css = 'rotation ' + time / 1000 + 's infinite linear',
|
||||
spinners = document.querySelectorAll('.umap-slideshow-toolbox .play .spinner')
|
||||
for (var i = 0; i < spinners.length; i++) {
|
||||
spinners[i].style.animation = css
|
||||
spinners[i].style['-webkit-animation'] = css
|
||||
spinners[i].style['-moz-animation'] = css
|
||||
spinners[i].style['-o-animation'] = css
|
||||
}
|
||||
},
|
||||
|
||||
resetSpinners: function () {
|
||||
// Make that animnation is coordinated with user actions
|
||||
var spinners = document.querySelectorAll('.umap-slideshow-toolbox .play .spinner'),
|
||||
el,
|
||||
newOne
|
||||
for (var i = 0; i < spinners.length; i++) {
|
||||
el = spinners[i]
|
||||
newOne = el.cloneNode(true)
|
||||
el.parentNode.replaceChild(newOne, el)
|
||||
}
|
||||
},
|
||||
|
||||
play: function () {
|
||||
if (this._id) return
|
||||
if (this.map.editEnabled || !this.map.options.slideshow.active) return
|
||||
L.DomUtil.addClass(document.body, L.U.Slideshow.CLASSNAME)
|
||||
this._id = window.setInterval(L.bind(this.loop, this), this.options.delay)
|
||||
this.resetSpinners()
|
||||
this.loop()
|
||||
},
|
||||
|
||||
loop: function () {
|
||||
this.current = this.next
|
||||
this.step()
|
||||
},
|
||||
|
||||
pause: function () {
|
||||
if (this._id) {
|
||||
L.DomUtil.removeClass(document.body, L.U.Slideshow.CLASSNAME)
|
||||
window.clearInterval(this._id)
|
||||
this._id = null
|
||||
}
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
this.pause()
|
||||
this.current = null
|
||||
},
|
||||
|
||||
forward: function () {
|
||||
this.pause()
|
||||
this.current = this.next
|
||||
this.step()
|
||||
},
|
||||
|
||||
backward: function () {
|
||||
this.pause()
|
||||
if (this.current) this.current = this.current.getPrevious()
|
||||
this.step()
|
||||
},
|
||||
|
||||
step: function () {
|
||||
if (!this.current) return this.stop()
|
||||
this.current.zoomTo({ easing: this.options.easing })
|
||||
this.current.view()
|
||||
},
|
||||
|
||||
renderToolbox: function (container) {
|
||||
var box = L.DomUtil.create('ul', 'umap-slideshow-toolbox'),
|
||||
play = L.DomUtil.create('li', 'play', box),
|
||||
stop = L.DomUtil.create('li', 'stop', box),
|
||||
prev = L.DomUtil.create('li', 'prev', box),
|
||||
next = L.DomUtil.create('li', 'next', box)
|
||||
L.DomUtil.create('div', 'spinner', play)
|
||||
play.title = L._('Start slideshow')
|
||||
stop.title = L._('Stop slideshow')
|
||||
next.title = L._('Zoom to the next')
|
||||
prev.title = L._('Zoom to the previous')
|
||||
var toggle = function () {
|
||||
if (this._id) this.pause()
|
||||
else this.play()
|
||||
}
|
||||
L.DomEvent.on(play, 'click', L.DomEvent.stop).on(play, 'click', toggle, this)
|
||||
L.DomEvent.on(stop, 'click', L.DomEvent.stop).on(stop, 'click', this.stop, this)
|
||||
L.DomEvent.on(prev, 'click', L.DomEvent.stop).on(prev, 'click', this.backward, this)
|
||||
L.DomEvent.on(next, 'click', L.DomEvent.stop).on(next, 'click', this.forward, this)
|
||||
container.appendChild(box)
|
||||
this.timeSpinner()
|
||||
return box
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,107 +1,121 @@
|
|||
L.U.TableEditor = L.Class.extend({
|
||||
initialize: function (datalayer) {
|
||||
this.datalayer = datalayer
|
||||
this.table = L.DomUtil.create('div', 'table')
|
||||
this.header = L.DomUtil.create('div', 'thead', this.table)
|
||||
this.body = L.DomUtil.create('div', 'tbody', this.table)
|
||||
this.resetProperties()
|
||||
},
|
||||
|
||||
initialize: function (datalayer) {
|
||||
this.datalayer = datalayer;
|
||||
this.table = L.DomUtil.create('div', 'table');
|
||||
this.header = L.DomUtil.create('div', 'thead', this.table);
|
||||
this.body = L.DomUtil.create('div', 'tbody', this.table);
|
||||
this.resetProperties();
|
||||
},
|
||||
|
||||
renderHeaders: function () {
|
||||
this.header.innerHTML = '';
|
||||
for (var i = 0; i < this.properties.length; i++) {
|
||||
this.renderHeader(this.properties[i]);
|
||||
}
|
||||
},
|
||||
|
||||
renderHeader: function (property) {
|
||||
var container = L.DomUtil.create('div', 'tcell', this.header),
|
||||
title = L.DomUtil.add('span', '', container, property),
|
||||
del = L.DomUtil.create('i', 'umap-delete', container),
|
||||
rename = L.DomUtil.create('i', 'umap-edit', container);
|
||||
del.title = L._('Delete this property on all the features');
|
||||
rename.title = L._('Rename this property on all the features');
|
||||
var doDelete = function () {
|
||||
if (confirm(L._('Are you sure you want to delete this property on all the features?'))) {
|
||||
this.datalayer.eachLayer(function (feature) {
|
||||
feature.deleteProperty(property);
|
||||
});
|
||||
this.datalayer.deindexProperty(property);
|
||||
this.resetProperties();
|
||||
this.edit();
|
||||
}
|
||||
};
|
||||
var doRename = function () {
|
||||
var newName = prompt(L._('Please enter the new name of this property'), property);
|
||||
if (!newName || !this.validateName(newName)) return;
|
||||
this.datalayer.eachLayer(function (feature) {
|
||||
feature.renameProperty(property, newName);
|
||||
});
|
||||
this.datalayer.deindexProperty(property);
|
||||
this.datalayer.indexProperty(newName);
|
||||
this.resetProperties();
|
||||
this.edit();
|
||||
};
|
||||
L.DomEvent.on(del, 'click', doDelete, this);
|
||||
L.DomEvent.on(rename, 'click', doRename, this);
|
||||
},
|
||||
|
||||
renderRow: function (feature) {
|
||||
var builder = new L.U.FormBuilder(feature, this.field_properties,
|
||||
{
|
||||
id: 'umap-feature-properties_' + L.stamp(feature),
|
||||
className: 'trow',
|
||||
callback: feature.resetTooltip
|
||||
}
|
||||
);
|
||||
this.body.appendChild(builder.build());
|
||||
},
|
||||
|
||||
compileProperties: function () {
|
||||
if (this.properties.length === 0) this.properties = ['name'];
|
||||
// description is a forced textarea, don't edit it in a text input, or you lose cariage returns
|
||||
if (this.properties.indexOf('description') !== -1) this.properties.splice(this.properties.indexOf('description'), 1);
|
||||
this.properties.sort();
|
||||
this.field_properties = [];
|
||||
for (var i = 0; i < this.properties.length; i++) {
|
||||
this.field_properties.push(['properties.' + this.properties[i], {wrapper: 'div', wrapperClass: 'tcell'}]);
|
||||
}
|
||||
},
|
||||
|
||||
resetProperties: function () {
|
||||
this.properties = this.datalayer._propertiesIndex;
|
||||
},
|
||||
|
||||
validateName: function (name) {
|
||||
if (name.indexOf(".") !== -1) {
|
||||
this.datalayer.map.ui.alert({content: L._('Invalide property name: {name}', {name: name}), level: 'error'});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
edit: function () {
|
||||
var id = 'tableeditor:edit';
|
||||
this.datalayer.map.fire('dataloading', {id: id});
|
||||
this.compileProperties();
|
||||
this.renderHeaders();
|
||||
this.body.innerHTML = '';
|
||||
this.datalayer.eachLayer(this.renderRow, this);
|
||||
var addButton = L.DomUtil.create('li', 'add-property');
|
||||
L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton);
|
||||
var label = L.DomUtil.create('span', '', addButton);
|
||||
label.textContent = label.title = L._('Add a new property');
|
||||
var addProperty = function () {
|
||||
var newName = prompt(L._('Please enter the name of the property'));
|
||||
if (!newName || !this.validateName(newName)) return;
|
||||
this.datalayer.indexProperty(newName);
|
||||
this.edit();
|
||||
};
|
||||
L.DomEvent.on(addButton, 'click', addProperty, this);
|
||||
var className = (this.properties.length > 2) ? 'umap-table-editor fullwidth dark' : 'umap-table-editor dark';
|
||||
this.datalayer.map.ui.openPanel({data: {html: this.table}, className: className, actions: [addButton]});
|
||||
this.datalayer.map.fire('dataload', {id: id});
|
||||
renderHeaders: function () {
|
||||
this.header.innerHTML = ''
|
||||
for (var i = 0; i < this.properties.length; i++) {
|
||||
this.renderHeader(this.properties[i])
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
renderHeader: function (property) {
|
||||
var container = L.DomUtil.create('div', 'tcell', this.header),
|
||||
title = L.DomUtil.add('span', '', container, property),
|
||||
del = L.DomUtil.create('i', 'umap-delete', container),
|
||||
rename = L.DomUtil.create('i', 'umap-edit', container)
|
||||
del.title = L._('Delete this property on all the features')
|
||||
rename.title = L._('Rename this property on all the features')
|
||||
var doDelete = function () {
|
||||
if (
|
||||
confirm(
|
||||
L._('Are you sure you want to delete this property on all the features?')
|
||||
)
|
||||
) {
|
||||
this.datalayer.eachLayer(function (feature) {
|
||||
feature.deleteProperty(property)
|
||||
})
|
||||
this.datalayer.deindexProperty(property)
|
||||
this.resetProperties()
|
||||
this.edit()
|
||||
}
|
||||
}
|
||||
var doRename = function () {
|
||||
var newName = prompt(L._('Please enter the new name of this property'), property)
|
||||
if (!newName || !this.validateName(newName)) return
|
||||
this.datalayer.eachLayer(function (feature) {
|
||||
feature.renameProperty(property, newName)
|
||||
})
|
||||
this.datalayer.deindexProperty(property)
|
||||
this.datalayer.indexProperty(newName)
|
||||
this.resetProperties()
|
||||
this.edit()
|
||||
}
|
||||
L.DomEvent.on(del, 'click', doDelete, this)
|
||||
L.DomEvent.on(rename, 'click', doRename, this)
|
||||
},
|
||||
|
||||
renderRow: function (feature) {
|
||||
var builder = new L.U.FormBuilder(feature, this.field_properties, {
|
||||
id: 'umap-feature-properties_' + L.stamp(feature),
|
||||
className: 'trow',
|
||||
callback: feature.resetTooltip,
|
||||
})
|
||||
this.body.appendChild(builder.build())
|
||||
},
|
||||
|
||||
compileProperties: function () {
|
||||
if (this.properties.length === 0) this.properties = ['name']
|
||||
// description is a forced textarea, don't edit it in a text input, or you lose cariage returns
|
||||
if (this.properties.indexOf('description') !== -1)
|
||||
this.properties.splice(this.properties.indexOf('description'), 1)
|
||||
this.properties.sort()
|
||||
this.field_properties = []
|
||||
for (var i = 0; i < this.properties.length; i++) {
|
||||
this.field_properties.push([
|
||||
'properties.' + this.properties[i],
|
||||
{ wrapper: 'div', wrapperClass: 'tcell' },
|
||||
])
|
||||
}
|
||||
},
|
||||
|
||||
resetProperties: function () {
|
||||
this.properties = this.datalayer._propertiesIndex
|
||||
},
|
||||
|
||||
validateName: function (name) {
|
||||
if (name.indexOf('.') !== -1) {
|
||||
this.datalayer.map.ui.alert({
|
||||
content: L._('Invalide property name: {name}', { name: name }),
|
||||
level: 'error',
|
||||
})
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
|
||||
edit: function () {
|
||||
var id = 'tableeditor:edit'
|
||||
this.datalayer.map.fire('dataloading', { id: id })
|
||||
this.compileProperties()
|
||||
this.renderHeaders()
|
||||
this.body.innerHTML = ''
|
||||
this.datalayer.eachLayer(this.renderRow, this)
|
||||
var addButton = L.DomUtil.create('li', 'add-property')
|
||||
L.DomUtil.create('i', 'umap-icon-16 umap-add', addButton)
|
||||
var label = L.DomUtil.create('span', '', addButton)
|
||||
label.textContent = label.title = L._('Add a new property')
|
||||
var addProperty = function () {
|
||||
var newName = prompt(L._('Please enter the name of the property'))
|
||||
if (!newName || !this.validateName(newName)) return
|
||||
this.datalayer.indexProperty(newName)
|
||||
this.edit()
|
||||
}
|
||||
L.DomEvent.on(addButton, 'click', addProperty, this)
|
||||
var className =
|
||||
this.properties.length > 2
|
||||
? 'umap-table-editor fullwidth dark'
|
||||
: 'umap-table-editor dark'
|
||||
this.datalayer.map.ui.openPanel({
|
||||
data: { html: this.table },
|
||||
className: className,
|
||||
actions: [addButton],
|
||||
})
|
||||
this.datalayer.map.fire('dataload', { id: id })
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,176 +1,209 @@
|
|||
/*
|
||||
* Modals
|
||||
*/
|
||||
* Modals
|
||||
*/
|
||||
L.U.UI = L.Evented.extend({
|
||||
ALERTS: Array(),
|
||||
ALERT_ID: null,
|
||||
TOOLTIP_ID: null,
|
||||
|
||||
ALERTS: Array(),
|
||||
ALERT_ID: null,
|
||||
TOOLTIP_ID: null,
|
||||
initialize: function (parent) {
|
||||
this.parent = parent
|
||||
this.container = L.DomUtil.create('div', 'leaflet-ui-container', this.parent)
|
||||
L.DomEvent.disableClickPropagation(this.container)
|
||||
L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation) // Do not activate our custom context menu.
|
||||
L.DomEvent.on(this.container, 'mousewheel', L.DomEvent.stopPropagation)
|
||||
L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation)
|
||||
this._panel = L.DomUtil.create('div', '', this.container)
|
||||
this._panel.id = 'umap-ui-container'
|
||||
this._alert = L.DomUtil.create('div', 'with-transition', this.container)
|
||||
this._alert.id = 'umap-alert-container'
|
||||
this._tooltip = L.DomUtil.create('div', '', this.container)
|
||||
this._tooltip.id = 'umap-tooltip-container'
|
||||
},
|
||||
|
||||
initialize: function (parent) {
|
||||
this.parent = parent;
|
||||
this.container = L.DomUtil.create('div', 'leaflet-ui-container', this.parent);
|
||||
L.DomEvent.disableClickPropagation(this.container);
|
||||
L.DomEvent.on(this.container, 'contextmenu', L.DomEvent.stopPropagation); // Do not activate our custom context menu.
|
||||
L.DomEvent.on(this.container, 'mousewheel', L.DomEvent.stopPropagation);
|
||||
L.DomEvent.on(this.container, 'MozMousePixelScroll', L.DomEvent.stopPropagation);
|
||||
this._panel = L.DomUtil.create('div', '', this.container);
|
||||
this._panel.id = 'umap-ui-container';
|
||||
this._alert = L.DomUtil.create('div', 'with-transition', this.container);
|
||||
this._alert.id = 'umap-alert-container';
|
||||
this._tooltip = L.DomUtil.create('div', '', this.container);
|
||||
this._tooltip.id = 'umap-tooltip-container';
|
||||
},
|
||||
resetPanelClassName: function () {
|
||||
this._panel.className = 'with-transition'
|
||||
},
|
||||
|
||||
resetPanelClassName: function () {
|
||||
this._panel.className = 'with-transition';
|
||||
},
|
||||
openPanel: function (e) {
|
||||
this.fire('panel:open')
|
||||
// We reset all because we can't know which class has been added
|
||||
// by previous ui processes...
|
||||
this.resetPanelClassName()
|
||||
this._panel.innerHTML = ''
|
||||
var actionsContainer = L.DomUtil.create('ul', 'toolbox', this._panel)
|
||||
var body = L.DomUtil.create('div', 'body', this._panel)
|
||||
if (e.data.html.nodeType && e.data.html.nodeType === 1)
|
||||
body.appendChild(e.data.html)
|
||||
else body.innerHTML = e.data.html
|
||||
var closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer)
|
||||
L.DomUtil.add('i', 'umap-close-icon', closeLink)
|
||||
var label = L.DomUtil.create('span', '', closeLink)
|
||||
label.title = label.textContent = L._('Close')
|
||||
if (e.actions) {
|
||||
for (var i = 0; i < e.actions.length; i++) {
|
||||
actionsContainer.appendChild(e.actions[i])
|
||||
}
|
||||
}
|
||||
if (e.className) L.DomUtil.addClass(this._panel, e.className)
|
||||
if (L.DomUtil.hasClass(this.parent, 'umap-ui')) {
|
||||
// Already open.
|
||||
this.fire('panel:ready')
|
||||
} else {
|
||||
L.DomEvent.once(
|
||||
this._panel,
|
||||
'transitionend',
|
||||
function (e) {
|
||||
this.fire('panel:ready')
|
||||
},
|
||||
this
|
||||
)
|
||||
L.DomUtil.addClass(this.parent, 'umap-ui')
|
||||
}
|
||||
L.DomEvent.on(closeLink, 'click', this.closePanel, this)
|
||||
},
|
||||
|
||||
openPanel: function (e) {
|
||||
this.fire('panel:open');
|
||||
// We reset all because we can't know which class has been added
|
||||
// by previous ui processes...
|
||||
this.resetPanelClassName();
|
||||
this._panel.innerHTML = '';
|
||||
var actionsContainer = L.DomUtil.create('ul', 'toolbox', this._panel);
|
||||
var body = L.DomUtil.create('div', 'body', this._panel);
|
||||
if (e.data.html.nodeType && e.data.html.nodeType === 1) body.appendChild(e.data.html);
|
||||
else body.innerHTML = e.data.html;
|
||||
var closeLink = L.DomUtil.create('li', 'umap-close-link', actionsContainer);
|
||||
L.DomUtil.add('i', 'umap-close-icon', closeLink);
|
||||
var label = L.DomUtil.create('span', '', closeLink);
|
||||
label.title = label.textContent = L._('Close');
|
||||
if (e.actions) {
|
||||
for (var i = 0; i < e.actions.length; i++) {
|
||||
actionsContainer.appendChild(e.actions[i]);
|
||||
}
|
||||
}
|
||||
if (e.className) L.DomUtil.addClass(this._panel, e.className);
|
||||
if (L.DomUtil.hasClass(this.parent, 'umap-ui')) {
|
||||
// Already open.
|
||||
this.fire('panel:ready');
|
||||
} else {
|
||||
L.DomEvent.once(this._panel, 'transitionend', function (e) {
|
||||
this.fire('panel:ready');
|
||||
}, this);
|
||||
L.DomUtil.addClass(this.parent, 'umap-ui');
|
||||
}
|
||||
L.DomEvent.on(closeLink, 'click', this.closePanel, this);
|
||||
},
|
||||
closePanel: function () {
|
||||
this.resetPanelClassName()
|
||||
L.DomUtil.removeClass(this.parent, 'umap-ui')
|
||||
this.fire('panel:closed')
|
||||
},
|
||||
|
||||
closePanel: function () {
|
||||
this.resetPanelClassName();
|
||||
L.DomUtil.removeClass(this.parent, 'umap-ui');
|
||||
this.fire('panel:closed');
|
||||
},
|
||||
alert: function (e) {
|
||||
if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e)
|
||||
else this.popAlert(e)
|
||||
},
|
||||
|
||||
alert: function (e) {
|
||||
if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e);
|
||||
else this.popAlert(e);
|
||||
},
|
||||
popAlert: function (e) {
|
||||
var self = this
|
||||
if (!e) {
|
||||
if (this.ALERTS.length) e = this.ALERTS.pop()
|
||||
else return
|
||||
}
|
||||
var timeoutID,
|
||||
level_class = e.level && e.level == 'info' ? 'info' : 'error'
|
||||
this._alert.innerHTML = ''
|
||||
L.DomUtil.addClass(this.parent, 'umap-alert')
|
||||
L.DomUtil.addClass(this._alert, level_class)
|
||||
var close = function () {
|
||||
if (timeoutID !== this.ALERT_ID) {
|
||||
return
|
||||
} // Another alert has been forced
|
||||
this._alert.innerHTML = ''
|
||||
L.DomUtil.removeClass(this.parent, 'umap-alert')
|
||||
L.DomUtil.removeClass(this._alert, level_class)
|
||||
if (timeoutID) window.clearTimeout(timeoutID)
|
||||
this.popAlert()
|
||||
}
|
||||
var closeLink = L.DomUtil.create('a', 'umap-close-link', this._alert)
|
||||
closeLink.href = '#'
|
||||
L.DomUtil.add('i', 'umap-close-icon', closeLink)
|
||||
var label = L.DomUtil.create('span', '', closeLink)
|
||||
label.title = label.textContent = L._('Close')
|
||||
L.DomEvent.on(closeLink, 'click', L.DomEvent.stop).on(
|
||||
closeLink,
|
||||
'click',
|
||||
close,
|
||||
this
|
||||
)
|
||||
L.DomUtil.add('div', '', this._alert, e.content)
|
||||
if (e.actions) {
|
||||
var action, el
|
||||
for (var i = 0; i < e.actions.length; i++) {
|
||||
action = e.actions[i]
|
||||
el = L.DomUtil.element('a', { className: 'umap-action' }, this._alert)
|
||||
el.href = '#'
|
||||
el.textContent = action.label
|
||||
L.DomEvent.on(el, 'click', L.DomEvent.stop).on(el, 'click', close, this)
|
||||
if (action.callback)
|
||||
L.DomEvent.on(
|
||||
el,
|
||||
'click',
|
||||
action.callback,
|
||||
action.callbackContext || this.map
|
||||
)
|
||||
}
|
||||
}
|
||||
self.ALERT_ID = timeoutID = window.setTimeout(
|
||||
L.bind(close, this),
|
||||
e.duration || 3000
|
||||
)
|
||||
},
|
||||
|
||||
popAlert: function (e) {
|
||||
var self = this;
|
||||
if(!e) {
|
||||
if (this.ALERTS.length) e = this.ALERTS.pop();
|
||||
else return;
|
||||
}
|
||||
var timeoutID,
|
||||
level_class = e.level && e.level == 'info'? 'info': 'error';
|
||||
this._alert.innerHTML = '';
|
||||
L.DomUtil.addClass(this.parent, 'umap-alert');
|
||||
L.DomUtil.addClass(this._alert, level_class);
|
||||
var close = function () {
|
||||
if (timeoutID !== this.ALERT_ID) { return;} // Another alert has been forced
|
||||
this._alert.innerHTML = '';
|
||||
L.DomUtil.removeClass(this.parent, 'umap-alert');
|
||||
L.DomUtil.removeClass(this._alert, level_class);
|
||||
if (timeoutID) window.clearTimeout(timeoutID);
|
||||
this.popAlert();
|
||||
};
|
||||
var closeLink = L.DomUtil.create('a', 'umap-close-link', this._alert);
|
||||
closeLink.href = '#';
|
||||
L.DomUtil.add('i', 'umap-close-icon', closeLink);
|
||||
var label = L.DomUtil.create('span', '', closeLink);
|
||||
label.title = label.textContent = L._('Close');
|
||||
L.DomEvent.on(closeLink, 'click', L.DomEvent.stop)
|
||||
.on(closeLink, 'click', close, this);
|
||||
L.DomUtil.add('div', '', this._alert, e.content);
|
||||
if (e.actions) {
|
||||
var action, el;
|
||||
for (var i = 0; i < e.actions.length; i++) {
|
||||
action = e.actions[i];
|
||||
el = L.DomUtil.element('a', {'className': 'umap-action'}, this._alert);
|
||||
el.href = '#';
|
||||
el.textContent = action.label;
|
||||
L.DomEvent.on(el, 'click', L.DomEvent.stop)
|
||||
.on(el, 'click', close, this);
|
||||
if (action.callback) L.DomEvent.on(el, 'click', action.callback, action.callbackContext || this.map);
|
||||
}
|
||||
}
|
||||
self.ALERT_ID = timeoutID = window.setTimeout(L.bind(close, this), e.duration || 3000);
|
||||
},
|
||||
tooltip: function (e) {
|
||||
this.TOOLTIP_ID = Math.random()
|
||||
var id = this.TOOLTIP_ID
|
||||
L.DomUtil.addClass(this.parent, 'umap-tooltip')
|
||||
if (e.anchor && e.position === 'top') this.anchorTooltipTop(e.anchor)
|
||||
else if (e.anchor && e.position === 'left') this.anchorTooltipLeft(e.anchor)
|
||||
else this.anchorTooltipAbsolute()
|
||||
this._tooltip.innerHTML = e.content
|
||||
function closeIt() {
|
||||
this.closeTooltip(id)
|
||||
}
|
||||
if (e.anchor) L.DomEvent.once(e.anchor, 'mouseout', closeIt, this)
|
||||
if (e.duration !== Infinity)
|
||||
window.setTimeout(L.bind(closeIt, this), e.duration || 3000)
|
||||
},
|
||||
|
||||
tooltip: function (e) {
|
||||
this.TOOLTIP_ID = Math.random();
|
||||
var id = this.TOOLTIP_ID;
|
||||
L.DomUtil.addClass(this.parent, 'umap-tooltip');
|
||||
if (e.anchor && e.position === 'top') this.anchorTooltipTop(e.anchor);
|
||||
else if (e.anchor && e.position === 'left') this.anchorTooltipLeft(e.anchor);
|
||||
else this.anchorTooltipAbsolute();
|
||||
this._tooltip.innerHTML = e.content;
|
||||
function closeIt () { this.closeTooltip(id); }
|
||||
if (e.anchor) L.DomEvent.once(e.anchor, 'mouseout', closeIt, this);
|
||||
if (e.duration !== Infinity) window.setTimeout(L.bind(closeIt, this), e.duration || 3000);
|
||||
},
|
||||
anchorTooltipAbsolute: function () {
|
||||
this._tooltip.className = ''
|
||||
var left =
|
||||
this.parent.offsetLeft +
|
||||
this.parent.clientWidth / 2 -
|
||||
this._tooltip.clientWidth / 2,
|
||||
top = this.parent.offsetTop + 75
|
||||
this.setTooltipPosition({ top: top, left: left })
|
||||
},
|
||||
|
||||
anchorTooltipAbsolute: function () {
|
||||
this._tooltip.className = '';
|
||||
var left = this.parent.offsetLeft + (this.parent.clientWidth / 2) - (this._tooltip.clientWidth / 2),
|
||||
top = this.parent.offsetTop + 75;
|
||||
this.setTooltipPosition({top: top, left: left});
|
||||
},
|
||||
anchorTooltipTop: function (el) {
|
||||
this._tooltip.className = 'tooltip-top'
|
||||
var coords = this.getPosition(el)
|
||||
this.setTooltipPosition({
|
||||
left: coords.left - 10,
|
||||
bottom: this.getDocHeight() - coords.top + 11,
|
||||
})
|
||||
},
|
||||
|
||||
anchorTooltipTop: function (el) {
|
||||
this._tooltip.className = 'tooltip-top';
|
||||
var coords = this.getPosition(el);
|
||||
this.setTooltipPosition({left: coords.left - 10, bottom: this.getDocHeight() - coords.top + 11});
|
||||
},
|
||||
anchorTooltipLeft: function (el) {
|
||||
this._tooltip.className = 'tooltip-left'
|
||||
var coords = this.getPosition(el)
|
||||
this.setTooltipPosition({
|
||||
top: coords.top,
|
||||
right: document.documentElement.offsetWidth - coords.left + 11,
|
||||
})
|
||||
},
|
||||
|
||||
anchorTooltipLeft: function (el) {
|
||||
this._tooltip.className = 'tooltip-left';
|
||||
var coords = this.getPosition(el);
|
||||
this.setTooltipPosition({top: coords.top, right: document.documentElement.offsetWidth - coords.left + 11});
|
||||
},
|
||||
closeTooltip: function (id) {
|
||||
if (id && id !== this.TOOLTIP_ID) return
|
||||
this._tooltip.innerHTML = ''
|
||||
L.DomUtil.removeClass(this.parent, 'umap-tooltip')
|
||||
},
|
||||
|
||||
closeTooltip: function (id) {
|
||||
if (id && id !== this.TOOLTIP_ID) return;
|
||||
this._tooltip.innerHTML = '';
|
||||
L.DomUtil.removeClass(this.parent, 'umap-tooltip');
|
||||
},
|
||||
getPosition: function (el) {
|
||||
return el.getBoundingClientRect()
|
||||
},
|
||||
|
||||
getPosition: function (el) {
|
||||
return el.getBoundingClientRect();
|
||||
},
|
||||
setTooltipPosition: function (coords) {
|
||||
if (coords.left) this._tooltip.style.left = coords.left + 'px'
|
||||
else this._tooltip.style.left = 'initial'
|
||||
if (coords.right) this._tooltip.style.right = coords.right + 'px'
|
||||
else this._tooltip.style.right = 'initial'
|
||||
if (coords.top) this._tooltip.style.top = coords.top + 'px'
|
||||
else this._tooltip.style.top = 'initial'
|
||||
if (coords.bottom) this._tooltip.style.bottom = coords.bottom + 'px'
|
||||
else this._tooltip.style.bottom = 'initial'
|
||||
},
|
||||
|
||||
setTooltipPosition: function (coords) {
|
||||
if (coords.left) this._tooltip.style.left = coords.left + 'px';
|
||||
else this._tooltip.style.left = 'initial';
|
||||
if (coords.right) this._tooltip.style.right = coords.right + 'px';
|
||||
else this._tooltip.style.right = 'initial';
|
||||
if (coords.top) this._tooltip.style.top = coords.top + 'px';
|
||||
else this._tooltip.style.top = 'initial';
|
||||
if (coords.bottom) this._tooltip.style.bottom = coords.bottom + 'px';
|
||||
else this._tooltip.style.bottom = 'initial';
|
||||
},
|
||||
|
||||
getDocHeight: function () {
|
||||
var D = document;
|
||||
return Math.max(
|
||||
D.body.scrollHeight, D.documentElement.scrollHeight,
|
||||
D.body.offsetHeight, D.documentElement.offsetHeight,
|
||||
D.body.clientHeight, D.documentElement.clientHeight
|
||||
);
|
||||
},
|
||||
|
||||
});
|
||||
getDocHeight: function () {
|
||||
var D = document
|
||||
return Math.max(
|
||||
D.body.scrollHeight,
|
||||
D.documentElement.scrollHeight,
|
||||
D.body.offsetHeight,
|
||||
D.documentElement.offsetHeight,
|
||||
D.body.clientHeight,
|
||||
D.documentElement.clientHeight
|
||||
)
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,285 +1,296 @@
|
|||
L.U.Xhr = L.Evented.extend({
|
||||
initialize: function (ui) {
|
||||
this.ui = ui
|
||||
},
|
||||
|
||||
initialize: function (ui) {
|
||||
this.ui = ui;
|
||||
},
|
||||
|
||||
_wrapper: function () {
|
||||
var wrapper;
|
||||
if (window.XMLHttpRequest === undefined) {
|
||||
wrapper = function() {
|
||||
try {
|
||||
return new window.ActiveXObject('Microsoft.XMLHTTP.6.0');
|
||||
}
|
||||
catch (e1) {
|
||||
try {
|
||||
return new window.ActiveXObject('Microsoft.XMLHTTP.3.0');
|
||||
}
|
||||
catch (e2) {
|
||||
throw new Error('XMLHttpRequest is not supported');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
wrapper = window.XMLHttpRequest;
|
||||
}
|
||||
return new wrapper();
|
||||
},
|
||||
|
||||
_ajax: function (settings) {
|
||||
var xhr = this._wrapper(), id = Math.random(), self = this;
|
||||
this.fire('dataloading', {id: id});
|
||||
var loaded = function () {self.fire('dataload', {id: id});};
|
||||
|
||||
_wrapper: function () {
|
||||
var wrapper
|
||||
if (window.XMLHttpRequest === undefined) {
|
||||
wrapper = function () {
|
||||
try {
|
||||
xhr.open(settings.verb, settings.uri, true);
|
||||
} catch (err) {
|
||||
// Unknown protocol?
|
||||
this.ui.alert({content: L._('Error while fetching {url}', {url: settings.uri}), level: 'error'});
|
||||
loaded();
|
||||
return
|
||||
return new window.ActiveXObject('Microsoft.XMLHTTP.6.0')
|
||||
} catch (e1) {
|
||||
try {
|
||||
return new window.ActiveXObject('Microsoft.XMLHTTP.3.0')
|
||||
} catch (e2) {
|
||||
throw new Error('XMLHttpRequest is not supported')
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
wrapper = window.XMLHttpRequest
|
||||
}
|
||||
return new wrapper()
|
||||
},
|
||||
|
||||
if (settings.uri.indexOf('http') !== 0 || settings.uri.indexOf(window.location.origin) === 0) {
|
||||
// "X-" mode headers cause the request to be in preflight mode,
|
||||
// we don"t want that by default for CORS requests
|
||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
||||
}
|
||||
if (settings.headers) {
|
||||
for (var name in settings.headers) {
|
||||
xhr.setRequestHeader(name, settings.headers[name]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status == 200) {
|
||||
settings.callback.call(settings.context || xhr, xhr.responseText, xhr);
|
||||
}
|
||||
else if (xhr.status === 403) {
|
||||
self.ui.alert({content: xhr.responseText || L._('Action not allowed :('), level: 'error'});
|
||||
}
|
||||
else if (xhr.status === 412) {
|
||||
var msg = L._('Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.');
|
||||
var actions = [
|
||||
{
|
||||
label: L._('Save anyway'),
|
||||
callback: function () {
|
||||
delete settings.headers['If-Match'];
|
||||
self._ajax(settings);
|
||||
},
|
||||
callbackContext: self
|
||||
},
|
||||
{
|
||||
label: L._('Cancel')
|
||||
}
|
||||
];
|
||||
self.ui.alert({content: msg, level: 'error', duration: 100000, actions: actions});
|
||||
}
|
||||
else {
|
||||
if (xhr.status !== 0) { // 0 === request cut by user
|
||||
self.ui.alert({'content': L._('Problem in the response'), 'level': 'error'});
|
||||
}
|
||||
}
|
||||
loaded();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
xhr.send(settings.data);
|
||||
} catch (e) {
|
||||
// Pass
|
||||
loaded();
|
||||
console.error('Bad Request', e);
|
||||
}
|
||||
},
|
||||
|
||||
// supports only JSON as response data type
|
||||
_json: function (verb, uri, options) {
|
||||
var args = arguments,
|
||||
self = this;
|
||||
var default_options = {
|
||||
'async': true,
|
||||
'callback': null,
|
||||
'responseType': 'text',
|
||||
'data': null,
|
||||
'listen_form': null // optional form to listen in default callback
|
||||
};
|
||||
var settings = L.Util.extend({}, default_options, options);
|
||||
|
||||
if (verb === 'POST') {
|
||||
// find a way not to make this django specific
|
||||
var token = document.cookie.replace(/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/, '$1');
|
||||
if (token) {
|
||||
settings.headers = settings.headers || {};
|
||||
settings.headers['X-CSRFToken'] = token;
|
||||
}
|
||||
}
|
||||
|
||||
var callback = function(responseText, response) {
|
||||
var data;
|
||||
try {
|
||||
data = JSON.parse(responseText);
|
||||
}
|
||||
catch (err) {
|
||||
console.log(err);
|
||||
self.ui.alert({content: L._('Problem in the response format'), level: 'error'});
|
||||
return;
|
||||
}
|
||||
if (data.errors) {
|
||||
console.log(data.errors);
|
||||
self.ui.alert({content: L._('An error occured'), level: 'error'});
|
||||
} else if (data.login_required) {
|
||||
// login_required should be an URL for the login form
|
||||
if (settings.login_callback) settings.login_callback(data);
|
||||
else self.login(data, args);
|
||||
}
|
||||
else {
|
||||
if (settings.callback) L.bind(settings.callback, settings.context || this)(data, response);
|
||||
else self.default_callback(data, settings, response);
|
||||
}
|
||||
};
|
||||
|
||||
this._ajax({
|
||||
verb: verb,
|
||||
uri: uri,
|
||||
data: settings.data,
|
||||
callback: callback,
|
||||
headers: settings.headers,
|
||||
listener: settings.listener
|
||||
});
|
||||
},
|
||||
|
||||
get: function(uri, options) {
|
||||
this._json('GET', uri, options);
|
||||
},
|
||||
|
||||
post: function(uri, options) {
|
||||
this._json('POST', uri, options);
|
||||
},
|
||||
|
||||
submit_form: function(form_id, options) {
|
||||
if(typeof options === 'undefined') options = {};
|
||||
var form = L.DomUtil.get(form_id);
|
||||
var formData = new FormData(form);
|
||||
if(options.extraFormData) formData.append(options.extraFormData);
|
||||
options.data = formData;
|
||||
this.post(form.action, options);
|
||||
return false;
|
||||
},
|
||||
|
||||
listen_form: function (form_id, options) {
|
||||
var form = L.DomUtil.get(form_id), self = this;
|
||||
if (!form) return;
|
||||
L.DomEvent
|
||||
.on(form, 'submit', L.DomEvent.stopPropagation)
|
||||
.on(form, 'submit', L.DomEvent.preventDefault)
|
||||
.on(form, 'submit', function () {
|
||||
self.submit_form(form_id, options);
|
||||
});
|
||||
},
|
||||
|
||||
listen_link: function (link_id, options) {
|
||||
var link = L.DomUtil.get(link_id), self = this;
|
||||
if (link) {
|
||||
L.DomEvent
|
||||
.on(link, 'click', L.DomEvent.stop)
|
||||
.on(link, 'click', function () {
|
||||
if (options.confirm && !confirm(options.confirm)) { return;}
|
||||
self.get(link.href, options);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
default_callback: function (data, options) {
|
||||
// default callback, to avoid boilerplate
|
||||
if (data.redirect) {
|
||||
var newPath = data.redirect;
|
||||
if (window.location.pathname == newPath) window.location.reload(); // Keep the hash, so the current view
|
||||
else window.location = newPath;
|
||||
}
|
||||
else if (data.info) {
|
||||
this.ui.alert({content: data.info, level: 'info'});
|
||||
this.ui.closePanel();
|
||||
}
|
||||
else if (data.error) {
|
||||
this.ui.alert({content: data.error, level: 'error'});
|
||||
}
|
||||
else if (data.html) {
|
||||
var ui_options = {'data': data},
|
||||
listen_options;
|
||||
if (options.className) ui_options.className = options.className;
|
||||
this.ui.openPanel(ui_options);
|
||||
// To low boilerplate, if there is a form, listen it
|
||||
if (options.listen_form) {
|
||||
// Listen form again
|
||||
listen_options = L.Util.extend({}, options, options.listen_form.options);
|
||||
this.listen_form(options.listen_form.id, listen_options);
|
||||
}
|
||||
if (options.listen_link) {
|
||||
for (var i=0, l=options.listen_link.length; i<l; i++) {
|
||||
// Listen link again
|
||||
listen_options = L.Util.extend({}, options, options.listen_link[i].options);
|
||||
this.listen_link(options.listen_link[i].id, listen_options);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (options.success) {
|
||||
// Success is called only if data contain no msg and no html
|
||||
options.success(data);
|
||||
}
|
||||
},
|
||||
|
||||
login: function (data, args) {
|
||||
// data.html: login form
|
||||
// args: args of the first _json call, to call again at process end
|
||||
var self = this;
|
||||
var proceed = function () {
|
||||
self.ui.closePanel();
|
||||
if (typeof args !== 'undefined') self._json.apply(self, args);
|
||||
else self.default_callback(data, {});
|
||||
};
|
||||
var ask_for_login = function (data) {
|
||||
self.ui.openPanel({'data': data, className: 'login-panel'});
|
||||
self.listen_form('login_form', {
|
||||
'callback': function (data) {
|
||||
if (data.html) ask_for_login(data); // Problem in the login - ask again
|
||||
else proceed();
|
||||
}
|
||||
});
|
||||
// Auth links
|
||||
var links = document.getElementsByClassName('umap-login-popup');
|
||||
Object.keys(links).forEach(function (el) {
|
||||
var link = links[el];
|
||||
L.DomEvent
|
||||
.on(link, 'click', L.DomEvent.stop)
|
||||
.on(link, 'click', function () {
|
||||
self.ui.closePanel();
|
||||
var win = window.open(link.href);
|
||||
window.umap_proceed = function () {
|
||||
proceed();
|
||||
win.close();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
};
|
||||
if (data.login_required) {
|
||||
this.get(data.login_required, {
|
||||
'callback': function (data) {
|
||||
ask_for_login(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
ask_for_login(data);
|
||||
}
|
||||
},
|
||||
|
||||
logout: function(url) {
|
||||
this.get(url);
|
||||
_ajax: function (settings) {
|
||||
var xhr = this._wrapper(),
|
||||
id = Math.random(),
|
||||
self = this
|
||||
this.fire('dataloading', { id: id })
|
||||
var loaded = function () {
|
||||
self.fire('dataload', { id: id })
|
||||
}
|
||||
|
||||
});
|
||||
try {
|
||||
xhr.open(settings.verb, settings.uri, true)
|
||||
} catch (err) {
|
||||
// Unknown protocol?
|
||||
this.ui.alert({
|
||||
content: L._('Error while fetching {url}', { url: settings.uri }),
|
||||
level: 'error',
|
||||
})
|
||||
loaded()
|
||||
return
|
||||
}
|
||||
|
||||
if (
|
||||
settings.uri.indexOf('http') !== 0 ||
|
||||
settings.uri.indexOf(window.location.origin) === 0
|
||||
) {
|
||||
// "X-" mode headers cause the request to be in preflight mode,
|
||||
// we don"t want that by default for CORS requests
|
||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest')
|
||||
}
|
||||
if (settings.headers) {
|
||||
for (var name in settings.headers) {
|
||||
xhr.setRequestHeader(name, settings.headers[name])
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (xhr.readyState === 4) {
|
||||
if (xhr.status == 200) {
|
||||
settings.callback.call(settings.context || xhr, xhr.responseText, xhr)
|
||||
} else if (xhr.status === 403) {
|
||||
self.ui.alert({
|
||||
content: xhr.responseText || L._('Action not allowed :('),
|
||||
level: 'error',
|
||||
})
|
||||
} else if (xhr.status === 412) {
|
||||
var msg = L._(
|
||||
'Woops! Someone else seems to have edited the data. You can save anyway, but this will erase the changes made by others.'
|
||||
)
|
||||
var actions = [
|
||||
{
|
||||
label: L._('Save anyway'),
|
||||
callback: function () {
|
||||
delete settings.headers['If-Match']
|
||||
self._ajax(settings)
|
||||
},
|
||||
callbackContext: self,
|
||||
},
|
||||
{
|
||||
label: L._('Cancel'),
|
||||
},
|
||||
]
|
||||
self.ui.alert({
|
||||
content: msg,
|
||||
level: 'error',
|
||||
duration: 100000,
|
||||
actions: actions,
|
||||
})
|
||||
} else {
|
||||
if (xhr.status !== 0) {
|
||||
// 0 === request cut by user
|
||||
self.ui.alert({ content: L._('Problem in the response'), level: 'error' })
|
||||
}
|
||||
}
|
||||
loaded()
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
xhr.send(settings.data)
|
||||
} catch (e) {
|
||||
// Pass
|
||||
loaded()
|
||||
console.error('Bad Request', e)
|
||||
}
|
||||
},
|
||||
|
||||
// supports only JSON as response data type
|
||||
_json: function (verb, uri, options) {
|
||||
var args = arguments,
|
||||
self = this
|
||||
var default_options = {
|
||||
async: true,
|
||||
callback: null,
|
||||
responseType: 'text',
|
||||
data: null,
|
||||
listen_form: null, // optional form to listen in default callback
|
||||
}
|
||||
var settings = L.Util.extend({}, default_options, options)
|
||||
|
||||
if (verb === 'POST') {
|
||||
// find a way not to make this django specific
|
||||
var token = document.cookie.replace(
|
||||
/(?:(?:^|.*;\s*)csrftoken\s*\=\s*([^;]*).*$)|^.*$/,
|
||||
'$1'
|
||||
)
|
||||
if (token) {
|
||||
settings.headers = settings.headers || {}
|
||||
settings.headers['X-CSRFToken'] = token
|
||||
}
|
||||
}
|
||||
|
||||
var callback = function (responseText, response) {
|
||||
var data
|
||||
try {
|
||||
data = JSON.parse(responseText)
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
self.ui.alert({
|
||||
content: L._('Problem in the response format'),
|
||||
level: 'error',
|
||||
})
|
||||
return
|
||||
}
|
||||
if (data.errors) {
|
||||
console.log(data.errors)
|
||||
self.ui.alert({ content: L._('An error occured'), level: 'error' })
|
||||
} else if (data.login_required) {
|
||||
// login_required should be an URL for the login form
|
||||
if (settings.login_callback) settings.login_callback(data)
|
||||
else self.login(data, args)
|
||||
} else {
|
||||
if (settings.callback)
|
||||
L.bind(settings.callback, settings.context || this)(data, response)
|
||||
else self.default_callback(data, settings, response)
|
||||
}
|
||||
}
|
||||
|
||||
this._ajax({
|
||||
verb: verb,
|
||||
uri: uri,
|
||||
data: settings.data,
|
||||
callback: callback,
|
||||
headers: settings.headers,
|
||||
listener: settings.listener,
|
||||
})
|
||||
},
|
||||
|
||||
get: function (uri, options) {
|
||||
this._json('GET', uri, options)
|
||||
},
|
||||
|
||||
post: function (uri, options) {
|
||||
this._json('POST', uri, options)
|
||||
},
|
||||
|
||||
submit_form: function (form_id, options) {
|
||||
if (typeof options === 'undefined') options = {}
|
||||
var form = L.DomUtil.get(form_id)
|
||||
var formData = new FormData(form)
|
||||
if (options.extraFormData) formData.append(options.extraFormData)
|
||||
options.data = formData
|
||||
this.post(form.action, options)
|
||||
return false
|
||||
},
|
||||
|
||||
listen_form: function (form_id, options) {
|
||||
var form = L.DomUtil.get(form_id),
|
||||
self = this
|
||||
if (!form) return
|
||||
L.DomEvent.on(form, 'submit', L.DomEvent.stopPropagation)
|
||||
.on(form, 'submit', L.DomEvent.preventDefault)
|
||||
.on(form, 'submit', function () {
|
||||
self.submit_form(form_id, options)
|
||||
})
|
||||
},
|
||||
|
||||
listen_link: function (link_id, options) {
|
||||
var link = L.DomUtil.get(link_id),
|
||||
self = this
|
||||
if (link) {
|
||||
L.DomEvent.on(link, 'click', L.DomEvent.stop).on(link, 'click', function () {
|
||||
if (options.confirm && !confirm(options.confirm)) {
|
||||
return
|
||||
}
|
||||
self.get(link.href, options)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
default_callback: function (data, options) {
|
||||
// default callback, to avoid boilerplate
|
||||
if (data.redirect) {
|
||||
var newPath = data.redirect
|
||||
if (window.location.pathname == newPath)
|
||||
window.location.reload() // Keep the hash, so the current view
|
||||
else window.location = newPath
|
||||
} else if (data.info) {
|
||||
this.ui.alert({ content: data.info, level: 'info' })
|
||||
this.ui.closePanel()
|
||||
} else if (data.error) {
|
||||
this.ui.alert({ content: data.error, level: 'error' })
|
||||
} else if (data.html) {
|
||||
var ui_options = { data: data },
|
||||
listen_options
|
||||
if (options.className) ui_options.className = options.className
|
||||
this.ui.openPanel(ui_options)
|
||||
// To low boilerplate, if there is a form, listen it
|
||||
if (options.listen_form) {
|
||||
// Listen form again
|
||||
listen_options = L.Util.extend({}, options, options.listen_form.options)
|
||||
this.listen_form(options.listen_form.id, listen_options)
|
||||
}
|
||||
if (options.listen_link) {
|
||||
for (var i = 0, l = options.listen_link.length; i < l; i++) {
|
||||
// Listen link again
|
||||
listen_options = L.Util.extend({}, options, options.listen_link[i].options)
|
||||
this.listen_link(options.listen_link[i].id, listen_options)
|
||||
}
|
||||
}
|
||||
} else if (options.success) {
|
||||
// Success is called only if data contain no msg and no html
|
||||
options.success(data)
|
||||
}
|
||||
},
|
||||
|
||||
login: function (data, args) {
|
||||
// data.html: login form
|
||||
// args: args of the first _json call, to call again at process end
|
||||
var self = this
|
||||
var proceed = function () {
|
||||
self.ui.closePanel()
|
||||
if (typeof args !== 'undefined') self._json.apply(self, args)
|
||||
else self.default_callback(data, {})
|
||||
}
|
||||
var ask_for_login = function (data) {
|
||||
self.ui.openPanel({ data: data, className: 'login-panel' })
|
||||
self.listen_form('login_form', {
|
||||
callback: function (data) {
|
||||
if (data.html) ask_for_login(data) // Problem in the login - ask again
|
||||
else proceed()
|
||||
},
|
||||
})
|
||||
// Auth links
|
||||
var links = document.getElementsByClassName('umap-login-popup')
|
||||
Object.keys(links).forEach(function (el) {
|
||||
var link = links[el]
|
||||
L.DomEvent.on(link, 'click', L.DomEvent.stop).on(link, 'click', function () {
|
||||
self.ui.closePanel()
|
||||
var win = window.open(link.href)
|
||||
window.umap_proceed = function () {
|
||||
proceed()
|
||||
win.close()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
if (data.login_required) {
|
||||
this.get(data.login_required, {
|
||||
callback: function (data) {
|
||||
ask_for_login(data)
|
||||
},
|
||||
})
|
||||
} else {
|
||||
ask_for_login(data)
|
||||
}
|
||||
},
|
||||
|
||||
logout: function (url) {
|
||||
this.get(url)
|
||||
},
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue