Split popupTemplate in popupShape + popupTemplate

cf #600
This commit is contained in:
Yohan Boniface 2018-08-15 17:07:21 +02:00
parent 81f6b429bc
commit 6ad9df8044
8 changed files with 153 additions and 140 deletions

View file

@ -55,6 +55,10 @@ COMMIT;
- fixed popup template parsing of url with url as query string (#607) - fixed popup template parsing of url with url as query string (#607)
- naive support for nested variables in templates (#600) - naive support for nested variables in templates (#600)
- Removed Map.tilelayer foreignkey - Removed Map.tilelayer foreignkey
- split popupTemplate in popupShape and popupTemplate: popupShape is for
choosing between proper popup and panel, while popupTemplate now will allow
to choose between default "name + description" mode, or table, or geoRss ones.
Allows to add more of those in the future also.
## 1.0.0.rc-1 ## 1.0.0.rc-1
- BREAKING: support of python 2 is removed per upgrading to Django 2.0 - BREAKING: support of python 2 is removed per upgrading to Django 2.0

View file

@ -585,7 +585,7 @@ input[type=hidden].blur + .button {
} }
#umap-ui-container { #umap-ui-container {
width: 400px; width: 400px;
position: fixed; position: absolute;
top: 0; top: 0;
bottom: 0; bottom: 0;
right: -400px; right: -400px;
@ -597,6 +597,10 @@ input[type=hidden].blur + .button {
opacity: 0.98; opacity: 0.98;
cursor: initial; cursor: initial;
} }
#umap-ui-container.login-panel {
position: fixed; /* Should not scroll when used in content pages (like home page) */
z-index: 1011; /* Above a map panel if any */
}
#umap-ui-container.dark { #umap-ui-container.dark {
border-left: 1px solid #222; border-left: 1px solid #222;
background-color: #323737; background-color: #323737;

View file

