161 lines
4.7 KiB
JavaScript
161 lines
4.7 KiB
JavaScript
import ol_ext_element from '../element.js';
|
|
import ol_ext_input_Base from './Base.js'
|
|
|
|
/** Base class for input popup
|
|
* @constructor
|
|
* @extends {ol_ext_input_Base}
|
|
* @fires change:color
|
|
* @fires color
|
|
* @param {*} options
|
|
* @param {string} [options.className]
|
|
* @param {ol.colorLike} [options.color] default color
|
|
* @param {Element} [options.input] input element, if non create one
|
|
* @param {Element} [options.parent] parent element, if create an input
|
|
* @param {string} [options.position='popup'] fixed | static | popup | inline (no popup)
|
|
* @param {boolean} [options.autoClose=true] close when click on color
|
|
* @param {boolean} [options.hidden=false] display the input
|
|
*/
|
|
var ol_ext_input_PopupBase = class olextinputPopupBase extends ol_ext_input_Base {
|
|
constructor(options) {
|
|
options = options || {};
|
|
|
|
options.hidden = options.hidden !== false;
|
|
super(options);
|
|
|
|
this.set('autoClose', options.autoClose !== false);
|
|
|
|
this.element = ol_ext_element.create('DIV', {
|
|
className: ('ol-ext-popup-input ' + (options.className || '')).trim(),
|
|
tabindex: 0,
|
|
on: {
|
|
keydown: function(e) {
|
|
this._handleKey(e)
|
|
}.bind(this)
|
|
}
|
|
});
|
|
switch (options.position) {
|
|
case 'inline': break;
|
|
case 'static':
|
|
case 'fixed': {
|
|
this.element.classList.add('ol-popup');
|
|
this.element.classList.add('ol-popup-fixed');
|
|
this._fixed = (options.position === 'fixed');
|
|
break;
|
|
}
|
|
default: {
|
|
this.element.classList.add('ol-popup');
|
|
break;
|
|
}
|
|
}
|
|
|
|
var input = this.input;
|
|
if (input.parentNode)
|
|
input.parentNode.insertBefore(this.element, input);
|
|
|
|
// Show on element click
|
|
this.element.addEventListener('click', function () {
|
|
if (this.isCollapsed())
|
|
setTimeout(function () { this.collapse(false); }.bind(this));
|
|
}.bind(this));
|
|
|
|
this._elt = {};
|
|
// Popup container
|
|
this._elt.popup = ol_ext_element.create('DIV', { className: 'ol-popup', parent: this.element });
|
|
this._elt.popup.addEventListener('click', function (e) { e.stopPropagation(); });
|
|
|
|
// Hide on click outside
|
|
var down = false;
|
|
this._elt.popup.addEventListener('pointerdown', function () {
|
|
down = true;
|
|
});
|
|
this._elt.popup.addEventListener('click', function () {
|
|
down = false;
|
|
});
|
|
document.addEventListener('click', function () {
|
|
if (!this.moving && !down)
|
|
this.collapse(true);
|
|
down = false;
|
|
}.bind(this));
|
|
// Hide on window resize
|
|
window.addEventListener('resize', function () {
|
|
this.collapse(true);
|
|
}.bind(this));
|
|
}
|
|
/** Handle key pressed on input
|
|
* @private
|
|
*/
|
|
_handleKey(e) {
|
|
switch (e.key) {
|
|
case 'Enter':
|
|
case ' ':
|
|
case 'Space': {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
this.toggle();
|
|
break;
|
|
}
|
|
case 'Escape': {
|
|
e.stopPropagation();
|
|
e.preventDefault();
|
|
this.collapse(true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
/** show/hide color picker
|
|
* @param {boolean} [b=false]
|
|
*/
|
|
collapse(b) {
|
|
if (b != this.isCollapsed()) {
|
|
this.dispatchEvent({
|
|
type: 'change:visible',
|
|
visible: !this.isCollapsed()
|
|
});
|
|
}
|
|
this.dispatchEvent({
|
|
type: 'collapse',
|
|
visible: !b
|
|
});
|
|
if (b) {
|
|
this._elt.popup.classList.remove('ol-visible');
|
|
} else {
|
|
this._elt.popup.classList.add('ol-visible');
|
|
if (this._fixed) {
|
|
// Get fixed position
|
|
var pos = this.element.getBoundingClientRect();
|
|
var offset = ol_ext_element.getFixedOffset(this.element);
|
|
pos = {
|
|
bottom: pos.bottom - offset.top,
|
|
left: pos.left - offset.left
|
|
};
|
|
// Test window overflow + recenter
|
|
var dh = pos.bottom + this._elt.popup.offsetHeight + offset.top;
|
|
if (dh > document.documentElement.clientHeight) {
|
|
this._elt.popup.style.top = Math.max(document.documentElement.clientHeight - this._elt.popup.offsetHeight - offset.top, 0) + 'px';
|
|
} else {
|
|
this._elt.popup.style.top = pos.bottom + 'px';
|
|
}
|
|
var dw = pos.left + this._elt.popup.offsetWidth + offset.left;
|
|
if (dw > document.documentElement.clientWidth) {
|
|
this._elt.popup.style.left = Math.max(document.documentElement.clientWidth - this._elt.popup.offsetWidth - offset.left, 0) + 'px';
|
|
} else {
|
|
this._elt.popup.style.left = pos.left + 'px';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/** Is the popup collapsed ?
|
|
* @returns {boolean}
|
|
*/
|
|
isCollapsed() {
|
|
return !this._elt.popup.classList.contains('ol-visible');
|
|
}
|
|
/** Toggle the popup
|
|
*/
|
|
toggle() {
|
|
this.collapse(!this.isCollapsed());
|
|
}
|
|
}
|
|
|
|
export default ol_ext_input_PopupBase
|