' +
this.mapsvg.options.menu.noResultsText +
"
");
}
if (_this.mapsvg.options.menu.categories.on) {
if (_this.mapsvg.options.menu.categories.collapse && items.length > 1) {
$$9(this.containers.contentView).find(".mapsvg-category-block").addClass("collapsed");
}
else if (_this.mapsvg.options.menu.categories.collapse && items.length === 1) {
$$9(this.containers.contentView).find(".mapsvg-category-item").addClass("active");
$$9(this.containers.contentView).find(".mapsvg-category-block").addClass("active");
const panel = $$9(this.containers.contentView).find(".mapsvg-category-block")[0];
if (panel)
panel.style.maxHeight = panel.scrollHeight + "px";
}
else if (!_this.mapsvg.options.menu.categories.collapse) {
$$9(this.containers.contentView).find(".mapsvg-category-item").addClass("active");
$$9(this.containers.contentView).find(".mapsvg-category-block").addClass("active");
const panels = $$9(this.containers.contentView).find(".mapsvg-category-block");
if (panels.length)
panels.each(function (i, panel) {
panel.style.maxHeight = panel.scrollHeight + "px";
});
}
}
this.updateTopShift();
this.updateScroll();
}
toggle(on) {
const _this = this;
if (on) {
$$9(this.containers.main).parent().show();
$$9(_this.mapsvg.containers.mapContainer).hide();
$$9(this.menuBtn).addClass("active");
$$9(this.mapBtn).removeClass("active");
}
else {
$$9(this.containers.main).parent().hide();
$$9(_this.mapsvg.containers.mapContainer).show();
$$9(this.menuBtn).removeClass("active");
$$9(this.mapBtn).addClass("active");
}
if (!$$9(this.containers.main).parent().is(":visible")) {
if (MapSVG.isPhone) {
$$9(_this.mapsvg.containers.wrap).css("height", "auto");
_this.updateScroll();
}
}
else {
if (MapSVG.isPhone &&
$$9(this.containers.main).height() < parseInt(this.mapsvg.options.menu.minHeight)) {
$$9(_this.mapsvg.containers.wrap).css("height", parseInt(this.mapsvg.options.menu.minHeight) + "px");
_this.updateScroll();
}
}
this.updateTopShift();
}
addPagination(pager) {
$$9(this.containers.contentView).append('');
$$9(this.containers.contentView).find(".mapsvg-pagination-container").html(pager);
}
convertId(id) {
return (id + "")
.split(" ")
.join("_")
.replace(/(:|\(|\)|\.|\[|\]|,|=|@)/g, "\\$1");
}
}
const $$a = jQuery;
class DetailsController extends Controller {
constructor(options) {
super(options);
this.modal = options.modal;
}
getToolbarTemplate() {
if (this.withToolbar)
return '
* @license MIT
*/
(function sortableModule(factory) {
{
module.exports = factory();
}
})(function sortableFactory() {
if (typeof window == "undefined" || !window.document) {
return function sortableError() {
throw new Error("Sortable.js requires a window with a document");
};
}
var dragEl,
parentEl,
ghostEl,
cloneEl,
rootEl,
nextEl,
scrollEl,
scrollParentEl,
scrollCustomFn,
lastEl,
lastCSS,
lastParentCSS,
oldIndex,
newIndex,
activeGroup,
putSortable,
autoScroll = {},
tapEvt,
touchEvt,
moved,
/** @const */
RSPACE = /\s+/g,
expando = "Sortable" + new Date().getTime(),
win = window,
document = win.document,
parseInt = win.parseInt,
$ = win.jQuery || win.Zepto,
Polymer = win.Polymer,
supportDraggable = !!("draggable" in document.createElement("div")),
supportCssPointerEvents = (function (el) {
// false when IE11
if (navigator.userAgent.match(/Trident.*rv[ :]?11\./)) {
return false;
}
el = document.createElement("x");
el.style.cssText = "pointer-events:auto";
return el.style.pointerEvents === "auto";
})(),
_silent = false,
abs = Math.abs,
min = Math.min,
touchDragOverListeners = [],
_autoScroll = _throttle(function (
/**Event*/ evt,
/**Object*/ options,
/**HTMLElement*/ rootEl
) {
// Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=505521
if (rootEl && options.scroll) {
var el,
rect,
sens = options.scrollSensitivity,
speed = options.scrollSpeed,
x = evt.clientX,
y = evt.clientY,
winWidth = window.innerWidth,
winHeight = window.innerHeight,
vx,
vy,
scrollOffsetX,
scrollOffsetY;
// Delect scrollEl
if (scrollParentEl !== rootEl) {
scrollEl = options.scroll;
scrollParentEl = rootEl;
scrollCustomFn = options.scrollFn;
if (scrollEl === true) {
scrollEl = rootEl;
do {
if (
scrollEl.offsetWidth < scrollEl.scrollWidth ||
scrollEl.offsetHeight < scrollEl.scrollHeight
) {
break;
}
/* jshint boss:true */
} while ((scrollEl = scrollEl.parentNode));
}
}
if (scrollEl) {
el = scrollEl;
rect = scrollEl.getBoundingClientRect();
vx = (abs(rect.right - x) <= sens) - (abs(rect.left - x) <= sens);
vy = (abs(rect.bottom - y) <= sens) - (abs(rect.top - y) <= sens);
}
if (!(vx || vy)) {
vx = (winWidth - x <= sens) - (x <= sens);
vy = (winHeight - y <= sens) - (y <= sens);
/* jshint expr:true */
(vx || vy) && (el = win);
}
if (autoScroll.vx !== vx || autoScroll.vy !== vy || autoScroll.el !== el) {
autoScroll.el = el;
autoScroll.vx = vx;
autoScroll.vy = vy;
clearInterval(autoScroll.pid);
if (el) {
autoScroll.pid = setInterval(function () {
scrollOffsetY = vy ? vy * speed : 0;
scrollOffsetX = vx ? vx * speed : 0;
if ("function" === typeof scrollCustomFn) {
return scrollCustomFn.call(
_this,
scrollOffsetX,
scrollOffsetY,
evt
);
}
if (el === win) {
win.scrollTo(
win.pageXOffset + scrollOffsetX,
win.pageYOffset + scrollOffsetY
);
} else {
el.scrollTop += scrollOffsetY;
el.scrollLeft += scrollOffsetX;
}
}, 24);
}
}
}
},
30),
_prepareGroup = function (options) {
function toFn(value, pull) {
if (value === void 0 || value === true) {
value = group.name;
}
if (typeof value === "function") {
return value;
} else {
return function (to, from) {
var fromGroup = from.options.group.name;
return pull
? value
: value &&
(value.join ? value.indexOf(fromGroup) > -1 : fromGroup == value);
};
}
}
var group = {};
var originalGroup = options.group;
if (!originalGroup || typeof originalGroup != "object") {
originalGroup = { name: originalGroup };
}
group.name = originalGroup.name;
group.checkPull = toFn(originalGroup.pull, true);
group.checkPut = toFn(originalGroup.put);
options.group = group;
};
/**
* @class Sortable
* @param {HTMLElement} el
* @param {Object} [options]
*/
function Sortable(el, options) {
if (!(el && el.nodeType && el.nodeType === 1)) {
throw "Sortable: `el` must be HTMLElement, and not " + {}.toString.call(el);
}
this.el = el; // root element
this.options = options = _extend({}, options);
// Export instance
el[expando] = this;
// Default options
var defaults = {
group: Math.random(),
sort: true,
disabled: false,
store: null,
handle: null,
scroll: true,
scrollSensitivity: 30,
scrollSpeed: 10,
draggable: /[uo]l/i.test(el.nodeName) ? "li" : ">*",
ghostClass: "sortable-ghost",
chosenClass: "sortable-chosen",
dragClass: "sortable-drag",
ignore: "a, img",
filter: null,
animation: 0,
setData: function (dataTransfer, dragEl) {
dataTransfer.setData("Text", dragEl.textContent);
},
dropBubble: false,
dragoverBubble: false,
dataIdAttr: "data-id",
delay: 0,
forceFallback: false,
fallbackClass: "sortable-fallback",
fallbackOnBody: false,
fallbackTolerance: 0,
fallbackOffset: { x: 0, y: 0 },
};
// Set default options
for (var name in defaults) {
!(name in options) && (options[name] = defaults[name]);
}
_prepareGroup(options);
// Bind all private methods
for (var fn in this) {
if (fn.charAt(0) === "_" && typeof this[fn] === "function") {
this[fn] = this[fn].bind(this);
}
}
// Setup drag mode
this.nativeDraggable = options.forceFallback ? false : supportDraggable;
// Bind events
_on(el, "mousedown", this._onTapStart);
_on(el, "touchstart", this._onTapStart);
if (this.nativeDraggable) {
_on(el, "dragover", this);
_on(el, "dragenter", this);
}
touchDragOverListeners.push(this._onDragOver);
// Restore sorting
options.store && this.sort(options.store.get(this));
}
Sortable.prototype = /** @lends Sortable.prototype */ {
constructor: Sortable,
_onTapStart: function (/** Event|TouchEvent */ evt) {
if (evt.target.tagName == "i" || evt.target.tagName == "I") {
evt.target.click();
return;
}
var _this = this,
el = this.el,
options = this.options,
type = evt.type,
touch = evt.touches && evt.touches[0],
target = (touch || evt).target,
originalTarget = (evt.target.shadowRoot && evt.path[0]) || target,
filter = options.filter,
startIndex;
// Don't trigger start event when an element is been dragged, otherwise the evt.oldindex always wrong when set option.group.
if (dragEl) {
return;
}
if ((type === "mousedown" && evt.button !== 0) || options.disabled) {
return; // only left button or enabled
}
if (options.handle && !_closest(originalTarget, options.handle, el)) {
return;
}
target = _closest(target, options.draggable, el);
if (!target) {
return;
}
// Get the index of the dragged element within its parent
startIndex = _index(target, options.draggable);
// Check filter
if (typeof filter === "function") {
if (filter.call(this, evt, target, this)) {
_dispatchEvent(_this, originalTarget, "filter", target, el, startIndex);
evt.preventDefault();
return; // cancel dnd
}
} else if (filter) {
filter = filter.split(",").some(function (criteria) {
criteria = _closest(originalTarget, criteria.trim(), el);
if (criteria) {
_dispatchEvent(_this, criteria, "filter", target, el, startIndex);
return true;
}
});
if (filter) {
evt.preventDefault();
return; // cancel dnd
}
}
// Prepare `dragstart`
this._prepareDragStart(evt, touch, target, startIndex);
},
_prepareDragStart: function (
/** Event */ evt,
/** Touch */ touch,
/** HTMLElement */ target,
/** Number */ startIndex
) {
var _this = this,
el = _this.el,
options = _this.options,
ownerDocument = el.ownerDocument,
dragStartFn;
if (target && !dragEl && target.parentNode === el) {
tapEvt = evt;
rootEl = el;
dragEl = target;
parentEl = dragEl.parentNode;
nextEl = dragEl.nextSibling;
activeGroup = options.group;
oldIndex = startIndex;
this._lastX = (touch || evt).clientX;
this._lastY = (touch || evt).clientY;
dragEl.style["will-change"] = "transform";
dragStartFn = function () {
// Delayed drag has been triggered
// we can re-enable the events: touchmove/mousemove
_this._disableDelayedDrag();
// Make the element draggable
dragEl.draggable = _this.nativeDraggable;
// Chosen item
_toggleClass(dragEl, options.chosenClass, true);
// Bind the events: dragstart/dragend
_this._triggerDragStart(touch);
// Drag start event
_dispatchEvent(_this, rootEl, "choose", dragEl, rootEl, oldIndex);
};
// Disable "draggable"
options.ignore.split(",").forEach(function (criteria) {
_find(dragEl, criteria.trim(), _disableDraggable);
});
_on(ownerDocument, "mouseup", _this._onDrop);
_on(ownerDocument, "touchend", _this._onDrop);
_on(ownerDocument, "touchcancel", _this._onDrop);
if (options.delay) {
// If the user moves the pointer or let go the click or touch
// before the delay has been reached:
// disable the delayed drag
_on(ownerDocument, "mouseup", _this._disableDelayedDrag);
_on(ownerDocument, "touchend", _this._disableDelayedDrag);
_on(ownerDocument, "touchcancel", _this._disableDelayedDrag);
_on(ownerDocument, "mousemove", _this._disableDelayedDrag);
_on(ownerDocument, "touchmove", _this._disableDelayedDrag);
_this._dragStartTimer = setTimeout(dragStartFn, options.delay);
} else {
dragStartFn();
}
}
},
_disableDelayedDrag: function () {
var ownerDocument = this.el.ownerDocument;
clearTimeout(this._dragStartTimer);
_off(ownerDocument, "mouseup", this._disableDelayedDrag);
_off(ownerDocument, "touchend", this._disableDelayedDrag);
_off(ownerDocument, "touchcancel", this._disableDelayedDrag);
_off(ownerDocument, "mousemove", this._disableDelayedDrag);
_off(ownerDocument, "touchmove", this._disableDelayedDrag);
},
_triggerDragStart: function (/** Touch */ touch) {
if (touch) {
// Touch device support
tapEvt = {
target: dragEl,
clientX: touch.clientX,
clientY: touch.clientY,
};
this._onDragStart(tapEvt, "touch");
} else if (!this.nativeDraggable) {
this._onDragStart(tapEvt, true);
} else {
_on(dragEl, "dragend", this);
_on(rootEl, "dragstart", this._onDragStart);
}
try {
if (document.selection) {
// Timeout neccessary for IE9
setTimeout(function () {
document.selection.empty();
});
} else {
window.getSelection().removeAllRanges();
}
} catch (err) {}
},
_dragStarted: function () {
if (rootEl && dragEl) {
var options = this.options;
// Apply effect
_toggleClass(dragEl, options.ghostClass, true);
_toggleClass(dragEl, options.dragClass, false);
Sortable.active = this;
// Drag start event
_dispatchEvent(this, rootEl, "start", dragEl, rootEl, oldIndex);
}
},
_emulateDragOver: function () {
if (touchEvt) {
if (this._lastX === touchEvt.clientX && this._lastY === touchEvt.clientY) {
return;
}
this._lastX = touchEvt.clientX;
this._lastY = touchEvt.clientY;
if (!supportCssPointerEvents) {
_css(ghostEl, "display", "none");
}
var target = document.elementFromPoint(touchEvt.clientX, touchEvt.clientY),
parent = target,
i = touchDragOverListeners.length;
if (parent) {
do {
if (parent[expando]) {
while (i--) {
touchDragOverListeners[i]({
clientX: touchEvt.clientX,
clientY: touchEvt.clientY,
target: target,
rootEl: parent,
});
}
break;
}
target = parent; // store last element
} while (
/* jshint boss:true */
(parent = parent.parentNode)
);
}
if (!supportCssPointerEvents) {
_css(ghostEl, "display", "");
}
}
},
_onTouchMove: function (/**TouchEvent*/ evt) {
if (tapEvt) {
var options = this.options,
fallbackTolerance = options.fallbackTolerance,
fallbackOffset = options.fallbackOffset,
touch = evt.touches ? evt.touches[0] : evt,
dx = touch.clientX - tapEvt.clientX + fallbackOffset.x,
dy = touch.clientY - tapEvt.clientY + fallbackOffset.y,
translate3d = evt.touches
? "translate3d(" + dx + "px," + dy + "px,0)"
: "translate(" + dx + "px," + dy + "px)";
// only set the status to dragging, when we are actually dragging
if (!Sortable.active) {
if (
fallbackTolerance &&
min(abs(touch.clientX - this._lastX), abs(touch.clientY - this._lastY)) <
fallbackTolerance
) {
return;
}
this._dragStarted();
}
// as well as creating the ghost element on the document body
this._appendGhost();
moved = true;
touchEvt = touch;
_css(ghostEl, "webkitTransform", translate3d);
_css(ghostEl, "mozTransform", translate3d);
_css(ghostEl, "msTransform", translate3d);
_css(ghostEl, "transform", translate3d);
evt.preventDefault();
}
},
_appendGhost: function () {
if (!ghostEl) {
var rect = dragEl.getBoundingClientRect(),
css = _css(dragEl),
options = this.options,
ghostRect;
ghostEl = dragEl.cloneNode(true);
_toggleClass(ghostEl, options.ghostClass, false);
_toggleClass(ghostEl, options.fallbackClass, true);
_toggleClass(ghostEl, options.dragClass, true);
_css(ghostEl, "top", rect.top - parseInt(css.marginTop, 10));
_css(ghostEl, "left", rect.left - parseInt(css.marginLeft, 10));
_css(ghostEl, "width", rect.width);
_css(ghostEl, "height", rect.height);
_css(ghostEl, "opacity", "0.8");
_css(ghostEl, "position", "fixed");
_css(ghostEl, "zIndex", "100000");
_css(ghostEl, "pointerEvents", "none");
(options.fallbackOnBody && document.body.appendChild(ghostEl)) ||
rootEl.appendChild(ghostEl);
// Fixing dimensions.
ghostRect = ghostEl.getBoundingClientRect();
_css(ghostEl, "width", rect.width * 2 - ghostRect.width);
_css(ghostEl, "height", rect.height * 2 - ghostRect.height);
}
},
_onDragStart: function (/**Event*/ evt, /**boolean*/ useFallback) {
var dataTransfer = evt.dataTransfer,
options = this.options;
this._offUpEvents();
if (activeGroup.checkPull(this, this, dragEl, evt) == "clone") {
cloneEl = _clone(dragEl);
_css(cloneEl, "display", "none");
rootEl.insertBefore(cloneEl, dragEl);
_dispatchEvent(this, rootEl, "clone", dragEl);
}
_toggleClass(dragEl, options.dragClass, true);
if (useFallback) {
if (useFallback === "touch") {
// Bind touch events
_on(document, "touchmove", this._onTouchMove);
_on(document, "touchend", this._onDrop);
_on(document, "touchcancel", this._onDrop);
} else {
// Old brwoser
_on(document, "mousemove", this._onTouchMove);
_on(document, "mouseup", this._onDrop);
}
this._loopId = setInterval(this._emulateDragOver, 50);
} else {
if (dataTransfer) {
dataTransfer.effectAllowed = "move";
options.setData && options.setData.call(this, dataTransfer, dragEl);
}
_on(document, "drop", this);
setTimeout(this._dragStarted, 0);
}
},
_onDragOver: function (/**Event*/ evt) {
var el = this.el,
target,
dragRect,
targetRect,
revert,
options = this.options,
group = options.group,
activeSortable = Sortable.active,
isOwner = activeGroup === group,
canSort = options.sort;
if (evt.preventDefault !== void 0) {
evt.preventDefault();
!options.dragoverBubble && evt.stopPropagation();
}
moved = true;
if (
activeGroup &&
!options.disabled &&
(isOwner
? canSort || (revert = !rootEl.contains(dragEl)) // Reverting item into the original list
: putSortable === this ||
(activeGroup.checkPull(this, activeSortable, dragEl, evt) &&
group.checkPut(this, activeSortable, dragEl, evt))) &&
(evt.rootEl === void 0 || evt.rootEl === this.el) // touch fallback
) {
// Smart auto-scrolling
_autoScroll(evt, options, this.el);
if (_silent) {
return;
}
target = _closest(evt.target, options.draggable, el);
dragRect = dragEl.getBoundingClientRect();
putSortable = this;
if (revert) {
_cloneHide(true);
parentEl = rootEl; // actualization
if (cloneEl || nextEl) {
rootEl.insertBefore(dragEl, cloneEl || nextEl);
} else if (!canSort) {
rootEl.appendChild(dragEl);
}
return;
}
if (
el.children.length === 0 ||
el.children[0] === ghostEl ||
(el === evt.target && (target = _ghostIsLast(el, evt)))
) {
if (target) {
if (target.animated) {
return;
}
targetRect = target.getBoundingClientRect();
}
_cloneHide(isOwner);
if (_onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt) !== false) {
if (!dragEl.contains(el)) {
el.appendChild(dragEl);
parentEl = el; // actualization
}
this._animate(dragRect, dragEl);
target && this._animate(targetRect, target);
}
} else if (
target &&
!target.animated &&
target !== dragEl &&
target.parentNode[expando] !== void 0
) {
if (lastEl !== target) {
lastEl = target;
lastCSS = _css(target);
lastParentCSS = _css(target.parentNode);
}
targetRect = target.getBoundingClientRect();
var width = targetRect.right - targetRect.left,
height = targetRect.bottom - targetRect.top,
floating =
/left|right|inline/.test(lastCSS.cssFloat + lastCSS.display) ||
(lastParentCSS.display == "flex" &&
lastParentCSS["flex-direction"].indexOf("row") === 0),
isWide = target.offsetWidth > dragEl.offsetWidth,
isLong = target.offsetHeight > dragEl.offsetHeight,
halfway =
(floating
? (evt.clientX - targetRect.left) / width
: (evt.clientY - targetRect.top) / height) > 0.5,
nextSibling = target.nextElementSibling,
moveVector = _onMove(rootEl, el, dragEl, dragRect, target, targetRect, evt),
after;
if (moveVector !== false) {
_silent = true;
setTimeout(_unsilent, 30);
_cloneHide(isOwner);
if (moveVector === 1 || moveVector === -1) {
after = moveVector === 1;
} else if (floating) {
var elTop = dragEl.offsetTop,
tgTop = target.offsetTop;
if (elTop === tgTop) {
after =
(target.previousElementSibling === dragEl && !isWide) ||
(halfway && isWide);
} else if (
target.previousElementSibling === dragEl ||
dragEl.previousElementSibling === target
) {
after = (evt.clientY - targetRect.top) / height > 0.5;
} else {
after = tgTop > elTop;
}
} else {
after = (nextSibling !== dragEl && !isLong) || (halfway && isLong);
}
if (!dragEl.contains(el)) {
if (after && !nextSibling) {
el.appendChild(dragEl);
} else {
target.parentNode.insertBefore(
dragEl,
after ? nextSibling : target
);
}
}
parentEl = dragEl.parentNode; // actualization
this._animate(dragRect, dragEl);
this._animate(targetRect, target);
}
}
}
},
_animate: function (prevRect, target) {
var ms = this.options.animation;
if (ms) {
var currentRect = target.getBoundingClientRect();
_css(target, "transition", "none");
_css(
target,
"transform",
"translate3d(" +
(prevRect.left - currentRect.left) +
"px," +
(prevRect.top - currentRect.top) +
"px,0)"
);
target.offsetWidth; // repaint
_css(target, "transition", "all " + ms + "ms");
_css(target, "transform", "translate3d(0,0,0)");
clearTimeout(target.animated);
target.animated = setTimeout(function () {
_css(target, "transition", "");
_css(target, "transform", "");
target.animated = false;
}, ms);
}
},
_offUpEvents: function () {
var ownerDocument = this.el.ownerDocument;
_off(document, "touchmove", this._onTouchMove);
_off(ownerDocument, "mouseup", this._onDrop);
_off(ownerDocument, "touchend", this._onDrop);
_off(ownerDocument, "touchcancel", this._onDrop);
},
_onDrop: function (/**Event*/ evt) {
var el = this.el,
options = this.options;
clearInterval(this._loopId);
clearInterval(autoScroll.pid);
clearTimeout(this._dragStartTimer);
// Unbind events
_off(document, "mousemove", this._onTouchMove);
if (this.nativeDraggable) {
_off(document, "drop", this);
_off(el, "dragstart", this._onDragStart);
}
this._offUpEvents();
if (evt) {
if (moved) {
evt.preventDefault();
!options.dropBubble && evt.stopPropagation();
}
ghostEl && ghostEl.parentNode.removeChild(ghostEl);
if (dragEl) {
if (this.nativeDraggable) {
_off(dragEl, "dragend", this);
}
_disableDraggable(dragEl);
dragEl.style["will-change"] = "";
// Remove class's
_toggleClass(dragEl, this.options.ghostClass, false);
_toggleClass(dragEl, this.options.chosenClass, false);
if (rootEl !== parentEl) {
newIndex = _index(dragEl, options.draggable);
if (newIndex >= 0) {
// Add event
_dispatchEvent(
null,
parentEl,
"add",
dragEl,
rootEl,
oldIndex,
newIndex
);
// Remove event
_dispatchEvent(
this,
rootEl,
"remove",
dragEl,
rootEl,
oldIndex,
newIndex
);
// drag from one list and drop into another
_dispatchEvent(
null,
parentEl,
"sort",
dragEl,
rootEl,
oldIndex,
newIndex
);
_dispatchEvent(
this,
rootEl,
"sort",
dragEl,
rootEl,
oldIndex,
newIndex
);
}
} else {
// Remove clone
cloneEl && cloneEl.parentNode.removeChild(cloneEl);
if (dragEl.nextSibling !== nextEl) {
// Get the index of the dragged element within its parent
newIndex = _index(dragEl, options.draggable);
if (newIndex >= 0) {
// drag & drop within the same list
_dispatchEvent(
this,
rootEl,
"update",
dragEl,
rootEl,
oldIndex,
newIndex
);
_dispatchEvent(
this,
rootEl,
"sort",
dragEl,
rootEl,
oldIndex,
newIndex
);
}
}
}
if (Sortable.active) {
/* jshint eqnull:true */
if (newIndex == null || newIndex === -1) {
newIndex = oldIndex;
}
_dispatchEvent(this, rootEl, "end", dragEl, rootEl, oldIndex, newIndex);
// Save sorting
this.save();
}
}
}
this._nulling();
},
_nulling: function () {
rootEl = dragEl = parentEl = ghostEl = nextEl = cloneEl = scrollEl = scrollParentEl = tapEvt = touchEvt = moved = newIndex = lastEl = lastCSS = putSortable = activeGroup = Sortable.active = null;
},
handleEvent: function (/**Event*/ evt) {
var type = evt.type;
if (type === "dragover" || type === "dragenter") {
if (dragEl) {
this._onDragOver(evt);
_globalDragOver(evt);
}
} else if (type === "drop" || type === "dragend") {
this._onDrop(evt);
}
},
/**
* Serializes the item into an array of string.
* @returns {String[]}
*/
toArray: function () {
var order = [],
el,
children = this.el.children,
i = 0,
n = children.length,
options = this.options;
for (; i < n; i++) {
el = children[i];
if (_closest(el, options.draggable, this.el)) {
order.push(el.getAttribute(options.dataIdAttr) || _generateId(el));
}
}
return order;
},
/**
* Sorts the elements according to the array.
* @param {String[]} order order of the items
*/
sort: function (order) {
var items = {},
rootEl = this.el;
this.toArray().forEach(function (id, i) {
var el = rootEl.children[i];
if (_closest(el, this.options.draggable, rootEl)) {
items[id] = el;
}
}, this);
order.forEach(function (id) {
if (items[id]) {
rootEl.removeChild(items[id]);
rootEl.appendChild(items[id]);
}
});
},
/**
* Save the current sorting
*/
save: function () {
var store = this.options.store;
store && store.set(this);
},
/**
* For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
* @param {HTMLElement} el
* @param {String} [selector] default: `options.draggable`
* @returns {HTMLElement|null}
*/
closest: function (el, selector) {
return _closest(el, selector || this.options.draggable, this.el);
},
/**
* Set/get option
* @param {string} name
* @param {*} [value]
* @returns {*}
*/
option: function (name, value) {
var options = this.options;
if (value === void 0) {
return options[name];
} else {
options[name] = value;
if (name === "group") {
_prepareGroup(options);
}
}
},
/**
* Destroy
*/
destroy: function () {
var el = this.el;
el[expando] = null;
_off(el, "mousedown", this._onTapStart);
_off(el, "touchstart", this._onTapStart);
if (this.nativeDraggable) {
_off(el, "dragover", this);
_off(el, "dragenter", this);
}
// Remove draggable attributes
Array.prototype.forEach.call(el.querySelectorAll("[draggable]"), function (el) {
el.removeAttribute("draggable");
});
touchDragOverListeners.splice(touchDragOverListeners.indexOf(this._onDragOver), 1);
this._onDrop();
this.el = el = null;
},
};
function _cloneHide(state) {
if (cloneEl && cloneEl.state !== state) {
_css(cloneEl, "display", state ? "none" : "");
!state && cloneEl.state && rootEl.insertBefore(cloneEl, dragEl);
cloneEl.state = state;
}
}
function _closest(/**HTMLElement*/ el, /**String*/ selector, /**HTMLElement*/ ctx) {
if (el) {
ctx = ctx || document;
do {
if ((selector === ">*" && el.parentNode === ctx) || _matches(el, selector)) {
return el;
}
/* jshint boss:true */
} while ((el = _getParentOrHost(el)));
}
return null;
}
function _getParentOrHost(el) {
var parent = el.host;
return parent && parent.nodeType ? parent : el.parentNode;
}
function _globalDragOver(/**Event*/ evt) {
if (evt.dataTransfer) {
evt.dataTransfer.dropEffect = "move";
}
evt.preventDefault();
}
function _on(el, event, fn) {
el.addEventListener(event, fn, false);
}
function _off(el, event, fn) {
el.removeEventListener(event, fn, false);
}
function _toggleClass(el, name, state) {
if (el) {
if (el.classList) {
el.classList[state ? "add" : "remove"](name);
} else {
var className = (" " + el.className + " ")
.replace(RSPACE, " ")
.replace(" " + name + " ", " ");
el.className = (className + (state ? " " + name : "")).replace(RSPACE, " ");
}
}
}
function _css(el, prop, val) {
var style = el && el.style;
if (style) {
if (val === void 0) {
if (document.defaultView && document.defaultView.getComputedStyle) {
val = document.defaultView.getComputedStyle(el, "");
} else if (el.currentStyle) {
val = el.currentStyle;
}
return prop === void 0 ? val : val[prop];
} else {
if (!(prop in style)) {
prop = "-webkit-" + prop;
}
style[prop] = val + (typeof val === "string" ? "" : "px");
}
}
}
function _find(ctx, tagName, iterator) {
if (ctx) {
var list = ctx.getElementsByTagName(tagName),
i = 0,
n = list.length;
if (iterator) {
for (; i < n; i++) {
iterator(list[i], i);
}
}
return list;
}
return [];
}
function _dispatchEvent(sortable, rootEl, name, targetEl, fromEl, startIndex, newIndex) {
sortable = sortable || rootEl[expando];
var evt = document.createEvent("Event"),
options = sortable.options,
onName = "on" + name.charAt(0).toUpperCase() + name.substr(1);
evt.initEvent(name, true, true);
evt.to = rootEl;
evt.from = fromEl || rootEl;
evt.item = targetEl || rootEl;
evt.clone = cloneEl;
evt.oldIndex = startIndex;
evt.newIndex = newIndex;
rootEl.dispatchEvent(evt);
if (options[onName]) {
options[onName].call(sortable, evt);
}
}
function _onMove(fromEl, toEl, dragEl, dragRect, targetEl, targetRect, originalEvt) {
var evt,
sortable = fromEl[expando],
onMoveFn = sortable.options.onMove,
retVal;
evt = document.createEvent("Event");
evt.initEvent("move", true, true);
evt.to = toEl;
evt.from = fromEl;
evt.dragged = dragEl;
evt.draggedRect = dragRect;
evt.related = targetEl || toEl;
evt.relatedRect = targetRect || toEl.getBoundingClientRect();
fromEl.dispatchEvent(evt);
if (onMoveFn) {
retVal = onMoveFn.call(sortable, evt, originalEvt);
}
return retVal;
}
function _disableDraggable(el) {
el.draggable = false;
}
function _unsilent() {
_silent = false;
}
/** @returns {HTMLElement|false} */
function _ghostIsLast(el, evt) {
var lastEl = el.lastElementChild,
rect = lastEl.getBoundingClientRect();
// 5 — min delta
// abs — нельзя добавлять, а то глюки при наведении сверху
return (
(evt.clientY - (rect.top + rect.height) > 5 ||
evt.clientX - (rect.right + rect.width) > 5) &&
lastEl
);
}
/**
* Generate id
* @param {HTMLElement} el
* @returns {String}
* @private
*/
function _generateId(el) {
var str = el.tagName + el.className + el.src + el.href + el.textContent,
i = str.length,
sum = 0;
while (i--) {
sum += str.charCodeAt(i);
}
return sum.toString(36);
}
/**
* Returns the index of an element within its parent for a selected set of
* elements
* @param {HTMLElement} el
* @param {selector} selector
* @return {number}
*/
function _index(el, selector) {
var index = 0;
if (!el || !el.parentNode) {
return -1;
}
while (el && (el = el.previousElementSibling)) {
if (
el.nodeName.toUpperCase() !== "TEMPLATE" &&
(selector === ">*" || _matches(el, selector))
) {
index++;
}
}
return index;
}
function _matches(/**HTMLElement*/ el, /**String*/ selector) {
if (el) {
selector = selector.split(".");
var tag = selector.shift().toUpperCase(),
re = new RegExp("\\s(" + selector.join("|") + ")(?=\\s)", "g");
return (
(tag === "" || el.nodeName.toUpperCase() == tag) &&
(!selector.length ||
((" " + el.className + " ").match(re) || []).length == selector.length)
);
}
return false;
}
function _throttle(callback, ms) {
var args, _this;
return function () {
if (args === void 0) {
args = arguments;
_this = this;
setTimeout(function () {
if (args.length === 1) {
callback.call(_this, args[0]);
} else {
callback.apply(_this, args);
}
args = void 0;
}, ms);
}
};
}
function _extend(dst, src) {
if (dst && src) {
for (var key in src) {
if (src.hasOwnProperty(key)) {
dst[key] = src[key];
}
}
}
return dst;
}
function _clone(el) {
return $
? $(el).clone(true)[0]
: Polymer && Polymer.dom
? Polymer.dom(el).cloneNode(true)
: el.cloneNode(true);
}
// Export utils
Sortable.utils = {
on: _on,
off: _off,
css: _css,
find: _find,
is: function (el, selector) {
return !!_closest(el, selector, el);
},
extend: _extend,
throttle: _throttle,
closest: _closest,
toggleClass: _toggleClass,
clone: _clone,
index: _index,
};
/**
* Create sortable instance
* @param {HTMLElement} el
* @param {Object} [options]
*/
Sortable.create = function (el, options) {
return new Sortable(el, options);
};
// Export
Sortable.version = "1.4.2";
return Sortable;
});
});
const $$h = jQuery;
class ImagesFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchType = options.searchType || "fulltext";
this.mediaUploader = external.mediaUploader;
this.button_text = options.button_text || "Browse...";
this.db_type = "text";
this.label = options.label || "Images";
this.name = options.name || "images";
this.images = this.value || [];
this.value = JSON.stringify(this.value);
}
init() {
super.init();
this.redrawImages();
}
setDomElements() {
super.setDomElements();
}
getData() {
this.updateData();
return { name: this.name, value: this.images };
}
getSchema() {
const schema = super.getSchema();
schema.button_text = this.button_text;
return schema;
}
updateData() {
const newListOfImages = [];
$$h(this.domElements.main)
.find(".mapsvg-thumbnail-wrap")
.each(function (index, el) {
const imageData = $$h(el).data("image");
newListOfImages.push(imageData);
});
this.images = newListOfImages;
this.value = JSON.stringify(this.images);
$$h(this.domElements.main).find("input").val(this.value);
}
setEventHandlers() {
super.setEventHandlers();
if (this.formBuilder.editMode) {
return;
}
const _this = this;
const imageDOM = $$h(this.domElements.main).find(".mapsvg-data-images");
this.external.mediaUploader.on("select", () => {
if (_this.formBuilder.mediaUploaderisOpenedFor !== _this)
return false;
const attachments = _this.external.mediaUploader.state().get("selection").toJSON();
attachments.forEach(function (img) {
const image = { sizes: {} };
for (const type in img.sizes) {
image[type] = img.sizes[type].url
.replace("http://", "//")
.replace("https://", "//");
image.sizes[type] = {
width: img.sizes[type].width,
height: img.sizes[type].height,
};
}
if (!image.thumbnail) {
image.thumbnail = image.full;
image.sizes.thumbnail = {
width: img.sizes.full.width,
height: img.sizes.full.height,
};
}
if (!image.medium) {
image.medium = image.full;
image.sizes.medium = {
width: img.sizes.full.width,
height: img.sizes.full.height,
};
}
image.caption = img.caption;
image.description = img.description;
_this.images.push(image);
});
this.setValue(this.images);
_this.redrawImages();
});
$$h(_this.domElements.main).on("click", ".mapsvg-upload-image", function (e) {
e.preventDefault();
_this.formBuilder.mediaUploaderisOpenedFor = _this;
_this.external.mediaUploader.open();
});
$$h(_this.domElements.main).on("click", ".mapsvg-image-delete", function (e) {
e.preventDefault();
$$h(this).closest(".mapsvg-thumbnail-wrap").remove();
_this.updateData();
});
_this.sortable = new sortable_min(imageDOM[0], {
animation: 150,
onStart: function () {
$$h(_this.domElements.main).addClass("sorting");
},
onEnd: function (evt) {
_this.images = [];
$$h(_this.domElements.main)
.find("img")
.each(function (i, image) {
_this.images.push($$h(image).data("image"));
});
this.value = JSON.stringify(_this.images);
$$h(_this.domElements.main).find("input").val(this.value);
$$h(_this.domElements.main).removeClass("sorting");
},
});
}
redrawImages() {
const imageDOM = $$h(this.domElements.main).find(".mapsvg-data-images");
imageDOM.empty();
this.images &&
this.images.forEach(function (image) {
const img = $$h('
')
.attr("src", image.thumbnail)
.data("image", image);
const imgContainer = $$h('').data("image", image);
imgContainer.append(img);
imgContainer.append('');
imageDOM.append(imgContainer);
});
$$h(this.domElements.main).find("input").val(this.value);
}
destroy() {
super.destroy();
this.external.mediaUploader.off("select");
}
}
const $$i = jQuery;
class LocationFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.label = this.label || (options.label === undefined ? "Location" : options.label);
this.name = "location";
this.db_type = "text";
this.languages = [
{ value: "sq", label: "Albanian" },
{ value: "ar", label: "Arabic" },
{
value: "eu",
label: "Basque",
},
{ value: "be", label: "Belarusian" },
{ value: "bg", label: "Bulgarian" },
{
value: "my",
label: "Burmese",
},
{ value: "bn", label: "Bengali" },
{ value: "ca", label: "Catalan" },
{
value: "zh-cn",
label: "Chinese (simplified)",
},
{ value: "zh-tw", label: "Chinese (traditional)" },
{
value: "hr",
label: "Croatian",
},
{ value: "cs", label: "Czech" },
{ value: "da", label: "Danish" },
{
value: "nl",
label: "Dutch",
},
{ value: "en", label: "English" },
{
value: "en-au",
label: "English (australian)",
},
{ value: "en-gb", label: "English (great Britain)" },
{
value: "fa",
label: "Farsi",
},
{ value: "fi", label: "Finnish" },
{ value: "fil", label: "Filipino" },
{
value: "fr",
label: "French",
},
{ value: "gl", label: "Galician" },
{ value: "de", label: "German" },
{
value: "el",
label: "Greek",
},
{ value: "gu", label: "Gujarati" },
{ value: "iw", label: "Hebrew" },
{
value: "hi",
label: "Hindi",
},
{ value: "hu", label: "Hungarian" },
{ value: "id", label: "Indonesian" },
{
value: "it",
label: "Italian",
},
{ value: "ja", label: "Japanese" },
{ value: "kn", label: "Kannada" },
{
value: "kk",
label: "Kazakh",
},
{ value: "ko", label: "Korean" },
{ value: "ky", label: "Kyrgyz" },
{
value: "lt",
label: "Lithuanian",
},
{ value: "lv", label: "Latvian" },
{ value: "mk", label: "Macedonian" },
{
value: "ml",
label: "Malayalam",
},
{ value: "mr", label: "Marathi" },
{ value: "no", label: "Norwegian" },
{
value: "pl",
label: "Polish",
},
{ value: "pt", label: "Portuguese" },
{
value: "pt-br",
label: "Portuguese (brazil)",
},
{ value: "pt-pt", label: "Portuguese (portugal)" },
{
value: "pa",
label: "Punjabi",
},
{ value: "ro", label: "Romanian" },
{ value: "ru", label: "Russian" },
{
value: "sr",
label: "Serbian",
},
{ value: "sk", label: "Slovak" },
{ value: "sl", label: "Slovenian" },
{
value: "es",
label: "Spanish",
},
{ value: "sv", label: "Swedish" },
{ value: "tl", label: "Tagalog" },
{
value: "ta",
label: "Tamil",
},
{ value: "te", label: "Telugu" },
{ value: "th", label: "Thai" },
{
value: "tr",
label: "Turkish",
},
{ value: "uk", label: "Ukrainian" },
{ value: "uz", label: "Uzbek" },
{
value: "vi",
label: "Vietnamese",
},
];
this.language = options.language;
this.markerImages = MapSVG.markerImages;
this.markersByField = options.markersByField;
this.markerField = options.markerField;
this.markersByFieldEnabled = MapSVG.parseBoolean(options.markersByFieldEnabled);
this.defaultMarkerPath =
options.defaultMarkerPath ||
this.formBuilder.mapsvg.getData().options.defaultMarkerImage;
this.templates.marker = Handlebars.compile($$i("#mapsvg-data-tmpl-marker").html());
}
init() {
super.init();
if (this.value) {
this.renderMarker();
}
this.renderMarkerSelector();
}
getSchema() {
const schema = super.getSchema();
schema.language = this.language;
schema.defaultMarkerPath = this.defaultMarkerPath;
schema.markersByField = this.markersByField;
schema.markerField = this.markerField;
schema.markersByFieldEnabled = MapSVG.parseBoolean(this.markersByFieldEnabled);
return schema;
}
getData() {
return { name: this.name, value: this.value };
}
getDataForTemplate() {
const data = super.getDataForTemplate();
if (this.formBuilder.admin) {
data.languages = this.languages;
data.markerImages = MapSVG.markerImages;
data.markersByField = this.markersByField;
data.markerField = this.markerField;
data.markersByFieldEnabled = MapSVG.parseBoolean(this.markersByFieldEnabled);
const _this = this;
data.markerImages.forEach(function (m) {
if (m.relativeUrl === _this.defaultMarkerPath) {
m.default = true;
}
else {
m.default = false;
}
});
}
data.language = this.language;
if (this.value) {
data.location = this.value;
if (data.location.marker) {
data.location.img =
(this.value.marker.src.indexOf(MapSVG.urls.uploads) === 0 ? "uploads/" : "") +
this.value.marker.src.split("/").pop();
}
}
data.showUploadBtn = data.external.filtersMode;
return data;
}
initEditor() {
super.initEditor();
this.renderMarkerSelector();
this.fillMarkersByFieldOptions(this.markerField);
}
setDomElements() {
super.setDomElements();
this.domElements.markerImageButton = $$i(this.domElements.main).find("img")[0];
}
setEventHandlers() {
super.setEventHandlers();
const _this = this;
const server = new Server();
if (_this.formBuilder.mapsvg.isGeo()) {
const locations = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace("formatted_address"),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: server.getUrl("geocoding") + "?address=%QUERY%&language=" + this.language,
wildcard: "%QUERY%",
transform: function (response) {
if (response.error_message) {
alert(response.error_message);
}
return response.results;
},
rateLimitWait: 600,
},
});
const thContainer = $$i(this.domElements.main).find(".typeahead");
const tH = thContainer
.typeahead({ minLength: 3 }, {
name: "mapsvg-addresses",
display: "formatted_address",
async: true,
source: (query, sync, async) => {
const preg = new RegExp(/^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/);
if (preg.test(query)) {
const latlng = query.split(",").map((item) => item.trim());
const item = {
formatted_address: latlng.join(","),
address_components: [],
geometry: {
location: {
lat: () => latlng[0],
lng: () => latlng[1],
},
},
};
sync([item]);
return;
}
MapSVG.geocode({ address: query }, async);
},
})
.on("typeahead:asyncrequest", function (e) {
$$i(e.target).addClass("tt-loading");
})
.on("typeahead:asynccancel typeahead:asyncreceive", function (e) {
$$i(e.target).removeClass("tt-loading");
});
thContainer.on("typeahead:select", (ev, item) => {
this.setValue(null, false);
const address = {};
address.formatted = item.formatted_address;
item.address_components.forEach((addr_item) => {
const type = addr_item.types[0];
address[type] = addr_item.long_name;
if (addr_item.short_name != addr_item.long_name) {
address[type + "_short"] = addr_item.short_name;
}
});
const locationData = {
address: address,
geoPoint: new GeoPoint(item.geometry.location.lat(), item.geometry.location.lng()),
img: this.getMarkerImage(this.formBuilder.getData()),
imagePath: this.getMarkerImage(this.formBuilder.getData()),
};
this.setValue(locationData, false);
thContainer.typeahead("val", "");
this.triggerChanged();
});
}
$$i(this.domElements.main).on("change", ".marker-file-uploader", function () {
_this.markerIconUpload(this);
});
$$i(this.domElements.main).on("click", ".mapsvg-marker-image-btn-trigger", function (e) {
e.preventDefault();
$$i(this).toggleClass("active");
_this.toggleMarkerSelector();
});
$$i(this.domElements.main).on("click", ".mapsvg-marker-delete", function (e) {
e.preventDefault();
_this.setValue(null);
_this.triggerChanged();
});
}
setEditorEventHandlers() {
super.setEditorEventHandlers();
const _this = this;
$$i(this.domElements.edit).on("change", ".marker-file-uploader", function () {
_this.markerIconUpload(this);
});
$$i(this.domElements.edit).on("change", 'select[name="markerField"]', function () {
const fieldName = $$i(this).val();
_this.resetMarkersByField();
const newOptions = _this.fillMarkersByFieldOptions(fieldName);
_this.setMarkersByField(newOptions);
});
$$i(this.domElements.edit).on("click", ".mapsvg-marker-image-selector button", function (e) {
e.preventDefault();
const src = $$i(this).find("img").attr("src");
$$i(this).parent().find("button").removeClass("active");
$$i(this).addClass("active");
_this.setDefaultMarkerPath(src);
});
$$i(this.domElements.edit).on("click", ".mapsvg-marker-image-btn-trigger", function (e) {
$$i(this).toggleClass("active");
_this.toggleMarkerSelectorInLocationEditor.call(_this, $$i(this), e);
});
}
markerIconUpload(input) {
const uploadBtn = $$i(input).closest(".btn-file").buttonLoading(true);
for (let i = 0; i < input.files.length; i++) {
const data = new FormData();
data.append("file", input.files[0]);
const server = new Server();
server
.ajax("markers", {
type: "POST",
data: data,
processData: false,
contentType: false,
})
.done((resp) => {
if (resp.error) {
alert(resp.error);
}
else {
const marker = resp.marker;
const newMarker = `
`;
$$i(this.domElements.markerSelector)
.find(".mapsvg-marker-image-btn.active")
.removeClass("active");
$$i(newMarker).appendTo(this.domElements.markerSelector);
this.setMarkerImage(marker.relativeUrl);
MapSVG.markerImages.push(marker);
}
})
.always(function () {
uploadBtn.buttonLoading(false);
});
}
}
mayBeAddDistanceRow() {
const _this = this;
if (!this.domElements.editDistanceRow) {
this.domElements.editDistanceRow = $$i($$i("#mapsvg-edit-distance-row").html())[0];
}
const z = $$i(this.domElements.edit).find(".mapsvg-edit-distance-row:last-child input");
if (z && z.last() && z.last().val() && (z.last().val() + "").trim().length) {
const newRow = $$i(this.templates.editDistanceRow).clone();
newRow.insertAfter($$i(_this.domElements.edit).find(".mapsvg-edit-distance-row:last-child"));
}
const rows = $$i(_this.domElements.edit).find(".mapsvg-edit-distance-row");
const row1 = rows.eq(rows.length - 2);
const row2 = rows.eq(rows.length - 1);
if (row1.length &&
row2.length &&
!row1.find("input:eq(0)").val().toString().trim() &&
!row2.find("input:eq(0)").val().toString().trim()) {
row2.remove();
}
}
fillMarkersByFieldOptions(fieldName) {
const _this = this;
const field = _this.formBuilder.mapsvg.objectsRepository.getSchema().getField(fieldName);
const options = {};
if (field) {
const markerImg = _this.formBuilder.mapsvg.options.defaultMarkerImage;
const rows = [];
field.options.forEach(function (option) {
const value = field.type === "region" ? option.id : option.value;
const label = field.type === "region" ? option.title || option.id : option.label;
const img = _this.markersByField && _this.markersByField[value]
? _this.markersByField[value]
: markerImg;
rows.push('| ' +
label +
' | |
');
options[value] = img;
});
$$i("#markers-by-field").empty().append(rows);
}
return options;
}
renderMarker(marker) {
if (marker && marker.location) {
this.value = marker.location.getData();
}
this.renderMarkerHtml();
}
renderMarkerHtml() {
if (!this.value) {
$$i(this.domElements.main).find(".mapsvg-new-marker").hide();
}
else {
$$i(this.domElements.main)
.find(".mapsvg-new-marker")
.show()
.html(this.templates.marker(this.value));
}
}
toggleMarkerSelector() {
if (this.domElements.markerSelectorWrap &&
$$i(this.domElements.markerSelectorWrap).is(":visible")) {
$$i(this.domElements.markerSelectorWrap).hide();
return;
}
if (this.domElements.markerSelectorWrap &&
$$i(this.domElements.markerSelectorWrap).not(":visible")) {
$$i(this.domElements.markerSelector).find(".active").removeClass("active");
if (this.value && this.value.markerImagePath) {
$$i(this.domElements.markerSelector)
.find('[src="' + this.value.markerImagePath + '"]')
.parent()
.addClass("active");
}
$$i(this.domElements.markerSelectorWrap).show();
return;
}
}
renderMarkerSelector() {
const _this = this;
const view = this.formBuilder.editMode ? this.domElements.edit : this.domElements.main;
if (!view)
return;
const currentImage = this.value ? this.value.markerImagePath : null;
const images = MapSVG.markerImages.map(function (image) {
return ('');
});
this.domElements.markerSelectorWrap = $$i(view).find(".mapsvg-marker-image-selector")[0];
this.domElements.markerSelector = $$i(this.domElements.markerSelectorWrap).find(".mapsvg-marker-images")[0];
if (this.domElements.markerSelector) {
$$i(this.domElements.markerSelector).empty();
}
if (!this.formBuilder.editMode) {
this.domElements.markerSelectorWrap.style.display = "none";
$$i(this.domElements.markerSelector).on("click", ".mapsvg-marker-image-btn-choose", function (e) {
e.preventDefault();
const src = $$i(this).find("img").attr("src");
$$i(_this.domElements.markerSelectorWrap).hide();
$$i(_this.domElements.markerSelector).find(".active").removeClass("active");
$$i(this).addClass("active");
$$i(_this.domElements.main)
.find(".mapsvg-marker-image-btn-trigger")
.toggleClass("active", false);
$$i(_this.domElements.markerImageButton).attr("src", src);
_this.setMarkerImage(src);
});
}
$$i(this.domElements.markerSelector).html(images.join(""));
}
setMarkerImage(src) {
this.setDefaultMarkerPath(src);
const value = this.value;
if (value) {
value.img = src;
value.imagePath = src;
this.setValue(value);
this.triggerChanged();
this.renderMarker();
}
}
toggleMarkerSelectorInLocationEditor(jQueryObj, e) {
e.preventDefault();
const _this = this;
if (jQueryObj.data("markerSelector") && jQueryObj.data("markerSelector").is(":visible")) {
jQueryObj.data("markerSelector").hide();
return;
}
if (jQueryObj.data("markerSelector") && jQueryObj.data("markerSelector").not(":visible")) {
jQueryObj.data("markerSelector").show();
return;
}
const markerBtn = $$i(this).closest("td").find(".mapsvg-marker-image-btn-trigger");
const currentImage = markerBtn.attr("src");
const images = MapSVG.markerImages.map(function (image) {
return ('');
});
if (!jQueryObj.data("markerSelector")) {
const ms = $$i('');
jQueryObj.closest("td").append(ms);
jQueryObj.data("markerSelector", ms);
}
else {
jQueryObj.data("markerSelector").empty();
}
jQueryObj.data("markerSelector").html(images.join(""));
jQueryObj
.data("markerSelector")
.on("click", ".mapsvg-marker-image-btn-choose", function (e) {
e.preventDefault();
const src = $$i(this).find("img").attr("src");
jQueryObj.data("markerSelector").hide();
const td = $$i(this).closest("td");
const fieldId = $$i(this).closest("tr").data("option-id");
const btn = td.find(".mapsvg-marker-image-btn-trigger");
btn.toggleClass("active", false);
btn.find("img").attr("src", src);
_this.setMarkerByField(fieldId, src);
});
}
setMarkersByField(options) {
this.markersByField = options;
}
resetMarkersByField() {
this.markersByField = {};
}
setMarkerByField(fieldId, markerImg) {
this.markersByField = this.markersByField || {};
this.markersByField[fieldId] = markerImg;
}
deleteMarker() {
$$i(this.domElements.main).find(".mapsvg-new-marker").hide();
$$i(this.domElements.main).find(".mapsvg-marker-id").attr("disabled", "disabled");
}
destroy() {
if ($$i().mselect2) {
const sel = $$i(this.domElements.main).find(".mapsvg-select2");
if (sel.length) {
sel.mselect2("destroy");
}
}
this.domElements.markerSelector && $$i(this.domElements.markerSelector).popover("dispose");
}
setDefaultMarkerPath(path) {
this.defaultMarkerPath = path;
this.formBuilder.mapsvg.setDefaultMarkerImage(path);
}
getMarkerImage(data) {
let fieldValue;
if (this.markersByFieldEnabled) {
fieldValue = data[this.markerField];
if (!fieldValue) {
return this.defaultMarkerPath || MapSVG.defaultMarkerImage;
}
else {
if (this.markerField === "regions") {
fieldValue = fieldValue[0] && fieldValue[0].id;
}
else if (typeof fieldValue === "object" && fieldValue.length) {
fieldValue = fieldValue[0].value;
}
if (this.markersByField[fieldValue]) {
return (this.markersByField[fieldValue] ||
this.defaultMarkerPath ||
MapSVG.defaultMarkerImage);
}
}
}
else {
return this.defaultMarkerPath || MapSVG.defaultMarkerImage;
}
}
setValue(value, updateInput = true) {
this.value = value;
if (this.value) {
if (!this.value.address) {
this.value.address = {};
}
if (Object.keys(this.value.address).length < 2 && this.value.geoPoint) {
this.value.address.formatted =
this.value.geoPoint.lat + "," + this.value.geoPoint.lng;
}
}
this.renderMarker();
}
}
const $$j = jQuery;
class ModalFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.showButtonText = options.showButtonText;
}
getSchema() {
const schema = super.getSchema();
schema.showButtonText = this.showButtonText;
return schema;
}
}
const $$k = jQuery;
class PostFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
if (this.formBuilder.admin)
this.post_types = this.formBuilder.admin.getPostTypes();
this.post_type = options.post_type || this.post_types[0];
this.add_fields = MapSVG.parseBoolean(options.add_fields);
this.db_type = "int(11)";
this.name = "post";
this.post = options.post;
}
setDomElements() {
super.setDomElements();
this.inputs.postSelect = ($$k(this.domElements.main).find(".mapsvg-find-post")[0]);
}
getSchema() {
const schema = super.getSchema();
schema.post_type = this.post_type;
schema.add_fields = this.add_fields;
return schema;
}
destroy() {
if ($$k().mselect2) {
const sel = $$k(this.domElements.main).find(".mapsvg-select2");
if (sel.length) {
sel.mselect2("destroy");
}
}
}
getDataForTemplate() {
const data = super.getDataForTemplate();
if (this.formBuilder.admin)
data.post_types = this.formBuilder.admin.getPostTypes();
data.post_type = this.post_type;
data.post = this.post;
data.add_fields = this.add_fields || 0;
return data;
}
setEventHandlers() {
super.setEventHandlers();
const server = new Server();
$$k(this.inputs.postSelect)
.mselect2({
placeholder: "Search post by title",
allowClear: true,
disabled: this.readonly,
ajax: {
url: server.getUrl("posts"),
dataType: "json",
delay: 250,
data: (params) => {
return {
filters: { post_type: this.post_type },
search: params.term,
page: params.page,
};
},
processResults: (data, params) => {
params.page = params.page || 1;
return {
results: data.posts ? data.posts : [],
pagination: {
more: false,
},
};
},
cache: true,
},
escapeMarkup: (markup) => {
return markup;
},
minimumInputLength: 1,
templateResult: this.formatRepo,
templateSelection: this.formatRepoSelection,
})
.on("select2:select", (e) => {
const post = e.params.data;
this.setValue(post);
this.setInputValue(post);
this.triggerChanged();
})
.on("change", (e) => {
if (e.target.value === "") {
$$k(this.domElements.main).find(".mapsvg-post-id").text("");
$$k(this.domElements.main).find(".mapsvg-post-url").text("");
this.setValue(null, false);
this.triggerChanged();
}
});
}
formatRepo(repo) {
if (repo.loading) {
return repo.text;
}
else {
return "" + repo.post_title + "
";
}
}
formatRepoSelection(repo) {
return repo.post_title || repo.text;
}
setValue(post, updateInput = true) {
this.value = post;
if (updateInput) {
this.setInputValue(post);
}
}
setInputValue(post) {
$$k(this.domElements.main).find(".mapsvg-post-id").text(post.id);
$$k(this.domElements.main).find(".mapsvg-post-url").text(post.url).attr("href", post.url);
}
}
const $$l = jQuery;
class RadioFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.setOptions(options.options);
}
setDomElements() {
super.setDomElements();
this.inputs.radios = this.formBuilder.getForm().elements[this.name];
this.$radios = $$l(this.domElements.main).find('input[type="radio"]');
}
setEventHandlers() {
super.setEventHandlers();
this.$radios.on("change", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
setInputValue(value) {
if (value === null) {
this.$radios.prop("checked", false);
}
else {
this.inputs.radios.value = value;
}
}
}
const $$m = jQuery;
class RegionsFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchable = MapSVG.parseBoolean(options.searchable);
this.options = this.formBuilder.getRegionsList();
this.label = options.label === undefined ? "Regions" : options.label;
this.name = "regions";
this.db_type = "text";
if (typeof this.value === "undefined") {
this.value = [];
}
this.regionsTableName = this.formBuilder.mapsvg.regionsRepository.getSchema().name;
}
setDomElements() {
super.setDomElements();
this.inputs.select = $$m(this.domElements.main).find("select")[0];
}
getData() {
return { name: "regions", value: this.value };
}
getSchema() {
const schema = super.getSchema();
if (schema.multiselect)
schema.db_type = "text";
const opts = $$m.extend(true, {}, { options: this.options });
schema.options = opts.options;
schema.optionsDict = {};
schema.options.forEach(function (option) {
schema.optionsDict[option.id] = option.title || option.id;
});
return schema;
}
getDataForTemplate() {
const data = super.getDataForTemplate();
data.regionsTableName = this.regionsTableName;
data.regionsFromCurrentTable = this.getRegionsForCurrentTable();
return data;
}
getRegionsForCurrentTable() {
return this.value
? this.value.filter((region) => region.tableName === this.regionsTableName)
: [];
}
setEventHandlers() {
super.setEventHandlers();
$$m(this.inputs.select).on("change", (e) => {
const selectedOptions = Array.from(this.inputs.select.selectedOptions);
const selectedValues = selectedOptions.map((option) => option.value);
this.setValue(selectedValues, false);
this.triggerChanged();
});
}
destroy() {
if ($$m().mselect2) {
const sel = $$m(this.domElements.main).find(".mapsvg-select2");
if (sel.length) {
sel.mselect2("destroy");
}
}
}
setValue(regionIds, updateInput = true) {
const regionsFromOtherTables = this.value.filter((region) => region.tableName !== this.regionsTableName);
const regions = [];
regionIds.forEach((regionId) => {
const region = this.formBuilder.mapsvg.getRegion(regionId);
regions.push({ id: region.id, title: region.title, tableName: this.regionsTableName });
});
this.value = regions.concat(regionsFromOtherTables);
if (updateInput) {
this.setInputValue(regionIds);
}
}
}
const $$n = jQuery;
class SaveFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.readonly = true;
}
setDomElements() {
super.setDomElements();
this.inputs.btnSave = $$n(this.domElements.main).find(".btn-save")[0];
this.inputs.btnClose = $$n(this.domElements.main).find(".mapsvg-close")[0];
}
setEventHandlers() {
super.setEventHandlers();
$$n(this.inputs.btnSave).on("click", (e) => {
e.preventDefault();
this.events.trigger("click.btn.save");
});
$$n(this.inputs.btnClose).on("click", (e) => {
e.preventDefault();
this.events.trigger("click.btn.close");
});
}
}
const $$o = jQuery;
class SearchFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchFallback = MapSVG.parseBoolean(options.searchFallback) || false;
this.width = options.width || "100%";
this.name = "search";
}
setDomElements() {
super.setDomElements();
this.inputs.text = $$o(this.domElements.main).find("input")[0];
}
setEventHandlers() {
super.setEventHandlers();
$$o(this.inputs.text).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
setInputValue(value) {
this.inputs.text.value = value;
}
getSchema() {
const schema = super.getSchema();
schema.searchFallback = MapSVG.parseBoolean(this.searchFallback);
schema.placeholder = this.placeholder;
schema.width = this.width;
return schema;
}
}
const $$p = jQuery;
class SelectFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchable = MapSVG.parseBoolean(options.searchable);
this.multiselect = MapSVG.parseBoolean(options.multiselect);
this.optionsGrouped = options.optionsGrouped;
this.db_type = this.multiselect ? "text" : "varchar(255)";
this.setOptions(options.options);
}
setDomElements() {
super.setDomElements();
this.inputs.select = $$p(this.domElements.main).find("select")[0];
}
getSchema() {
const schema = super.getSchema();
schema.multiselect = MapSVG.parseBoolean(this.multiselect);
if (schema.multiselect)
schema.db_type = "text";
schema.optionsGrouped = this.optionsGrouped;
const opts = $$p.extend(true, {}, { options: this.options });
schema.options = opts.options || [];
schema.optionsDict = {};
schema.options.forEach(function (option) {
schema.optionsDict[option.value] = option.label;
});
return schema;
}
setEventHandlers() {
super.setEventHandlers();
$$p(this.inputs.select).on("change", (e) => {
if (this.multiselect) {
const selectedOptions = Array.from(this.inputs.select.selectedOptions);
const selectedValues = selectedOptions.map((option) => {
return { label: option.label, value: option.value };
});
this.setValue(selectedValues, false);
this.triggerChanged();
}
else {
this.setValue(this.inputs.select.value, false);
this.triggerChanged();
}
});
}
addSelect2() {
if ($$p().mselect2) {
const select2Options = {};
if (this.formBuilder.filtersMode && this.type == "select") {
select2Options.placeholder = this.placeholder;
if (!this.multiselect) {
select2Options.allowClear = true;
}
}
$$p(this.domElements.main)
.find("select")
.css({ width: "100%", display: "block" })
.mselect2(select2Options)
.on("select2:focus", function () {
$$p(this).mselect2("open");
});
$$p(this.domElements.main)
.find(".select2-selection--multiple .select2-search__field")
.css("width", "100%");
}
}
setOptions(options) {
if (options) {
this.options = [];
this.optionsDict = {};
options.forEach((value, key) => {
this.options.push(value);
if (this.optionsGrouped) {
value.options.forEach((value2, key2) => {
this.optionsDict[value2.value] = value2;
});
}
else {
this.optionsDict[key] = value;
}
});
return this.options;
}
else {
return this.setOptions([
{ label: "Option one", name: "option_one", value: 1 },
{ label: "Option two", name: "option_two", value: 2 },
]);
}
}
setInputValue(value) {
if (this.multiselect) {
if (this.value) {
$$p(this.inputs.select).val(this.value.map((el) => el.value));
}
else {
$$p(this.inputs.select).val([]);
}
}
else {
this.inputs.select.value = this.value;
}
$$p(this.inputs.select).trigger("change.select2");
}
}
const $$q = jQuery;
class StatusFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.label = options.label || "Status";
this.name = "status";
this.setOptions(options.options);
}
setDomElements() {
super.setDomElements();
this.inputs.select = $$q(this.domElements.main).find("select")[0];
if ($$q().colorpicker) {
$$q(this.domElements.main)
.find(".cpicker")
.colorpicker()
.on("changeColor.colorpicker", function (event) {
const input = $$q(this).find("input");
if (input.val() == "")
$$q(this).find("i").css({ "background-color": "" });
});
this.domElements.edit &&
$$q(this.domElements.edit)
.find(".cpicker")
.colorpicker()
.on("changeColor.colorpicker", function (event) {
const input = $$q(this).find("input");
if (input.val() == "")
$$q(this).find("i").css({ "background-color": "" });
});
}
}
destroy() {
if ($$q().mselect2) {
const sel = $$q(this.domElements.main).find(".mapsvg-select2");
if (sel.length) {
sel.mselect2("destroy");
}
}
}
setEditorEventHandlers() {
super.setEditorEventHandlers();
const _this = this;
$$q(this.domElements.edit).on("keyup change paste", ".mapsvg-edit-status-row input", function () {
_this.mayBeAddStatusRow();
});
}
initEditor() {
super.initEditor();
const _this = this;
$$q(_this.domElements.edit)
.find(".cpicker")
.colorpicker()
.on("changeColor.colorpicker", function (event) {
const input = $$q(this).find("input");
const index = $$q(this).closest("tr").index();
if (input.val() == "")
$$q(this).find("i").css({ "background-color": "" });
_this.options[index] = _this.options[index] || {
label: "",
value: "",
color: "",
disabled: false,
};
_this.options[index]["color"] = input.val();
});
_this.mayBeAddStatusRow();
}
mayBeAddStatusRow() {
const _this = this;
const editStatusRow = $$q($$q("#mapsvg-edit-status-row").html());
const z = $$q(_this.domElements.edit).find(".mapsvg-edit-status-label:last-child");
if (z && z.last() && z.last().val() && (z.last().val() + "").trim().length) {
const newRow = editStatusRow.clone();
newRow.insertAfter($$q(_this.domElements.edit).find(".mapsvg-edit-status-row:last-child"));
newRow
.find(".cpicker")
.colorpicker()
.on("changeColor.colorpicker", function (event) {
const input = $$q(this).find("input");
const index = $$q(this).closest("tr").index();
if (input.val() == "")
$$q(this).find("i").css({ "background-color": "" });
_this.options[index] = _this.options[index] || {
label: "",
value: "",
color: "",
disabled: false,
};
_this.options[index]["color"] = input.val();
});
}
const rows = $$q(_this.domElements.edit).find(".mapsvg-edit-status-row");
const row1 = rows.eq(rows.length - 2);
const row2 = rows.eq(rows.length - 1);
if (row1.length &&
row2.length &&
!(row1.find("input:eq(0)").val().toString().trim() ||
row1.find("input:eq(1)").val().toString().trim() ||
row1.find("input:eq(2)").val().toString().trim()) &&
!(row2.find("input:eq(0)").val().toString().trim() ||
row2.find("input:eq(1)").val().toString().trim() ||
row2.find("input:eq(2)").val().toString().trim())) {
row2.remove();
}
}
setEventHandlers() {
super.setEventHandlers();
$$q(this.inputs.select).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
getSchema() {
const schema = super.getSchema();
const opts = $$q.extend(true, {}, { options: this.options });
schema.options = opts.options;
schema.optionsDict = {};
schema.options.forEach(function (option, index) {
if (schema.options[index].value === "") {
schema.options.splice(index, 1);
}
else {
schema.options[index].disabled = MapSVG.parseBoolean(schema.options[index].disabled);
schema.optionsDict[option.value] = option;
}
});
return schema;
}
setInputValue(value) {
this.inputs.select.value = value;
}
}
const $$r = jQuery;
class TextareaFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchType = options.searchType || "fulltext";
this.searchable = MapSVG.parseBoolean(options.searchable);
this.autobr = options.autobr;
this.html = options.html;
this.db_type = "text";
}
setDomElements() {
super.setDomElements();
this.inputs.textarea = $$r(this.domElements.main).find("textarea")[0];
if (this.html) {
this.editor = CodeMirror.fromTextArea(this.inputs.textarea, {
mode: { name: "handlebars", base: "text/html" },
matchBrackets: true,
lineNumbers: true,
});
if (this.formBuilder.admin) {
this.editor.on("change", this.setTextareaValue);
}
}
}
setEventHandlers() {
super.setEventHandlers();
$$r(this.inputs.textarea).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
getSchema() {
const schema = super.getSchema();
schema.autobr = this.autobr;
schema.html = this.html;
return schema;
}
getDataForTemplate() {
const data = super.getDataForTemplate();
data.html = this.html;
return data;
}
setTextareaValue(codemirror, changeobj) {
const handler = codemirror.getValue();
const textarea = $$r(codemirror.getTextArea());
textarea.val(handler).trigger("change");
}
destroy() {
const cm = $$r(this.domElements.main).find(".CodeMirror");
if (cm.length) {
cm.empty().remove();
}
}
}
const $$s = jQuery;
class TextFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchFallback = MapSVG.parseBoolean(options.searchFallback);
this.searchType = options.searchType;
this.width =
this.formBuilder.filtersHide && !this.formBuilder.modal
? null
: options.width || "100%";
this.db_type = "varchar(255)";
}
setDomElements() {
super.setDomElements();
this.inputs.text = $$s(this.domElements.main).find('input[type="text"]')[0];
}
getSchema() {
const schema = super.getSchema();
schema.searchType = this.searchType;
return schema;
}
setEventHandlers() {
super.setEventHandlers();
$$s(this.inputs.text).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
setInputValue(value) {
this.inputs.text.value = value;
}
}
const $$t = jQuery;
class TitleFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchFallback = MapSVG.parseBoolean(options.searchFallback);
this.width =
this.formBuilder.filtersHide && !this.formBuilder.modal
? null
: options.width || "100%";
this.db_type = "varchar(255)";
}
setDomElements() {
super.setDomElements();
this.inputs.text = $$t(this.domElements.main).find('input[type="text"]')[0];
}
getSchema() {
const schema = super.getSchema();
schema.searchType = this.searchType;
return schema;
}
setEventHandlers() {
super.setEventHandlers();
$$t(this.inputs.text).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
}
setInputValue(value) {
this.inputs.text.value = value;
}
}
const $$u = jQuery;
class ColorPickerFormElement extends FormElement {
constructor(options, formBuilder, external) {
super(options, formBuilder, external);
this.searchFallback = MapSVG.parseBoolean(options.searchFallback);
this.width =
this.formBuilder.filtersHide && !this.formBuilder.modal
? null
: options.width || "100%";
this.db_type = "varchar(255)";
}
setDomElements() {
super.setDomElements();
this.inputs.text = $$u(this.domElements.main).find("input.cpicker")[0];
$$u(this.domElements.main).find(".colorpicker-element").colorpicker();
}
getSchema() {
const schema = super.getSchema();
schema.searchType = this.searchType;
return schema;
}
setEventHandlers() {
super.setEventHandlers();
$$u(this.inputs.text).on("change keyup paste", (e) => {
this.setValue(e.target.value, false);
this.triggerChanged();
});
$$u(this.domElements.main).find(".colorpicker-element").colorpicker().on("changeColor.colorpicker", (e) => {
this.setValue(this.inputs.text.value, false);
this.triggerChanged();
});
}
setInputValue(value) {
this.inputs.text.value = value;
}
}
const $$v = jQuery;
class FormElementFactory {
constructor(options) {
this.mapsvg = options.mapsvg;
this.editMode = options.editMode;
this.filtersMode = options.filtersMode;
this.namespace = options.namespace;
this.mediaUploader = options.mediaUploader;
this.formBuilder = options.formBuilder;
this.showNames = options.showNames !== false;
}
create(options) {
const types = {
checkbox: CheckboxFormElement,
checkboxes: CheckboxesFormElement,
date: DateFormElement,
distance: DistanceFormElement,
empty: EmptyFormElement,
id: IdFormElement,
image: ImagesFormElement,
location: LocationFormElement,
modal: ModalFormElement,
post: PostFormElement,
radio: RadioFormElement,
region: RegionsFormElement,
save: SaveFormElement,
search: SearchFormElement,
select: SelectFormElement,
status: StatusFormElement,
text: TextFormElement,
textarea: TextareaFormElement,
title: TitleFormElement,
colorpicker: ColorPickerFormElement,
};
const formElement = new types[options.type](options, this.formBuilder, this.getExtraParams());
formElement.init();
return formElement;
}
getExtraParams() {
const databaseFields = [];
const databaseFieldsFilterable = [];
const databaseFieldsFilterableShort = [];
const regionFields = [];
const regionFieldsFilterable = [];
const regions = new ArrayIndexed("id");
let mapIsGeo = false;
if (this.mapsvg) {
mapIsGeo = this.mapsvg.isGeo();
const schemaObjects = this.mapsvg.objectsRepository.getSchema();
if (schemaObjects) {
schemaObjects.getFields().forEach(function (obj) {
if (obj.type == "text" ||
obj.type == "region" ||
obj.type == "textarea" ||
obj.type == "post" ||
obj.type == "select" ||
obj.type == "radio" ||
obj.type == "checkbox") {
if (obj.type == "post") {
databaseFields.push("Object.post.post_title");
}
else {
databaseFields.push("Object." + obj.name);
}
}
if (obj.type == "region" || obj.type == "select" || obj.type == "radio") {
databaseFieldsFilterable.push("Object." + obj.name);
databaseFieldsFilterableShort.push(obj.name);
}
});
}
const schemaRegions = this.mapsvg.regionsRepository.getSchema();
if (schemaRegions) {
schemaRegions.getFieldsAsArray().forEach(function (obj) {
if (obj.type == "status" ||
obj.type == "text" ||
obj.type == "textarea" ||
obj.type == "post" ||
obj.type == "select" ||
obj.type == "radio" ||
obj.type == "checkbox") {
if (obj.type == "post") {
regionFields.push("Region.post.post_title");
}
else {
regionFields.push("Region." + obj.name);
}
}
if (obj.type == "status" || obj.type == "select" || obj.type == "radio") {
regionFieldsFilterable.push("Region." + obj.name);
}
});
}
this.mapsvg.regions.forEach((region) => {
regions.push({ id: region.id, title: region.title });
});
}
return {
databaseFields: databaseFields,
databaseFieldsFilterable: databaseFieldsFilterable,
databaseFieldsFilterableShort: databaseFieldsFilterableShort,
regionFields: regionFields,
regionFieldsFilterable: regionFieldsFilterable,
regions: regions,
mapIsGeo: mapIsGeo,
mediaUploader: this.mediaUploader,
filtersMode: this.filtersMode,
showNames: this.showNames,
};
}
}
const $$w = jQuery;
class FormBuilder {
constructor(options) {
const _this = this;
this.events = new Events();
this.container = options.container;
this.namespace = options.namespace;
this.mediaUploader = options.mediaUploader;
this.schema = options.schema || [];
this.editMode = options.editMode == undefined ? false : options.editMode;
this.filtersMode = options.filtersMode == undefined ? false : options.filtersMode;
this.filtersHide = options.filtersHide == undefined ? false : options.filtersHide;
this.modal = options.modal == undefined ? false : options.modal;
this.admin = options.admin;
this.mapsvg = options.mapsvg;
this.data = options.data || {};
this.clearButton = options.clearButton || false;
this.clearButtonText = options.clearButtonText || "";
this.searchButton = options.searchButton || false;
this.searchButtonText = options.searchButtonText || "";
this.showButtonText = options.showButtonText || "";
this.scrollable =
typeof options.scrollable !== "undefined"
? options.scrollable
: !_this.editMode && !_this.filtersMode;
this.showNames = typeof options.showNames !== "undefined" ? options.showNames : true;
this.formElementFactory = new FormElementFactory({
mapsvg: this.mapsvg,
formBuilder: this,
mediaUploader: this.mediaUploader,
editMode: this.editMode,
filtersMode: this.filtersMode,
namespace: this.namespace,
showNames: this.showNames,
});
this.events = new Events(this);
if (options.events && Object.keys(options.events).length > 0) {
for (const eventName in options.events) {
this.events.on(eventName, options.events[eventName]);
}
}
this.template = "form-builder";
this.closeOnSave = options.closeOnSave === true;
this.newRecord = options.newRecord === true;
this.types = options.types || [
"text",
"textarea",
"checkbox",
"radio",
"select",
"image",
"region",
"location",
"post",
"date",
];
this.templates = {};
this.elements = {};
this.view = $$w("").addClass("mapsvg-form-builder")[0];
if (this.editMode)
$$w(this.view).addClass("full-flex");
if (!this.showNames) {
$$w(this.view).addClass("hide-names");
}
this.formElements = new ArrayIndexed("name");
if (!MapSVG.templatesLoaded[this.template]) {
this.loadTemplates(() => this.init());
}
else {
this.init();
}
}
loadTemplates(callback) {
$$w.get(MapSVG.urls.root + "dist/" + this.template + ".html?v=" + MapSVG.version, (data) => {
$$w(data).appendTo("body");
MapSVG.templatesLoaded[this.template] = true;
Handlebars.registerPartial("dataMarkerPartial", $$w("#mapsvg-data-tmpl-marker").html());
if (this.editMode) {
Handlebars.registerPartial("markerByFieldPartial", $$w("#mapsvg-markers-by-field-tmpl-partial").html());
}
callback();
});
}
init() {
const _this = this;
MapSVG.formBuilder = this;
this.form = document.createElement("form");
this.form.className = "mapsvg-data-form-view";
if (!this.filtersMode) {
this.form.classList.add("form-horizontal");
}
if (this.editMode) {
const template = document.getElementById("mapsvg-form-editor-tmpl-ui").innerHTML;
const templateCompiled = Handlebars.compile(template);
this.view.innerHTML = templateCompiled({ types: this.types });
this.view.classList.add("edit");
this.form.classList.add("mapsvg-data-flex-full");
this.form.classList.add("mapsvg-data-container");
$$w(this.view).find(".mapsvg-data-preview").prepend(this.form);
this.formEditor = $$w(this.view).find("#mapsvg-data-form-edit")[0];
}
else {
this.view.appendChild(this.form);
}
_this.elements = {
buttons: {
text: $$w(_this.view).find("#mapsvg-data-btn-text")[0],
textarea: $$w(_this.view).find("#mapsvg-data-btn-textarea")[0],
checkbox: $$w(_this.view).find("#mapsvg-data-btn-checkbox")[0],
radio: $$w(_this.view).find("#mapsvg-data-btn-radio")[0],
select: $$w(_this.view).find("#mapsvg-data-btn-select")[0],
image: $$w(_this.view).find("#mapsvg-data-btn-image")[0],
region: $$w(_this.view).find("#mapsvg-data-btn-region")[0],
marker: $$w(_this.view).find("#mapsvg-data-btn-marker")[0],
saveSchema: $$w(_this.view).find("#mapsvg-data-btn-save-schema")[0],
},
containers: {
buttons_add: $$w(_this.view).find("#mapsvg-data-buttons-add")[0],
},
};
_this.redraw();
}
getForm() {
return this.form;
}
getFormEditor() {
return this.formEditor;
}
viewDidLoad() { }
setEventHandlers() {
const _this = this;
$$w(this.getForm()).on("submit", (e) => {
e.preventDefault();
});
if (this.filtersMode && this.clearButton) {
$$w(this.elements.buttons.clearButton).on("click", (e) => {
e.preventDefault();
this.clearAllFields();
});
}
$$w(window)
.off("keydown.form.mapsvg")
.on("keydown.form.mapsvg", function (e) {
if (MapSVG.formBuilder) {
if ((e.metaKey || e.ctrlKey) && e.keyCode == 13)
MapSVG.formBuilder.save();
else if (e.keyCode == 27)
MapSVG.formBuilder.close();
}
});
if (this.editMode) {
$$w(this.view).on("click", "#mapsvg-data-buttons-add button", function (e) {
e.preventDefault();
const type = $$w(this).data("create");
const formElement = _this.formElementFactory.create({ type: type });
_this.addField(formElement);
});
$$w(this.view).on("click", "#mapsvg-data-btn-save-schema", function (e) {
e.preventDefault();
const fields = _this.getSchema();
const counts = {};
_this.formElements.forEach(function (elem) {
counts[elem.name] = (counts[elem.name] || 0) + 1;
});
$$w(_this.getForm()).find(".form-group").removeClass("has-error");
const errors = [];
const reservedFields = [
"lat",
"lon",
"lng",
"location",
"location_lat",
"location_lon",
"location_lng",
"location_address",
"location_img",
"marker",
"marker_id",
"regions",
"region_id",
"post",
"post_title",
"post_url",
"keywords",
"status",
];
const reservedFieldsToTypes = {
regions: "region",
status: "status",
post: "post",
marker: "marker",
location: "location",
};
let errUnique, errEmpty;
_this.formElements.forEach(function (formElement, index) {
let err = false;
if (!_this.filtersMode) {
if (counts[formElement.name] > 1) {
if (!errUnique) {
errUnique = "Field names should be unique";
errors.push(errUnique);
err = true;
}
}
else if (formElement.name.length === 0) {
if (!errEmpty) {
errEmpty = "Field name can't be empty";
errors.push(errEmpty);
err = true;
}
}
else if (reservedFields.indexOf(formElement.name) != -1) {
if (!reservedFieldsToTypes[formElement.name] ||
(reservedFieldsToTypes[formElement.name] &&
reservedFieldsToTypes[formElement.name] != formElement.type)) {
const msg = 'Field name "' +
formElement.name +
'" is reserved, please set another name';
errors.push(msg);
err = true;
}
}
}
if (formElement.options &&
formElement.type != "region" &&
formElement.type != "marker") {
const vals = formElement.options.map(function (obj) {
return obj.value;
});
const uniq = [...Array.from(new Set(vals).values())];
if (vals.length != uniq.length) {
errors.push('Check "Options" list - values should not repeat');
err = true;
}
}
err && $$w(formElement.domElements.main).addClass("has-error");
});
if (errors.length === 0) {
_this.events.trigger("saveSchema", _this, [_this, fields]);
}
else {
jQuery.growl.error({ title: "Errors", message: errors.join("
") });
}
});
setTimeout(function () {
const el = _this.getForm();
_this.sortable = new Sortable(el, {
animation: 150,
onStart: function () {
$$w(_this.getForm()).addClass("sorting");
},
onEnd: function () {
setTimeout(function () {
$$w(_this.getForm()).removeClass("sorting");
_this.formElements.clear();
$$w(el)
.find(".form-group")
.each(function (index, elem) {
_this.formElements.push($$w(elem).data("formElement"));
});
}, 500);
},
});
}, 1000);
}
new ResizeSensor(this.view, function () {
_this.scrollApi && _this.scrollApi.reinitialise();
});
}
clearAllFields() {
this.formElements.forEach((f) => f.setValue(null));
this.events.trigger("cleared");
}
setFormElementEventHandlers(formElement) {
if (this.editMode) {
formElement.events.on("click", (elem) => {
this.edit(elem);
});
formElement.events.on("delete", (elem) => {
this.deleteField(elem);
});
}
else {
formElement.events.on("changed", (_formElement) => {
const name = _formElement.name;
const value = _formElement.getValue();
if (_formElement.type !== "search") {
this.events.trigger("changed.field", _formElement, [_formElement, name, value]);
}
else {
this.events.trigger("changed.search", _formElement, [_formElement, value]);
}
});
}
}
save() {
const _this = this;
if (_this.markerBackup) {
const marker = _this.mapsvg.getEditingMarker();
marker.events.off("change");
_this.markerBackup = marker.getOptions();
_this.mapsvg.unsetEditingMarker();
}
const data = _this.getData();
_this.saved = true;
this.events.trigger("save", _this, [_this, data]);
}
getFormElementByType(type) {
return this.formElements.find((el) => el.type === type);
}
getData() {
const data = {};
this.formElements.forEach((formElement) => {
if (formElement.readonly === false || formElement.type === "id") {
const _formElementData = formElement.getData();
data[_formElementData.name] = _formElementData.value;
}
});
return data;
}
reset() {
this.formElements.forEach((formElement) => {
formElement.setValue(null);
});
}
update(data) {
this.schema.getFields().forEach((field) => {
const formElement = this.formElements.get(field.name);
if (formElement) {
if (typeof data[field.name] !== "undefined") {
if (formElement.getValue() !== data[field.name]) {
formElement.setValue(data[field.name]);
}
}
else {
formElement.setValue(null);
}
}
});
}
redraw() {
const _this = this;
delete _this.markerBackup;
$$w(this.container).empty();
$$w(this.getForm()).empty();
this.formElements.clear();
this.schema &&
this.schema.fields.length > 0 &&
this.schema.fields.forEach((fieldSettings) => {
if (this.filtersMode) {
if (fieldSettings.type == "distance") {
fieldSettings.value = this.data.distance
? this.data.distance
: fieldSettings.value !== undefined
? fieldSettings.value
: null;
}
else {
fieldSettings.value = this.data[fieldSettings.parameterNameShort];
}
}
else {
fieldSettings.value = this.data
? this.data[fieldSettings.name]
: fieldSettings.value !== undefined
? fieldSettings.value
: null;
}
if (fieldSettings.type == "location" && !this.editMode) {
if (fieldSettings.value &&
fieldSettings.value.marker &&
fieldSettings.value.marker.id) ;
this.admin && this.admin.setMode && this.admin.setMode("editMarkers");
this.admin && this.admin.enableMarkersMode(true);
}
else if (fieldSettings.type == "post") {
fieldSettings.post = this.data["post"];
}
else if (fieldSettings.type === "region") {
fieldSettings.options = new ArrayIndexed("id", this.getRegionsList());
}
const formElement = this.formElementFactory.create(fieldSettings);
if (this.filtersMode) {
if (!this.filtersHide ||
(this.filtersHide && this.modal && fieldSettings.type !== "search") ||
(!this.modal && fieldSettings.type === "search")) {
this.addField(formElement);
}
}
else {
this.addField(formElement);
}
});
if (!_this.editMode) {
if (this.schema.fields.length === 0 && !this.filtersMode) {
const formElement = this.formElementFactory.create({ type: "empty" });
_this.addField(formElement);
}
else {
if (_this.admin && !_this.admin.isMetabox) {
const formElement = this.formElementFactory.create({ type: "save" });
formElement.events.on("click.btn.save", () => {
this.save();
});
formElement.events.on("click.btn.close", () => {
this.close();
});
_this.addField(formElement);
}
}
}
if (_this.filtersMode && _this.filtersHide && !_this.modal) {
const formElement = this.formElementFactory.create({
type: "modal",
showButtonText: _this.showButtonText,
});
this.showFiltersButton = _this.addField(formElement);
}
if (this.scrollable) {
const nano = $$w('');
const nanoContent = $$w('');
nano.append(nanoContent);
nanoContent.append(this.view);
$$w(_this.container).append(nano);
nano.jScrollPane({ contentWidth: "0px", mouseWheelSpeed: 30 });
_this.scrollApi = nano.data("jsp");
}
else {
$$w(_this.container).append(this.view);
}
if (_this.filtersMode && _this.clearButton) {
_this.elements.buttons.clearButton = $$w('' +
'
")[0];
$$w(this.getForm()).append(_this.elements.buttons.clearButton);
}
if (_this.filtersMode && _this.searchButton) {
_this.elements.buttons.searchButton = $$w('")[0];
$$w(this.getForm()).append(_this.elements.buttons.searchButton);
}
if (!this.editMode && !_this.filtersMode)
$$w(this.view).find("input:visible,textarea:visible").not(".tt-hint").first().focus();
const cm = $$w(this.container).find(".CodeMirror");
cm.each(function (index, el) {
el && el.CodeMirror.refresh();
});
_this.setEventHandlers();
this.events.trigger("init", this, [this, this.getData()]);
this.events.trigger("loaded", this, [this]);
}
updateExtraParamsInFormElements() {
this.formElements.forEach((formElement) => {
formElement.setExternal(this.formElementFactory.getExtraParams());
if (formElement.type === "location") {
formElement.redraw();
}
});
}
deleteField(formElement) {
const _this = this;
_this.formElements.delete(formElement.name);
}
getExtraParams() {
const databaseFields = [];
this.mapsvg.objectsRepository
.getSchema()
.getFields()
.forEach(function (obj) {
if (obj.type == "text" ||
obj.type == "region" ||
obj.type == "textarea" ||
obj.type == "post" ||
obj.type == "select" ||
obj.type == "radio" ||
obj.type == "checkbox") {
if (obj.type == "post") {
databaseFields.push("Object.post.post_title");
}
else {
databaseFields.push("Object." + obj.name);
}
}
});
let databaseFieldsFilterableShort = [];
databaseFieldsFilterableShort = this.mapsvg.objectsRepository
.getSchema()
.getFieldsAsArray()
.filter(function (obj) {
return obj.type == "select" || obj.type == "radio" || obj.type == "region";
})
.map(function (obj) {
return obj.name;
});
let markerFieldsShort = [];
markerFieldsShort = databaseFieldsFilterableShort.filter((o) => o.type === "select" || o.type === "radio");
const regionFields = this.mapsvg.regionsRepository
.getSchema()
.getFieldsAsArray()
.map(function (obj) {
if (obj.type == "status" ||
obj.type == "text" ||
obj.type == "textarea" ||
obj.type == "post" ||
obj.type == "select" ||
obj.type == "radio" ||
obj.type == "checkbox") {
if (obj.type == "post") {
return "Region.post.post_title";
}
else {
return "Region." + obj.name;
}
}
});
return {
databaseFields: databaseFields,
databaseFieldsFilterableShort: databaseFieldsFilterableShort,
regionFields: regionFields,
markerFieldsShort: markerFieldsShort,
};
}
addField(formElement) {
const _this = this;
if (["region", "marker", "post", "status", "distance", "location", "search"].indexOf(formElement.type) != -1) {
let repeat = false;
_this.formElements.forEach(function (control) {
if (control.type == formElement.type)
repeat = true;
});
if (repeat) {
jQuery.growl.error({
title: "Error",
message: 'You can add only 1 "' + MapSVG.ucfirst(formElement.type) + '" field',
});
return;
}
}
_this.formElements.push(formElement);
_this.getForm().append(formElement.domElements.main);
this.setFormElementEventHandlers(formElement);
if (this.editMode) {
if (formElement.protected) {
formElement.hide();
}
else {
this.edit(formElement);
}
}
return formElement;
}
edit(formElement) {
const _this = this;
_this.currentlyEditing && _this.currentlyEditing.destroyEditor();
this.getFormEditor().appendChild(formElement.getEditor());
formElement.initEditor();
_this.currentlyEditing = formElement;
$$w(_this.getForm()).find(".form-group.active").removeClass("active");
$$w(formElement.domElements.main).addClass("active");
}
get() {
}
getSchema() {
return this.formElements.map(function (formElement) {
return formElement.getSchema();
});
}
close() {
this.formElements.forEach((formElement) => formElement.destroy());
this.mediaUploader && this.mediaUploader.off("select");
MapSVG.formBuilder = null;
this.events.trigger("close", this, [this]);
}
destroy() {
$$w(this.view).empty().remove();
this.sortable = null;
}
toJSON(addEmpty) {
const obj = {};
function add(obj, name, value) {
if (!addEmpty && !value)
return false;
if (name.length == 1) {
obj[name[0]] = value;
}
else {
if (obj[name[0]] == null) {
if (name[1] === "") {
obj[name[0]] = [];
}
else {
obj[name[0]] = {};
}
}
if (obj[name[0]].length !== undefined) {
obj[name[0]].push(value);
}
else {
add(obj[name[0]], name.slice(1), value);
}
}
}
$$w(this.elements.containers.formView)
.find("input, textarea, select")
.each(function () {
if (!$$w(this).data("skip") &&
!$$w(this).prop("disabled") &&
$$w(this).attr("name") &&
!(!addEmpty &&
$$w(this).attr("type") == "checkbox" &&
$$w(this).attr("checked") == undefined) &&
!($$w(this).attr("type") == "radio" && $$w(this).attr("checked") == undefined)) {
let value;
if ($$w(this).attr("type") == "checkbox") {
value = $$w(this).prop("checked");
}
else {
value = $$w(this).val();
}
add(obj, $$w(this).attr("name").replace(/]/g, "").split("["), value);
}
});
return obj;
}
getRegionsList() {
return this.mapsvg.regions.map(function (r) {
return { id: r.id, title: r.title };
});
}
getRegionsAsArray() {
return this.mapsvg.regions;
}
setRegions(location) {
const regionsFormElement = this.formElements.get("regions");
if (this.mapsvg.options.source.indexOf("/geo-calibrated/usa.svg") !== -1) {
regionsFormElement.setValue(["US-" + location.address.state_short]);
}
else if (this.mapsvg.options.source.indexOf("/geo-calibrated/world.svg") !== -1) {
if (location.address.country_short) {
regionsFormElement.setValue([location.address.country_short]);
}
}
else {
if (location.address.administrative_area_level_1) {
this.mapsvg.regions.forEach((_region) => {
if (_region.title === location.address.administrative_area_level_1 ||
_region.title === location.address.administrative_area_level_2 ||
_region.id ===
location.address.country_short +
"-" +
location.address.administrative_area_level_1_short) {
regionsFormElement.setValue([_region.id]);
}
});
}
}
}
setIsLoading(value) {
this.isLoading = value;
if (this.searchButton) {
if (this.isLoading) {
$$w(this.elements.buttons.searchButton).find("button").attr("disabled", "disabled");
}
else {
$$w(this.elements.buttons.searchButton).find("button").removeAttr("disabled");
}
}
}
}
const $$x = jQuery;
class FiltersController extends DetailsController {
constructor(options) {
super(options);
this.showButtonText = options.showButtonText;
this.clearButton = options.clearButton;
this.clearButtonText = options.clearButtonText;
this.searchButton = options.searchButton;
this.searchButtonText = options.searchButtonText;
this.padding = options.padding;
this.schema = options.schema;
this.hideFilters = options.hide;
this.query = options.query;
}
viewDidLoad() {
super.viewDidLoad();
const _this = this;
this.formBuilder = new FormBuilder({
container: this.containers.contentView,
filtersMode: true,
schema: this.schema,
modal: this.modal,
filtersHide: this.hideFilters,
showButtonText: this.showButtonText,
clearButton: this.clearButton,
clearButtonText: this.clearButtonText,
searchButton: this.searchButton,
searchButtonText: this.searchButtonText,
editMode: false,
mapsvg: this.mapsvg,
data: {},
admin: false,
events: {
"changed.field": (formElement, field, value) => {
const filters = {};
let _value = value;
if (field === "regions") {
_value = {};
_value.region_ids = value instanceof Array ? value : [value];
_value.table_name = this.mapsvg.options.database.regionsTableName;
if (_value.region_ids.length === 0 || _value.region_ids[0] === "") {
_value = null;
}
}
filters[field] = _value;
this.query.setFilters(filters);
_this.events.trigger("changed.field", _this, [field, value]);
_this.events.trigger("changed.fields", _this, [field, value]);
},
"changed.search": (formElement, value) => {
this.query.setSearch(value);
_this.events.trigger("changed.search", _this, [value]);
},
cleared: (formBuilder) => {
this.query.clearFilters();
this.events.trigger("cleared", _this, []);
},
loaded: (formBuilder) => {
$$x(formBuilder.container).find(".mapsvg-form-builder").css({
padding: _this.padding,
});
this.updateScroll();
this.events.trigger("loaded");
},
},
});
}
reset() {
this.formBuilder && this.formBuilder.reset();
}
update(query) {
const _query = Object.assign({}, query.filters);
_query.search = query.search;
this.formBuilder && this.formBuilder.update(_query);
}
setFiltersCounter() {
if (this.hideFilters) {
const filtersCounter = Object.keys(this.query.filters).length;
const filtersCounterString = filtersCounter === 0 ? "" : filtersCounter.toString();
this.formBuilder &&
this.formBuilder.showFiltersButton &&
$$x(this.formBuilder.showFiltersButton.domElements.main)
.find("button")
.html(this.showButtonText + " " + filtersCounterString + "");
}
}
setEventHandlers() {
super.setEventHandlers();
const _this = this;
$$x(this.containers.view).on("click", ".mapsvg-btn-show-filters", function () {
_this.events.trigger("click.btn.showFilters");
});
$$x(this.containers.view).on("click", "#mapsvg-search-container button", function () {
_this.events.trigger("click.btn.searchButton");
});
}
}
const $$y = jQuery;
class PopoverController extends Controller {
constructor(options) {
super(options);
this.autoresize = true;
this.point = options.point;
this.yShift = options.yShift;
this.mapObject = options.mapObject;
this.id = this.mapObject.id + "_" + Math.random();
$$y(this.containers.main).data("popover-id", this.id);
}
setPoint(point) {
this.point = point;
}
getToolbarTemplate() {
if (this.withToolbar)
return '';
else
return "";
}
viewDidLoad() {
super.viewDidLoad.call(this);
if (MapSVG.isPhone &&
this.mapsvg.options.popovers.mobileFullscreen &&
!this.mobileCloseBtn) {
this.mobileCloseBtn = $$y('")[0];
$$y(this.containers.view).append(this.mobileCloseBtn);
}
this.adjustScreenPosition();
$$y(this.containers.main).toggleClass("mapsvg-popover-animate", true);
$$y(this.containers.main).toggleClass("mapsvg-popover-visible", true);
this.adjustHeight();
this.updateScroll();
this.autoresize && this.resizeSensor.setScroll();
this.events.trigger("shown", this, [this]);
}
adjustHeight() {
$$y(this.containers.main).height($$y(this.containers.main).find(".mapsvg-auto-height").outerHeight() +
(this.containers.toolbar ? $$y(this.containers.toolbar).outerHeight() : 0));
}
adjustScreenPosition() {
if (this.point) {
const pos = this.mapsvg.converter.convertSVGToPixel(this.point);
pos.y -= this.yShift;
pos.x = Math.round(pos.x);
pos.y = Math.round(pos.y);
this.setScreenPosition(pos.x, pos.y);
}
}
moveSrceenPositionBy(deltaX, deltaY) {
const oldPos = this.screenPoint, x = oldPos.x - deltaX, y = oldPos.y - deltaY;
this.setScreenPosition(x, y);
}
setScreenPosition(x, y) {
this.screenPoint = new ScreenPoint(x, y);
$$y(this.containers.main).css({
transform: "translateX(-50%) translate(" + x + "px," + y + "px)",
});
}
setEventHandlers() {
$$y("body").off(".popover.mapsvg");
$$y(this.containers.view).on("click touchend", ".mapsvg-popover-close, .mapsvg-mobile-modal-close", (e) => {
e.stopImmediatePropagation();
this.close();
});
$$y("body").on("mouseup.popover.mapsvg touchend.popover.mapsvg", (e) => {
if (this.mapsvg.isScrolling ||
$$y(e.target).closest(".mapsvg-directory").length ||
$$y(e.target).closest(".mapsvg-popover").length ||
$$y(e.target).hasClass("mapsvg-btn-map"))
return;
this.close();
});
}
close() {
if ($$y(this.containers.main).data("popover-id") != this.id ||
!$$y(this.containers.main).is(":visible"))
return;
this.destroy();
if (this.mapObject instanceof Region) {
this.mapsvg.deselectRegion(this.mapObject);
}
if (this.mapObject instanceof Marker) {
this.mapsvg.deselectAllMarkers();
}
this.events.trigger("closed", this, [this]);
}
destroy() {
$$y(this.containers.main).toggleClass("mapsvg-popover-animate", false);
$$y(this.containers.main).toggleClass("mapsvg-popover-visible", false);
super.destroy.call(this);
}
show() {
$$y(this.containers.main).toggleClass("mapsvg-popover-animate", true);
$$y(this.containers.main).toggleClass("mapsvg-popover-visible", true);
}
}
const $$z = jQuery;
class Tooltip extends Controller {
constructor(options) {
super(options);
this.scrollable = false;
this.withToolbar = false;
this.autoresize = false;
this.screenPoint = new ScreenPoint(0, 0);
this.posOriginal = {};
this.posShifted = {};
this.posShiftedPrev = {};
this.mirror = {};
this.noPadding = true;
this.setPosition(options.position);
this.setSize(options.minWidth, options.maxWidth);
}
setSize(minWidth, maxWidth) {
this.minWidth = minWidth;
this.maxWidth = maxWidth;
this.containers.main.style["min-width"] = this.minWidth + "px";
this.containers.main.style["max-width"] = this.maxWidth + "px";
}
setPosition(position) {
const ex = position.split("-");
if (ex[0].indexOf("top") != -1 || ex[0].indexOf("bottom") != -1) {
this.posOriginal.topbottom = ex[0];
}
if (ex[0].indexOf("left") != -1 || ex[0].indexOf("right") != -1) {
this.posOriginal.leftright = ex[0];
}
if (ex[1]) {
this.posOriginal.leftright = ex[1];
}
this.containers.main.className = this.containers.main.className.replace(/(^|\s)mapsvg-tt-\S+/g, "");
this.containers.main.classList.add("mapsvg-tt-" + position);
}
setScreenPoint(x, y) {
this.screenPoint.x = x;
this.screenPoint.y = y;
}
viewDidLoad() {
super.viewDidLoad.call(this);
}
viewDidAppear() {
super.viewDidAppear();
this.events.trigger("shown", this, [this]);
}
setScreenPosition(x, y) {
this.setScreenPoint(x, y);
this.containers.main.style.transform =
"translateX(-50%) translate(" + x + "px," + y + "px)";
}
setEventHandlers() {
const event = "mousemove.tooltip.mapsvg-" + this.mapsvg.id;
$$z("body")
.off(event)
.on(event, (e) => {
MapSVG.mouse = MapSVG.mouseCoords(e);
this.containers.main.style.left =
e.clientX +
$$z(window).scrollLeft() -
$$z(this.mapsvg.containers.map).offset().left +
"px";
this.containers.main.style.top =
e.clientY +
$$z(window).scrollTop() -
$$z(this.mapsvg.containers.map).offset().top +
"px";
const m = new ScreenPoint(e.clientX + $$z(window).scrollLeft(), e.clientY + $$z(window).scrollTop());
const _tbbox = this.containers.main.getBoundingClientRect();
const _mbbox = this.mapsvg.containers.map.getBoundingClientRect();
const tbbox = {
top: _tbbox.top + $$z(window).scrollTop(),
bottom: _tbbox.bottom + $$z(window).scrollTop(),
left: _tbbox.left + $$z(window).scrollLeft(),
right: _tbbox.right + $$z(window).scrollLeft(),
width: _tbbox.width,
height: _tbbox.height,
};
const mbbox = {
top: _mbbox.top + $$z(window).scrollTop(),
bottom: _mbbox.bottom + $$z(window).scrollTop(),
left: _mbbox.left + $$z(window).scrollLeft(),
right: _mbbox.right + $$z(window).scrollLeft(),
width: _mbbox.width,
height: _mbbox.height,
};
if (m.x > mbbox.right ||
m.y > mbbox.bottom ||
m.x < mbbox.left ||
m.y < mbbox.top) {
return;
}
if (this.mirror.top || this.mirror.bottom) {
if (this.mirror.top && m.y > this.mirror.top) {
this.mirror.top = 0;
delete this.posShifted.topbottom;
}
else if (this.mirror.bottom && m.y < this.mirror.bottom) {
this.mirror.bottom = 0;
delete this.posShifted.topbottom;
}
}
else {
if (tbbox.bottom < mbbox.top + tbbox.height) {
this.posShifted.topbottom = "bottom";
this.mirror.top = m.y;
}
else if (tbbox.top > mbbox.bottom - tbbox.height) {
this.posShifted.topbottom = "top";
this.mirror.bottom = m.y;
}
}
if (this.mirror.right || this.mirror.left) {
if (this.mirror.left && m.x > this.mirror.left) {
this.mirror.left = 0;
delete this.posShifted.leftright;
}
else if (this.mirror.right && m.x < this.mirror.right) {
this.mirror.right = 0;
delete this.posShifted.leftright;
}
}
else {
if (tbbox.right < mbbox.left + tbbox.width) {
this.posShifted.leftright = "right";
this.mirror.left = m.x;
}
else if (tbbox.left > mbbox.right - tbbox.width) {
this.posShifted.leftright = "left";
this.mirror.right = m.x;
}
}
let pos = $$z.extend({}, this.posOriginal, this.posShifted);
const _pos = [];
pos.topbottom && _pos.push(pos.topbottom);
pos.leftright && _pos.push(pos.leftright);
pos = _pos.join("-");
if (this.posShifted.topbottom != this.posOriginal.topbottom ||
this.posShifted.leftright != this.posOriginal.leftright) {
this.containers.main.className = this.containers.main.className.replace(/(^|\s)mapsvg-tt-\S+/g, "");
this.containers.main.classList.add("mapsvg-tt-" + pos);
this.posShiftedPrev = pos;
}
});
}
setContent(template, data) {
this.containers.main.innerHTML = template(data);
return this;
}
show() {
this.containers.main.classList.add("mapsvg-tooltip-visible");
return this;
}
hide() {
this.containers.main.classList.remove("mapsvg-tooltip-visible");
return this;
}
}
const $$A = jQuery;
class MapSVGMap {
constructor(containerId, mapParams, externalParams) {
this.markerOptions = { src: MapSVG.urls.root + "markers/pin1_red.png" };
const options = mapParams.options;
this.updateOutdatedOptions(options);
this.dirtyFields = [];
this.containerId = containerId;
this.options = $$A.extend(true, {}, DefaultOptions, options);
this.options.source = this.urlToRelativePath(this.options.source);
this.editMode = this.options.editMode;
delete this.options.editMode;
this.id = mapParams.id;
this.svgFileLastChanged = mapParams.svgFileLastChanged;
this.regions = new ArrayIndexed("id");
this.objects = new ArrayIndexed("id");
this.events = new Events(this);
this.highlightedRegions = [];
this.editRegions = { on: false };
this.editMarkers = { on: false };
this.editData = { on: false };
this.controllers = {};
this.containers = {
map: document.getElementById(this.containerId),
scrollpane: $$A('')[0],
scrollpaneWrap: $$A('')[0],
layers: $$A('')[0],
};
this.containers.map.appendChild(this.containers.layers);
this.containers.map.appendChild(this.containers.scrollpaneWrap);
this.containers.scrollpaneWrap.appendChild(this.containers.scrollpane);
this.whRatio = 0;
this.isScrolling = false;
this.markerOptions = {};
this.svgDefault = {};
this.scale = 1;
this._scale = 1;
this.selected_id = [];
this.regions = new ArrayIndexed("id");
if (!this.options.database.regionsTableName) {
this.options.database.regionsTableName = "regions_" + this.id;
}
if (!this.options.database.objectsTableName) {
this.options.database.objectsTableName = "objects_" + this.id;
}
this.regionsRepository = new Repository("region", "regions/" + this.options.database.regionsTableName);
this.regionsRepository.query.update({ perpage: 0 });
this.objectsRepository = new Repository("object", "objects/" + this.options.database.objectsTableName);
if (this.options.database.noFiltersNoLoad) {
this.objectsRepository.setNoFiltersNoLoad(true);
}
this.objectsRepository.query.update({
perpage: this.options.database.pagination.on
? this.options.database.pagination.perpage
: 0,
});
this.schemaRepository = new SchemaRepository();
this.markers = new ArrayIndexed("id");
this.markersClusters = new ArrayIndexed("id");
this._viewBox = new ViewBox(0, 0, 0, 0);
this.viewBox = new ViewBox(0, 0, 0, 0);
this.zoomLevel = 0;
this.scroll = {
tx: 0,
ty: 0,
vxi: 0,
vyi: 0,
x: 0,
y: 0,
dx: 0,
dy: 0,
vx: 0,
vy: 0,
gx: 0,
gy: 0,
touchScrollStart: 0,
};
this.layers = {};
this.geoCoordinates = false;
this.geoViewBox = new GeoViewBox(new GeoPoint(0, 0), new GeoPoint(0, 0));
this.eventsPreventList = {};
this.googleMaps = {
loaded: false,
initialized: false,
map: null,
zoomLimit: true,
maxZoomService: null,
};
this.afterLoadBlockers = 1;
this.loaded = false;
if (this.id) {
this.afterLoadBlockers += 2;
}
if (this.options.googleMaps.on) {
this.afterLoadBlockers++;
}
if (this.filtersShouldBeShown()) {
this.afterLoadBlockers++;
}
this.init();
}
urlToRelativePath(url) {
if (url.indexOf("//") === 0)
url = url.replace(/^\/\/[^/]+/, "").replace("//", "/");
else
url = url.replace(/^.*:\/\/[^/]+/, "").replace("//", "/");
return url;
}
setGroups(groups) {
const _this = this;
if (!this.groups) {
_this.groups = new ArrayIndexed("id", _this.options.groups, {
autoId: true,
unique: true,
});
}
else {
this.options.groups = this.groups;
}
_this.groups.forEach(function (g) {
g.objects &&
g.objects.length &&
g.objects.forEach(function (obj) {
_this.containers.svg
.querySelector("#" + obj.value)
.classList.toggle("mapsvg-hidden", !g.visible);
});
});
}
getGroupSelectOptions() {
const _this = this;
const optionGroups = [];
const options = [];
const options2 = [];
$$A(_this.containers.svg)
.find("g")
.each(function (index) {
const id = $$A(this)[0].getAttribute("id");
if (id) {
const title = $$A(this)[0].getAttribute("title");
options.push({ label: title || id, value: id });
}
});
optionGroups.push({ title: "SVG Layers / Groups", options: options });
$$A(_this.containers.svg)
.find("path,ellipse,circle,polyline,polygon,rectangle,img,text")
.each(function (index) {
const id = $$A(this)[0].getAttribute("id");
if (id) {
const title = $$A(this)[0].getAttribute("title");
options2.push({ label: title || id, value: id });
}
});
optionGroups.push({ title: "Other SVG objects", options: options2 });
return optionGroups;
}
setLayersControl(options) {
const _this = this;
if (options)
$$A.extend(true, this.options.layersControl, options);
if (this.options.layersControl.on) {
if (!this.containers.layersControl) {
this.containers.layersControl = document.createElement("div");
this.containers.layersControl.classList.add("mapsvg-layers-control");
this.containers.layersControlLabel = document.createElement("div");
this.containers.layersControlLabel.classList.add("mapsvg-layers-label");
this.containers.layersControl.appendChild(this.containers.layersControlLabel);
const layersControlWrap = document.createElement("div");
layersControlWrap.classList.add("mapsvg-layers-list-wrap");
this.containers.layersControl.appendChild(layersControlWrap);
this.containers.layersControlListNano = document.createElement("div");
this.containers.layersControlListNano.classList.add("nano");
layersControlWrap.appendChild(this.containers.layersControlListNano);
this.containers.layersControlList = document.createElement("div");
this.containers.layersControlList.classList.add("mapsvg-layers-list");
this.containers.layersControlList.classList.add("nano-content");
this.containers.layersControlListNano.appendChild(this.containers.layersControlList);
this.containers.mapContainer.appendChild(this.containers.layersControl);
}
this.containers.layersControl.style.display = "block";
this.containers.layersControlLabel.innerHTML = this.options.layersControl.label;
this.containers.layersControlLabel.style.display = "block";
this.containers.layersControlList.innerHTML = "";
while (this.containers.layersControlList.firstChild) {
this.containers.layersControlList.removeChild(this.containers.layersControlList.firstChild);
}
this.containers.layersControl.classList.remove("mapsvg-top-left", "mapsvg-top-right", "mapsvg-bottom-left", "mapsvg-bottom-right");
this.containers.layersControl.classList.add("mapsvg-" + this.options.layersControl.position);
if (this.options.menu.on &&
!this.options.menu.customContainer &&
this.options.layersControl.position.indexOf("left") !== -1) {
this.containers.layersControl.style.left = this.options.menu.width;
}
this.containers.layersControl.style.maxHeight = this.options.layersControl.maxHeight;
this.options.groups.forEach((g) => {
const item = document.createElement("div");
item.classList.add("mapsvg-layers-item");
item.setAttribute("data-group-id", g.id);
item.innerHTML =
'";
this.containers.layersControlList.appendChild(item);
});
$$A(this.containers.layersControlListNano).nanoScroller({
preventPageScrolling: true,
iOSNativeScrolling: true,
});
$$A(this.containers.layersControl).off();
$$A(this.containers.layersControl).on("click", ".mapsvg-layers-item", function () {
const id = $$A(this).data("group-id");
const input = $$A(this).find("input");
input.prop("checked", !input.prop("checked"));
_this.groups.forEach(function (g) {
if (g.id === id)
g.visible = !g.visible;
});
_this.setGroups();
});
$$A(this.containers.layersControlLabel).off();
$$A(this.containers.layersControlLabel).on("click", () => {
$$A(_this.containers.layersControl).toggleClass("closed");
});
$$A(this.containers.layersControl).toggleClass("closed", !this.options.layersControl.expanded);
}
else {
if (this.containers.layersControl) {
this.containers.layersControl.style.display = "none";
}
}
}
loadDataObjects(params) {
return this.objectsRepository.find(params);
}
loadDirectory() {
if (!this.editMode &&
this.options.menu.source === "database" &&
!this.objectsRepository.loaded) {
return;
}
if (this.options.menu.on) {
this.controllers.directory.loadItemsToDirectory();
}
this.setPagination();
}
setPagination() {
const _this = this;
this.containers.pagerMap && $$A(this.containers.pagerMap).empty().remove();
this.containers.pagerDir && $$A(this.containers.pagerDir).empty().remove();
if (_this.options.database.pagination.on &&
_this.options.database.pagination.perpage !== 0) {
this.containers.directory.classList.toggle("mapsvg-with-pagination", ["directory", "both"].indexOf(_this.options.database.pagination.showIn) !== -1);
this.containers.map.classList.toggle("mapsvg-with-pagination", ["map", "both"].indexOf(_this.options.database.pagination.showIn) !== -1);
if (_this.options.menu.on) {
this.containers.pagerDir = _this.getPagination();
_this.controllers.directory.addPagination(this.containers.pagerDir);
}
this.containers.pagerMap = _this.getPagination();
this.containers.map.appendChild(this.containers.pagerMap);
}
}
getPagination(callback) {
const _this = this;
const pager = $$A('');
if (this.objectsRepository.onFirstPage() && this.objectsRepository.onLastPage()) {
pager.hide();
}
else {
pager.find(".mapsvg-prev").removeClass("disabled");
pager.find(".mapsvg-first").removeClass("disabled");
pager.find(".mapsvg-last").removeClass("disabled");
pager.find(".mapsvg-next").removeClass("disabled");
this.objectsRepository.onLastPage() &&
pager.find(".mapsvg-next").addClass("disabled") &&
pager.find(".mapsvg-last").addClass("disabled");
this.objectsRepository.onFirstPage() &&
pager.find(".mapsvg-prev").addClass("disabled") &&
pager.find(".mapsvg-first").addClass("disabled");
}
pager
.on("click", ".mapsvg-next:not(.disabled)", (e) => {
e.preventDefault();
if (this.objectsRepository.onLastPage())
return;
const query = new Query({ page: this.objectsRepository.query.page + 1 });
this.objectsRepository.find(query).done(function () {
callback && callback();
});
})
.on("click", ".mapsvg-prev:not(.disabled)", function (e) {
e.preventDefault();
if (_this.objectsRepository.onFirstPage())
return;
const query = new Query({ page: _this.objectsRepository.query.page - 1 });
_this.objectsRepository.find(query).done(function () {
callback && callback();
});
})
.on("click", ".mapsvg-first:not(.disabled)", function (e) {
e.preventDefault();
if (_this.objectsRepository.onFirstPage())
return;
const query = new Query({ page: 1 });
_this.objectsRepository.find(query).done(function () {
callback && callback();
});
})
.on("click", ".mapsvg-last:not(.disabled)", function (e) {
e.preventDefault();
if (_this.objectsRepository.onLastPage())
return;
const query = new Query({ lastpage: true });
_this.objectsRepository.find(query).done(function () {
callback && callback();
});
});
return pager[0];
}
deleteMarkers() {
while (this.markers.length) {
this.markerDelete(this.markers[0]);
}
}
deleteClusters() {
if (this.markersClusters) {
this.markersClusters.forEach(function (markerCluster) {
markerCluster.destroy();
});
this.markersClusters.clear();
}
}
addLocations() {
const _this = this;
this.firstDataLoad = this.firstDataLoad === undefined;
let locationField = this.objectsRepository.getSchema().getFieldByType("location");
if (!locationField) {
return;
}
locationField = locationField.name;
if (locationField) {
if (this.firstDataLoad) {
this.setMarkerImagesDependency();
}
_this.deleteMarkers();
_this.deleteClusters();
_this.clusters = {};
_this.clustersByZoom = [];
if (this.objectsRepository.getLoaded().length > 0) {
this.objectsRepository.getLoaded().forEach(function (object) {
if (object[locationField]) {
if (object[locationField].img &&
(object[locationField].geoPoint || object[locationField].svgPoint)) {
new Marker({
location: object[locationField],
object: object,
mapsvg: _this,
});
}
}
});
if (_this.options.clustering.on) {
_this.startClusterizer();
}
else {
this.objectsRepository.getLoaded().forEach(function (object) {
if (object.location && object.location.marker) {
_this.markerAdd(object.location.marker);
}
});
_this.mayBeFitMarkers();
}
}
}
}
addClustersFromWorker(zoomLevel, clusters) {
const _this = this;
_this.clustersByZoom[zoomLevel] = [];
for (const cell in clusters) {
const markers = clusters[cell].markers.map(function (marker) {
return _this.objectsRepository.objects.findById(marker.id).location.marker;
});
_this.clustersByZoom[zoomLevel].push(new MarkerCluster({
markers: markers,
svgPoint: new SVGPoint(clusters[cell].x, clusters[cell].y),
cellX: clusters[cell].cellX,
cellY: clusters[cell].cellY,
}, _this));
}
if (_this.zoomLevel === zoomLevel) {
_this.clusterizeMarkers();
}
}
startClusterizer() {
if (!this.objectsRepository || this.objectsRepository.getLoaded().length === 0) {
return;
}
const locationField = this.objectsRepository.getSchema().getFieldByType("location");
if (!locationField) {
return false;
}
if (!this.clusterizerWorker) {
this.clusterizerWorker = new Worker(MapSVG.urls.root + "js/mapsvg/Core/clustering.js");
this.clusterizerWorker.onmessage = (evt) => {
if (evt.data.clusters) {
this.addClustersFromWorker(evt.data.zoomLevel, evt.data.clusters);
}
};
}
const objectsData = [];
this.objectsRepository
.getLoaded()
.filter((o) => {
return o.location && o.location.marker;
})
.forEach((o) => {
objectsData.push({
id: o.id,
x: o.location.marker.svgPoint.x,
y: o.location.marker.svgPoint.y,
});
});
this.clusterizerWorker.postMessage({
objects: objectsData,
cellSize: 50,
mapWidth: this.containers.map.clientWidth,
zoomLevels: this.zoomLevels,
zoomLevel: this.zoomLevel,
zoomDelta: this.zoomDelta,
svgViewBox: this.svgDefault.viewBox,
});
this.events.on("zoom", () => {
this.clusterizerWorker.postMessage({
message: "zoom",
zoomLevel: this.zoomLevel,
});
});
}
clusterizeMarkers(skipFitMarkers) {
$$A(this.layers.markers)
.children()
.each((i, obj) => {
$$A(obj).detach();
});
this.markers.clear();
this.markersClusters.clear();
this.clustersByZoom &&
this.clustersByZoom[this.zoomLevel] &&
this.clustersByZoom[this.zoomLevel].forEach((cluster) => {
if (this.options.googleMaps.on &&
this.googleMaps.map &&
this.googleMaps.map.getZoom() >= 17) {
this.markerAdd(cluster.markers[0]);
}
else {
if (cluster.markers.length > 1) {
this.markersClusterAdd(cluster);
}
else {
this.markerAdd(cluster.markers[0]);
}
}
});
if (this.editingMarker) {
this.markerAdd(this.editingMarker);
}
if (!skipFitMarkers) {
this.mayBeFitMarkers();
}
if (this.options.labelsMarkers.on) {
this.setLabelsMarkers();
}
}
getCssUrl() {
return MapSVG.urls.root + "css/mapsvg.css";
}
isGeo() {
return this.mapIsGeo;
}
functionFromString(string) {
let func;
let error;
const fn = string.trim();
if (fn.indexOf("{") == -1 || fn.indexOf("function") !== 0 || fn.indexOf("(") == -1) {
return new SyntaxError("MapSVG user function error: no function body.");
}
const fnBody = fn.substring(fn.indexOf("{") + 1, fn.lastIndexOf("}"));
const params = fn.substring(fn.indexOf("(") + 1, fn.indexOf(")"));
try {
func = new Function(params, fnBody);
}
catch (err) {
error = err;
}
if (!error)
return func;
else
return error;
}
getOptions(forTemplate, forWeb) {
const options = $$A.extend(true, {}, this.options);
function clearEmpties(o) {
for (const k in o) {
if (!o[k] || typeof o[k] !== "object") {
continue;
}
clearEmpties(o[k]);
if (Object.keys(o[k]).length === 0) {
delete o[k];
}
}
}
clearEmpties(options.regions);
$$A.extend(true, options, this.optionsDelta);
options.viewBox = this._viewBox.toArray();
options.filtersSchema = this.filtersSchema.getFieldsAsArray();
if (options.filtersSchema.length > 0) {
options.filtersSchema.forEach((field) => {
if (field.type === "distance") {
field.value = "";
}
});
}
delete options.markers;
if (forTemplate) {
options.svgFilename = options.source.split("/").pop();
options.svgFiles = MapSVG.svgFiles;
}
if (forWeb)
$$A.each(options, (key, val) => {
if (JSON.stringify(val) == JSON.stringify(this.defaults[key]))
delete options[key];
});
delete options.backend;
return options;
}
restoreDeltaOptions() {
this.update(this.optionsDelta);
this.optionsDelta = {};
}
setEvents(functions) {
let compiledFunction;
for (const eventName in functions) {
if (typeof functions[eventName] === "string") {
compiledFunction =
functions[eventName] != ""
? this.functionFromString(functions[eventName])
: null;
if (!compiledFunction ||
compiledFunction.error ||
compiledFunction instanceof TypeError ||
compiledFunction instanceof SyntaxError) {
continue;
}
}
else if (typeof functions[eventName] === "function") {
compiledFunction = functions[eventName];
}
this.events.off(eventName);
this.events.on(eventName, compiledFunction);
if (eventName.indexOf("directory") !== -1) {
const event = eventName.split(".")[0];
if (this.controllers && this.controllers.directory) {
this.controllers.directory.events.off(event);
this.controllers.directory.events.on(event, compiledFunction);
}
}
}
$$A.extend(true, this.options.events, functions);
}
setActions(options) {
$$A.extend(true, this.options.actions, options);
}
setDetailsView(options) {
options = options || this.options.detailsView || {};
$$A.extend(true, this.options.detailsView, options);
if (this.options.detailsView.location === "top" && this.options.menu.position === "left") {
this.options.detailsView.location = "leftSidebar";
}
else if (this.options.detailsView.location === "top" &&
this.options.menu.position === "right") {
this.options.detailsView.location = "rightSidebar";
}
if (this.options.detailsView.location === "near" ||
this.options.detailsView.location === "mapContainer") {
this.options.detailsView.location = "map";
}
if (!this.containers.detailsView) {
this.containers.detailsView = $$A('')[0];
}
$$A(this.containers.detailsView).toggleClass("mapsvg-details-container-relative", !(MapSVG.isPhone && this.options.detailsView.mobileFullscreen) &&
!this.shouldBeScrollable(this.options.detailsView.location));
if (this.options.detailsView.location === "custom") {
$$A("#" + this.options.detailsView.containerId).append($$A(this.containers.detailsView));
}
else {
if (MapSVG.isPhone && this.options.detailsView.mobileFullscreen) {
$$A("body").append($$A(this.containers.detailsView));
$$A(this.containers.detailsView).addClass("mapsvg-container-fullscreen");
}
else {
this.containers[this.options.detailsView.location].append(this.containers.detailsView);
}
if (this.options.detailsView.margin) {
$$A(this.containers.detailsView).css("margin", this.options.detailsView.margin);
}
$$A(this.containers.detailsView).css("width", this.options.detailsView.width);
}
}
setMobileView(options) {
$$A.extend(true, this.options.mobileView, options);
}
attachDataToRegions(object) {
this.regions.forEach(function (region) {
region.objects = [];
});
this.objectsRepository.getLoaded().forEach((obj, index) => {
const regions = obj.getRegionsForTable(this.options.database.regionsTableName);
if (regions && regions.length) {
regions.forEach((region) => {
const r = this.getRegion(region.id);
if (r)
r.objects.push(obj);
});
}
});
}
setTemplates(templates) {
this.templates = this.templates || {};
for (let name in templates) {
if (name != undefined) {
this.options.templates[name] = templates[name];
let t = this.options.templates[name];
if (name == "directoryItem" || name == "directoryCategoryItem") {
const dirItemTemplate = this.options.templates.directoryItem;
t =
'{{#each items}}' +
dirItemTemplate +
"
{{/each}}";
if (this.options.menu.categories &&
this.options.menu.categories.on &&
this.options.menu.categories.groupBy) {
const t2 = this.options.templates["directoryCategoryItem"];
t =
'{{#each items}}{{#with category}}' +
t2 +
'
{{/with}}' +
t +
"
{{/each}}";
}
name = "directory";
}
try {
this.options.templates[name] = t;
this.templates[name] = Handlebars.compile(t, { strict: false });
}
catch (err) {
console.error(err);
this.templates[name] = Handlebars.compile("", { strict: false });
}
if (this.editMode &&
(name == "directory" || name == "directoryCategoryItem") &&
this.controllers &&
this.controllers.directory) {
this.controllers.directory.templates.main = this.templates[name];
this.loadDirectory();
}
}
}
}
update(options) {
for (const key in options) {
if (key == "regions") {
for (const id in options.regions) {
const region = this.getRegion(id);
region && region.update(options.regions[id]);
if (options.regions[id].disabled != undefined) {
this.deselectRegion(region);
this.options.regions[id] = this.options.regions[id] || {};
this.options.regions[id].disabled = region.disabled;
}
}
}
else {
const setter = "set" + MapSVG.ucfirst(key);
if (typeof this[setter] == "function")
this[setter](options[key]);
else {
this.options[key] = options[key];
}
}
}
}
getDirtyFields() {
return this.getData();
}
clearDirtyFields() {
this.dirtyFields = [];
}
setTitle(title) {
title && (this.options.title = title);
}
setExtension(extension) {
if (extension) {
this.options.extension = extension;
}
else {
delete this.options.extension;
}
}
setDisableLinks(on) {
on = MapSVG.parseBoolean(on);
if (on) {
$$A(this.containers.map).on("click.a.mapsvg", "a", function (e) {
e.preventDefault();
});
}
else {
$$A(this.containers.map).off("click.a.mapsvg");
}
this.disableLinks = on;
}
setLoadingText(val) {
this.options.loadingText = val;
}
setLockAspectRatio(onoff) {
this.options.lockAspectRatio = MapSVG.parseBoolean(onoff);
}
setMarkerEditHandler(handler) {
this.markerEditHandler = handler;
}
setChoroplethSourceField(field) {
this.options.choropleth.sourceField = field;
this.redrawChoropleth();
}
setRegionEditHandler(handler) {
this.regionEditHandler = handler;
}
setDisableAll(on) {
on = MapSVG.parseBoolean(on);
$$A.extend(true, this.options, { disableAll: on });
$$A(this.containers.map).toggleClass("mapsvg-disabled-regions", on);
}
setRegionStatuses(_statuses) {
this.options.regionStatuses = {};
const colors = {};
_statuses.forEach((statusOptions) => {
this.options.regionStatuses[statusOptions.value] = statusOptions;
colors[statusOptions.value] = statusOptions.color.length
? statusOptions.color
: undefined;
});
this.setColors({ status: colors });
}
setColorsIgnore(val) {
this.options.colorsIgnore = MapSVG.parseBoolean(val);
this.regionsRedrawColors();
}
setColors(colors) {
for (const i in colors) {
if (i === "status") {
for (const s in colors[i]) {
MapSVG.fixColorHash(colors[i][s]);
}
}
else {
if (typeof colors[i] == "string") {
MapSVG.fixColorHash(colors[i]);
}
}
}
$$A.extend(true, this.options, { colors: colors });
if (colors && colors.status)
this.options.colors.status = colors.status;
if (this.options.colors.markers) {
for (const z in this.options.colors.markers) {
for (const x in this.options.colors.markers[z]) {
this.options.colors.markers[z][x] = parseInt(this.options.colors.markers[z][x]);
}
}
}
if (this.options.colors.background)
$$A(this.containers.map).css({ background: this.options.colors.background });
if (this.options.colors.hover) {
this.options.colors.hover = !isNaN(this.options.colors.hover)
? parseInt(this.options.colors.hover + "")
: this.options.colors.hover;
}
if (this.options.colors.selected) {
this.options.colors.selected = !isNaN(this.options.colors.selected)
? parseInt(this.options.colors.selected + "")
: this.options.colors.selected;
}
$$A(this.containers.leftSidebar).css({
"background-color": this.options.colors.leftSidebar,
});
$$A(this.containers.rightSidebar).css({
"background-color": this.options.colors.rightSidebar,
});
$$A(this.containers.header).css({ "background-color": this.options.colors.header });
$$A(this.containers.footer).css({ "background-color": this.options.colors.footer });
if ($$A(this.containers.detailsView) && this.options.colors.detailsView !== undefined) {
$$A(this.containers.detailsView).css({
"background-color": this.options.colors.detailsView,
});
}
if ($$A(this.containers.directory) && this.options.colors.directory !== undefined) {
$$A(this.containers.directory).css({
"background-color": this.options.colors.directory,
});
}
if ($$A(this.containers.filtersModal) && this.options.colors.modalFilters !== undefined) {
$$A(this.containers.filtersModal).css({
"background-color": this.options.colors.modalFilters,
});
}
if ($$A(this.containers.filters) && this.options.colors.directorySearch) {
$$A(this.containers.filters).css({
"background-color": this.options.colors.directorySearch,
});
}
else if ($$A(this.containers.filters)) {
$$A(this.containers.filters).css({
"background-color": "",
});
}
if (!this.containers.clustersCss) {
this.containers.clustersCss = ($$A("").appendTo("body")[0]);
}
let css = "";
if (this.options.colors.clusters) {
css += "background-color: " + this.options.colors.clusters + ";";
}
if (this.options.colors.clustersBorders) {
css += "border-color: " + this.options.colors.clustersBorders + ";";
}
if (this.options.colors.clustersText) {
css += "color: " + this.options.colors.clustersText + ";";
}
$$A(this.containers.clustersCss).html(".mapsvg-marker-cluster {" + css + "}");
if (!this.containers.clustersHoverCss) {
this.containers.clustersHoverCss = ($$A("").appendTo("body")[0]);
}
let cssHover = "";
if (this.options.colors.clustersHover) {
cssHover += "background-color: " + this.options.colors.clustersHover + ";";
}
if (this.options.colors.clustersHoverBorders) {
cssHover += "border-color: " + this.options.colors.clustersHoverBorders + ";";
}
if (this.options.colors.clustersHoverText) {
cssHover += "color: " + this.options.colors.clustersHoverText + ";";
}
$$A(this.containers.clustersHoverCss).html(".mapsvg-marker-cluster:hover {" + cssHover + "}");
if (!this.containers.markersCss) {
this.containers.markersCss = $$A("").appendTo("head")[0];
}
const markerCssText = ".mapsvg-with-marker-active .mapsvg-marker {\n" +
" opacity: " +
this.options.colors.markers.inactive.opacity / 100 +
";\n" +
" -webkit-filter: grayscale(" +
(100 - this.options.colors.markers.inactive.saturation) +
"%);\n" +
" filter: grayscale(" +
(100 - this.options.colors.markers.inactive.saturation) +
"%);\n" +
"}\n" +
".mapsvg-with-marker-active .mapsvg-marker-active {\n" +
" opacity: " +
this.options.colors.markers.active.opacity / 100 +
";\n" +
" -webkit-filter: grayscale(" +
(100 - this.options.colors.markers.active.saturation) +
"%);\n" +
" filter: grayscale(" +
(100 - this.options.colors.markers.active.saturation) +
"%);\n" +
"}\n" +
".mapsvg-with-marker-hover .mapsvg-marker {\n" +
" opacity: " +
this.options.colors.markers.unhovered.opacity / 100 +
";\n" +
" -webkit-filter: grayscale(" +
(100 - this.options.colors.markers.unhovered.saturation) +
"%);\n" +
" filter: grayscale(" +
(100 - this.options.colors.markers.unhovered.saturation) +
"%);\n" +
"}\n" +
".mapsvg-with-marker-hover .mapsvg-marker-hover {\n" +
" opacity: " +
this.options.colors.markers.hovered.opacity / 100 +
";\n" +
" -webkit-filter: grayscale(" +
(100 - this.options.colors.markers.hovered.saturation) +
"%);\n" +
" filter: grayscale(" +
(100 - this.options.colors.markers.hovered.saturation) +
"%);\n" +
"}\n";
$$A(this.containers.markersCss).html(markerCssText);
$$A.each(this.options.colors, (key, color) => {
if (color === null || color == "")
delete this.options.colors[key];
});
this.regionsRedrawColors();
}
setTooltips(options) {
if (options.on !== undefined)
options.on = MapSVG.parseBoolean(options.on);
$$A.extend(true, this.options, { tooltips: options });
if (!this.containers.tooltip) {
this.containers.tooltip = $$A("").addClass("mapsvg-tooltip")[0];
$$A(this.containers.map).append(this.containers.tooltip);
this.controllers.tooltip = new Tooltip({
mapsvg: this,
container: this.containers.tooltip,
position: this.options.tooltips.position,
maxWidth: this.options.tooltips.maxWidth,
minWidth: this.options.tooltips.minWidth,
});
this.controllers.tooltip._init();
}
if (typeof this.options.tooltips.position !== "undefined") {
this.controllers.tooltip.setPosition(this.options.tooltips.position);
}
if (typeof this.options.tooltips.maxWidth !== "undefined" ||
typeof this.options.tooltips.minWidth !== "undefined") {
this.controllers.tooltip.setSize(this.options.tooltips.minWidth, this.options.tooltips.maxWidth);
}
}
setPopovers(options) {
if (options.on !== undefined)
options.on = MapSVG.parseBoolean(options.on);
$$A.extend(this.options.popovers, options);
if (!this.containers.popover) {
this.containers.popover = $$A("").addClass("mapsvg-popover")[0];
this.layers.popovers.append(this.containers.popover);
}
$$A(this.containers.popover).css({
width: this.options.popovers.width + (this.options.popovers.width == "auto" ? "" : "px"),
"max-width": this.options.popovers.maxWidth + "%",
"max-height": (this.options.popovers.maxHeight * $$A(this.containers.wrap).outerHeight()) / 100 +
"px",
});
if (this.options.popovers.mobileFullscreen && MapSVG.isPhone) {
$$A("body").toggleClass("mapsvg-fullscreen-popovers", true);
$$A(this.containers.popover).appendTo("body");
}
}
setRegionPrefix(prefix) {
this.options.regionPrefix = prefix;
}
setInitialViewBox(v) {
if (typeof v == "string")
v = v
.trim()
.split(" ")
.map(function (v) {
return parseFloat(v);
});
this._viewBox.update(new ViewBox(v));
if (this.options.googleMaps.on) {
this.options.googleMaps.center = this.googleMaps.map.getCenter().toJSON();
this.options.googleMaps.zoom = this.googleMaps.map.getZoom();
}
this.zoomLevel = 0;
this.setZoomLevels();
}
setViewBoxOnStart() {
this.viewBoxFull = this.svgDefault.viewBox;
this.viewBoxFake = this.viewBox;
this.whRatioFull = this.viewBoxFull.width / this.viewBox.width;
this.containers.svg.setAttribute("viewBox", this.viewBoxFull.toString());
if ((MapSVG.device.ios || MapSVG.device.android) && this.svgDefault.viewBox.width > 1500) {
this.iosDownscaleFactor = this.svgDefault.viewBox.width > 9999 ? 100 : 10;
this.containers.svg.style.width =
(this.svgDefault.viewBox.width / this.iosDownscaleFactor).toString() + "px";
}
else {
this.containers.svg.style.width = this.svgDefault.viewBox.width + "px";
}
this.vbStart = true;
}
setViewBox(viewBox, adjustGoogleMap = true) {
let initial = false;
if (typeof viewBox === "undefined" || (viewBox.width === 0 && viewBox.height === 0)) {
viewBox = this.svgDefault.viewBox;
initial = true;
}
const isZooming = viewBox.width != this.viewBox.width || viewBox.height != this.viewBox.height;
this.viewBox.update(viewBox);
this.whRatio = this.viewBox.width / this.viewBox.height;
!this.vbStart && this.setViewBoxOnStart();
if (initial) {
if (this._viewBox.width === 0 && this._viewBox.height === 0) {
this._viewBox.update(this.viewBox);
}
this._scale = 1;
}
this.scale = this.getScale();
this.superScale = (this.whRatioFull * this.svgDefault.viewBox.width) / this.viewBox.width;
const w = this.svgDefault.viewBox.width / this.containers.map.clientWidth;
this.superScale = this.superScale / w;
if ((MapSVG.device.ios || MapSVG.device.android) && this.svgDefault.viewBox.width > 1500) {
this.superScale *= this.iosDownscaleFactor;
}
this.scroll.tx = Math.round((this.svgDefault.viewBox.x - this.viewBox.x) * this.scale);
this.scroll.ty = Math.round((this.svgDefault.viewBox.y - this.viewBox.y) * this.scale);
if (this.googleMaps.map && adjustGoogleMap !== false) {
const googlePrevZoom = this.googleMaps.map.getZoom();
this.googleMaps.map.setCenter(this.getCenterGeoPoint());
this.googleMaps.map.setZoom(this.getZoomForGoogle());
}
else {
this.containers.scrollpane.style.transform =
"translate(" + this.scroll.tx + "px," + this.scroll.ty + "px)";
this.containers.svg.style.transform = "scale(" + this.superScale + ")";
this.syncZoomLevelWithGoogle();
}
this.movingItemsAdjustScreenPosition();
if (isZooming) {
this.adjustStrokes();
this.toggleSvgLayerOnZoom();
if (this.options.clustering.on) {
this.throttle(this.clusterizeOnZoom, 400, this);
}
else {
this.events.trigger("zoom");
}
}
return true;
}
syncZoomLevelWithGoogle() {
if (this.googleMaps.map &&
this.googleMaps.map.getZoom() !== this.getZoomForGoogle() &&
typeof this.zoomDelta !== "undefined") {
this.zoomLevel = this.googleMaps.map.getZoom() - this.zoomDelta;
}
}
getCenterGeoPoint() {
return this.converter.convertSVGToGeo(this.getCenterSvgPoint());
}
getCenterSvgPoint() {
return new SVGPoint(this.viewBox.x + this.viewBox.width / 2, this.viewBox.y + this.viewBox.height / 2);
}
getZoomForGoogle() {
if (typeof this.zoomLevel === "string") {
this.zoomLevel = parseInt(this.zoomLevel);
}
return this.zoomLevel + this.zoomDelta;
}
getZoomRange() {
const range = { min: 0, max: 0 };
if (this.options.googleMaps.on) {
range.min = Math.max(0, this.options.zoom.limit[0] + this.zoomDelta) - this.zoomDelta;
range.max = Math.min(22, this.options.zoom.limit[1] + this.zoomDelta) - this.zoomDelta;
}
else {
range.min = this.options.zoom.limit[0];
range.max = this.options.zoom.limit[1];
}
return range;
}
enableMovingElementsAnimation() {
$$A(this.containers.map).removeClass("no-transitions-markers no-transitions-labels no-transitions-bubbles");
}
disableMovingElementsAnimation() {
$$A(this.containers.map).addClass("no-transitions-markers no-transitions-labels no-transitions-bubbles");
}
clusterizeOnZoom() {
if (this.options.googleMaps.on && this.googleMaps.map && this.zoomDelta) {
this.zoomLevel = this.googleMaps.map.getZoom() - this.zoomDelta;
}
this.events.trigger("zoom");
this.clusterizeMarkers(true);
}
throttle(method, delay, scope, params) {
clearTimeout(method._tId);
method._tId = setTimeout(function () {
method.apply(scope, params);
}, delay);
}
setViewBoxByGoogleMapBounds() {
const googleMapBounds = this.googleMaps.map.getBounds();
if (!googleMapBounds)
return;
const googleMapBoundsJSON = googleMapBounds.toJSON();
if (googleMapBoundsJSON.west == -180 && googleMapBoundsJSON.east == 180) {
const center = this.googleMaps.map.getCenter().toJSON();
}
const ne = new GeoPoint(googleMapBounds.getNorthEast().lat(), googleMapBounds.getNorthEast().lng());
const sw = new GeoPoint(googleMapBounds.getSouthWest().lat(), googleMapBounds.getSouthWest().lng());
const xyNE = this.converter.convertGeoToSVG(ne);
const xySW = this.converter.convertGeoToSVG(sw);
if (xyNE.x < xySW.y) {
const mapPointsWidth = (this.svgDefault.viewBox.width / this.converter.mapLonDelta) * 360;
xySW.x = -(mapPointsWidth - xySW.y);
}
const width = xyNE.x - xySW.x;
const height = xySW.y - xyNE.y;
const viewBox = new ViewBox(xySW.x, xyNE.y, width, height);
this.setViewBox(viewBox);
}
redraw() {
this.disableAnimation();
if (MapSVG.browser.ie) {
$$A(this.containers.svg).css({ height: this.svgDefault.viewBox.height });
}
if (this.options.googleMaps.on && this.googleMaps.map) {
google.maps.event.trigger(this.googleMaps.map, "resize");
}
else {
this.setViewBox(this.viewBox);
}
$$A(this.containers.popover) &&
$$A(this.containers.popover).css({
"max-height": (this.options.popovers.maxHeight * $$A(this.containers.wrap).outerHeight()) /
100 +
"px",
});
if (this.controllers && this.controllers.directory) {
this.controllers.directory.updateTopShift();
this.controllers.directory.updateScroll();
}
this.movingItemsAdjustScreenPosition();
this.adjustStrokes();
this.enableAnimation();
}
setSize(width, height, responsive) {
this.options.width = width;
this.options.height = height;
this.options.responsive =
responsive != null && responsive != undefined
? MapSVG.parseBoolean(responsive)
: this.options.responsive;
if (!this.options.width && !this.options.height) {
this.options.width = this.svgDefault.width;
this.options.height = this.svgDefault.height;
}
else if (!this.options.width && this.options.height) {
this.options.width =
(this.options.height * this.svgDefault.width) / this.svgDefault.height;
}
else if (this.options.width && !this.options.height) {
this.options.height =
(this.options.width * this.svgDefault.height) / this.svgDefault.width;
}
this.whRatio = this.options.width / this.options.height;
this.scale = this.getScale();
this.setResponsive(responsive);
if (this.options.choropleth.on && this.options.choropleth.bubbleMode) {
this.redrawBubbles();
}
this.movingItemsAdjustScreenPosition();
}
setResponsive(on) {
on = on != undefined ? MapSVG.parseBoolean(on) : this.options.responsive;
$$A(this.containers.map).css({
width: "100%",
height: "0",
"padding-bottom": (this.viewBox.height * 100) / this.viewBox.width + "%",
});
if (on) {
$$A(this.containers.wrap).css({
width: "100%",
height: "auto",
});
}
else {
$$A(this.containers.wrap).css({
width: this.options.width + "px",
height: this.options.height + "px",
});
}
$$A.extend(true, this.options, { responsive: on });
if (!this.resizeSensor) {
this.resizeSensor = new ResizeSensor(this.containers.map, () => {
this.redraw();
});
}
this.redraw();
}
setScroll(options, skipEvents) {
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
options.limit != undefined && (options.limit = MapSVG.parseBoolean(options.limit));
$$A.extend(true, this.options, { scroll: options });
!skipEvents && this.setEventHandlers();
}
setZoom(options) {
options = options || {};
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
options.fingers != undefined && (options.fingers = MapSVG.parseBoolean(options.fingers));
options.mousewheel != undefined &&
(options.mousewheel = MapSVG.parseBoolean(options.mousewheel));
options.delta = 2;
if (options.limit) {
if (typeof options.limit == "string")
options.limit = options.limit.split(";");
options.limit = [parseInt(options.limit[0]), parseInt(options.limit[1])];
}
if (!this.zoomLevels) {
this.setZoomLevels();
}
$$A.extend(true, this.options, { zoom: options });
$$A(this.containers.scrollpaneWrap).off("wheel.mapsvg");
if (this.options.zoom.mousewheel) {
if (MapSVG.browser.firefox) {
this.firefoxScroll = { insideIframe: false, scrollX: 0, scrollY: 0 };
$$A(this.containers.scrollpaneWrap)
.on("mouseenter", () => {
this.firefoxScroll.insideIframe = true;
this.firefoxScroll.scrollX = window.scrollX;
this.firefoxScroll.scrollY = window.scrollY;
})
.on("mouseleave", () => {
this.firefoxScroll.insideIframe = false;
});
$$A(document).scroll(() => {
if (this.firefoxScroll.insideIframe)
window.scrollTo(this.firefoxScroll.scrollX, this.firefoxScroll.scrollY);
});
}
$$A(this.containers.scrollpaneWrap).on("wheel.mapsvg", (event) => {
event.preventDefault();
this.mouseWheelZoom(event);
return false;
});
$$A(this.layers.markers).on("wheel.mapsvg", (event) => {
event.preventDefault();
this.mouseWheelZoom(event);
return false;
});
}
this.canZoom = true;
}
mouseWheelZoom(event) {
event.preventDefault();
const d = Math.sign(-event.originalEvent.deltaY);
const center = this.getSvgPointAtClick(event.originalEvent);
d > 0 ? this.zoomIn(center) : this.zoomOut(center);
}
setControls(options) {
options = options || {};
$$A.extend(true, this.options, { controls: options });
this.options.controls.zoom = MapSVG.parseBoolean(this.options.controls.zoom);
this.options.controls.zoomReset = MapSVG.parseBoolean(this.options.controls.zoomReset);
this.options.controls.userLocation = MapSVG.parseBoolean(this.options.controls.userLocation);
this.options.controls.previousMap = MapSVG.parseBoolean(this.options.controls.previousMap);
const loc = this.options.controls.location || "right";
if (!this.containers.controls) {
const buttons = $$A("").addClass("mapsvg-buttons");
const zoomGroup = $$A("").addClass("mapsvg-btn-group").appendTo(buttons);
const zoomIn = $$A("").addClass("mapsvg-btn-map mapsvg-in");
zoomIn.on("touchend click", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.zoomIn();
});
const zoomOut = $$A("").addClass("mapsvg-btn-map mapsvg-out");
zoomOut.on("touchend click", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.zoomOut();
});
zoomGroup.append(zoomIn).append(zoomOut);
const location = $$A("").addClass("mapsvg-btn-map mapsvg-btn-location");
location.on("touchend click", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.showUserLocation((location) => {
if (this.options.scroll.on) {
this.centerOn(location.marker);
}
});
});
const userLocationIcon = '';
location.html(userLocationIcon);
const locationGroup = $$A("").addClass("mapsvg-btn-group").appendTo(buttons);
locationGroup.append(location);
const zoomResetIcon = '';
const zoomResetButton = $$A("")
.html(zoomResetIcon)
.addClass("mapsvg-btn-map mapsvg-btn-zoom-reset");
zoomResetButton.on("touchend click", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.viewBoxReset(true);
});
const zoomResetGroup = $$A("").addClass("mapsvg-btn-group").appendTo(buttons);
zoomResetGroup.append(zoomResetButton);
const previousMapIcon = '';
const previousMapButton = $$A("")
.html(previousMapIcon)
.addClass("mapsvg-btn-map mapsvg-btn-previous-map");
previousMapButton.on("touchend click", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.loadPreviousMap();
});
const previousMapGroup = $$A("").addClass("mapsvg-btn-group").appendTo(buttons);
previousMapGroup.append(previousMapButton);
this.containers.controls = buttons[0];
this.controls = {
zoom: zoomGroup[0],
userLocation: locationGroup[0],
zoomReset: zoomResetGroup[0],
previousMap: previousMapGroup[0],
};
$$A(this.containers.map).append($$A(this.containers.controls));
}
$$A(this.controls.zoom).toggle(this.options.controls.zoom);
$$A(this.controls.userLocation).toggle(this.options.controls.userLocation);
$$A(this.controls.zoomReset).toggle(this.options.controls.zoomReset);
$$A(this.controls.previousMap).toggle(this.options.controls.previousMap && this.options.previousMapsIds.length > 0);
$$A(this.containers.controls).removeClass("left");
$$A(this.containers.controls).removeClass("right");
(loc == "right" && $$A(this.containers.controls).addClass("right")) ||
(loc == "left" && $$A(this.containers.controls).addClass("left"));
}
setZoomLevels() {
if (!this.zoomLevels) {
this.zoomLevels = new ArrayIndexed("zoomLevel");
}
else {
this.zoomLevels.clear();
}
for (let i = -20; i < 0; i++) {
const _scale = 1 / Math.pow(this.options.zoom.delta, Math.abs(i));
this.zoomLevels.push({
zoomLevel: i,
_scale: _scale,
viewBox: new ViewBox(0, 0, this._viewBox.width / _scale, this._viewBox.height / _scale),
});
}
for (let z = 0; z <= 20; z++) {
const _scale = Math.pow(this.options.zoom.delta, Math.abs(z));
this.zoomLevels.push({
zoomLevel: z,
_scale: _scale,
viewBox: new ViewBox(0, 0, this._viewBox.width / _scale, this._viewBox.height / _scale),
});
}
}
setCursor(type) {
type = type == "pointer" ? "pointer" : "default";
this.options.cursor = type;
if (type == "pointer")
$$A(this.containers.map).addClass("mapsvg-cursor-pointer");
else
$$A(this.containers.map).removeClass("mapsvg-cursor-pointer");
}
setMultiSelect(on, deselect) {
this.options.multiSelect = MapSVG.parseBoolean(on);
if (deselect !== false)
this.deselectAllRegions();
}
_new_setChoropleth(options) {
options = options || this.options.choropleth;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
if (typeof options.coloring === "undefined" ||
typeof options.coloring.palette === "undefined" ||
typeof options.coloring.palette.colors === "undefined") {
if (typeof options.sourceFieldSelect === "undefined" ||
typeof options.sourceFieldSelect.variants === "undefined") {
$$A.extend(true, this.options.choropleth, options);
}
else {
this.options.choropleth.sourceFieldSelect.variants =
options.sourceFieldSelect.variants;
}
}
else {
const paletteColorsIndexes = Object.keys(options.coloring.palette.colors);
if (paletteColorsIndexes.length > 1 ||
(paletteColorsIndexes[0] == "0" &&
Object.keys(options.coloring.palette.colors[0]).length > 1)) {
this.options.choropleth.coloring.palette.colors = options.coloring.palette.colors;
}
else {
const paletteColorIndex = Object.keys(options.coloring.palette.colors)[0];
$$A.extend(true, this.options.choropleth.coloring.palette.colors[paletteColorIndex], options.coloring.palette.colors[paletteColorIndex]);
}
}
this.updateChoroplethMinMax();
if (this.options.choropleth.on &&
this.options.choropleth.sourceFieldSelect.on &&
this.options.choropleth.sourceFieldSelect.variants) {
if (!this.containers.choroplethSourceSelect) {
const sourceSelectOptions = [];
this.options.choropleth.sourceFieldSelect.variants.forEach((variant) => {
sourceSelectOptions.push($$A('"));
});
this.containers.choroplethSourceSelect = {
container: $$A('')[0],
select: $$A('')[0],
options: sourceSelectOptions,
};
$$A(this.containers.choroplethSourceSelect.select).append(this.containers.choroplethSourceSelect.options);
$$A(this.containers.choroplethSourceSelect.container).append($$A(this.containers.choroplethSourceSelect.select));
$$A(this.containers.map).append($$A(this.containers.choroplethSourceSelect.container));
$$A(this.containers.choroplethSourceSelect.select).mselect2();
$$A(this.containers.choroplethSourceSelect.select)
.mselect2()
.on("select2:select select2:unselecting", (e) => {
if (e.cancelable) {
e.preventDefault();
}
e.stopPropagation();
this.setChoropleth({ sourceField: $$A(e.target).mselect2().val() });
});
}
else {
$$A(this.containers.choroplethSourceSelect.select).mselect2("destroy");
$$A(this.containers.choroplethSourceSelect.select).find("option").remove();
this.containers.choroplethSourceSelect.options = [];
this.options.choropleth.sourceFieldSelect.variants.forEach((variant) => {
this.containers.choroplethSourceSelect.options.push($$A('")[0]);
});
$$A(this.containers.choroplethSourceSelect.select).append(this.containers.choroplethSourceSelect.options);
$$A(this.containers.choroplethSourceSelect.select).mselect2({ width: "100%" });
}
}
if ((!this.options.choropleth.on || !this.options.choropleth.sourceFieldSelect.on) &&
this.containers.choroplethSourceSelect &&
$$A(this.containers.choroplethSourceSelect.container).is(":visible")) {
$$A(this.containers.choroplethSourceSelect.container).hide();
}
else if (this.options.choropleth.on &&
this.options.choropleth.sourceFieldSelect.on &&
this.containers.choroplethSourceSelect &&
!$$A(this.containers.choroplethSourceSelect.container).is(":visible")) {
$$A(this.containers.choroplethSourceSelect.container).show();
}
$$A(this.containers.map).find(".mapsvg-choropleth-legend").remove();
if (this.options.choropleth.on && this.options.choropleth.coloring.legend.on) {
const legend = this.options.choropleth.coloring.legend;
let coloring = "";
if (this.options.choropleth.coloring.mode === "gradient") {
coloring +=
'' +
this.options.choropleth.coloring.noData.description +
"
";
let legendGradient = "";
for (let chunkIdx = 1; chunkIdx < 5; chunkIdx++) {
legendGradient +=
'' +
((this.options.choropleth.coloring.gradient.values.maxAdjusted * chunkIdx) /
5 +
this.options.choropleth.coloring.gradient.values.min) +
"
";
}
coloring +=
'' +
legendGradient +
"
";
}
else {
coloring +=
'' +
'
' +
'
' +
this.options.choropleth.coloring.noData.description +
"
" +
"
";
coloring +=
'' +
'
' +
'
' +
this.options.choropleth.coloring.palette.outOfRange.description +
"
" +
"
";
const paletteColors = this.options.choropleth.coloring.palette.colors;
paletteColors.forEach((paletteColor, idx) => {
let paletteColorElementText = "";
if (paletteColor.description) {
paletteColorElementText = paletteColor.description;
}
else {
if (idx === 0 && !paletteColor.valueFrom && paletteColor.valueFrom !== 0) {
if (legend.layout === "vertical") {
paletteColorElementText = "Less then " + paletteColor.valueTo;
}
else {
paletteColorElementText = "< " + paletteColor.valueTo;
}
}
else if (idx === paletteColors.length - 1 && !paletteColor.valueTo) {
if (legend.layout === "vertical") {
paletteColorElementText = paletteColor.valueFrom + " or more";
}
else {
paletteColorElementText = paletteColor.valueFrom + " <";
}
}
else {
paletteColorElementText =
paletteColor.valueFrom + " ≤ " + paletteColor.valueTo;
}
}
coloring +=
'' +
'
' +
'
' +
paletteColorElementText +
"
" +
"
";
});
}
this.containers.legend = {
title: $$A('' + legend.title + "
")[0],
text: $$A('' + legend.text + "
")[0],
coloring: $$A('' +
coloring +
"
")[0],
description: $$A('' +
legend.description +
"
")[0],
container: $$A("").addClass("mapsvg-choropleth-legend mapsvg-choropleth-legend-" +
legend.layout +
" mapsvg-choropleth-legend-container-" +
legend.container)[0],
};
$$A(this.containers.legend.container)
.append(this.containers.legend.title)
.append(this.containers.legend.text)
.append(this.containers.legend.coloring)
.append(this.containers.legend.description);
$$A(this.containers.map).append(this.containers.legend.container);
this.setChoroplethLegendCSS();
this.regionsRepository.events.on("updated", () => {
this.redrawChoropleth();
});
this.objectsRepository.events.on("updated", () => {
this.redrawChoropleth();
});
}
if (this.options.choropleth.on && this.options.choropleth.coloring.mode === "gradient") {
const colors = this.options.choropleth.coloring.gradient.colors;
if (colors) {
colors.lowRGB = tinycolor(colors.low).toRgb();
colors.highRGB = tinycolor(colors.high).toRgb();
colors.diffRGB = {
r: colors.highRGB.r - colors.lowRGB.r,
g: colors.highRGB.g - colors.lowRGB.g,
b: colors.highRGB.b - colors.lowRGB.b,
a: colors.highRGB.a - colors.lowRGB.a,
};
this.containers.legend && this.setChoroplethLegendCSS();
}
}
this.redrawChoropleth();
}
redrawChoropleth() {
this.updateChoroplethMinMax();
this.redrawBubbles();
this.regionsRedrawColors();
}
updateChoroplethMinMax() {
if (this.options.choropleth.on) {
const gradient = this.options.choropleth.coloring.gradient, values = [];
gradient.values.min = 0;
gradient.values.max = null;
if (this.options.choropleth.source === "regions") {
this.regions.forEach((region) => {
const choropleth = region.data && region.data[this.options.choropleth.sourceField];
choropleth != undefined && choropleth !== "" && values.push(choropleth);
});
}
else {
this.objectsRepository.objects.forEach((object) => {
const choropleth = object[this.options.choropleth.sourceField];
choropleth != undefined && choropleth !== "" && values.push(choropleth);
});
}
if (values.length > 0) {
gradient.values.min = Math.min.apply(null, values);
gradient.values.max = Math.max.apply(null, values);
gradient.values.maxAdjusted = gradient.values.max - gradient.values.min;
}
}
}
setChoroplethLegendCSS() {
const gradient = this.options.choropleth.coloring.gradient, legend = this.options.choropleth.coloring.legend, noData = this.options.choropleth.coloring.noData, outOfRange = this.options.choropleth.coloring.palette.outOfRange;
$$A(".mapsvg-choropleth-legend").css({
width: legend.width,
height: legend.height,
});
if (this.options.choropleth.coloring.mode === "gradient") {
if (legend.layout === "horizontal") {
$$A(".mapsvg-choropleth-legend-horizontal .mapsvg-choropleth-legend-gradient-colors").css({
background: "linear-gradient(to right," +
gradient.colors.low +
" 1%," +
gradient.colors.high +
" 100%)",
});
}
else {
$$A(".mapsvg-choropleth-legend-vertical .mapsvg-choropleth-legend-gradient-colors").css({
background: "linear-gradient(to bottom," +
gradient.colors.low +
" 1%," +
gradient.colors.high +
" 100%)",
});
}
$$A(".mapsvg-choropleth-legend-gradient-no-data").css({
"background-color": noData.color,
});
}
else {
const paletteColors = this.options.choropleth.coloring.palette.colors;
paletteColors.forEach(function (paletteColor, idx) {
$$A('.mapsvg-choropleth-legend-palette-color-wrap[data-idx="' +
idx +
'"] .mapsvg-choropleth-legend-palette-color').css({
"background-color": paletteColor.color,
});
});
$$A('.mapsvg-choropleth-legend-palette-color-wrap[data-idx="no-data"] .mapsvg-choropleth-legend-palette-color').css({
"background-color": noData.color,
});
$$A('.mapsvg-choropleth-legend-palette-color-wrap[data-idx="out-of-range"] .mapsvg-choropleth-legend-palette-color').css({
"background-color": outOfRange.color,
});
}
}
setCss(css) {
this.options.css =
css || (this.options.css ? this.options.css.replace(/%id%/g, "" + this.id) : "");
this.liveCss = this.liveCss || $$A("").appendTo("head")[0];
$$A(this.liveCss).html(this.options.css);
}
setFilters(options) {
options = options || this.options.filters;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
options.hide != undefined && (options.hide = MapSVG.parseBoolean(options.hide));
$$A.extend(true, this.options, { filters: options });
if (!MapSVG.googleMapsApiLoaded &&
this.options.filters.on &&
this.filtersSchema.getField("distance")) {
this.loadGoogleMapsAPI(() => {
return 1;
}, () => {
return 1;
});
}
if (["leftSidebar", "rightSidebar", "header", "footer", "custom", "map"].indexOf(this.options.filters.location) === -1) {
this.options.filters.location = "leftSidebar";
}
if (this.options.filters.on) {
if (this.formBuilder) {
this.formBuilder.destroy();
}
if (!this.containers.filters) {
this.containers.filters = $$A('')[0];
}
else {
$$A(this.containers.filters).empty();
$$A(this.containers.filters).show();
}
$$A(this.containers.filters).css({
"background-color": this.options.colors.directorySearch,
});
if ($$A(this.containers.filtersModal)) {
$$A(this.containers.filtersModal).css({ width: this.options.filters.width });
}
if (this.options.filters.location === "custom") {
$$A(this.containers.filters)
.removeClass("mapsvg-filter-container-custom")
.addClass("mapsvg-filter-container-custom");
if ($$A("#" + this.options.filters.containerId).length) {
$$A("#" + this.options.filters.containerId).append(this.containers.filters);
}
else {
$$A(this.containers.filters).hide();
console.error("MapSVG: filter container #" +
this.options.filters.containerId +
" does not exists");
}
}
else {
if (MapSVG.isPhone) {
$$A(this.containers.header).append($$A(this.containers.filters));
this.setContainers({ header: { on: true } });
}
else {
const location = MapSVG.isPhone ? "header" : this.options.filters.location;
if (this.options.menu.on &&
this.controllers.directory &&
this.options.menu.location === this.options.filters.location) {
$$A(this.controllers.directory.containers.view)
.find(".mapsvg-directory-filter-wrap")
.append($$A(this.containers.filters));
this.controllers.directory.updateTopShift();
}
else {
$$A(this.containers[location]).append($$A(this.containers.filters));
this.controllers.directory && this.controllers.directory.updateTopShift();
}
}
}
this.loadFiltersController(this.containers.filters, false);
this.updateFiltersState();
}
else {
if ($$A(this.containers.filters)) {
$$A(this.containers.filters).empty();
$$A(this.containers.filters).hide();
}
}
if (this.options.menu.on &&
this.controllers.directory &&
this.options.menu.location === this.options.filters.location) {
this.controllers.directory.updateTopShift();
}
}
updateFiltersState() {
if (this.options.filters && this.options.filters.on && this.controllers.filters) {
this.controllers.filters.update(this.objectsRepository.query);
this.updateFilterTags();
}
}
setGlobalDistanceFilter() {
if (this.objectsRepository &&
this.objectsRepository.query.filters &&
this.objectsRepository.query.filters.distance) {
const dist = this.objectsRepository.query.filters.distance;
MapSVG.distanceSearch = this.objectsRepository.query.filters.distance;
}
else {
MapSVG.distanceSearch = null;
}
}
updateFilterTags() {
$$A(this.containers.filterTags) && $$A(this.containers.filterTags).empty();
for (const field_name in this.objectsRepository.query.filters) {
let field_value = this.objectsRepository.query.filters[field_name];
let _field_name = field_name;
const filterField = this.filtersSchema.getField(_field_name);
if (field_name == "regions") {
_field_name = "";
field_value = field_value.region_ids.map((id) => this.getRegion(id).title);
}
else {
_field_name = filterField && filterField.label;
}
if (field_name !== "distance") {
if (!this.containers.filterTags) {
this.containers.filterTags = $$A('')[0];
if ($$A(this.containers.filters)) ;
else {
if (this.options.menu.on && this.controllers.directory) {
$$A(this.controllers.directory.containers.toolbar).append(this.containers.filterTags);
this.controllers.directory.updateTopShift();
}
else {
$$A(this.containers.map).append(this.containers.filterTags);
if (this.options.zoom.buttons.on) {
if (this.options.layersControl.on) {
if (this.options.layersControl.position == "top-left") {
$$A(this.containers.filterTags).css({
right: 0,
bottom: 0,
});
}
else {
$$A(this.containers.filterTags).css({
bottom: 0,
});
}
}
else {
if (this.options.zoom.buttons.location == "left") {
$$A(this.containers.filterTags).css({
right: 0,
});
}
}
}
}
}
$$A(this.containers.filterTags).on("click", ".mapsvg-filter-delete", (e) => {
const filterField = $$A(e.target).data("filter");
$$A(e.target).parent().remove();
this.objectsRepository.query.removeFilter(filterField);
this.deselectAllRegions();
this.loadDataObjects();
});
}
$$A(this.containers.filterTags).append('' +
(_field_name ? _field_name + ": " : "") +
field_value +
' ×
');
}
}
}
setContainers(options) {
const _this = this;
if (!this.containersCreated) {
this.containers.wrapAll = document.createElement("div");
this.containers.wrapAll.classList.add("mapsvg-wrap-all");
this.containers.wrapAll.id = "mapsvg-map-" + this.id;
this.containers.wrapAll.setAttribute("data-map-id", this.id ? this.id.toString() : "");
this.containers.wrap = document.createElement("div");
this.containers.wrap.classList.add("mapsvg-wrap");
this.containers.mapContainer = document.createElement("div");
this.containers.mapContainer.classList.add("mapsvg-map-container");
this.containers.leftSidebar = document.createElement("div");
this.containers.leftSidebar.className =
"mapsvg-sidebar mapsvg-top-container mapsvg-sidebar-left";
this.containers.rightSidebar = document.createElement("div");
this.containers.rightSidebar.className =
"mapsvg-sidebar mapsvg-top-container mapsvg-sidebar-right";
this.containers.header = document.createElement("div");
this.containers.header.className = "mapsvg-header mapsvg-top-container";
this.containers.footer = document.createElement("div");
this.containers.footer.className = "mapsvg-footer mapsvg-top-container";
_this.containers.wrapAll = $$A('')
.attr("id", "mapsvg-map-" + this.id)
.attr("data-map-id", this.id)[0];
_this.containers.wrap = $$A('')[0];
_this.containers.mapContainer = $$A('')[0];
_this.containers.leftSidebar = $$A('')[0];
_this.containers.rightSidebar = $$A('')[0];
_this.containers.header = $$A('')[0];
_this.containers.footer = $$A('')[0];
$$A(_this.containers.wrapAll).insertBefore(_this.containers.map);
$$A(_this.containers.wrapAll).append(_this.containers.header);
$$A(_this.containers.wrapAll).append(_this.containers.wrap);
$$A(_this.containers.wrapAll).append(_this.containers.footer);
$$A(_this.containers.mapContainer).append(_this.containers.map);
$$A(_this.containers.wrap).append(_this.containers.leftSidebar);
$$A(_this.containers.wrap).append(_this.containers.mapContainer);
$$A(_this.containers.wrap).append(_this.containers.rightSidebar);
_this.containersCreated = true;
}
options = options || _this.options.containers || {};
for (const contName in options) {
if (options[contName].on !== undefined) {
options[contName].on = MapSVG.parseBoolean(options[contName].on);
}
if (options[contName].width) {
if (typeof options[contName].width != "string" ||
(options[contName].width.indexOf("px") === -1 &&
options[contName].width.indexOf("%") === -1 &&
options[contName].width !== "auto")) {
options[contName].width = options[contName].width + "px";
}
$$A(_this.containers[contName]).css({ "flex-basis": options[contName].width });
}
if (options[contName].height) {
if (typeof options[contName].height != "string" ||
(options[contName].height.indexOf("px") === -1 &&
options[contName].height.indexOf("%") === -1 &&
options[contName].height !== "auto")) {
options[contName].height = options[contName].height + "px";
}
$$A(_this.containers[contName]).css({
"flex-basis": options[contName].height,
height: options[contName].height,
});
}
$$A.extend(true, _this.options, { containers: options });
let on = _this.options.containers[contName].on;
if (MapSVG.isPhone &&
_this.options.menu.hideOnMobile &&
_this.options.menu.location === contName &&
["leftSidebar", "rightSidebar"].indexOf(contName) !== -1) {
on = false;
}
else if (MapSVG.isPhone &&
_this.options.menu.location === "custom" &&
["leftSidebar", "rightSidebar"].indexOf(contName) !== -1) {
on = false;
$$A(_this.containers.wrapAll).addClass("mapsvg-hide-map-list-buttons");
}
else if (MapSVG.isPhone &&
!_this.options.menu.hideOnMobile &&
_this.options.menu.location === contName &&
["leftSidebar", "rightSidebar"].indexOf(contName) !== -1) {
$$A(_this.containers.wrapAll).addClass("mapsvg-hide-map-list-buttons");
$$A(_this.containers.wrapAll).addClass("mapsvg-directory-visible");
}
$$A(_this.containers[contName]).toggle(on);
}
_this.setDetailsView();
}
shouldBeScrollable(container) {
const _this = this;
switch (container) {
case "map":
case "leftSidebar":
case "rightSidebar":
return true;
case "custom":
return false;
case "header":
case "footer":
if (_this.options.containers[container].height &&
_this.options.containers[container].height !== "auto" &&
_this.options.containers[container].height !== "100%") {
return true;
}
else {
return false;
}
default:
return false;
}
}
setDirectory(options) {
return this.setMenu(options);
}
setMenu(options) {
options = options || this.options.menu;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
options.search != undefined && (options.search = MapSVG.parseBoolean(options.search));
options.showMapOnClick != undefined &&
(options.showMapOnClick = MapSVG.parseBoolean(options.showMapOnClick));
options.searchFallback != undefined &&
(options.searchFallback = MapSVG.parseBoolean(options.searchFallback));
options.customContainer != undefined &&
(options.customContainer = MapSVG.parseBoolean(options.customContainer));
$$A.extend(true, this.options, { menu: options });
this.controllers = this.controllers || {};
if (!this.containers.directory) {
this.containers.directory = $$A('')[0];
}
$$A(this.containers.directory).toggleClass("flex", this.shouldBeScrollable(this.options.menu.location));
if (this.options.menu.on) {
if (!this.controllers.directory) {
this.controllers.directory = new DirectoryController({
container: this.containers.directory,
template: this.options.templates.directory,
mapsvg: this,
repository: this.options.menu.source === "regions"
? this.regionsRepository
: this.objectsRepository,
scrollable: this.shouldBeScrollable(this.options.menu.location),
events: {
click: (e, regionOrObject, mapsvg) => {
this.events.trigger("click.directoryItem", this, [
e,
regionOrObject,
mapsvg,
]);
},
mouseover: (e, regionOrObject, mapsvg) => {
this.events.trigger("mouseover.directoryItem", this, [
e,
regionOrObject,
mapsvg,
]);
},
mouseout: (e, regionOrObject, mapsvg) => {
this.events.trigger("mouseout.directoryItem", this, [
e,
regionOrObject,
mapsvg,
]);
},
},
});
this.controllers.directory._init();
}
if (options.source) {
this.controllers.directory.repository =
this.options.menu.source === "regions"
? this.regionsRepository
: this.objectsRepository;
}
if (options.sortBy || options.sortDirection) {
this.controllers.directory.repository.query.update({
sort: [
{
field: this.options.menu.sortBy,
order: this.options.menu.sortDirection,
},
],
});
}
this.setFilterOut();
if (options.location) {
this.controllers.directory.scrollable = this.shouldBeScrollable(this.options.menu.location);
}
let $container;
if (MapSVG.isPhone && this.options.menu.hideOnMobile) {
$container = $$A(this.containers.leftSidebar);
}
else {
$container =
this.options.menu.location !== "custom"
? $$A(this.containers[this.options.menu.location])
: $$A("#" + this.options.menu.containerId);
}
$container.append(this.containers.directory);
if (this.options.colors.directory) {
$$A(this.containers.directory).css({
"background-color": this.options.colors.directory,
});
}
this.setFilters();
this.setTemplates({ directoryItem: this.options.templates.directoryItem });
if ((this.options.menu.source === "regions" && this.regionsRepository.loaded) ||
(this.options.menu.source === "database" && this.objectsRepository.loaded)) {
if (this.editMode &&
(options.sortBy || options.sortDirection || options.filterout)) {
this.controllers.directory.repository.reload();
}
this.loadDirectory();
}
}
else {
this.controllers.directory && this.controllers.directory.destroy();
this.controllers.directory = null;
}
}
setDatabase(options) {
options = options || this.options.database;
if (options.pagination) {
if (options.pagination.on != undefined) {
options.pagination.on = MapSVG.parseBoolean(options.pagination.on);
}
if (options.pagination.perpage != undefined) {
options.pagination.perpage = parseInt(options.pagination.perpage);
}
}
$$A.extend(true, this.options, { database: options });
if (options.pagination) {
if (options.pagination.on !== undefined || options.pagination.perpage) {
const query = new Query({
perpage: this.options.database.pagination.on
? this.options.database.pagination.perpage
: 0,
});
this.objectsRepository.find(query);
}
else {
this.setPagination();
}
}
}
updateGoogleMapsMaxZoom(geoPoint) {
this.googleMaps.maxZoomService.getMaxZoomAtLatLng(geoPoint, (result) => {
if (result.status === "OK") {
this.googleMaps.currentMaxZoom = result.zoom;
}
});
}
setGoogleMaps(options) {
options = options || this.options.googleMaps;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
if (!this.googleMaps) {
this.googleMaps = { loaded: false, initialized: false, map: null, overlay: null };
}
$$A.extend(true, this.options, { googleMaps: options });
if (this.options.googleMaps.on) {
$$A(this.containers.map).toggleClass("mapsvg-with-google-map", true);
if (!MapSVG.googleMapsApiLoaded) {
this.loadGoogleMapsAPI(() => {
this.setGoogleMaps();
}, () => {
this.setGoogleMaps({ on: false });
});
}
else {
if (!this.googleMaps.map) {
this.containers.googleMaps = $$A('').prependTo(this.containers.map)[0];
$$A(this.containers.googleMaps).css({
position: "absolute",
top: 0,
left: 0,
bottom: 0,
right: 0,
"z-index": "0",
});
this.googleMaps.map = new google.maps.Map(this.containers.googleMaps, {
mapTypeId: options.type,
fullscreenControl: false,
keyboardShortcuts: false,
mapTypeControl: false,
scaleControl: false,
scrollwheel: false,
streetViewControl: false,
zoomControl: false,
styles: options.styleJSON,
tilt: 0,
});
const southWest = new google.maps.LatLng(this.geoViewBox.sw.lat, this.geoViewBox.sw.lng);
const northEast = new google.maps.LatLng(this.geoViewBox.ne.lat, this.geoViewBox.ne.lng);
const bounds = new google.maps.LatLngBounds(southWest, northEast);
this.googleMaps.overlay = this.createGoogleMapOverlay(bounds, this.googleMaps.map);
if (!this.options.googleMaps.center || !this.options.googleMaps.zoom) {
this.googleMaps.map.fitBounds(bounds, 0);
}
else {
this.googleMaps.map.setZoom(this.options.googleMaps.zoom);
this.googleMaps.map.setCenter(this.options.googleMaps.center);
}
this.googleMaps.initialized = true;
this.googleMaps.maxZoomService = new google.maps.MaxZoomService();
this.googleMaps.map.addListener("idle", () => {
this.isZooming = false;
});
google.maps.event.addListenerOnce(this.googleMaps.map, "idle", () => {
setTimeout(() => {
$$A(this.containers.map).addClass("mapsvg-fade-in");
setTimeout(() => {
$$A(this.containers.map).removeClass("mapsvg-google-map-loading");
$$A(this.containers.map).removeClass("mapsvg-fade-in");
if (!this.options.googleMaps.center ||
!this.options.googleMaps.zoom) {
this.options.googleMaps.center = this.googleMaps.map
.getCenter()
.toJSON();
this.options.googleMaps.zoom = this.googleMaps.map.getZoom();
}
this.zoomDelta = this.options.googleMaps.zoom - this.zoomLevel;
this.updateGoogleMapsMaxZoom(this.options.googleMaps.center);
this.setInitialViewBox(this.viewBox);
this.toggleSvgLayerOnZoom();
this.events.trigger("googleMapsLoaded");
this.afterLoadBlockers--;
this.finalizeMapLoading();
}, 300);
}, 1);
});
this.events.on("googleMapsBoundsChanged", (bounds) => {
this.setViewBoxByGoogleMapsOverlay();
});
}
else {
$$A(this.containers.map).toggleClass("mapsvg-with-google-map", true);
$$A(this.containers.googleMaps) && $$A(this.containers.googleMaps).show();
if (options.type) {
this.googleMaps.map.setMapTypeId(options.type);
}
this.setViewBoxByGoogleMapsOverlay();
}
}
}
else {
$$A(this.containers.map).toggleClass("mapsvg-with-google-map", false);
$$A(this.containers.googleMaps) && $$A(this.containers.googleMaps).hide();
this.googleMaps.initialized = false;
}
if (this.converter) {
this.converter.setWorldShift(this.options.googleMaps.on);
}
}
createGoogleMapOverlay(bounds, map) {
class GoogleMapsOverlay extends google.maps.OverlayView {
constructor(bounds, googleMapInstance, mapsvg) {
super();
this.bounds_ = bounds;
this.map_ = googleMapInstance;
this.mapsvg = mapsvg;
this.setMap(googleMapInstance);
this.prevCoords = {
sw: { x: 0, y: 0 },
sw2: { x: 0, y: 0 },
ne: { x: 0, y: 0 },
ne2: { x: 0, y: 0 },
};
}
draw() {
this.mapsvg.events.trigger("googleMapsBoundsChanged", this.map_, [
this.getPixelBounds(),
this.map_,
]);
}
onAdd() {
this.element = document.createElement("div");
this.element.style.borderStyle = "none";
this.element.style.borderWidth = "0px";
this.element.style.position = "absolute";
const panes = this.getPanes();
panes.overlayLayer.appendChild(this.element);
}
getPixelBounds() {
const overlayProjection = this.getProjection();
if (!overlayProjection)
return;
const geoSW = this.bounds_.getSouthWest();
const geoNE = this.bounds_.getNorthEast();
const coords = {
sw: overlayProjection.fromLatLngToDivPixel(geoSW),
ne: overlayProjection.fromLatLngToDivPixel(geoNE),
sw2: overlayProjection.fromLatLngToContainerPixel(geoSW),
ne2: overlayProjection.fromLatLngToContainerPixel(geoNE),
};
const ww = overlayProjection.getWorldWidth();
if (this.prevCoords.sw) {
if (coords.ne.x < coords.sw.x) {
if (Math.abs(this.prevCoords.sw.x - coords.sw.x) >
Math.abs(this.prevCoords.ne.x - coords.ne.x)) {
coords.sw.x = coords.sw.x - ww;
}
else {
coords.ne.x = coords.ne.x + ww;
}
if (Math.abs(this.prevCoords.sw2.x - coords.sw2.x) >
Math.abs(this.prevCoords.ne2.x - coords.ne2.x)) {
coords.sw2.x = coords.sw2.x - ww;
}
else {
coords.ne2.x = coords.ne2.x + ww;
}
}
}
this.prevCoords = coords;
return { sw: coords.sw2, ne: coords.ne2 };
}
}
return new GoogleMapsOverlay(bounds, map, this);
}
loadGoogleMapsAPI(callback, fail) {
if (!this.options.googleMaps.apiKey) {
console.error("MapSVG: can't load Google API because no API key has been provided");
return;
}
if (window.google !== undefined && google.maps) {
MapSVG.googleMapsApiLoaded = true;
}
if (MapSVG.googleMapsApiLoaded) {
if (typeof callback == "function") {
callback();
}
return;
}
MapSVG.googleMapsLoadCallbacks = MapSVG.googleMapsLoadCallbacks || [];
if (typeof callback == "function") {
MapSVG.googleMapsLoadCallbacks.push(callback);
}
if (MapSVG.googleMapsApiIsLoading) {
return;
}
MapSVG.googleMapsApiIsLoading = true;
window.gm_authFailure = () => {
if (MapSVG.GoogleMapBadApiKey) {
MapSVG.GoogleMapBadApiKey();
}
else {
if (this.editMode) {
alert("Google maps API key is incorrect.");
}
else {
console.error("MapSVG: Google maps API key is incorrect.");
}
}
};
this.googleMapsScript = document.createElement("script");
this.googleMapsScript.onload = () => {
MapSVG.googleMapsApiLoaded = true;
MapSVG.googleMapsLoadCallbacks.forEach((_callback) => {
if (typeof callback == "function")
_callback();
});
};
const gmLibraries = [];
if (this.options.googleMaps.drawingTools) {
gmLibraries.push("drawing");
}
if (this.options.googleMaps.geometry) {
gmLibraries.push("geometry");
}
let libraries = "";
if (gmLibraries.length > 0) {
libraries = "&libraries=" + gmLibraries.join(",");
}
this.googleMapsScript.src =
"https://maps.googleapis.com/maps/api/js?language=" +
this.options.googleMaps.language +
"&key=" +
this.options.googleMaps.apiKey +
libraries;
document.head.appendChild(this.googleMapsScript);
}
loadDetailsView(obj) {
this.controllers.popover && this.controllers.popover.close();
if (this.controllers.detailsView)
this.controllers.detailsView.destroy();
this.controllers.detailsView = new DetailsController({
autoresize: MapSVG.isPhone &&
this.options.detailsView.mobileFullscreen &&
this.options.detailsView.location !== "custom"
? false
: this.options.detailsView.autoresize,
container: this.containers.detailsView,
template: obj instanceof Region
? this.options.templates.detailsViewRegion
: this.options.templates.detailsView,
mapsvg: this,
data: obj.getData(),
modal: MapSVG.isPhone &&
this.options.detailsView.mobileFullscreen &&
this.options.detailsView.location !== "custom",
scrollable: (MapSVG.isPhone &&
this.options.detailsView.mobileFullscreen &&
this.options.detailsView.location !== "custom") ||
this.shouldBeScrollable(this.options.detailsView.location),
withToolbar: !(MapSVG.isPhone &&
this.options.detailsView.mobileFullscreen &&
this.options.detailsView.location !== "custom") && this.shouldBeScrollable(this.options.detailsView.location),
events: {
shown: (detailsController) => {
this.events.trigger("shown.detailsView", this, [this, detailsController]);
$$A(window).trigger("shown.detailsView", [this, detailsController]);
},
closed: (detailsController) => {
this.deselectAllRegions();
this.deselectAllMarkers();
this.controllers &&
this.controllers.directory &&
this.controllers.directory.deselectItems();
this.events.trigger("closed.detailsView", [this, detailsController]);
},
},
});
this.controllers.detailsView._init();
}
loadFiltersModal() {
if (this.options.filters.modalLocation != "custom") {
if (!this.containers.filtersModal) {
this.containers.filtersModal = $$A('')[0];
}
this.setColors();
$$A(this.containers.filtersModal).css({ width: this.options.filters.width });
if (MapSVG.isPhone) {
$$A("body").append($$A(this.containers.filtersModal));
$$A(this.containers.filtersModal).css({ width: "" });
}
else {
$$A(this.containers[this.options.filters.modalLocation]).append($$A(this.containers.filtersModal));
}
}
else {
this.containers.filtersModal = $$A("#" + this.options.filters.containerId)[0];
$$A(this.containers.filtersModal).css({ width: "" });
}
this.loadFiltersController(this.containers.filtersModal, true);
}
loadFiltersController(container, modal = false) {
if (!this.filtersShouldBeShown()) {
return;
}
let filtersInDirectory, filtersHide;
if (MapSVG.isPhone) {
filtersInDirectory = true;
filtersHide = this.options.filters.hideOnMobile;
}
else {
filtersInDirectory =
this.options.menu.on &&
this.controllers.directory &&
this.options.menu.location === this.options.filters.location;
filtersHide = this.options.filters.hide;
}
const scrollable = modal ||
(!filtersInDirectory &&
["leftSidebar", "rightSidebar"].indexOf(this.options.filters.location) !== -1);
this.filtersRepository =
this.options.filters.source === "regions"
? this.regionsRepository
: this.objectsRepository;
if (this.options.filters.searchButton) {
this.changedFields = null;
this.changedSearch = null;
}
else {
this.changedSearch = () => {
this.filtersRepository.query.searchFallback = this.filtersSchema.getFieldByType("search").searchFallback;
this.throttle(this.filtersRepository.reload, 400, this.filtersRepository);
};
this.changedFields = () => {
this.throttle(this.filtersRepository.reload, 400, this.filtersRepository);
};
}
this.controllers.filters = new FiltersController({
container: container,
query: this.filtersRepository.query,
mapsvg: this,
schema: this.filtersSchema,
template: '',
scrollable: scrollable,
modal: modal,
withToolbar: MapSVG.isPhone ? false : modal,
width: $$A(container).hasClass("mapsvg-map-container")
? this.options.filters.width
: "100%",
hide: this.options.filters.hide,
hideOnMobile: this.options.filters.hideOnMobile,
showButtonText: this.options.filters.showButtonText,
clearButton: this.options.filters.clearButton,
clearButtonText: this.options.filters.clearButtonText,
searchButton: this.options.filters.searchButton,
searchButtonText: this.options.filters.searchButtonText,
padding: this.options.filters.padding,
events: {
cleared: () => {
this.deselectAllRegions();
this.filtersRepository.reload();
},
"changed.fields": this.changedFields,
"changed.search": this.changedSearch,
"click.btn.searchButton": () => {
this.filtersRepository.reload();
},
loaded: () => {
this.controllers.directory && this.controllers.directory.updateTopShift();
this.afterLoadBlockers--;
this.finalizeMapLoading();
},
"click.btn.showFilters": () => {
this.loadFiltersModal();
},
},
});
this.controllers.filters._init();
}
filtersShouldBeShown() {
return (this.options.filters.on &&
this.options.filtersSchema &&
this.options.filtersSchema.length > 0);
}
textSearch(text, fallback = false) {
const query = new Query({
filters: { search: text },
searchFallback: fallback,
});
this.filtersRepository.find(query);
}
getRegion(id) {
return this.regions.findById(id);
}
getRegions() {
return this.regions;
}
getMarker(id) {
return this.markers.findById(id);
}
checkId(id) {
if (this.getRegion(id))
return { canUse: false, error: "This ID is already being used by a Region" };
else if (this.getMarker(id))
return { canUse: false, error: "This ID is already being used by another Marker" };
else
return { canUse: true, error: "" };
}
regionsRedrawColors() {
this.regions.forEach((region) => {
region.setFill();
});
}
redrawBubbles() {
$$A(this.containers.map).removeClass("bubbles-regions-on bubbles-database-on");
if (this.options.choropleth.on && this.options.choropleth.bubbleMode) {
$$A(this.containers.map).addClass("bubbles-" + this.options.choropleth.source + "-on");
}
this.regions.forEach(function (region) {
region.drawBubble();
});
const markersBubbleMode = this.options.choropleth.on &&
this.options.choropleth.source == "database" &&
this.options.choropleth.bubbleMode;
this.markers.forEach(function (marker) {
marker.setBubbleMode(markersBubbleMode);
});
}
destroy() {
if (this.controllers && this.controllers.directory) {
this.controllers.directory.mobileButtons.remove();
}
$$A(this.containers.map)
.empty()
.insertBefore($$A(this.containers.wrapAll))
.attr("style", "")
.removeClass("mapsvg mapsvg-responsive");
this.controllers.popover && this.controllers.popover.close();
if (this.controllers.detailsView)
this.controllers.detailsView.destroy();
$$A(this.containers.detailsView).remove();
$$A(this.containers.popover).remove();
$$A(this.containers.tooltip).remove();
$$A(this.containers.wrapAll).remove();
}
getData() {
return {
id: this.id,
title: this.options.title,
options: this.getOptions(false, false),
};
}
mayBeFitMarkers() {
if (!this.lastTimeFitWas) {
this.lastTimeFitWas = Date.now() - 99999;
}
this.fitDelta = Date.now() - this.lastTimeFitWas;
if (this.fitDelta > 1000 &&
!this.firstDataLoad &&
!this.fitOnDataLoadDone &&
this.options.fitMarkers) {
this.fitMarkers();
this.fitOnDataLoadDone = true;
}
if (this.firstDataLoad &&
(this.options.fitMarkersOnStart ||
(this.options.fitMarkers && this.options.database.loadOnStart === false))) {
this.firstDataLoad = false;
if (this.options.googleMaps.on && !this.googleMaps.map) {
this.events.on("googleMapsLoaded", () => {
this.fitMarkers();
});
}
else {
this.fitMarkers();
}
}
this.lastTimeFitWas = Date.now();
}
fitMarkers() {
const dbObjects = this.objectsRepository.getLoaded();
if (!dbObjects || dbObjects.length === 0) {
return;
}
if (this.options.googleMaps.on && typeof google !== "undefined") {
const lats = [];
const lngs = [];
if (dbObjects.length > 1) {
dbObjects.forEach((object) => {
if (object.location && object.location.geoPoint) {
lats.push(object.location.geoPoint.lat);
lngs.push(object.location.geoPoint.lng);
}
});
const minlat = Math.min.apply(null, lats), maxlat = Math.max.apply(null, lats);
const minlng = Math.min.apply(null, lngs), maxlng = Math.max.apply(null, lngs);
const bbox = new google.maps.LatLngBounds({ lat: minlat, lng: minlng }, { lat: maxlat, lng: maxlng });
this.googleMaps.map.fitBounds(bbox, 0);
}
else {
if (dbObjects[0].location &&
dbObjects[0].location.geoPoint.lat &&
dbObjects[0].location.geoPoint.lng) {
const coords = {
lat: dbObjects[0].location.geoPoint.lat,
lng: dbObjects[0].location.geoPoint.lng,
};
if (this.googleMaps.map) {
this.googleMaps.map.setCenter(coords);
this.googleMaps.map.setZoom(this.options.fitSingleMarkerZoom);
}
}
}
}
else {
if (this.options.clustering.on) {
const arr = [];
this.markersClusters.forEach((c) => {
arr.push(c);
});
this.markers.forEach((m) => {
arr.push(m);
});
this.zoomTo(arr);
return;
}
else {
this.zoomTo(this.markers);
return;
}
}
}
setFitSingleMarkerZoom(zoom) {
this.options.fitSingleMarkerZoom = parseInt(zoom);
}
showUserLocation(callback) {
this.getUserLocation((geoPoint) => {
this.userLocation = null;
this.userLocation = new Location({
geoPoint: geoPoint,
img: MapSVG.urls.root + "/markers/user-location.svg",
});
this.userLocationMarker && this.userLocationMarker.delete();
this.userLocationMarker = new Marker({
location: this.userLocation,
mapsvg: this,
width: 15,
height: 15,
});
$$A(this.userLocationMarker.element).addClass("mapsvg-user-location");
this.userLocationMarker.centered = true;
this.getLayer("markers").append(this.userLocationMarker.element);
this.userLocationMarker.adjustScreenPosition();
callback && callback(this.userLocation);
});
}
getUserLocation(callback) {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function (position) {
const pos = new GeoPoint(position.coords.latitude, position.coords.longitude);
callback && callback(pos);
});
}
else {
return false;
}
}
getScale() {
const scale2 = this.containers.map.clientWidth / this.viewBox.width;
return scale2 || 1;
}
getViewBox() {
return this.viewBox;
}
viewBoxSetBySize(width, height) {
this.setSize(width, height);
this._viewBox.update(this.viewBoxGetBySize(width, height));
this.setViewBox(this._viewBox);
$$A(window).trigger("resize");
this.setSize(width, height);
this.setZoomLevels();
return this.viewBox;
}
viewBoxGetBySize(width, height) {
const new_ratio = width / height;
const old_ratio = this.svgDefault.viewBox.width / this.svgDefault.viewBox.height;
const vb = this.svgDefault.viewBox.clone();
if (new_ratio != old_ratio) {
if (new_ratio > old_ratio) {
vb.width = this.svgDefault.viewBox.height * new_ratio;
vb.x = this.svgDefault.viewBox.x - (vb.width - this.svgDefault.viewBox.width) / 2;
}
else {
vb.height = this.svgDefault.viewBox.width / new_ratio;
vb.y = this.svgDefault.viewBox.y - (vb.height - this.svgDefault.viewBox.height) / 2;
}
}
return vb;
}
viewBoxReset(toInitial) {
if (this.options.googleMaps.on && this.googleMaps.map) {
if (!toInitial) {
this.options.googleMaps.center = null;
this.options.googleMaps.zoom = null;
}
if (!this.options.googleMaps.center || !this.options.googleMaps.zoom) {
const southWest = new google.maps.LatLng(this.geoViewBox.sw.lat, this.geoViewBox.sw.lng);
const northEast = new google.maps.LatLng(this.geoViewBox.ne.lat, this.geoViewBox.ne.lng);
const bounds = new google.maps.LatLngBounds(southWest, northEast);
this.googleMaps.map.fitBounds(bounds, 0);
this.options.googleMaps.center = this.googleMaps.map.getCenter().toJSON();
this.options.googleMaps.zoom = this.googleMaps.map.getZoom();
}
else {
this.googleMaps.map.setZoom(this.options.googleMaps.zoom);
this.googleMaps.map.setCenter(this.options.googleMaps.center);
}
}
else {
if (toInitial) {
const v = this._viewBox || this.svgDefault.viewBox;
this.zoomLevel = 0;
this._scale = 1;
this.setViewBox(v);
}
else {
this.setViewBox();
}
}
return this.viewBox;
}
getGeoViewBox() {
const v = this.viewBox;
const p1 = new SVGPoint(v.x, v.y);
const p2 = new SVGPoint(v.x + v.width, v.y);
const p3 = new SVGPoint(v.x, v.y);
const p4 = new SVGPoint(v.x, v.y + v.height);
const leftLon = this.converter.convertSVGToGeo(p1).lng;
const rightLon = this.converter.convertSVGToGeo(p2).lng;
const topLat = this.converter.convertSVGToGeo(p3).lat;
const bottomLat = this.converter.convertSVGToGeo(p4).lat;
return [leftLon, topLat, rightLon, bottomLat];
}
setStrokes() {
$$A(this.containers.svg)
.find("path, polygon, circle, ellipse, rect, line, polyline")
.each((index, elem) => {
const width = MapObject.getComputedStyle("stroke-width", elem);
if (width) {
$$A(elem).attr("data-stroke-width", width.replace("px", ""));
}
});
}
adjustStrokes() {
$$A(this.containers.svg)
.find("path, polygon, circle, ellipse, rect, line, polyline")
.each((index, elem) => {
const width = elem.getAttribute("data-stroke-width");
if (width) {
$$A(elem).css("stroke-width", Number(width) / this.scale);
}
});
}
zoomIn(center) {
if (this.canZoom) {
this.isZooming = true;
this.canZoom = false;
setTimeout(() => {
this.isZooming = false;
this.canZoom = true;
}, 700);
this.zoom(1, center);
}
}
zoomOut(center) {
if (this.canZoom) {
this.isZooming = true;
this.canZoom = false;
setTimeout(() => {
this.isZooming = false;
this.canZoom = true;
}, 700);
this.zoom(-1, center);
}
}
zoomTo(mapObjects, zoomToLevel) {
if (mapObjects instanceof Marker || mapObjects instanceof MarkerCluster) {
return this.zoomToMarkerOrCluster(mapObjects, zoomToLevel);
}
else {
const convertedObjects = !Array.isArray(mapObjects) ? [mapObjects] : mapObjects;
const bbox = this.getGroupBBox(convertedObjects);
return this.fitViewBox(bbox, zoomToLevel);
}
}
zoomToMarkerOrCluster(mapObject, zoomToLevel) {
this.zoomLevel = zoomToLevel || 1;
const foundZoomLevel = this.zoomLevels.get(this.zoomLevel);
if (!foundZoomLevel) {
return false;
}
const vb = foundZoomLevel.viewBox;
if (this.canZoom) {
this.isZooming = true;
this.canZoom = false;
setTimeout(() => {
this.isZooming = false;
this.canZoom = true;
}, 700);
const vbNew = new ViewBox(mapObject.svgPoint.x - vb.width / 2, mapObject.svgPoint.y - vb.height / 2, vb.width, vb.height);
this.setViewBox(vbNew);
this._scale = foundZoomLevel._scale;
return true;
}
return false;
}
getGroupBBox(mapObjects) {
let _bbox;
const xmax = [];
const ymax = [];
const xmin = [];
const ymin = [];
for (let i = 0; i < mapObjects.length; i++) {
_bbox = mapObjects[i].getBBox();
xmin.push(_bbox.x);
ymin.push(_bbox.y);
const _w = _bbox.x + _bbox.width;
const _h = _bbox.y + _bbox.height;
xmax.push(_w);
ymax.push(_h);
}
const _xmin = Math.min(...xmin);
const _ymin = Math.min(...ymin);
const width = Math.max(...xmax) - _xmin;
const height = Math.max(...ymax) - _ymin;
let padding = 10;
const point1 = new ScreenPoint(padding, 0);
const point2 = new ScreenPoint(0, 0);
padding =
this.converter.convertPixelToSVG(point1).x - this.converter.convertPixelToSVG(point2).x;
return new ViewBox(_xmin - padding, _ymin - padding, width + padding * 2, height + padding * 2);
}
fitViewBox(fitViewBox, forceZoomLevel) {
let viewBoxPrev;
let foundZoomLevelNumber = 0;
let foundZoomLevel;
let newViewBox;
this.zoomLevels.forEach((zoomLevel) => {
if (viewBoxPrev && viewBoxPrev.x !== undefined) {
if (fitViewBox.fitsInViewBox(viewBoxPrev) &&
zoomLevel.viewBox.fitsInViewBox(fitViewBox, true)) {
foundZoomLevelNumber = forceZoomLevel ? forceZoomLevel : zoomLevel.zoomLevel;
foundZoomLevel = this.zoomLevels.get(foundZoomLevelNumber);
newViewBox = new ViewBox(fitViewBox.x - foundZoomLevel.viewBox.width / 2 + fitViewBox.width / 2, fitViewBox.y - foundZoomLevel.viewBox.height / 2 + fitViewBox.height / 2, foundZoomLevel.viewBox.width, foundZoomLevel.viewBox.height);
}
}
viewBoxPrev = zoomLevel && zoomLevel.viewBox;
});
if (foundZoomLevel) {
if (this.canZoom) {
this.isZooming = true;
this.canZoom = false;
setTimeout(() => {
this.isZooming = false;
this.canZoom = true;
}, 700);
this.zoomLevel = foundZoomLevelNumber;
this._scale = foundZoomLevel._scale;
this.setViewBox(newViewBox);
return true;
}
}
else {
return false;
}
}
zoomToRegion(region, zoomToLevel) {
this.fitViewBox(region.getBBox(), zoomToLevel);
return true;
}
centerOn(region, yShift) {
if (this.options.googleMaps.on) {
yShift = yShift ? (yShift + 12) / this.getScale() : 0;
$$A(this.containers.map).addClass("scrolling");
const latLng = region.getCenterLatLng(yShift);
this.googleMaps.map.panTo(latLng);
setTimeout(() => {
$$A(this.containers.map).removeClass("scrolling");
}, 100);
}
else {
yShift = yShift ? (yShift + 12) / this.getScale() : 0;
const bbox = region.getBBox();
const vb = this.viewBox;
const newViewBox = new ViewBox(bbox.x - vb.width / 2 + bbox.width / 2, bbox.y - vb.height / 2 + bbox.height / 2 - yShift, vb.width, vb.height);
this.setViewBox(newViewBox);
}
}
zoom(delta, center) {
let newViewBox = new ViewBox(0, 0, 0, 0);
const d = delta > 0 ? 1 : -1;
if (!this.zoomLevels.get(this.zoomLevel + d))
return;
const newZoomLevel = this.zoomLevel + d;
const zoomIn = d > 0;
const zoomOut = d < 0;
const zoomRange = this.getZoomRange();
const isInZoomRange = this.zoomLevel >= zoomRange.min && this.zoomLevel <= zoomRange.max;
const goingOutOfZoomRange = isInZoomRange && (newZoomLevel > zoomRange.max || newZoomLevel < zoomRange.min);
const outOfRangeAndMovingAway = !isInZoomRange &&
((zoomIn && newZoomLevel > zoomRange.max) || (zoomOut && newZoomLevel < zoomRange.min));
if (goingOutOfZoomRange || outOfRangeAndMovingAway) {
return;
}
this.zoomLevel = newZoomLevel;
const z = this.zoomLevels.get(this.zoomLevel);
this._scale = z._scale;
newViewBox = z.viewBox;
let shift = [];
if (center) {
const koef = zoomIn ? 0.5 : -1;
newViewBox.x = this.viewBox.x + (center.x - this.viewBox.x) * koef;
newViewBox.y = this.viewBox.y + (center.y - this.viewBox.y) * koef;
}
else {
shift = [
(this.viewBox.width - newViewBox.width) / 2,
(this.viewBox.height - newViewBox.height) / 2,
];
newViewBox.x = this.viewBox.x + shift[0];
newViewBox.y = this.viewBox.y + shift[1];
}
this.shiftViewBoxToScrollBoundaries(newViewBox);
this.setViewBox(newViewBox);
}
toggleSvgLayerOnZoom() {
if (this.options.googleMaps.on &&
this.googleMaps.map &&
this.options.zoom.hideSvg &&
this.googleMaps.map.getZoom() >= this.options.zoom.hideSvgZoomLevel) {
if (!$$A(this.containers.svg).hasClass("mapsvg-invisible")) {
$$A(this.containers.svg).animate({ opacity: 0 }, 400, "linear", () => {
$$A(this.containers.svg).addClass("mapsvg-invisible");
});
}
}
else {
if ($$A(this.containers.svg).hasClass("mapsvg-invisible")) {
$$A(this.containers.svg).animate({ opacity: 1 }, 400, "linear", () => {
$$A(this.containers.svg).removeClass("mapsvg-invisible");
});
}
}
}
shiftViewBoxToScrollBoundaries(newViewBox) {
if (this.options.scroll.limit) {
if (newViewBox.x < this.svgDefault.viewBox.x)
newViewBox.x = this.svgDefault.viewBox.x;
else if (newViewBox.x + newViewBox.width >
this.svgDefault.viewBox.x + this.svgDefault.viewBox.width)
newViewBox.x =
this.svgDefault.viewBox.x + this.svgDefault.viewBox.width - newViewBox.width;
if (newViewBox.y < this.svgDefault.viewBox.y)
newViewBox.y = this.svgDefault.viewBox.y;
else if (newViewBox.y + newViewBox.height >
this.svgDefault.viewBox.y + this.svgDefault.viewBox.height)
newViewBox.y =
this.svgDefault.viewBox.y + this.svgDefault.viewBox.height - newViewBox.height;
}
return newViewBox;
}
markerDelete(marker) {
if (this.editingMarker && this.editingMarker.id == marker.id) {
this.unsetEditingMarker();
}
if (this.markers.findById(marker.id)) {
this.markers.delete(marker.id);
}
marker.delete();
marker = null;
if (this.markers.length === 0)
this.options.markerLastID = 0;
}
markersClusterAdd(markersCluster) {
this.layers.markers.append(markersCluster.elem);
this.markersClusters.push(markersCluster);
markersCluster.adjustScreenPosition();
}
markerAdd(marker) {
$$A(marker.element).hide();
marker.adjustScreenPosition();
this.layers.markers.append(marker.element);
this.markers.push(marker);
marker.mapped = true;
setTimeout(function () {
$$A(marker.element).show();
}, 100);
}
markerRemove(marker) {
if (this.editingMarker && this.editingMarker.id == marker.id) {
this.editingMarker = null;
delete this.editingMarker;
}
if (this.markers.findById(marker.id)) {
this.markers.findById(marker.id).element.remove();
this.markers.delete(marker.id);
marker = null;
}
if (this.markers.length === 0)
this.options.markerLastID = 0;
}
markerId() {
this.options.markerLastID = this.options.markerLastID + 1;
const id = "marker_" + this.options.markerLastID;
if (this.getMarker(id))
return this.markerId();
else
return id;
}
movingItemsAdjustScreenPosition() {
this.markersAdjustScreenPosition();
this.popoverAdjustScreenPosition();
this.bubblesRegionsAdjustScreenPosition();
this.labelsRegionsAdjustScreenPosition();
}
movingItemsMoveScreenPositionBy(deltaX, deltaY) {
this.markersMoveScreenPositionBy(deltaX, deltaY);
this.popoverMoveScreenPositionBy(deltaX, deltaY);
this.bubblesRegionsMoveScreenPositionBy(deltaX, deltaY);
this.labelsRegionsMoveScreenPositionBy(deltaX, deltaY);
}
labelsRegionsAdjustScreenPosition() {
if ($$A(this.containers.map).is(":visible")) {
this.regions.forEach(function (region) {
region.adjustLabelScreenPosition();
});
}
}
bubblesRegionsAdjustScreenPosition() {
if ($$A(this.containers.map).is(":visible")) {
this.regions.forEach(function (region) {
region.adjustBubbleScreenPosition();
});
}
}
labelsRegionsMoveScreenPositionBy(deltaX, deltaY) {
if ($$A(this.containers.map).is(":visible")) {
this.regions.forEach(function (region) {
region.moveLabelScreenPositionBy(deltaX, deltaY);
});
}
}
bubblesRegionsMoveScreenPositionBy(deltaX, deltaY) {
if ($$A(this.containers.map).is(":visible")) {
this.regions.forEach((region) => {
region.moveBubbleScreenPositionBy(deltaX, deltaY);
});
}
}
markersAdjustScreenPosition() {
this.markers.forEach((marker) => {
marker.adjustScreenPosition();
});
this.markersClusters.forEach((cluster) => {
cluster.adjustScreenPosition();
});
if (this.userLocationMarker) {
this.userLocationMarker.adjustScreenPosition();
}
}
markersMoveScreenPositionBy(deltaX, deltaY) {
this.markers.forEach((marker) => {
marker.moveSrceenPositionBy(deltaX, deltaY);
});
this.markersClusters.forEach((cluster) => {
cluster.moveSrceenPositionBy(deltaX, deltaY);
});
if (this.userLocationMarker) {
this.userLocationMarker.moveSrceenPositionBy(deltaX, deltaY);
}
}
setEditingMarker(marker) {
this.editingMarker = marker;
if (!this.editingMarker.mapped) {
this.editingMarker.needToRemove = true;
this.markerAdd(this.editingMarker);
}
}
unsetEditingMarker() {
if (this.editingMarker && this.editingMarker.needToRemove) {
this.markerRemove(this.editingMarker);
}
this.editingMarker = null;
}
getEditingMarker() {
return this.editingMarker;
}
scrollStart(e, mapsvg) {
if ($$A(e.target).hasClass("mapsvg-btn-map") ||
$$A(e.target).closest(".mapsvg-choropleth").length)
return;
if (this.editMarkers.on && $$A(e.target).hasClass("mapsvg-marker"))
return;
e.preventDefault();
$$A(this.containers.map).addClass("no-transitions");
const ce = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0]
? e.originalEvent.touches[0]
: e;
this.scrollStarted = true;
this.scroll = {
tx: this.scroll.tx || 0,
ty: this.scroll.ty || 0,
vxi: this.viewBox.x,
vyi: this.viewBox.y,
x: ce.clientX,
y: ce.clientY,
dx: 0,
dy: 0,
vx: 0,
vy: 0,
gx: ce.clientX,
gy: ce.clientY,
touchScrollStart: 0,
};
if (e.type.indexOf("mouse") === 0) {
$$A(document).on("mousemove.scroll.mapsvg", (e) => {
this.scrollMove(e);
});
if (this.options.scroll.spacebar) {
$$A(document).on("keyup.scroll.mapsvg", (e) => {
if (e.keyCode == 32) {
this.scrollEnd(e, mapsvg);
}
});
}
else {
$$A(document).on("mouseup.scroll.mapsvg", (e) => {
this.scrollEnd(e, mapsvg);
});
}
}
}
scrollMove(e) {
e.preventDefault();
if (!this.isScrolling) {
this.isScrolling = true;
$$A(this.containers.map).addClass("scrolling");
}
const ce = e.originalEvent && e.originalEvent.touches && e.originalEvent.touches[0]
? e.originalEvent.touches[0]
: e;
this.panBy(this.scroll.gx - ce.clientX, this.scroll.gy - ce.clientY);
this.scroll.gx = ce.clientX;
this.scroll.gy = ce.clientY;
this.scroll.dx = this.scroll.x - ce.clientX;
this.scroll.dy = this.scroll.y - ce.clientY;
let vx = this.scroll.vxi + this.scroll.dx / this.scale;
let vy = this.scroll.vyi + this.scroll.dy / this.scale;
if (this.options.scroll.limit) {
if (vx < this.svgDefault.viewBox.x)
vx = this.svgDefault.viewBox.x;
else if (this.viewBox.width + vx >
this.svgDefault.viewBox.x + this.svgDefault.viewBox.width)
vx = this.svgDefault.viewBox.x + this.svgDefault.viewBox.width - this.viewBox.width;
if (vy < this.svgDefault.viewBox.y)
vy = this.svgDefault.viewBox.y;
else if (this.viewBox.height + vy >
this.svgDefault.viewBox.y + this.svgDefault.viewBox.height)
vy =
this.svgDefault.viewBox.y +
this.svgDefault.viewBox.height -
this.viewBox.height;
}
this.scroll.vx = vx;
this.scroll.vy = vy;
}
scrollEnd(e, mapsvg, noClick) {
setTimeout(() => {
this.enableAnimation();
this.scrollStarted = false;
this.isScrolling = false;
}, 100);
if (this.googleMaps && this.googleMaps.overlay) {
this.googleMaps.overlay.draw();
}
$$A(this.containers.map).removeClass("scrolling");
$$A(document).off("keyup.scroll.mapsvg");
$$A(document).off("mousemove.scroll.mapsvg");
$$A(document).off("mouseup.scroll.mapsvg");
if (noClick !== true && Math.abs(this.scroll.dx) < 5 && Math.abs(this.scroll.dy) < 5) {
if (this.editMarkers.on)
this.clickAddsMarker && this.markerAddClickHandler(e);
else if (this.objectClickedBeforeScroll)
if (this.objectClickedBeforeScroll instanceof Marker) {
this.markerClickHandler(e, this.objectClickedBeforeScroll);
}
else if (this.objectClickedBeforeScroll instanceof Region) {
this.regionClickHandler(e, this.objectClickedBeforeScroll);
}
else if (this.objectClickedBeforeScroll instanceof MarkerCluster) {
this.markerClusterClickHandler(e, this.objectClickedBeforeScroll);
}
}
this.viewBox.x = this.scroll.vx || this.viewBox.x;
this.viewBox.y = this.scroll.vy || this.viewBox.y;
}
setViewBoxByGoogleMapsOverlay() {
const bounds = this.googleMaps.overlay.getPixelBounds();
const scale = (bounds.ne.x - bounds.sw.x) / this.svgDefault.viewBox.width;
const vb = new ViewBox(this.svgDefault.viewBox.x - bounds.sw.x / scale, this.svgDefault.viewBox.y - bounds.ne.y / scale, this.containers.map.offsetWidth / scale, this.containers.map.offsetHeight / scale);
this.setViewBox(vb, false);
}
panBy(x, y) {
let tx = this.scroll.tx - x;
let ty = this.scroll.ty - y;
const scrolled = { x: true, y: true };
if (this.options.scroll.limit) {
const svg = $$A(this.containers.svg)[0].getBoundingClientRect();
const bounds = $$A(this.containers.map)[0].getBoundingClientRect();
if ((svg.left - x > bounds.left && x < 0) || (svg.right - x < bounds.right && x > 0)) {
tx = this.scroll.tx;
scrolled.x = false;
}
if ((svg.top - y > bounds.top && y < 0) || (svg.bottom - y < bounds.bottom && y > 0)) {
ty = this.scroll.ty;
scrolled.y = false;
}
}
$$A(this.containers.scrollpane).css({
transform: "translate(" + tx + "px," + ty + "px)",
});
this.scroll.tx = tx;
this.scroll.ty = ty;
if (scrolled.x || scrolled.y) {
const moveX = scrolled.x ? x : 0;
const moveY = scrolled.y ? y : 0;
this.movingItemsMoveScreenPositionBy(moveX, moveY);
if (this.googleMaps.map) {
let point = this.googleMaps.map.getCenter();
const projection = this.googleMaps.overlay.getProjection();
const pixelpoint = projection.fromLatLngToDivPixel(point);
pixelpoint.x += moveX;
pixelpoint.y += moveY;
point = projection.fromDivPixelToLatLng(pixelpoint);
this.googleMaps.map.setCenter(point);
}
}
return scrolled;
}
setObjectClickedBeforeScroll(object) {
this.objectClickedBeforeScroll = object;
}
touchStart(_e, mapsvg) {
_e.preventDefault();
if (this.scrollStarted) {
this.scrollEnd(_e, mapsvg, true);
}
const e = _e.originalEvent;
if (this.options.zoom.fingers && e.touches && e.touches.length == 2) {
this.touchZoomStart = true;
this.scaleDistStart = Math.hypot(e.touches[0].pageX - e.touches[1].pageX, e.touches[0].pageY - e.touches[1].pageY);
}
else if (e.touches && e.touches.length == 1) {
this.scrollStart(_e, mapsvg);
}
$$A(document)
.on("touchmove.scroll.mapsvg", (e) => {
e.preventDefault();
this.touchMove(e, this);
})
.on("touchend.scroll.mapsvg", (e) => {
e.preventDefault();
this.touchEnd(e, this);
});
}
touchMove(_e, mapsvg) {
_e.preventDefault();
const e = _e.originalEvent;
if (this.options.zoom.fingers && e.touches && e.touches.length == 2) {
if (!MapSVG.ios) {
e.scale =
Math.hypot(e.touches[0].pageX - e.touches[1].pageX, e.touches[0].pageY - e.touches[1].pageY) / this.scaleDistStart;
}
if (e.scale != 1 && this.canZoom) {
const d = e.scale > 1 ? 1 : -1;
const cx = e.touches[0].pageX >= e.touches[1].pageX
? e.touches[0].pageX -
(e.touches[0].pageX - e.touches[1].pageX) / 2 -
$$A(this.containers.map).offset().left
: e.touches[1].pageX -
(e.touches[1].pageX - e.touches[0].pageX) / 2 -
$$A(this.containers.map).offset().left;
const cy = e.touches[0].pageY >= e.touches[1].pageY
? e.touches[0].pageY -
(e.touches[0].pageY - e.touches[1].pageY) -
$$A(this.containers.map).offset().top
: e.touches[1].pageY -
(e.touches[1].pageY - e.touches[0].pageY) -
$$A(this.containers.map).offset().top;
const center = this.converter.convertPixelToSVG(new ScreenPoint(cx, cy));
if (d > 0)
this.zoomIn(center);
else
this.zoomOut(center);
}
}
else if (e.touches && e.touches.length == 1) {
this.scrollMove(_e);
}
}
touchEnd(_e, mapsvg) {
_e.preventDefault();
const e = _e.originalEvent;
if (this.touchZoomStart) {
this.touchZoomStart = false;
}
else if (this.scrollStarted) {
this.scrollEnd(_e, mapsvg);
}
$$A(document).off("touchmove.scroll.mapsvg");
$$A(document).off("touchend.scroll.mapsvg");
}
getSelected() {
return this.selected_id;
}
selectRegion(id, skipDirectorySelection) {
let region;
if (typeof id == "string") {
region = this.getRegion(id);
}
else {
region = id;
}
if (!region)
return;
let ids;
if (this.options.multiSelect && !this.editRegions.on) {
if (region.selected) {
this.deselectRegion(region);
if (!skipDirectorySelection && this.options.menu.on) {
if (this.options.menu.source == "database") {
if (region.objects && region.objects.length) {
ids = region.objects.map((obj) => {
return obj.id.toString();
});
}
}
else {
ids = [region.id];
}
this.controllers.directory.deselectItems();
}
return;
}
}
else if (this.selected_id.length > 0) {
this.deselectAllRegions();
if (!skipDirectorySelection && this.options.menu.on) {
if (this.options.menu.source == "database") {
if (region.objects && region.objects.length) {
ids = region.objects.map((obj) => {
return obj.id.toString();
});
}
}
else {
ids = [region.id];
}
this.controllers.directory.deselectItems();
}
}
this.selected_id.push(region.id);
region.select();
const skip = this.options.actions.region.click.filterDirectory;
if (!skip &&
!skipDirectorySelection &&
this.options.menu.on &&
this.controllers &&
this.controllers.directory) {
if (this.options.menu.source == "database") {
if (region.objects && region.objects.length) {
ids = region.objects.map((obj) => {
return obj.id.toString();
});
}
else {
ids = [region.id];
}
}
else {
ids = [region.id];
}
this.controllers.directory.selectItems(ids);
}
if (this.options.actions.region.click.addIdToUrl &&
!this.options.actions.region.click.showAnotherMap) {
window.location.hash = "/m/" + region.id;
}
}
deselectAllRegions() {
$$A.each(this.selected_id, (index, id) => {
this.deselectRegion(this.getRegion(id));
});
}
deselectRegion(region) {
if (!region)
region = this.getRegion(this.selected_id[0]);
if (region) {
region.deselect();
const i = $$A.inArray(region.id, this.selected_id);
this.selected_id.splice(i, 1);
}
if (this.options.actions.region.click.addIdToUrl) {
if (window.location.hash.indexOf(region.id) !== -1) {
history.replaceState(null, null, " ");
}
}
}
highlightRegions(regions) {
regions.forEach((region) => {
if (region && !region.selected && !region.disabled) {
this.highlightedRegions.push(region);
region.highlight();
}
});
}
unhighlightRegions() {
this.highlightedRegions.forEach((region) => {
if (region && !region.selected && !region.disabled)
region.unhighlight();
});
this.highlightedRegions = [];
}
selectMarker(marker) {
if (!(marker instanceof Marker))
return;
this.deselectAllMarkers();
marker.select();
this.selected_marker = marker;
$$A(this.layers.markers).addClass("mapsvg-with-marker-active");
if (this.options.menu.on && this.options.menu.source == "database") {
this.controllers.directory.deselectItems();
this.controllers.directory.selectItems(marker.object.id);
}
}
deselectAllMarkers() {
this.selected_marker && this.selected_marker.deselect();
$$A(this.layers.markers).removeClass("mapsvg-with-marker-active");
}
deselectMarker(marker) {
if (marker) {
marker.deselect();
}
}
highlightMarker(marker) {
$$A(this.layers.markers).addClass("mapsvg-with-marker-hover");
marker.highlight();
this.highlighted_marker = marker;
}
unhighlightMarker() {
$$A(this.layers.markers).removeClass("mapsvg-with-marker-hover");
this.highlighted_marker && this.highlighted_marker.unhighlight();
}
convertMouseToSVG(e) {
const mc = MapSVG.mouseCoords(e);
const x = mc.x - $$A(this.containers.map).offset().left;
const y = mc.y - $$A(this.containers.map).offset().top;
const screenPoint = new ScreenPoint(x, y);
return this.converter.convertPixelToSVG(screenPoint);
}
pickChoroplethColor(choroplethValue) {
const w = (choroplethValue - this.options.choropleth.coloring.gradient.values.min) /
this.options.choropleth.coloring.gradient.values.maxAdjusted;
const rgba = {
r: Math.round(this.options.choropleth.coloring.gradient.colors.diffRGB.r * w +
this.options.choropleth.coloring.gradient.colors.lowRGB.r),
g: Math.round(this.options.choropleth.coloring.gradient.colors.diffRGB.g * w +
this.options.choropleth.coloring.gradient.colors.lowRGB.g),
b: Math.round(this.options.choropleth.coloring.gradient.colors.diffRGB.b * w +
this.options.choropleth.coloring.gradient.colors.lowRGB.b),
a: Math.round(this.options.choropleth.coloring.gradient.colors.diffRGB.a * w +
this.options.choropleth.coloring.gradient.colors.lowRGB.a),
};
return rgba;
}
isRegionDisabled(id, svgfill) {
if (this.options.regions[id] && (this.options.regions[id].disabled || svgfill == "none")) {
return true;
}
else if ((this.options.regions[id] == undefined ||
MapSVG.parseBoolean(this.options.regions[id].disabled)) &&
(this.options.disableAll || svgfill == "none" || id == "labels" || id == "Labels")) {
return true;
}
else {
return false;
}
}
loadMap(id, container) {
if (!(container instanceof HTMLElement)) {
console.error("Can't load a new map: container was not provided.");
return;
}
const previousMapsIds = [...this.options.previousMapsIds];
const currentMapId = this.id;
if (previousMapsIds[previousMapsIds.length - 1] !== id) {
previousMapsIds.push(currentMapId);
}
else {
previousMapsIds.pop();
}
let showPreviousMapButton;
if (typeof this.options.actions.region.click.showAnotherMapContainerId !== "undefined") {
showPreviousMapButton = false;
}
else {
showPreviousMapButton = this.options.controls.previousMap;
}
const mapsRepo = new MapsRepository();
mapsRepo.findById(id).done((map) => {
this.destroy();
const newMap = new MapSVGMap(container.getAttribute("id"), map);
newMap.events.on("afterLoad", function () {
this.options.previousMapsIds = previousMapsIds;
this.options.controls.previousMap = showPreviousMapButton;
this.setControls(this.options.controls);
});
});
}
loadPreviousMap() {
const previousMapId = this.options.previousMapsIds[this.options.previousMapsIds.length - 1];
const container = document.getElementById(this.containerId);
this.loadMap(previousMapId, container);
}
markerClusterClickHandler(e, markerCluster) {
this.objectClickedBeforeScroll = null;
if (this.eventsPreventList["click"])
return;
this.zoomTo(markerCluster.markers);
return;
}
regionClickHandler(e, region) {
this.objectClickedBeforeScroll = null;
if (this.eventsPreventList["click"])
return;
this.selectRegion(region.id);
if (this.editRegions.on) {
this.regionEditHandler.call(region);
return;
}
const actions = this.options.actions;
if (actions.region.click.zoom) {
this.zoomTo(region, parseInt(actions.region.click.zoomToLevel));
}
if (actions.region.click.filterDirectory) {
const query = new Query({
filters: {
regions: {
table_name: this.regionsRepository.getSchema().name,
region_ids: [region.id],
},
},
});
this.objectsRepository.query.resetFilters();
this.setFilterOut();
this.objectsRepository.find(query).done(() => {
if (this.controllers.popover) {
this.controllers.popover.redraw(region.forTemplate());
}
if (this.controllers.detailsView) {
this.controllers.detailsView.redraw(region.forTemplate());
}
});
this.updateFiltersState();
}
if (actions.region.click.showDetails) {
this.loadDetailsView(region);
}
if (actions.region.click.showPopover) {
if (actions.region.click.zoom) {
setTimeout(() => {
this.showPopover(region);
}, 400);
}
else {
this.showPopover(region);
}
}
else if (e && e.type.indexOf("touch") !== -1 && actions.region.touch.showPopover) {
if (actions.region.click.zoom) {
setTimeout(() => {
this.showPopover(region);
}, 400);
}
else {
this.showPopover(region);
}
}
if (actions.region.click.goToLink) {
const linkParts = actions.region.click.linkField.split(".");
let url;
if (linkParts.length > 1) {
const obj = linkParts.shift();
const attr = "." + linkParts.join(".");
if (obj == "Region") {
if (region.data) {
try {
url = eval("region.data" + attr);
}
catch (err) {
console.log("No such field as region.data" + attr);
}
}
}
else {
if (region.objects && region.objects[0]) {
try {
url = eval("region.objects[0]" + attr);
}
catch (err) {
console.log("No such field as region.objects[0]" + attr);
}
}
}
if (url && !this.disableLinks) {
if (this.editMode) {
alert("Redirect: " + url + "\nLinks are disabled in the preview.");
return;
}
if (actions.region.click.newTab) {
const win = window.open(url, "_blank");
win.focus();
}
else {
window.location.href = url;
}
}
}
}
if (actions.region.click.showAnotherMap) {
if (this.editMode) {
alert('"Show another map" action is disabled in the preview');
return;
}
const linkParts = actions.region.click.showAnotherMapField.split(".");
if (linkParts.length > 1) {
const obj = linkParts.shift();
const attr = "." + linkParts.join(".");
let map_id;
if (obj == "Region") {
if (region.data)
map_id = eval("region.data" + attr);
}
else {
if (region.objects && region.objects[0])
map_id = eval("region.objects[0]" + attr);
}
if (map_id) {
const container = actions.region.click.showAnotherMapContainerId
? $$A("#" + actions.region.click.showAnotherMapContainerId)[0]
: $$A(this.containers.map)[0];
this.loadMap(map_id, container);
}
}
}
this.events.trigger("click.region", region, [e, region, this]);
}
markerClickHandler(e, marker) {
this.objectClickedBeforeScroll = null;
if (this.eventsPreventList["click"])
return;
const actions = this.options.actions;
this.selectMarker(marker);
const passingObject = marker.object;
if (actions.marker.click.zoom) {
this.zoomTo(marker, parseInt(actions.marker.click.zoomToLevel));
}
if (actions.marker.click.filterDirectory) {
const query = new Query({ filters: { id: marker.object.id } });
this.objectsRepository.find(query);
this.updateFiltersState();
}
if (actions.marker.click.showDetails)
this.loadDetailsView(passingObject);
if (actions.marker.click.showPopover) {
if (actions.marker.click.zoom) {
setTimeout(() => {
this.showPopover(passingObject);
}, 500);
}
else {
this.showPopover(passingObject);
}
}
else if (e && e.type.indexOf("touch") !== -1 && actions.marker.touch.showPopover) {
if (actions.marker.click.zoom) {
setTimeout(() => {
this.showPopover(passingObject);
}, 500);
}
else {
this.showPopover(passingObject);
}
}
if (actions.marker.click.goToLink) {
const linkParts = actions.marker.click.linkField.split(".");
let url;
if (linkParts.length > 1) {
const obj = linkParts.shift();
const attr = "." + linkParts.join(".");
try {
url = eval("passingObject" + attr);
}
catch (err) {
console.log("MapSVG: No such field as passingObject" + attr);
}
if (url && !this.disableLinks)
if (this.editMode) {
alert("Redirect: " + url + "\nLinks are disabled in the preview.");
return;
}
if (actions.marker.click.newTab) {
const win = window.open(url, "_blank");
win.focus();
}
else {
window.location.href = url;
}
}
}
this.events.trigger("click.marker", marker, [e, marker, this]);
}
fileExists(url) {
if (url.substr(0, 4) == "data")
return true;
const http = new XMLHttpRequest();
http.open("HEAD", url, false);
http.send();
return http.status != 404;
}
hideMarkers() {
this.markers.forEach(function (marker) {
marker.hide();
});
$$A(this.containers.wrap).addClass("mapsvg-edit-marker-mode");
}
hideMarkersExceptOne(id) {
this.markers.forEach(function (marker) {
if (typeof id === "undefined" || (marker.object && id != marker.object.id)) {
marker.hide();
}
});
$$A(this.containers.wrap).addClass("mapsvg-edit-marker-mode");
}
showMarkers() {
this.markers.forEach(function (m) {
m.show();
});
this.deselectAllMarkers();
$$A(this.containers.wrap).removeClass("mapsvg-edit-marker-mode");
}
markerAddClickHandler(e) {
if ($$A(e.target).hasClass("mapsvg-marker"))
return;
const svgPoint = this.getSvgPointAtClick(e);
const geoPoint = this.isGeo() ? this.converter.convertSVGToGeo(svgPoint) : null;
if (!$$A.isNumeric(svgPoint.x) || !$$A.isNumeric(svgPoint.y))
return;
if (this.editingMarker) {
if (geoPoint) {
this.editingMarker.location.setGeoPoint(geoPoint);
}
else {
this.editingMarker.location.setSvgPoint(svgPoint);
}
return;
}
const location = new Location({
svgPoint: svgPoint,
geoPoint: geoPoint,
img: this.options.defaultMarkerImage,
});
const marker = new Marker({
location: location,
mapsvg: this,
});
this.markerAdd(marker);
this.markerEditHandler && this.markerEditHandler.call(location, location);
}
getSvgPointAtClick(e) {
const mc = MapSVG.mouseCoords(e);
const x = mc.x - $$A(this.containers.map).offset().left;
const y = mc.y - $$A(this.containers.map).offset().top;
const screenPoint = new ScreenPoint(x, y);
return this.converter.convertPixelToSVG(screenPoint);
}
setDefaultMarkerImage(src) {
this.options.defaultMarkerImage = src;
}
setMarkerImagesDependency() {
this.locationField = this.objectsRepository.schema.getFieldByType("location");
if (this.locationField &&
this.locationField.markersByFieldEnabled &&
this.locationField.markerField &&
Object.values(this.locationField.markersByField).length > 0) {
this.setMarkersByField = true;
}
else {
this.setMarkersByField = false;
}
}
getMarkerImage(fieldValueOrObject, location) {
let fieldValue;
if (this.setMarkersByField) {
if (typeof fieldValueOrObject === "object") {
fieldValue = fieldValueOrObject[this.locationField.markerField];
if (this.locationField.markerField === "regions") {
fieldValue = fieldValue[0] && fieldValue[0].id;
}
else if (typeof fieldValue === "object" && fieldValue.length) {
fieldValue = fieldValue[0].value;
}
}
else {
fieldValue = fieldValueOrObject;
}
if (this.locationField.markersByField[fieldValue]) {
return this.locationField.markersByField[fieldValue];
}
}
return location && location.imagePath
? location.imagePath
: this.options.defaultMarkerImage
? this.options.defaultMarkerImage
: MapSVG.urls.root + "markers/_pin_default.png";
}
setMarkersEditMode(on, clickAddsMarker) {
this.editMarkers.on = MapSVG.parseBoolean(on);
this.clickAddsMarker = this.editMarkers.on;
this.setEventHandlers();
}
setRegionsEditMode(on) {
this.editRegions.on = MapSVG.parseBoolean(on);
this.deselectAllRegions();
this.setEventHandlers();
}
setEditMode(on) {
this.editMode = on;
}
setDataEditMode(on) {
this.editData.on = MapSVG.parseBoolean(on);
this.deselectAllRegions();
this.setEventHandlers();
}
download() {
window.location.href = window.location.origin + this.options.source;
}
popoverAdjustScreenPosition() {
if (this.controllers.popover instanceof PopoverController) {
this.controllers.popover.adjustScreenPosition();
}
}
popoverMoveScreenPositionBy(deltaX, deltaY) {
if (this.controllers.popover instanceof PopoverController) {
this.controllers.popover.moveSrceenPositionBy(deltaX, deltaY);
}
}
showPopover(object) {
const mapObject = object instanceof Region
? object
: object.location && object.location.marker
? object.location.marker
: null;
if (!mapObject)
return;
let point;
if (mapObject instanceof Marker) {
point = mapObject.svgPoint;
}
else {
point = mapObject.getCenterSVG();
}
this.controllers.popover && this.controllers.popover.destroy();
this.controllers.popover = new PopoverController({
container: this.containers.popover,
point: point,
yShift: mapObject instanceof Marker ? mapObject.height : 0,
template: object instanceof Region
? this.options.templates.popoverRegion
: this.options.templates.popoverMarker,
mapsvg: this,
data: object.getData(),
mapObject: mapObject,
scrollable: true,
withToolbar: !(MapSVG.isPhone && this.options.popovers.mobileFullscreen),
events: {
shown: (popover) => {
if (this.options.popovers.centerOn) {
const shift = popover.containers.main.offsetHeight / 2;
if (this.options.popovers.centerOn &&
!(MapSVG.isPhone && this.options.popovers.mobileFullscreen)) {
this.centerOn(mapObject, shift);
}
}
this.popoverShowingFor = mapObject;
this.events.trigger("shown.popover", this, [this, popover]);
$$A(window).trigger("shown.popover", [this, popover]);
},
closed: (popover) => {
this.options.popovers.resetViewboxOnClose && this.viewBoxReset(true);
this.popoverShowingFor = null;
this.events.trigger("closed.popover", this, [this, popover]);
},
resize: (popover) => {
if (this.options.popovers.centerOn) {
const shift = popover.containers.main.offsetHeight / 2;
if (this.options.popovers.centerOn &&
!(MapSVG.isPhone && this.options.popovers.mobileFullscreen)) {
this.centerOn(mapObject, shift);
}
}
},
},
});
this.controllers.popover._init();
}
hidePopover() {
this.controllers.popover && this.controllers.popover.close();
}
popoverOffHandler(e) {
if (this.isScrolling ||
$$A(e.target).closest(".mapsvg-popover").length ||
$$A(e.target).hasClass("mapsvg-btn-map"))
return;
this.controllers.popover && this.controllers.popover.close();
}
mouseOverHandler(e, object) {
if (this.eventsPreventList["mouseover"]) {
return;
}
if (object instanceof Marker) {
if (this.options.actions.marker.mouseover.showTooltip) {
this.showTooltip(object);
}
}
if (object instanceof Region) {
if (this.options.actions.region.mouseover.showTooltip) {
this.showTooltip(object);
}
}
let ids;
if (this.options.menu.on) {
if (this.options.menu.source == "database") {
if (object instanceof Region && object.objects.length) {
ids = object.objects.map((obj) => {
return obj.id;
});
}
if (object instanceof Marker) {
ids = object.object ? [object.object.id] : [];
}
}
else {
if (object instanceof Region) {
ids = [object.id];
}
if (this instanceof Marker &&
object.object.regions &&
object.object.regions.length) {
ids = object.object.regions.map((obj) => {
return obj.id;
});
}
}
this.controllers.directory.highlightItems(ids);
}
if (object instanceof Region) {
if (!object.selected)
object.highlight();
this.events.trigger("mouseover.region", object, [e, this]);
}
else {
this.highlightMarker(object);
this.events.trigger("mouseover.marker", object, [e, this]);
}
}
showTooltip(object) {
let name, _object;
if (object instanceof Region) {
name = "tooltipRegion";
_object = object;
}
else if (object instanceof Marker) {
name = "tooltipMarker";
_object = object.object;
}
else {
name = "tooltipMarker";
_object = object;
}
if (_object != null && this.popoverShowingFor !== object) {
this.controllers.tooltip.setMainTemplate(this.options.templates[name]);
this.controllers.tooltip.redraw(_object.getData());
this.controllers.tooltip.show();
}
}
mouseOutHandler(e, object) {
if (this.eventsPreventList["mouseout"]) {
return;
}
if (this.controllers.tooltip)
this.controllers.tooltip.hide();
if (object instanceof Region) {
if (!object.selected)
object.unhighlight();
this.events.trigger("mouseout.region", object, [e, this]);
}
else {
this.unhighlightMarker();
this.events.trigger("mouseout.marker", object, [e, this]);
}
let ids;
if (this.options.menu.on) {
if (this.options.menu.source == "database") {
if (object instanceof Marker) {
const marker = object;
ids = marker.object ? [marker.object.id] : [];
}
}
this.controllers.directory.unhighlightItems();
}
}
eventsPrevent(event) {
this.eventsPreventList[event] = true;
}
eventsRestore(event) {
if (event) {
this.eventsPreventList[event] = false;
}
else {
this.eventsPreventList = {};
}
}
setEventHandlers() {
const _this = this;
$$A(_this.containers.map).off(".common.mapsvg");
$$A(_this.containers.scrollpane).off(".common.mapsvg");
$$A(document).off(".scroll.mapsvg");
$$A(document).off(".scrollInit.mapsvg");
if (_this.editMarkers.on) {
$$A(_this.containers.map).on("touchstart.common.mapsvg mousedown.common.mapsvg", ".mapsvg-marker", function (e) {
e.originalEvent.preventDefault();
const marker = _this.getMarker($$A(this).attr("id"));
const startCoords = MapSVG.mouseCoords(e);
marker.drag(startCoords, _this.scale);
});
}
if (!_this.editMarkers.on) {
$$A(_this.containers.map)
.on("mouseover.common.mapsvg", ".mapsvg-region", function (e) {
const id = $$A(this).attr("id");
_this.mouseOverHandler.call(_this, e, _this.getRegion(id));
})
.on("mouseleave.common.mapsvg", ".mapsvg-region", function (e) {
const id = $$A(this).attr("id");
_this.mouseOutHandler.call(_this, e, _this.getRegion(id));
});
}
if (!_this.editRegions.on) {
$$A(_this.containers.map)
.on("mouseover.common.mapsvg", ".mapsvg-marker", function (e) {
const id = $$A(this).attr("id");
_this.mouseOverHandler.call(_this, e, _this.getMarker(id));
})
.on("mouseleave.common.mapsvg", ".mapsvg-marker", function (e) {
const id = $$A(this).attr("id");
_this.mouseOutHandler.call(_this, e, _this.getMarker(id));
});
}
if (_this.options.scroll.spacebar) {
$$A(document).on("keydown.scroll.mapsvg", function (e) {
if (!(document.activeElement.tagName === "INPUT" &&
$$A(document.activeElement).attr("type") === "text") &&
!_this.isScrolling &&
e.keyCode == 32) {
e.preventDefault();
$$A(_this.containers.map).addClass("mapsvg-scrollable");
$$A(document)
.on("mousemove.scrollInit.mapsvg", function (e) {
_this.isScrolling = true;
$$A(document).off("mousemove.scrollInit.mapsvg");
_this.scrollStart(e, _this);
})
.on("keyup.scroll.mapsvg", function (e) {
if (e.keyCode == 32) {
$$A(document).off("mousemove.scrollInit.mapsvg");
$$A(_this.containers.map).removeClass("mapsvg-scrollable");
}
});
}
});
}
else if (!_this.options.scroll.on) {
if (!_this.editMarkers.on) {
$$A(_this.containers.map).on("touchstart.common.mapsvg", ".mapsvg-region", function (e) {
_this.scroll.touchScrollStart = $$A(window).scrollTop();
});
$$A(_this.containers.map).on("touchstart.common.mapsvg", ".mapsvg-marker", function (e) {
_this.scroll.touchScrollStart = $$A(window).scrollTop();
});
$$A(_this.containers.map).on("touchend.common.mapsvg mouseup.common.mapsvg", ".mapsvg-region", function (e) {
if (e.cancelable) {
e.preventDefault();
}
if (!_this.scroll.touchScrollStart ||
_this.scroll.touchScrollStart === $$A(window).scrollTop()) {
_this.regionClickHandler(e, _this.getRegion($$A(this).attr("id")));
}
});
$$A(_this.containers.map).on("touchend.common.mapsvg mouseup.common.mapsvg", ".mapsvg-marker", function (e) {
if (e.cancelable) {
e.preventDefault();
}
if (!_this.scroll.touchScrollStart ||
_this.scroll.touchScrollStart === $$A(window).scrollTop()) {
_this.markerClickHandler.call(_this, e, _this.getMarker($$A(this).attr("id")));
}
});
$$A(_this.containers.map).on("touchend.common.mapsvg mouseup.common.mapsvg", ".mapsvg-marker-cluster", function (e) {
if (e.cancelable) {
e.preventDefault();
}
if (!_this.scroll.touchScrollStart ||
_this.scroll.touchScrollStart == $$A(window).scrollTop()) {
const cluster = $$A(this).data("cluster");
_this.zoomTo(cluster.markers);
}
});
}
else {
if (_this.clickAddsMarker)
$$A(_this.containers.map).on("touchend.common.mapsvg mouseup.common.mapsvg", function (e) {
if (e.cancelable) {
e.preventDefault();
}
_this.markerAddClickHandler(e);
});
}
}
else {
$$A(_this.containers.map).on("touchstart.common.mapsvg mousedown.common.mapsvg", function (e) {
if ($$A(e.target).hasClass("mapsvg-popover") ||
$$A(e.target).closest(".mapsvg-popover").length) {
if ($$A(e.target).hasClass("mapsvg-popover-close")) {
if (e.type == "touchstart") {
if (e.cancelable) {
e.preventDefault();
}
}
}
return;
}
if (e.type == "touchstart") {
if (e.cancelable) {
e.preventDefault();
}
}
let obj;
if (e.target &&
$$A(e.target).attr("class") &&
$$A(e.target).attr("class").indexOf("mapsvg-region") != -1) {
obj = _this.getRegion($$A(e.target).attr("id"));
_this.setObjectClickedBeforeScroll(obj);
}
else if (e.target &&
$$A(e.target).attr("class") &&
$$A(e.target).attr("class").indexOf("mapsvg-marker") != -1 &&
$$A(e.target).attr("class").indexOf("mapsvg-marker-cluster") === -1) {
if (_this.editMarkers.on) {
return;
}
obj = _this.getMarker($$A(e.target).attr("id"));
_this.setObjectClickedBeforeScroll(obj);
}
else if (e.target &&
$$A(e.target).attr("class") &&
$$A(e.target).attr("class").indexOf("mapsvg-marker-cluster") != -1) {
if (_this.editMarkers.on) {
return;
}
obj = $$A(e.target).data("cluster");
_this.setObjectClickedBeforeScroll(obj);
}
if (e.type == "mousedown") {
_this.scrollStart(e, _this);
}
else {
_this.touchStart(e, _this);
}
});
}
$$A(_this.containers.map).on("mouseleave.common.mapsvg", ".mapsvg-choropleth-gradient-wrap", (e) => {
this.controllers.tooltip.hide();
});
}
setLabelsRegions(options) {
options = options || this.options.labelsRegions;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
$$A.extend(true, this.options, { labelsRegions: options });
if (this.options.labelsRegions.on) {
this.regions.forEach((region) => {
if (!region.label) {
region.label = jQuery('')[0];
$$A(this.layers.labels).append(region.label);
}
try {
$$A(region.label).html(this.templates.labelRegion(region.forTemplate()));
}
catch (err) {
console.error('MapSVG: Error in the "Region Label" template');
}
});
this.labelsRegionsAdjustScreenPosition();
}
else {
this.regions.forEach((region) => {
if (region.label) {
$$A(region.label).remove();
region.label = null;
delete region.label;
}
});
}
}
setLabelsMarkers(options) {
options = options || this.options.labelsMarkers;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
$$A.extend(true, this.options, { labelsMarkers: options });
if (this.options.labelsMarkers.on) {
this.markers.forEach((marker) => {
try {
marker.setLabel(this.templates.labelMarker(marker.object));
}
catch (err) {
console.error('MapSVG: Error in the "Marker Label" template');
}
});
}
else {
this.markers.forEach((marker) => {
marker.setLabel("");
});
}
}
addLayer(name) {
this.layers[name] = $$A('')[0];
this.containers.layers.appendChild(this.layers[name]);
return this.layers[name];
}
getLayer(name) {
return this.layers[name];
}
getDb() {
return this.objectsRepository;
}
getDbRegions() {
return this.regionsRepository;
}
regionAdd(svgObject) {
const region = new Region(svgObject, this);
region.setStatus(1);
this.regions.push(region);
this.regions.sort(function (a, b) {
return a.id == b.id ? 0 : +(a.id > b.id) || -1;
});
return region;
}
regionDelete(id) {
if (this.regions.findById(id)) {
this.regions.findById(id).elem.remove();
this.regions.delete(id);
}
else if ($$A("#" + id).length) {
$$A("#" + id).remove();
}
}
reloadRegions() {
this.regions.clear();
$$A(this.containers.svg).find(".mapsvg-region").removeClass("mapsvg-region");
$$A(this.containers.svg)
.find(".mapsvg-region-disabled")
.removeClass("mapsvg-region-disabled");
$$A(this.containers.svg)
.find("path, polygon, circle, ellipse, rect")
.each((index, element) => {
const elem = element;
if ($$A(elem).closest("defs").length)
return;
if (elem.getAttribute("data-stroke-width")) {
elem.style["stroke-width"] = elem.getAttribute("data-stroke-width");
}
if (elem.getAttribute("id")) {
if (!this.options.regionPrefix ||
(this.options.regionPrefix &&
elem.getAttribute("id").indexOf(this.options.regionPrefix) === 0)) {
const region = new Region(elem, this);
this.regions.push(region);
}
}
});
}
reloadRegionsFull() {
const statuses = this.regionsRepository.getSchema().getFieldByType("status");
this.regions.forEach((region) => {
const _region = this.regionsRepository.getLoaded().findById(region.id);
if (_region) {
region.setData(_region);
if (statuses && _region.status !== undefined && _region.status !== null) {
region.setStatus(_region.status);
}
}
else {
if (this.options.filters.filteredRegionsStatus ||
this.options.filters.filteredRegionsStatus === 0 ||
(this.options.menu.source === "regions" &&
this.options.menu.filterout &&
this.options.menu.filterout.field === "status" &&
this.options.menu.filterout.val) ||
this.options.menu.filterout.val === 0) {
const status = this.options.filters.filteredRegionsStatus ||
this.options.filters.filteredRegionsStatus === 0
? this.options.filters.filteredRegionsStatus
: this.options.menu.filterout.val;
region.setStatus(status);
}
}
});
this.loadDirectory();
this.setChoropleth();
this.setLayersControl();
this.setGroups();
if (this.options.labelsRegions.on) {
this.setLabelsRegions();
}
}
fixMarkersWorldScreen() {
if (this.googleMaps.map)
setTimeout(() => {
const markers = { left: 0, right: 0, leftOut: 0, rightOut: 0 };
if (this.markers.length > 1) {
this.markers.forEach((m) => {
if ($$A(m.element).offset().left <
$$A(this.containers.map).offset().left +
this.containers.map.clientWidth / 2) {
markers.left++;
if ($$A(m.element).offset().left < $$A(this.containers.map).offset().left) {
markers.leftOut++;
}
}
else {
markers.right++;
if ($$A(m.element).offset().left >
$$A(this.containers.map).offset().left +
this.containers.map.clientWidth) {
markers.rightOut++;
}
}
});
if ((markers.left === 0 && markers.rightOut) ||
(markers.right === 0 && markers.leftOut)) {
const k = markers.left === 0 ? 1 : -1;
const ww = (this.svgDefault.viewBox.width / this.converter.mapLonDelta) *
360 *
this.getScale();
this.googleMaps.map.panBy(k * ww, 0);
}
}
}, 600);
}
updateOutdatedOptions(options) {
if (options.menu && (options.menu.position || options.menu.customContainer)) {
if (options.menu.customContainer) {
options.menu.location = "custom";
}
else {
options.menu.position = options.menu.position === "left" ? "left" : "right";
options.menu.location =
options.menu.position === "left" ? "leftSidebar" : "rightSidebar";
if (!options.containers || !options.containers[options.menu.location]) {
options.containers = options.containers || {};
options.containers[options.menu.location] = { on: false, width: "200px" };
}
options.containers[options.menu.location].width = options.menu.width;
if (MapSVG.parseBoolean(options.menu.on)) {
options.containers[options.menu.location].on = true;
}
}
delete options.menu.position;
delete options.menu.width;
delete options.menu.customContainer;
}
if (options.detailsView &&
(options.detailsView.location === "mapContainer" ||
options.detailsView.location === "near" ||
options.detailsView.location === "top")) {
options.detailsView.location = "map";
}
if (!options.controls) {
options.controls = {};
options.controls.zoom =
options.zoom &&
options.zoom.on &&
(!options.zoom.buttons || options.zoom.buttons.location !== "hide");
options.controls.location =
options.zoom && options.zoom.buttons && options.zoom.buttons.location !== "hide"
? options.zoom.buttons.location
: "right";
}
if (options.colors && !options.colors.markers) {
options.colors.markers = {
base: { opacity: 100, saturation: 100 },
hovered: { opacity: 100, saturation: 100 },
unhovered: { opacity: 100, saturation: 100 },
active: { opacity: 100, saturation: 100 },
inactive: { opacity: 100, saturation: 100 },
};
}
if (options.tooltipsMode) {
options.tooltips.mode = options.tooltipsMode;
delete options.tooltipsMode;
}
if (options.popover) {
options.popovers = options.popover;
delete options.popover;
}
}
init() {
MapSVG.addInstance(this);
if (this.options.source === "") {
throw new Error("MapSVG: please provide SVG file source.");
}
this.disableAnimation();
this.setEvents(this.options.events);
this.events.trigger("beforeLoad");
if (this.options.googleMaps.apiKey &&
(this.editMode ||
this.options.googleMaps.on ||
(this.options.filters.on &&
this.options.filtersSchema &&
this.options.filtersSchema.find((f) => f.type === "distance")))) {
this.loadGoogleMapsAPI(() => {
return 1;
}, () => {
return 1;
});
}
this.containers.map.classList.add("mapsvg");
this.setCss();
if (this.options.colors && this.options.colors.background) {
this.containers.map.style.background = this.options.colors.background;
}
this.setContainers(this.options.containers);
this.setColors();
this.addLoadingMessage();
this.addLayer("markers");
this.addLayer("labels");
this.addLayer("bubbles");
this.addLayer("popovers");
this.addLayer("scrollpane");
this.loadExtensions();
$$A.ajax({ url: this.options.source + "?v=" + this.svgFileLastChanged })
.fail((resp) => {
this.svgLoadingFailed(resp);
})
.done((xmlData) => {
this.renderSvgData(xmlData);
});
return this;
}
getContainer(name) {
return this.containers[name];
}
renderSvgData(xmlData) {
const svgTag = $$A(xmlData).find("svg");
this.containers.svg = svgTag[0];
if (svgTag.attr("width") && svgTag.attr("height")) {
this.svgDefault.width = parseFloat(svgTag.attr("width").replace(/px/g, ""));
this.svgDefault.height = parseFloat(svgTag.attr("height").replace(/px/g, ""));
this.svgDefault.viewBox = svgTag.attr("viewBox")
? new ViewBox(svgTag.attr("viewBox").split(" "))
: new ViewBox(0, 0, this.svgDefault.width, this.svgDefault.height);
}
else if (svgTag.attr("viewBox")) {
this.svgDefault.viewBox = new ViewBox(svgTag.attr("viewBox").split(" "));
this.svgDefault.width = this.svgDefault.viewBox.width;
this.svgDefault.height = this.svgDefault.viewBox.height;
}
else {
const msg = "MapSVG: width/height and viewBox are missing in the SVG file. Can't parse the file because of that.";
if (this.editMode) {
alert(msg);
}
else {
console.error(msg);
}
return false;
}
this.geoViewBox = this.getGeoViewBoxFromSvgTag(this.containers.svg);
if (this.options.viewBox && this.options.viewBox.length == 4) {
this._viewBox = new ViewBox(this.options.viewBox);
}
else {
this._viewBox = new ViewBox(this.svgDefault.viewBox);
}
svgTag.attr("preserveAspectRatio", "xMidYMid meet");
svgTag.removeAttr("width");
svgTag.removeAttr("height");
$$A(this.containers.scrollpane).append(svgTag);
this.setStrokes();
this.reloadRegions();
this.setSize(this.options.width, this.options.height, this.options.responsive);
if (this.options.disableAll) {
this.setDisableAll(true);
}
this.setViewBox(this._viewBox);
this.converter = new Converter(this.containers.map, this.svgDefault.viewBox, this.viewBox);
if (this.geoViewBox) {
this.converter.setGeoViewBox(this.geoViewBox);
}
this.setResponsive(this.options.responsive);
this.setScroll(this.options.scroll, true);
this.setZoom(this.options.zoom);
this.setControls(this.options.controls);
this.setGoogleMaps();
this.setTooltips(this.options.tooltips);
this.setPopovers(this.options.popovers);
if (this.options.cursor)
this.setCursor(this.options.cursor);
this.setTemplates(this.options.templates);
this.loadExtensions();
this.filtersSchema = new Schema({ fields: this.options.filtersSchema });
this.objectsRepository.events.on("load", () => {
this.showLoadingMessage();
});
this.objectsRepository.events.on("loaded", () => {
this.setGlobalDistanceFilter();
this.fitOnDataLoadDone = false;
this.addLocations();
this.fixMarkersWorldScreen();
this.attachDataToRegions();
this.loadDirectory();
if (this.options.labelsMarkers.on) {
this.setLabelsMarkers();
}
if (this.options.templates.labelRegion.indexOf("{{objects") !== -1) {
this.setLabelsRegions();
}
if (this.options.filters.on &&
this.options.filters.source === "database" &&
this.controllers.filters &&
this.controllers.filters.hideFilters) {
this.controllers.filters.setFiltersCounter();
}
this.hideLoadingMessage();
this.events.trigger("databaseLoaded");
this.updateFiltersState();
this.setChoropleth();
});
this.objectsRepository.events.on("schemaChanged", () => {
this.objectsRepository.reload();
});
this.objectsRepository.events.on("updated", (obj) => {
this.attachDataToRegions(obj);
this.reloadRegionsFull();
});
this.objectsRepository.events.on("created", (obj) => {
this.attachDataToRegions(obj);
this.reloadRegionsFull();
});
this.objectsRepository.events.on("deleted", (id) => {
this.attachDataToRegions();
this.reloadRegionsFull();
});
this.regionsRepository.events.on("load", () => {
this.showLoadingMessage();
});
this.regionsRepository.events.on("loaded", () => {
this.hideLoadingMessage();
this.reloadRegionsFull();
if (this.options.filters.on &&
this.options.filters.source === "regions" &&
this.controllers.filters &&
this.controllers.filters.hideFilters) {
this.controllers.filters.setFiltersCounter();
}
this.events.trigger("regionsLoaded");
});
this.regionsRepository.events.on("updated", (regionData) => {
this.reloadRegionsFull();
});
this.regionsRepository.events.on("created", (regionData) => {
this.reloadRegionsFull();
});
this.regionsRepository.events.on("deleted", (regionData) => {
this.reloadRegionsFull();
});
this.setMenu();
this.setFilters();
this.setFilterOut();
this.setEventHandlers();
this.afterLoadBlockers--;
if (!this.id) {
this.finalizeMapLoading();
return;
}
if (!this.options.data_regions) {
this.regionsRepository.find().done((data) => {
this.afterLoadBlockers--;
this.finalizeMapLoading();
});
}
else {
this.regionsRepository.loadDataFromResponse(this.options.data_regions);
this.afterLoadBlockers--;
}
if (!this.options.data_objects) {
if (this.options.database.loadOnStart || this.editMode) {
this.objectsRepository.find().done((data) => {
this.afterLoadBlockers--;
this.finalizeMapLoading();
});
}
else {
this.afterLoadBlockers--;
this.finalizeMapLoading();
}
}
else {
if (this.editMode || this.options.database.loadOnStart) {
this.objectsRepository.loadDataFromResponse(this.options.data_objects);
this.afterLoadBlockers--;
}
else {
this.afterLoadBlockers--;
}
delete this.options.data_regions;
delete this.options.data_objects;
this.finalizeMapLoading();
}
}
setFilterOut() {
if (this.options.menu.filterout.field) {
const f = {};
f[this.options.menu.filterout.field] = this.options.menu.filterout.val;
if (this.options.menu.source == "regions") ;
else {
this.objectsRepository.query.setFilterOut(f);
}
}
else {
this.objectsRepository.query.setFilterOut(null);
}
}
getGeoViewBoxFromSvgTag(svgTag) {
const geo = $$A(svgTag).attr("mapsvg:geoViewBox") || $$A(svgTag).attr("mapsvg:geoviewbox");
if (geo) {
const geoParts = geo.split(" ").map((p) => parseFloat(p));
if (geoParts.length == 4) {
this.mapIsGeo = true;
this.geoCoordinates = true;
const sw = new GeoPoint(geoParts[3], geoParts[0]);
const ne = new GeoPoint(geoParts[1], geoParts[2]);
return new GeoViewBox(sw, ne);
}
}
else {
return null;
}
}
svgLoadingFailed(resp) {
if (resp.status == 404) {
let msg = "MapSVG: file not found - " +
this.options.source +
"\n\nIf you moved MapSVG from another server please read the following docs page: https://mapsvg.com/docs/installation/moving";
if (this.editMode) {
msg +=
"\n\nIf you know the correct path for the SVG file, please write it and press OK:";
const oldSvgPath = this.options.source;
const userSvgPath = prompt(msg, oldSvgPath);
if (userSvgPath !== null) {
$$A.ajax({ url: userSvgPath + "?v=" + this.svgFileLastChanged })
.fail(function () {
location.reload();
})
.done((xmlData) => {
this.options.source = userSvgPath;
this.renderSvgData(xmlData);
const mapsRepo = new MapsRepository();
mapsRepo.update(this);
});
}
else {
location.reload();
}
}
else {
console.error(msg);
}
}
else {
const msg = "MapSVG: can't load SVG file for unknown reason. Please contact support: https://mapsvg.ticksy.com";
if (this.editMode) {
alert(msg);
}
else {
console.error(msg);
}
}
}
addLoadingMessage() {
this.containers.loading = document.createElement("div");
this.containers.loading.className = "mapsvg-loading";
const loadingTextBlock = document.createElement("div");
loadingTextBlock.className = "mapsvg-loading-text";
loadingTextBlock.innerHTML = this.options.loadingText;
const spinner = document.createElement("div");
spinner.className = "spinner-border spinner-border-sm";
this.containers.loading.appendChild(spinner);
this.containers.loading.appendChild(loadingTextBlock);
this.containers.map.appendChild(this.containers.loading);
if (this.options.googleMaps.on) {
$$A(this.containers.map).addClass("mapsvg-google-map-loading");
}
}
hideLoadingMessage() {
$$A(this.containers.loading).hide();
}
showLoadingMessage() {
$$A(this.containers.loading).show();
}
disableAnimation() {
this.containers.map.classList.add("no-transitions");
}
enableAnimation() {
$$A(this.containers.map).removeClass("no-transitions");
}
loadExtensions() {
if (this.options.extension &&
$$A().mapSvg.extensions &&
$$A().mapSvg.extensions[_this.options.extension]) {
const ext = $$A().mapSvg.extensions[_this.options.extension];
ext && ext.common(this);
}
}
finalizeMapLoading() {
if (this.afterLoadBlockers > 0 || this.loaded) {
return;
}
this.selectRegionByIdFromUrl();
setTimeout(() => {
this.movingItemsAdjustScreenPosition();
this.adjustStrokes();
setTimeout(() => {
this.hideLoadingMessage();
$$A(this.containers.loading).find(".mapsvg-loading-text").hide();
this.enableAnimation();
}, 200);
}, 100);
this.loaded = true;
this.events.trigger("afterLoad");
}
selectRegionByIdFromUrl() {
const match = RegExp("[?&]mapsvg_select=([^&]*)").exec(window.location.search);
if (match) {
const select = decodeURIComponent(match[1].replace(/\+/g, " "));
this.selectRegion(select);
}
if (window.location.hash) {
const query = window.location.hash.replace("#/m/", "");
const region = this.getRegion(query);
if (region && this.options.actions.map.afterLoad.selectRegion) {
this.regionClickHandler(null, region);
}
}
}
createForm(options) {
return new FormBuilder(options);
}
getApiUrl(path) {
const server = new Server();
return server.getUrl(path);
}
getConverter() {
return this.converter;
}
setChoropleth(options) {
const _this = this;
options = options || _this.options.choropleth;
options.on != undefined && (options.on = MapSVG.parseBoolean(options.on));
$$A.extend(true, _this.options, { choropleth: options });
let needsRedraw = false;
if (!_this.$gauge) {
_this.$gauge = {};
_this.$gauge.gradient = $$A(" | ").addClass("mapsvg-gauge-gradient");
_this.setGaugeGradientCSS();
_this.$gauge.container = $$A("").addClass("mapsvg-gauge").hide();
_this.$gauge.table = $$A("");
const tr = $$A("
");
_this.$gauge.labelLow = $$A("" + _this.options.choropleth.labels.low + " | ");
_this.$gauge.labelHigh = $$A("" + _this.options.choropleth.labels.high + " | ");
tr.append(_this.$gauge.labelLow);
tr.append(_this.$gauge.gradient);
tr.append(_this.$gauge.labelHigh);
_this.$gauge.table.append(tr);
_this.$gauge.container.append(_this.$gauge.table);
$$A(_this.containers.map).append(_this.$gauge.container);
}
if (!_this.options.choropleth.on && _this.$gauge.container.is(":visible")) {
_this.$gauge.container.hide();
needsRedraw = true;
}
else if (_this.options.choropleth.on && !_this.$gauge.container.is(":visible")) {
_this.$gauge.container.show();
needsRedraw = true;
_this.regionsRepository.events.on("change", function () {
_this.redrawGauge();
});
}
if (options.colors) {
_this.options.choropleth.colors.lowRGB = tinycolor(_this.options.choropleth.colors.low).toRgb();
_this.options.choropleth.colors.highRGB = tinycolor(_this.options.choropleth.colors.high).toRgb();
_this.options.choropleth.colors.diffRGB = {
r: _this.options.choropleth.colors.highRGB.r -
_this.options.choropleth.colors.lowRGB.r,
g: _this.options.choropleth.colors.highRGB.g -
_this.options.choropleth.colors.lowRGB.g,
b: _this.options.choropleth.colors.highRGB.b -
_this.options.choropleth.colors.lowRGB.b,
a: _this.options.choropleth.colors.highRGB.a -
_this.options.choropleth.colors.lowRGB.a,
};
needsRedraw = true;
_this.$gauge && _this.setGaugeGradientCSS();
}
if (options.labels) {
_this.$gauge.labelLow.html(_this.options.choropleth.labels.low);
_this.$gauge.labelHigh.html(_this.options.choropleth.labels.high);
}
needsRedraw && _this.redrawGauge();
}
redrawGauge() {
const _this = this;
_this.updateGaugeMinMax();
_this.regionsRedrawColors();
}
updateGaugeMinMax() {
const _this = this;
_this.options.choropleth.min = 0;
_this.options.choropleth.max = false;
const values = [];
_this.regions.forEach(function (r) {
const gauge = r.data && r.data[_this.options.regionChoroplethField];
gauge != undefined && values.push(gauge);
});
if (values.length > 0) {
_this.options.choropleth.min = values.length == 1 ? 0 : Math.min.apply(null, values);
_this.options.choropleth.max = Math.max.apply(null, values);
_this.options.choropleth.maxAdjusted =
_this.options.choropleth.max - _this.options.choropleth.min;
}
}
setGaugeGradientCSS() {
const _this = this;
_this.$gauge.gradient.css({
background: "linear-gradient(to right," +
_this.options.choropleth.colors.low +
" 1%," +
_this.options.choropleth.colors.high +
" 100%)",
filter: 'progid:DXImageTransform.Microsoft.gradient( startColorstr="' +
_this.options.choropleth.colors.low +
'", endColorstr="' +
_this.options.choropleth.colors.high +
'",GradientType=1 )',
});
}
get $map() {
return $$A(this.getContainer("map"));
}
get $svg() {
return $$A(this.getContainer("svg"));
}
get $popover() {
return $$A(this.getContainer("popover"));
}
get $details() {
return $$A(this.getContainer("detailsView"));
}
get $directory() {
return $$A(this.getContainer("directory"));
}
get database() {
return this.objectsRepository;
}
get regionsDatabase() {
return this.regionsRepository;
}
}
exports.MapSVGMap = MapSVGMap;
exports.arrayIndexed = ArrayIndexed;
exports.customObject = CustomObject;
exports.formBuilder = FormBuilder;
exports.geoPoint = GeoPoint;
exports.globals = MapSVG;
exports.location = Location;
exports.map = MapSVGMap;
exports.mapsRepository = MapsRepository;
exports.mapsV2Repository = MapsV2Repository;
exports.marker = Marker;
exports.query = Query;
exports.repository = Repository;
exports.schema = Schema;
exports.schemaRepository = SchemaRepository;
exports.screenPoint = ScreenPoint;
exports.server = Server;
exports.svgPoint = SVGPoint;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=mapsvg-front.umd.js.map