@ -143,6 +143,7 @@ L.U.FeatureMixin = {
getInteractionOptions: function () { getInteractionOptions: function () {
return [ return [
'properties._umap_options.popupShape',
'properties._umap_options.popupTemplate', 'properties._umap_options.popupTemplate',
'properties._umap_options.showLabel', 'properties._umap_options.showLabel',
'properties._umap_options.labelDirection', 'properties._umap_options.labelDirection',
@ -165,7 +166,8 @@ L.U.FeatureMixin = {
}, },
getPopupClass: function () { getPopupClass: function () {
return L.U.Popup[this.getOption('popupTemplate')] || L.U.Popup; var old = this.getOption('popupTemplate'); // Retrocompat.
return L.U.Popup[this.getOption('popupShape') || old] || L.U.Popup;
}, },
attachPopup: function () { attachPopup: function () {

View file

@ -212,23 +212,24 @@ L.FormBuilder.ProxyTTLSelect = L.FormBuilder.Select.extend({
}); });
L.FormBuilder.PopupTemplate = L.FormBuilder.Select.extend({ L.FormBuilder.PopupShape = L.FormBuilder.Select.extend({
selectOptions: [ selectOptions: [
['Default', L._('Name and description')], ['Default', L._('Popup')],
['Large', L._('Name and description (large)')], ['Large', L._('Popup (large)')],
['Panel', L._('Side panel')],
]
});
L.FormBuilder.PopupContent = L.FormBuilder.Select.extend({
selectOptions: [
['Default', L._('Default')],
['Table', L._('Table')], ['Table', L._('Table')],
['GeoRSSImage', L._('GeoRSS (title + image)')], ['GeoRSSImage', L._('GeoRSS (title + image)')],
['GeoRSSLink', L._('GeoRSS (only link)')], ['GeoRSSLink', L._('GeoRSS (only link)')],
['SimplePanel', L._('Side panel')], ]
['TablePanel', L._('Side panel')]
],
toJS: function () {
var value = L.FormBuilder.Select.prototype.toJS.apply(this);
if (value === 'table') { value = 'Table'; }
return value;
}
}); });
@ -735,7 +736,8 @@ L.U.FormBuilder = L.FormBuilder.extend({
dashArray: {label: L._('dash array'), helpEntries: 'dashArray', inheritable: true}, dashArray: {label: L._('dash array'), helpEntries: 'dashArray', inheritable: true},
iconClass: {handler: 'IconClassSwitcher', label: L._('Icon shape'), inheritable: true}, iconClass: {handler: 'IconClassSwitcher', label: L._('Icon shape'), inheritable: true},
iconUrl: {handler: 'IconUrl', label: L._('Icon symbol'), inheritable: true, helpText: L.U.Help.formatIconSymbol}, iconUrl: {handler: 'IconUrl', label: L._('Icon symbol'), inheritable: true, helpText: L.U.Help.formatIconSymbol},
popupTemplate: {handler: 'PopupTemplate', label: L._('Popup style'), inheritable: true}, popupShape: {handler: 'PopupShape', label: L._('Popup shape'), inheritable: true},
popupTemplate: {handler: 'PopupContent', label: L._('Popup content style'), inheritable: true},
popupContentTemplate: {label: L._('Popup content template'), handler: 'Textarea', helpEntries: ['dynamicProperties', 'textFormatting'], placeholder: '# {name}', inheritable: true}, popupContentTemplate: {label: L._('Popup content template'), handler: 'Textarea', helpEntries: ['dynamicProperties', 'textFormatting'], placeholder: '# {name}', inheritable: true},
datalayer: {handler: 'DataLayerSwitcher', label: L._('Choose the layer of the feature')}, datalayer: {handler: 'DataLayerSwitcher', label: L._('Choose the layer of the feature')},
moreControl: {handler: 'Switch', label: L._('Do you want to display the «more» control?')}, moreControl: {handler: 'Switch', label: L._('Do you want to display the «more» control?')},

View file

@ -1003,6 +1003,7 @@ L.U.Map.include({
'fillColor', 'fillColor',
'fillOpacity', 'fillOpacity',
'dashArray', 'dashArray',
'popupShape',
'popupTemplate', 'popupTemplate',
'popupContentTemplate', 'popupContentTemplate',
'zoomTo', 'zoomTo',
@ -1213,6 +1214,7 @@ L.U.Map.include({
defaultProperties.appendChild(builder.build()); defaultProperties.appendChild(builder.build());
var popupFields = [ var popupFields = [
'options.popupShape',
'options.popupTemplate', 'options.popupTemplate',
'options.popupContentTemplate', 'options.popupContentTemplate',
'options.showLabel', 'options.showLabel',
@ -1221,7 +1223,7 @@ L.U.Map.include({
]; ];
builder = new L.U.FormBuilder(this, popupFields, { builder = new L.U.FormBuilder(this, popupFields, {
callback: function (e) { callback: function (e) {
if (e.helper.field === 'options.popupTemplate' || e.helper.field === 'options.popupContentTemplate') return; if (e.helper.field === 'options.popupTemplate' || e.helper.field === 'options.popupContentTemplate' || e.helper.field === 'options.popupShape') return;
this.eachDataLayer(function (datalayer) { this.eachDataLayer(function (datalayer) {
datalayer.redraw(); datalayer.redraw();
}) })

View file

@ -781,6 +781,7 @@ L.U.DataLayer = L.Class.extend({
advancedProperties.appendChild(builder.build()); advancedProperties.appendChild(builder.build());
var popupFields = [ var popupFields = [
'options.popupShape',
'options.popupTemplate', 'options.popupTemplate',
'options.popupContentTemplate', 'options.popupContentTemplate',
'options.showLabel', 'options.showLabel',

View file

@ -1,3 +1,5 @@
/* Shapes */
L.U.Popup = L.Popup.extend({ L.U.Popup = L.Popup.extend({
options: { options: {
@ -12,68 +14,19 @@ L.U.Popup = L.Popup.extend({
this.setContent(this.container); this.setContent(this.container);
}, },
hasFooter: function () { format: function () {
return this.feature.hasPopupFooter(); var mode = this.feature.getOption('popupTemplate') || 'Default',
}, klass = L.U.PopupTemplate[mode] || L.U.PopupTemplate.Default;
this.content = new klass(this.feature, this.container);
renderTitle: function () {}, this.content.render();
var els = this.container.querySelectorAll('img,iframe');
renderBody: function () {
var template = this.feature.getOption('popupContentTemplate'),
container = L.DomUtil.create('div', ''),
content = '', properties, center;
if (this.options.parseTemplate) {
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;
var els = container.querySelectorAll('img,iframe');
for (var i = 0; i < els.length; i++) { for (var i = 0; i < els.length; i++) {
this.onElementLoaded(els[i]); this.onElementLoaded(els[i]);
} }
if (!els.length && container.textContent.replace('\n', '') === '') { if (!els.length && this.container.textContent.replace('\n', '') === '') {
container.innerHTML = ''; this.container.innerHTML = '';
L.DomUtil.add('h3', '', container, this.feature.getDisplayName()); L.DomUtil.add('h3', '', this.container, this.feature.getDisplayName());
} }
return container;
},
renderFooter: function () {
if (this.hasFooter()) {
var footer = L.DomUtil.create('ul', 'umap-popup-footer', this.container),
previousLi = L.DomUtil.create('li', 'previous', footer),
zoomLi = L.DomUtil.create('li', 'zoom', footer),
nextLi = L.DomUtil.create('li', 'next', footer),
next = this.feature.getNext(),
prev = this.feature.getPrevious();
if (next) {
nextLi.title = L._('Go to «{feature}»', {feature: next.properties.name || L._('next')});
}
if (prev) {
previousLi.title = L._('Go to «{feature}»', {feature: prev.properties.name || L._('previous')});
}
zoomLi.title = L._('Zoom to this feature');
L.DomEvent.on(nextLi, 'click', function () {
if (next) next.bringToCenter({zoomTo: next.getOption('zoomTo'), callback: next.view});
});
L.DomEvent.on(previousLi, 'click', function () {
if (prev) prev.bringToCenter({zoomTo: prev.getOption('zoomTo'), callback: prev.view});
});
L.DomEvent.on(zoomLi, 'click', function () {
this.bringToCenter({zoomTo: this.getOption('zoomTo')});
}, this.feature);
}
},
format: 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();
}, },
onElementLoaded: function (el) { onElementLoaded: function (el) {
@ -93,63 +46,13 @@ L.U.Popup.Large = L.U.Popup.extend({
} }
}); });
L.U.Popup.BaseWithTitle = L.U.Popup.extend({
renderTitle: function () { L.U.Popup.Panel = L.U.Popup.extend({
var title;
if (this.feature.getDisplayName()) {
title = L.DomUtil.create('h3', 'popup-title');
title.innerHTML = L.Util.escapeHTML(this.feature.getDisplayName());
}
return title;
}
});
L.U.Popup.GeoRSSImage = L.U.Popup.BaseWithTitle.extend({
options: { options: {
minWidth: 300, zoomAnimation: false
maxWidth: 500,
className: 'umap-popup-large umap-georss-image'
}, },
renderBody: function () {
var container = L.DomUtil.create('a');
container.href = this.feature.properties.link;
container.target = '_blank';
if (this.feature.properties.img) {
var img = L.DomUtil.create('img', '', container);
img.src = this.feature.properties.img;
// Sadly, we are unable to override this from JS the clean way
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
img.style.maxWidth = this.options.maxWidth + 'px';
img.style.maxHeight = this.options.maxWidth + 'px';
this.onElementLoaded(img);
}
return container;
}
});
L.U.Popup.GeoRSSLink = L.U.Popup.extend({
options: {
className: 'umap-georss-link'
},
renderBody: function () {
var title = this.renderTitle(this),
a = L.DomUtil.add('a');
a.href = this.feature.properties.link;
a.target = '_blank';
a.appendChild(title);
return a;
}
});
L.U.Popup.PanelMixin = {
allButton: function () { allButton: function () {
var button = L.DomUtil.create('li', ''); var button = L.DomUtil.create('li', '');
L.DomUtil.create('i', 'umap-icon-16 umap-list', button); L.DomUtil.create('i', 'umap-icon-16 umap-list', button);
@ -173,20 +76,70 @@ L.U.Popup.PanelMixin = {
_updatePosition: function () {}, _updatePosition: function () {},
_adjustPan: function () {} _adjustPan: function () {}
});
L.U.Popup.SimplePanel = L.U.Popup.Panel; // Retrocompat.
/* Content templates */
L.U.PopupTemplate = {};
L.U.PopupTemplate.Default = L.Class.extend({
initialize: function (feature, container) {
this.feature = feature;
this.container = container;
},
renderTitle: function () {},
renderBody: function () {
var template = this.feature.getOption('popupContentTemplate'),
container = L.DomUtil.create('div', ''),
content = '', properties, center;
properties = this.feature.extendedProperties();
// Resolve properties inside description
properties.description = L.Util.greedyTemplate(this.feature.properties.description || '', properties);
content = L.Util.greedyTemplate(template, properties);
content = L.Util.toHTML(content);
container.innerHTML = content;
return container;
},
renderFooter: function () {
if (this.feature.hasPopupFooter()) {
var footer = L.DomUtil.create('ul', 'umap-popup-footer', this.container),
previousLi = L.DomUtil.create('li', 'previous', footer),
zoomLi = L.DomUtil.create('li', 'zoom', footer),
nextLi = L.DomUtil.create('li', 'next', footer),
next = this.feature.getNext(),
prev = this.feature.getPrevious();
if (next) nextLi.title = L._('Go to «{feature}»', {feature: next.properties.name || L._('next')});
if (prev) previousLi.title = L._('Go to «{feature}»', {feature: prev.properties.name || L._('previous')});
zoomLi.title = L._('Zoom to this feature');
L.DomEvent.on(nextLi, 'click', function () {
if (next) next.bringToCenter({zoomTo: next.getOption('zoomTo'), callback: next.view});
});
L.DomEvent.on(previousLi, 'click', function () {
if (prev) prev.bringToCenter({zoomTo: prev.getOption('zoomTo'), callback: prev.view});
});
L.DomEvent.on(zoomLi, 'click', function () {
this.bringToCenter({zoomTo: this.getOption('zoomTo')});
}, this.feature);
} }
},
L.U.Popup.SimplePanel = L.U.Popup.extend({ render: function () {
var title = this.renderTitle();
includes: L.U.Popup.PanelMixin, if (title) this.container.appendChild(title);
var body = this.renderBody();
options: { if (body) L.DomUtil.add('div', 'umap-popup-content', this.container, body);
zoomAnimation: false this.renderFooter();
} }
}); });
L.U.Popup.TableMixin = { L.U.PopupTemplate.Table = L.U.PopupTemplate.Default.extend({
formatRow: function (key, value) { formatRow: function (key, value) {
if (value.indexOf('http') === 0) { if (value.indexOf('http') === 0) {
@ -212,14 +165,59 @@ L.U.Popup.TableMixin = {
return table; return table;
} }
};
L.U.Popup.Table = L.U.Popup.BaseWithTitle.extend({
includes: L.U.Popup.TableMixin
}); });
L.U.Popup.table = L.U.Popup.Table; // backward compatibility L.U.PopupTemplate.BaseWithTitle = L.U.PopupTemplate.Default.extend({
renderTitle: function () {
var title;
if (this.feature.getDisplayName()) {
title = L.DomUtil.create('h3', 'popup-title');
title.innerHTML = L.Util.escapeHTML(this.feature.getDisplayName());
}
return title;
}
L.U.Popup.TablePanel = L.U.Popup.extend({ });
includes: [L.U.Popup.PanelMixin, L.U.Popup.TableMixin]
L.U.PopupTemplate.GeoRSSImage = L.U.PopupTemplate.BaseWithTitle.extend({
options: {
minWidth: 300,
maxWidth: 500,
className: 'umap-popup-large umap-georss-image'
},
renderBody: function () {
var container = L.DomUtil.create('a');
container.href = this.feature.properties.link;
container.target = '_blank';
if (this.feature.properties.img) {
var img = L.DomUtil.create('img', '', container);
img.src = this.feature.properties.img;
// Sadly, we are unable to override this from JS the clean way
// See https://github.com/Leaflet/Leaflet/commit/61d746818b99d362108545c151a27f09d60960ee#commitcomment-6061847
img.style.maxWidth = this.options.maxWidth + 'px';
img.style.maxHeight = this.options.maxWidth + 'px';
this.onElementLoaded(img);
}
return container;
}
});
L.U.PopupTemplate.GeoRSSLink = L.U.PopupTemplate.Default.extend({
options: {
className: 'umap-georss-link'
},
renderBody: function () {
var title = this.renderTitle(this),
a = L.DomUtil.add('a');
a.href = this.feature.properties.link;
a.target = '_blank';
a.appendChild(title);
return a;
}
}); });

View file

@ -242,7 +242,7 @@ L.U.Xhr = L.Evented.extend({
else self.default_callback(data, {}); else self.default_callback(data, {});
}; };
var ask_for_login = function (data) { var ask_for_login = function (data) {
self.ui.openPanel({'data': data}); self.ui.openPanel({'data': data, className: 'login-panel'});
self.listen_form('login_form', { self.listen_form('login_form', {
'callback': function (data) { 'callback': function (data) {
if (data.html) ask_for_login(data); // Problem in the login - ask again if (data.html) ask_for_login(data); // Problem in the login - ask again