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 push -s
|
||||||
tx_pull:
|
tx_pull:
|
||||||
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",
|
"mocha-phantomjs": "^4.0.1",
|
||||||
"optimist": "~0.4.0",
|
"optimist": "~0.4.0",
|
||||||
"phantomjs": "^1.9.18",
|
"phantomjs": "^1.9.18",
|
||||||
|
"prettier": "^2.8.8",
|
||||||
"sinon": "^1.10.3",
|
"sinon": "^1.10.3",
|
||||||
"uglify-js": "~3.17.4"
|
"uglify-js": "~3.17.4"
|
||||||
}
|
}
|
||||||
|
@ -1920,6 +1921,21 @@
|
||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/process-nextick-args": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||||
|
@ -4071,6 +4087,12 @@
|
||||||
"pinkie": "^2.0.0"
|
"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": {
|
"process-nextick-args": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"mocha-phantomjs": "^4.0.1",
|
"mocha-phantomjs": "^4.0.1",
|
||||||
"optimist": "~0.4.0",
|
"optimist": "~0.4.0",
|
||||||
"phantomjs": "^1.9.18",
|
"phantomjs": "^1.9.18",
|
||||||
|
"prettier": "^2.8.8",
|
||||||
"sinon": "^1.10.3",
|
"sinon": "^1.10.3",
|
||||||
"uglify-js": "~3.17.4"
|
"uglify-js": "~3.17.4"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,314 +1,341 @@
|
||||||
L.U.AutoComplete = L.Class.extend({
|
L.U.AutoComplete = L.Class.extend({
|
||||||
|
options: {
|
||||||
|
placeholder: 'Start typing...',
|
||||||
|
emptyMessage: 'No result',
|
||||||
|
allowFree: true,
|
||||||
|
minChar: 2,
|
||||||
|
maxResults: 5,
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
CACHE: '',
|
||||||
placeholder: 'Start typing...',
|
RESULTS: [],
|
||||||
emptyMessage: 'No result',
|
|
||||||
allowFree: true,
|
|
||||||
minChar: 2,
|
|
||||||
maxResults: 5
|
|
||||||
},
|
|
||||||
|
|
||||||
CACHE: '',
|
initialize: function (el, options) {
|
||||||
RESULTS: [],
|
this.el = el
|
||||||
|
var ui = new L.U.UI(document.querySelector('header'))
|
||||||
initialize: function (el, options) {
|
this.xhr = new L.U.Xhr(ui)
|
||||||
this.el = el;
|
L.setOptions(this, options)
|
||||||
var ui = new L.U.UI(document.querySelector('header'));
|
var CURRENT = null
|
||||||
this.xhr = new L.U.Xhr(ui);
|
try {
|
||||||
L.setOptions(this, options);
|
Object.defineProperty(this, 'CURRENT', {
|
||||||
var CURRENT = null;
|
get: function () {
|
||||||
try {
|
return CURRENT
|
||||||
Object.defineProperty(this, 'CURRENT', {
|
},
|
||||||
get: function () {
|
set: function (index) {
|
||||||
return CURRENT;
|
if (typeof index === 'object') {
|
||||||
},
|
index = this.resultToIndex(index)
|
||||||
set: function (index) {
|
}
|
||||||
if (typeof index === 'object') {
|
CURRENT = index
|
||||||
index = this.resultToIndex(index);
|
},
|
||||||
}
|
})
|
||||||
CURRENT = index;
|
} catch (e) {
|
||||||
}
|
// Hello IE8
|
||||||
});
|
|
||||||
} 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);
|
|
||||||
}
|
}
|
||||||
|
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({
|
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) {
|
optionToResult: function (option) {
|
||||||
L.U.AutoComplete.prototype.initialize.call(this, el, options);
|
return {
|
||||||
if (!this.el) return this;
|
value: option.value,
|
||||||
this.createInput();
|
label: option.innerHTML,
|
||||||
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});
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
_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({
|
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 () {
|
displaySelected: function (result) {
|
||||||
return L.DomUtil.after(this.input, L.DomUtil.element('ul', {className: 'umap-multiresult'}));
|
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)
|
||||||
displaySelected: function (result) {
|
close.textContent = '×'
|
||||||
var result_el = L.DomUtil.element('li', {}, this.selected_container);
|
L.DomEvent.on(
|
||||||
result_el.textContent = result.item.label;
|
close,
|
||||||
var close = L.DomUtil.element('span', {className: 'close'}, result_el);
|
'click',
|
||||||
close.textContent = '×';
|
function () {
|
||||||
L.DomEvent.on(close, 'click', function () {
|
this.selected_container.removeChild(result_el)
|
||||||
this.selected_container.removeChild(result_el);
|
this.options.on_unselect(result)
|
||||||
this.options.on_unselect(result);
|
},
|
||||||
}, this);
|
this
|
||||||
this.hide();
|
)
|
||||||
}
|
this.hide()
|
||||||
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
L.U.AutoComplete.Ajax.Select = L.U.AutoComplete.Ajax.extend({
|
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 () {
|
displaySelected: function (result) {
|
||||||
return L.DomUtil.after(this.input, L.DomUtil.element('div', {className: 'umap-singleresult'}));
|
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)
|
||||||
displaySelected: function (result) {
|
close.textContent = '×'
|
||||||
var result_el = L.DomUtil.element('div', {}, this.selected_container);
|
this.input.style.display = 'none'
|
||||||
result_el.textContent = result.item.label;
|
L.DomEvent.on(
|
||||||
var close = L.DomUtil.element('span', {className: 'close'}, result_el);
|
close,
|
||||||
close.textContent = '×';
|
'click',
|
||||||
this.input.style.display = 'none';
|
function () {
|
||||||
L.DomEvent.on(close, 'click', function () {
|
this.selected_container.innerHTML = ''
|
||||||
this.selected_container.innerHTML = '';
|
this.input.style.display = 'block'
|
||||||
this.input.style.display = 'block';
|
},
|
||||||
}, this);
|
this
|
||||||
this.hide();
|
)
|
||||||
}
|
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({
|
L.U.Icon = L.DivIcon.extend({
|
||||||
initialize: function(map, options) {
|
initialize: function (map, options) {
|
||||||
this.map = map;
|
this.map = map
|
||||||
var default_options = {
|
var default_options = {
|
||||||
iconSize: null, // Made in css
|
iconSize: null, // Made in css
|
||||||
iconUrl: this.map.getDefaultOption('iconUrl'),
|
iconUrl: this.map.getDefaultOption('iconUrl'),
|
||||||
feature: null
|
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() : {});
|
|
||||||
}
|
}
|
||||||
|
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({
|
L.U.Icon.Default = L.U.Icon.extend({
|
||||||
default_options: {
|
default_options: {
|
||||||
iconAnchor: new L.Point(16, 40),
|
iconAnchor: new L.Point(16, 40),
|
||||||
popupAnchor: new L.Point(0, -40),
|
popupAnchor: new L.Point(0, -40),
|
||||||
tooltipAnchor: new L.Point(16, -24),
|
tooltipAnchor: new L.Point(16, -24),
|
||||||
className: 'umap-div-icon'
|
className: 'umap-div-icon',
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function(map, options) {
|
initialize: function (map, options) {
|
||||||
options = L.Util.extend({}, this.default_options, options);
|
options = L.Util.extend({}, this.default_options, options)
|
||||||
L.U.Icon.prototype.initialize.call(this, map, options);
|
L.U.Icon.prototype.initialize.call(this, map, options)
|
||||||
},
|
},
|
||||||
|
|
||||||
_setColor: function() {
|
_setColor: function () {
|
||||||
var color = this._getColor();
|
var color = this._getColor()
|
||||||
this.elements.container.style.backgroundColor = color;
|
this.elements.container.style.backgroundColor = color
|
||||||
this.elements.arrow.style.borderTopColor = color;
|
this.elements.arrow.style.borderTopColor = color
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function() {
|
createIcon: function () {
|
||||||
this.elements = {};
|
this.elements = {}
|
||||||
this.elements.main = L.DomUtil.create('div');
|
this.elements.main = L.DomUtil.create('div')
|
||||||
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
this.elements.container = L.DomUtil.create(
|
||||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
'div',
|
||||||
var src = this._getIconUrl('icon');
|
'icon_container',
|
||||||
if (src) {
|
this.elements.main
|
||||||
// An url.
|
)
|
||||||
if (src.indexOf('http') === 0 || src.indexOf('/') === 0 || src.indexOf('data:image') === 0) {
|
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main)
|
||||||
this.elements.img = L.DomUtil.create('img', null, this.elements.container);
|
var src = this._getIconUrl('icon')
|
||||||
this.elements.img.src = src;
|
if (src) {
|
||||||
} else {
|
// An url.
|
||||||
this.elements.span = L.DomUtil.create('span', null, this.elements.container)
|
if (
|
||||||
this.elements.span.textContent = src;
|
src.indexOf('http') === 0 ||
|
||||||
}
|
src.indexOf('/') === 0 ||
|
||||||
}
|
src.indexOf('data:image') === 0
|
||||||
this._setColor();
|
) {
|
||||||
this._setIconStyles(this.elements.main, 'icon');
|
this.elements.img = L.DomUtil.create('img', null, this.elements.container)
|
||||||
return this.elements.main;
|
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({
|
L.U.Icon.Circle = L.U.Icon.extend({
|
||||||
initialize: function(map, options) {
|
initialize: function (map, options) {
|
||||||
var default_options = {
|
var default_options = {
|
||||||
iconAnchor: new L.Point(6, 6),
|
iconAnchor: new L.Point(6, 6),
|
||||||
popupAnchor: new L.Point(0, -6),
|
popupAnchor: new L.Point(0, -6),
|
||||||
tooltipAnchor: new L.Point(6, 0),
|
tooltipAnchor: new L.Point(6, 0),
|
||||||
className: 'umap-circle-icon'
|
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;
|
|
||||||
}
|
}
|
||||||
|
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({
|
L.U.Icon.Drop = L.U.Icon.Default.extend({
|
||||||
default_options: {
|
default_options: {
|
||||||
iconAnchor: new L.Point(16, 42),
|
iconAnchor: new L.Point(16, 42),
|
||||||
popupAnchor: new L.Point(0, -42),
|
popupAnchor: new L.Point(0, -42),
|
||||||
tooltipAnchor: new L.Point(16, -24),
|
tooltipAnchor: new L.Point(16, -24),
|
||||||
className: 'umap-drop-icon'
|
className: 'umap-drop-icon',
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
L.U.Icon.Ball = L.U.Icon.Default.extend({
|
L.U.Icon.Ball = L.U.Icon.Default.extend({
|
||||||
default_options: {
|
default_options: {
|
||||||
iconAnchor: new L.Point(8, 30),
|
iconAnchor: new L.Point(8, 30),
|
||||||
popupAnchor: new L.Point(0, -28),
|
popupAnchor: new L.Point(0, -28),
|
||||||
tooltipAnchor: new L.Point(8, -23),
|
tooltipAnchor: new L.Point(8, -23),
|
||||||
className: 'umap-ball-icon'
|
className: 'umap-ball-icon',
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function() {
|
createIcon: function () {
|
||||||
this.elements = {};
|
this.elements = {}
|
||||||
this.elements.main = L.DomUtil.create('div');
|
this.elements.main = L.DomUtil.create('div')
|
||||||
this.elements.container = L.DomUtil.create('div', 'icon_container', this.elements.main);
|
this.elements.container = L.DomUtil.create(
|
||||||
this.elements.arrow = L.DomUtil.create('div', 'icon_arrow', this.elements.main);
|
'div',
|
||||||
this._setColor();
|
'icon_container',
|
||||||
this._setIconStyles(this.elements.main, 'icon');
|
this.elements.main
|
||||||
return 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() {
|
_setColor: function () {
|
||||||
var color = this._getColor('color'),
|
var color = this._getColor('color'),
|
||||||
background;
|
background
|
||||||
if (L.Browser.ielt9) {
|
if (L.Browser.ielt9) {
|
||||||
background = color;
|
background = color
|
||||||
}
|
} else if (L.Browser.webkit) {
|
||||||
else if (L.Browser.webkit) {
|
background =
|
||||||
background = '-webkit-gradient( radial, 6 38%, 0, 6 38%, 8, from(white), to(' + color + ') )';
|
'-webkit-gradient( radial, 6 38%, 0, 6 38%, 8, from(white), to(' + color + ') )'
|
||||||
}
|
} else {
|
||||||
else {
|
background =
|
||||||
background = 'radial-gradient(circle at 6px 38% , white -4px, ' + color + ' 8px) repeat scroll 0 0 transparent';
|
'radial-gradient(circle at 6px 38% , white -4px, ' +
|
||||||
}
|
color +
|
||||||
this.elements.container.style.background = background;
|
' 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({
|
L.U.Icon.Cluster = L.DivIcon.extend({
|
||||||
options: {
|
options: {
|
||||||
iconSize: [40, 40]
|
iconSize: [40, 40],
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function (datalayer, cluster) {
|
initialize: function (datalayer, cluster) {
|
||||||
this.datalayer = datalayer;
|
this.datalayer = datalayer
|
||||||
this.cluster = cluster;
|
this.cluster = cluster
|
||||||
},
|
},
|
||||||
|
|
||||||
createIcon: function () {
|
createIcon: function () {
|
||||||
var container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster'),
|
var container = L.DomUtil.create('div', 'leaflet-marker-icon marker-cluster'),
|
||||||
div = L.DomUtil.create('div', '', container),
|
div = L.DomUtil.create('div', '', container),
|
||||||
span = L.DomUtil.create('span', '', div),
|
span = L.DomUtil.create('span', '', div),
|
||||||
backgroundColor = this.datalayer.getColor();
|
backgroundColor = this.datalayer.getColor()
|
||||||
span.textContent = this.cluster.getChildCount();
|
span.textContent = this.cluster.getChildCount()
|
||||||
div.style.backgroundColor = backgroundColor;
|
div.style.backgroundColor = backgroundColor
|
||||||
return container;
|
return container
|
||||||
},
|
},
|
||||||
|
|
||||||
computeTextColor: function (el) {
|
computeTextColor: function (el) {
|
||||||
var color,
|
var color,
|
||||||
backgroundColor = this.datalayer.getColor();
|
backgroundColor = this.datalayer.getColor()
|
||||||
if (this.datalayer.options.cluster && this.datalayer.options.cluster.textColor) {
|
if (this.datalayer.options.cluster && this.datalayer.options.cluster.textColor) {
|
||||||
color = 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;
|
|
||||||
}
|
}
|
||||||
|
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
|
// 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.
|
// call the endpoint only when needed, saving one call at each save.
|
||||||
L.U.MapPermissions = L.Class.extend({
|
L.U.MapPermissions = L.Class.extend({
|
||||||
|
options: {
|
||||||
|
owner: null,
|
||||||
|
editors: [],
|
||||||
|
share_status: null,
|
||||||
|
edit_status: null,
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
initialize: function (map) {
|
||||||
owner: null,
|
this.setOptions(map.options.permissions)
|
||||||
editors: [],
|
this.map = map
|
||||||
share_status: null,
|
var isDirty = false,
|
||||||
edit_status: null
|
self = this
|
||||||
},
|
try {
|
||||||
|
Object.defineProperty(this, 'isDirty', {
|
||||||
initialize: function (map) {
|
get: function () {
|
||||||
this.setOptions(map.options.permissions);
|
return isDirty
|
||||||
this.map = map;
|
},
|
||||||
var isDirty = false,
|
set: function (status) {
|
||||||
self = this;
|
isDirty = status
|
||||||
try {
|
if (status) self.map.isDirty = status
|
||||||
Object.defineProperty(this, 'isDirty', {
|
},
|
||||||
get: function () {
|
})
|
||||||
return isDirty;
|
} catch (e) {
|
||||||
},
|
// Certainly IE8, which has a limited version of defineProperty
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
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 */
|
/* Shapes */
|
||||||
|
|
||||||
L.U.Popup = L.Popup.extend({
|
L.U.Popup = L.Popup.extend({
|
||||||
|
options: {
|
||||||
|
parseTemplate: true,
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
initialize: function (feature) {
|
||||||
parseTemplate: true
|
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) {
|
format: function () {
|
||||||
this.feature = feature;
|
var mode = this.feature.getOption('popupTemplate') || 'Default',
|
||||||
this.container = L.DomUtil.create('div', 'umap-popup');
|
klass = L.U.PopupTemplate[mode] || L.U.PopupTemplate.Default
|
||||||
this.format();
|
this.content = new klass(this.feature, this.container)
|
||||||
L.Popup.prototype.initialize.call(this, {}, feature);
|
this.content.render()
|
||||||
this.setContent(this.container);
|
var els = this.container.querySelectorAll('img,iframe')
|
||||||
},
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
this.onElementLoaded(els[i])
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
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({
|
L.U.Popup.Large = L.U.Popup.extend({
|
||||||
options: {
|
options: {
|
||||||
maxWidth: 500,
|
maxWidth: 500,
|
||||||
className: 'umap-popup-large'
|
className: 'umap-popup-large',
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
|
|
||||||
L.U.Popup.Panel = L.U.Popup.extend({
|
L.U.Popup.Panel = L.U.Popup.extend({
|
||||||
|
options: {
|
||||||
|
zoomAnimation: false,
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
allButton: function () {
|
||||||
zoomAnimation: false
|
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 () {
|
update: function () {
|
||||||
var button = L.DomUtil.create('li', '');
|
this.feature.map.ui.openPanel({
|
||||||
L.DomUtil.create('i', 'umap-icon-16 umap-list', button);
|
data: { html: this._content },
|
||||||
var label = L.DomUtil.create('span', '', button);
|
actions: [this.allButton()],
|
||||||
label.textContent = label.title = L._('See all');
|
})
|
||||||
L.DomEvent.on(button, 'click', this.feature.map.openBrowser, this.feature.map);
|
},
|
||||||
return button;
|
|
||||||
},
|
|
||||||
|
|
||||||
update: function () {
|
onRemove: function (map) {
|
||||||
this.feature.map.ui.openPanel({data: {html: this._content}, actions: [this.allButton()]});
|
map.ui.closePanel()
|
||||||
},
|
L.U.Popup.prototype.onRemove.call(this, map)
|
||||||
|
},
|
||||||
|
|
||||||
onRemove: function (map) {
|
_initLayout: function () {
|
||||||
map.ui.closePanel();
|
this._container = L.DomUtil.create('span')
|
||||||
L.U.Popup.prototype.onRemove.call(this, map);
|
},
|
||||||
},
|
_updateLayout: function () {},
|
||||||
|
_updatePosition: function () {},
|
||||||
_initLayout: function () {this._container = L.DomUtil.create('span');},
|
_adjustPan: function () {},
|
||||||
_updateLayout: function () {},
|
})
|
||||||
_updatePosition: function () {},
|
L.U.Popup.SimplePanel = L.U.Popup.Panel // Retrocompat.
|
||||||
_adjustPan: function () {}
|
|
||||||
|
|
||||||
});
|
|
||||||
L.U.Popup.SimplePanel = L.U.Popup.Panel; // Retrocompat.
|
|
||||||
|
|
||||||
/* Content templates */
|
/* Content templates */
|
||||||
|
|
||||||
L.U.PopupTemplate = {};
|
L.U.PopupTemplate = {}
|
||||||
|
|
||||||
L.U.PopupTemplate.Default = L.Class.extend({
|
L.U.PopupTemplate.Default = L.Class.extend({
|
||||||
|
initialize: function (feature, container) {
|
||||||
|
this.feature = feature
|
||||||
|
this.container = container
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function (feature, container) {
|
renderTitle: function () {},
|
||||||
this.feature = feature;
|
|
||||||
this.container = container;
|
|
||||||
},
|
|
||||||
|
|
||||||
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 () {
|
renderFooter: function () {
|
||||||
var template = this.feature.getOption('popupContentTemplate'),
|
if (this.feature.hasPopupFooter()) {
|
||||||
container = L.DomUtil.create('div', 'umap-popup-container'),
|
var footerContainer = L.DomUtil.create(
|
||||||
content = '', properties, center;
|
'div',
|
||||||
properties = this.feature.extendedProperties();
|
'umap-footer-container',
|
||||||
// Resolve properties inside description
|
this.container
|
||||||
properties.description = L.Util.greedyTemplate(this.feature.properties.description || '', properties);
|
),
|
||||||
content = L.Util.greedyTemplate(template, properties);
|
footer = L.DomUtil.create('ul', 'umap-popup-footer', footerContainer),
|
||||||
content = L.Util.toHTML(content);
|
previousLi = L.DomUtil.create('li', 'previous', footer),
|
||||||
container.innerHTML = content;
|
zoomLi = L.DomUtil.create('li', 'zoom', footer),
|
||||||
return container;
|
nextLi = L.DomUtil.create('li', 'next', footer),
|
||||||
},
|
next = this.feature.getNext(),
|
||||||
|
prev = this.feature.getPrevious()
|
||||||
renderFooter: function () {
|
if (next)
|
||||||
if (this.feature.hasPopupFooter()) {
|
nextLi.title = L._('Go to «{feature}»', {
|
||||||
var footerContainer = L.DomUtil.create('div', 'umap-footer-container', this.container),
|
feature: next.properties.name || L._('next'),
|
||||||
footer = L.DomUtil.create('ul', 'umap-popup-footer', footerContainer),
|
})
|
||||||
previousLi = L.DomUtil.create('li', 'previous', footer),
|
if (prev)
|
||||||
zoomLi = L.DomUtil.create('li', 'zoom', footer),
|
previousLi.title = L._('Go to «{feature}»', {
|
||||||
nextLi = L.DomUtil.create('li', 'next', footer),
|
feature: prev.properties.name || L._('previous'),
|
||||||
next = this.feature.getNext(),
|
})
|
||||||
prev = this.feature.getPrevious();
|
zoomLi.title = L._('Zoom to this feature')
|
||||||
if (next) nextLi.title = L._('Go to «{feature}»', {feature: next.properties.name || L._('next')});
|
L.DomEvent.on(nextLi, 'click', function () {
|
||||||
if (prev) previousLi.title = L._('Go to «{feature}»', {feature: prev.properties.name || L._('previous')});
|
if (next) next.zoomTo({ callback: next.view })
|
||||||
zoomLi.title = L._('Zoom to this feature');
|
})
|
||||||
L.DomEvent.on(nextLi, 'click', function () {
|
L.DomEvent.on(previousLi, 'click', function () {
|
||||||
if (next) next.zoomTo({callback: next.view});
|
if (prev) prev.zoomTo({ callback: prev.view })
|
||||||
});
|
})
|
||||||
L.DomEvent.on(previousLi, 'click', function () {
|
L.DomEvent.on(
|
||||||
if (prev) prev.zoomTo({callback: prev.view});
|
zoomLi,
|
||||||
});
|
'click',
|
||||||
L.DomEvent.on(zoomLi, 'click', function () {
|
function () {
|
||||||
this.zoomTo();
|
this.zoomTo()
|
||||||
}, this.feature);
|
},
|
||||||
}
|
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();
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
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({
|
L.U.PopupTemplate.BaseWithTitle = L.U.PopupTemplate.Default.extend({
|
||||||
|
renderTitle: function () {
|
||||||
renderTitle: function () {
|
var title
|
||||||
var title;
|
if (this.feature.getDisplayName()) {
|
||||||
if (this.feature.getDisplayName()) {
|
title = L.DomUtil.create('h3', 'popup-title')
|
||||||
title = L.DomUtil.create('h3', 'popup-title');
|
title.textContent = this.feature.getDisplayName()
|
||||||
title.textContent = this.feature.getDisplayName();
|
|
||||||
}
|
|
||||||
return title;
|
|
||||||
}
|
}
|
||||||
|
return title
|
||||||
});
|
},
|
||||||
|
})
|
||||||
|
|
||||||
L.U.PopupTemplate.Table = L.U.PopupTemplate.BaseWithTitle.extend({
|
L.U.PopupTemplate.Table = L.U.PopupTemplate.BaseWithTitle.extend({
|
||||||
|
formatRow: function (key, value) {
|
||||||
formatRow: function (key, value) {
|
if (value.indexOf('http') === 0) {
|
||||||
if (value.indexOf('http') === 0) {
|
value = '<a href="' + value + '" target="_blank">' + value + '</a>'
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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({
|
L.U.PopupTemplate.GeoRSSImage = L.U.PopupTemplate.BaseWithTitle.extend({
|
||||||
|
options: {
|
||||||
|
minWidth: 300,
|
||||||
|
maxWidth: 500,
|
||||||
|
className: 'umap-popup-large umap-georss-image',
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
renderBody: function () {
|
||||||
minWidth: 300,
|
var container = L.DomUtil.create('a')
|
||||||
maxWidth: 500,
|
container.href = this.feature.properties.link
|
||||||
className: 'umap-popup-large umap-georss-image'
|
container.target = '_blank'
|
||||||
},
|
if (this.feature.properties.img) {
|
||||||
|
var img = L.DomUtil.create('img', '', container)
|
||||||
renderBody: function () {
|
img.src = this.feature.properties.img
|
||||||
var container = L.DomUtil.create('a');
|
// Sadly, we are unable to override this from JS the clean way
|
||||||
container.href = this.feature.properties.link;
|
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
|
||||||
container.target = '_blank';
|
img.style.maxWidth = this.options.maxWidth + 'px'
|
||||||
if (this.feature.properties.img) {
|
img.style.maxHeight = this.options.maxWidth + 'px'
|
||||||
var img = L.DomUtil.create('img', '', container);
|
this.onElementLoaded(img)
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
return container
|
||||||
});
|
},
|
||||||
|
})
|
||||||
|
|
||||||
L.U.PopupTemplate.GeoRSSLink = L.U.PopupTemplate.Default.extend({
|
L.U.PopupTemplate.GeoRSSLink = L.U.PopupTemplate.Default.extend({
|
||||||
|
options: {
|
||||||
|
className: 'umap-georss-link',
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
renderBody: function () {
|
||||||
className: 'umap-georss-link'
|
var title = this.renderTitle(this),
|
||||||
},
|
a = L.DomUtil.add('a')
|
||||||
|
a.href = this.feature.properties.link
|
||||||
renderBody: function () {
|
a.target = '_blank'
|
||||||
var title = this.renderTitle(this),
|
a.appendChild(title)
|
||||||
a = L.DomUtil.add('a');
|
return 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({
|
L.U.Slideshow = L.Class.extend({
|
||||||
|
statics: {
|
||||||
|
CLASSNAME: 'umap-slideshow-active',
|
||||||
|
},
|
||||||
|
|
||||||
statics: {
|
options: {
|
||||||
CLASSNAME: 'umap-slideshow-active'
|
delay: 5000,
|
||||||
},
|
autoplay: false,
|
||||||
|
},
|
||||||
|
|
||||||
options: {
|
initialize: function (map, options) {
|
||||||
delay: 5000,
|
this.setOptions(options)
|
||||||
autoplay: false
|
this.map = map
|
||||||
},
|
this._id = null
|
||||||
|
var current = null, // current feature
|
||||||
initialize: function (map, options) {
|
self = this
|
||||||
this.setOptions(options);
|
try {
|
||||||
this.map = map;
|
Object.defineProperty(this, 'current', {
|
||||||
this._id = null;
|
get: function () {
|
||||||
var current = null, // current feature
|
if (!current) {
|
||||||
self = this;
|
var datalayer = this.defaultDatalayer()
|
||||||
try {
|
if (datalayer) current = datalayer.getFeatureByIndex(0)
|
||||||
Object.defineProperty(this, 'current', {
|
}
|
||||||
get: function () {
|
return current
|
||||||
if (!current) {
|
},
|
||||||
var datalayer = this.defaultDatalayer();
|
set: function (feature) {
|
||||||
if (datalayer) current = datalayer.getFeatureByIndex(0);
|
current = feature
|
||||||
}
|
},
|
||||||
return current;
|
})
|
||||||
},
|
} catch (e) {
|
||||||
set: function (feature) {
|
// Certainly IE8, which has a limited version of defineProperty
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
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({
|
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) {
|
renderHeaders: function () {
|
||||||
this.datalayer = datalayer;
|
this.header.innerHTML = ''
|
||||||
this.table = L.DomUtil.create('div', 'table');
|
for (var i = 0; i < this.properties.length; i++) {
|
||||||
this.header = L.DomUtil.create('div', 'thead', this.table);
|
this.renderHeader(this.properties[i])
|
||||||
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});
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
});
|
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({
|
L.U.UI = L.Evented.extend({
|
||||||
|
ALERTS: Array(),
|
||||||
|
ALERT_ID: null,
|
||||||
|
TOOLTIP_ID: null,
|
||||||
|
|
||||||
ALERTS: Array(),
|
initialize: function (parent) {
|
||||||
ALERT_ID: null,
|
this.parent = parent
|
||||||
TOOLTIP_ID: null,
|
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) {
|
resetPanelClassName: function () {
|
||||||
this.parent = parent;
|
this._panel.className = 'with-transition'
|
||||||
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 () {
|
openPanel: function (e) {
|
||||||
this._panel.className = 'with-transition';
|
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) {
|
closePanel: function () {
|
||||||
this.fire('panel:open');
|
this.resetPanelClassName()
|
||||||
// We reset all because we can't know which class has been added
|
L.DomUtil.removeClass(this.parent, 'umap-ui')
|
||||||
// by previous ui processes...
|
this.fire('panel:closed')
|
||||||
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 () {
|
alert: function (e) {
|
||||||
this.resetPanelClassName();
|
if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e)
|
||||||
L.DomUtil.removeClass(this.parent, 'umap-ui');
|
else this.popAlert(e)
|
||||||
this.fire('panel:closed');
|
},
|
||||||
},
|
|
||||||
|
|
||||||
alert: function (e) {
|
popAlert: function (e) {
|
||||||
if (L.DomUtil.hasClass(this.parent, 'umap-alert')) this.ALERTS.push(e);
|
var self = this
|
||||||
else this.popAlert(e);
|
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) {
|
tooltip: function (e) {
|
||||||
var self = this;
|
this.TOOLTIP_ID = Math.random()
|
||||||
if(!e) {
|
var id = this.TOOLTIP_ID
|
||||||
if (this.ALERTS.length) e = this.ALERTS.pop();
|
L.DomUtil.addClass(this.parent, 'umap-tooltip')
|
||||||
else return;
|
if (e.anchor && e.position === 'top') this.anchorTooltipTop(e.anchor)
|
||||||
}
|
else if (e.anchor && e.position === 'left') this.anchorTooltipLeft(e.anchor)
|
||||||
var timeoutID,
|
else this.anchorTooltipAbsolute()
|
||||||
level_class = e.level && e.level == 'info'? 'info': 'error';
|
this._tooltip.innerHTML = e.content
|
||||||
this._alert.innerHTML = '';
|
function closeIt() {
|
||||||
L.DomUtil.addClass(this.parent, 'umap-alert');
|
this.closeTooltip(id)
|
||||||
L.DomUtil.addClass(this._alert, level_class);
|
}
|
||||||
var close = function () {
|
if (e.anchor) L.DomEvent.once(e.anchor, 'mouseout', closeIt, this)
|
||||||
if (timeoutID !== this.ALERT_ID) { return;} // Another alert has been forced
|
if (e.duration !== Infinity)
|
||||||
this._alert.innerHTML = '';
|
window.setTimeout(L.bind(closeIt, this), e.duration || 3000)
|
||||||
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) {
|
anchorTooltipAbsolute: function () {
|
||||||
this.TOOLTIP_ID = Math.random();
|
this._tooltip.className = ''
|
||||||
var id = this.TOOLTIP_ID;
|
var left =
|
||||||
L.DomUtil.addClass(this.parent, 'umap-tooltip');
|
this.parent.offsetLeft +
|
||||||
if (e.anchor && e.position === 'top') this.anchorTooltipTop(e.anchor);
|
this.parent.clientWidth / 2 -
|
||||||
else if (e.anchor && e.position === 'left') this.anchorTooltipLeft(e.anchor);
|
this._tooltip.clientWidth / 2,
|
||||||
else this.anchorTooltipAbsolute();
|
top = this.parent.offsetTop + 75
|
||||||
this._tooltip.innerHTML = e.content;
|
this.setTooltipPosition({ top: top, left: left })
|
||||||
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 () {
|
anchorTooltipTop: function (el) {
|
||||||
this._tooltip.className = '';
|
this._tooltip.className = 'tooltip-top'
|
||||||
var left = this.parent.offsetLeft + (this.parent.clientWidth / 2) - (this._tooltip.clientWidth / 2),
|
var coords = this.getPosition(el)
|
||||||
top = this.parent.offsetTop + 75;
|
this.setTooltipPosition({
|
||||||
this.setTooltipPosition({top: top, left: left});
|
left: coords.left - 10,
|
||||||
},
|
bottom: this.getDocHeight() - coords.top + 11,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
anchorTooltipTop: function (el) {
|
anchorTooltipLeft: function (el) {
|
||||||
this._tooltip.className = 'tooltip-top';
|
this._tooltip.className = 'tooltip-left'
|
||||||
var coords = this.getPosition(el);
|
var coords = this.getPosition(el)
|
||||||
this.setTooltipPosition({left: coords.left - 10, bottom: this.getDocHeight() - coords.top + 11});
|
this.setTooltipPosition({
|
||||||
},
|
top: coords.top,
|
||||||
|
right: document.documentElement.offsetWidth - coords.left + 11,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
anchorTooltipLeft: function (el) {
|
closeTooltip: function (id) {
|
||||||
this._tooltip.className = 'tooltip-left';
|
if (id && id !== this.TOOLTIP_ID) return
|
||||||
var coords = this.getPosition(el);
|
this._tooltip.innerHTML = ''
|
||||||
this.setTooltipPosition({top: coords.top, right: document.documentElement.offsetWidth - coords.left + 11});
|
L.DomUtil.removeClass(this.parent, 'umap-tooltip')
|
||||||
},
|
},
|
||||||
|
|
||||||
closeTooltip: function (id) {
|
getPosition: function (el) {
|
||||||
if (id && id !== this.TOOLTIP_ID) return;
|
return el.getBoundingClientRect()
|
||||||
this._tooltip.innerHTML = '';
|
},
|
||||||
L.DomUtil.removeClass(this.parent, 'umap-tooltip');
|
|
||||||
},
|
|
||||||
|
|
||||||
getPosition: function (el) {
|
setTooltipPosition: function (coords) {
|
||||||
return el.getBoundingClientRect();
|
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) {
|
getDocHeight: function () {
|
||||||
if (coords.left) this._tooltip.style.left = coords.left + 'px';
|
var D = document
|
||||||
else this._tooltip.style.left = 'initial';
|
return Math.max(
|
||||||
if (coords.right) this._tooltip.style.right = coords.right + 'px';
|
D.body.scrollHeight,
|
||||||
else this._tooltip.style.right = 'initial';
|
D.documentElement.scrollHeight,
|
||||||
if (coords.top) this._tooltip.style.top = coords.top + 'px';
|
D.body.offsetHeight,
|
||||||
else this._tooltip.style.top = 'initial';
|
D.documentElement.offsetHeight,
|
||||||
if (coords.bottom) this._tooltip.style.bottom = coords.bottom + 'px';
|
D.body.clientHeight,
|
||||||
else this._tooltip.style.bottom = 'initial';
|
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({
|
L.U.Xhr = L.Evented.extend({
|
||||||
|
initialize: function (ui) {
|
||||||
|
this.ui = ui
|
||||||
|
},
|
||||||
|
|
||||||
initialize: function (ui) {
|
_wrapper: function () {
|
||||||
this.ui = ui;
|
var wrapper
|
||||||
},
|
if (window.XMLHttpRequest === undefined) {
|
||||||
|
wrapper = function () {
|
||||||
_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});};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
xhr.open(settings.verb, settings.uri, true);
|
return new window.ActiveXObject('Microsoft.XMLHTTP.6.0')
|
||||||
} catch (err) {
|
} catch (e1) {
|
||||||
// Unknown protocol?
|
try {
|
||||||
this.ui.alert({content: L._('Error while fetching {url}', {url: settings.uri}), level: 'error'});
|
return new window.ActiveXObject('Microsoft.XMLHTTP.3.0')
|
||||||
loaded();
|
} catch (e2) {
|
||||||
return
|
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) {
|
_ajax: function (settings) {
|
||||||
// "X-" mode headers cause the request to be in preflight mode,
|
var xhr = this._wrapper(),
|
||||||
// we don"t want that by default for CORS requests
|
id = Math.random(),
|
||||||
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
self = this
|
||||||
}
|
this.fire('dataloading', { id: id })
|
||||||
if (settings.headers) {
|
var loaded = function () {
|
||||||
for (var name in settings.headers) {
|
self.fire('dataload', { id: id })
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
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