2019-10-26 23:30:01 +00:00
|
|
|
import ngModule from '../../module';
|
|
|
|
import Component from '../../lib/component';
|
|
|
|
import './style.scss';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Base class for windows displayed over application content.
|
|
|
|
*/
|
|
|
|
export default class Popup extends Component {
|
2020-04-25 09:50:04 +00:00
|
|
|
constructor(...args) {
|
|
|
|
super(...args);
|
2019-10-26 23:30:01 +00:00
|
|
|
this._shown = false;
|
|
|
|
this.displayMode = 'centered';
|
|
|
|
}
|
|
|
|
|
|
|
|
$onDestroy() {
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @type {Boolean} Wether to show or hide the popup.
|
|
|
|
*/
|
|
|
|
get shown() {
|
|
|
|
return this._shown;
|
|
|
|
}
|
|
|
|
|
|
|
|
set shown(value) {
|
|
|
|
if (value)
|
|
|
|
this.show();
|
|
|
|
else
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-05-08 11:23:06 +00:00
|
|
|
* Displays the popup.
|
2019-10-26 23:30:01 +00:00
|
|
|
*/
|
|
|
|
show() {
|
|
|
|
if (this.shown) return;
|
|
|
|
this._shown = true;
|
|
|
|
|
2019-11-10 10:08:44 +00:00
|
|
|
if (this.closeTimeout) {
|
|
|
|
this.$timeout.cancel(this.closeTimeout);
|
|
|
|
this.onClose();
|
|
|
|
}
|
|
|
|
|
2019-10-26 23:30:01 +00:00
|
|
|
this.$contentScope = this.$.$new();
|
2020-05-06 12:38:09 +00:00
|
|
|
this.contentLinkFn(
|
|
|
|
this.$contentScope,
|
|
|
|
element => this.popup = element[0],
|
2019-10-26 23:30:01 +00:00
|
|
|
{parentBoundTranscludeFn: this.$transclude}
|
2020-05-06 12:38:09 +00:00
|
|
|
);
|
2020-04-25 09:50:04 +00:00
|
|
|
|
2019-10-28 16:31:33 +00:00
|
|
|
this.windowEl = this.popup.querySelector('.window');
|
2020-04-01 14:05:43 +00:00
|
|
|
this.windowEl.focus();
|
2019-10-26 23:30:01 +00:00
|
|
|
|
|
|
|
let classList = this.popup.classList;
|
|
|
|
classList.add(this.displayMode);
|
|
|
|
classList.add(...this.constructor.$classNames);
|
|
|
|
|
2019-11-12 07:51:50 +00:00
|
|
|
this.document.body.appendChild(this.popup);
|
2019-10-26 23:30:01 +00:00
|
|
|
|
|
|
|
this.keyDownHandler = e => this.onkeyDown(e);
|
|
|
|
this.document.addEventListener('keydown', this.keyDownHandler);
|
|
|
|
|
|
|
|
this.deregisterCallback = this.$transitions.onStart({},
|
|
|
|
() => this.hide());
|
|
|
|
|
2019-11-10 10:08:44 +00:00
|
|
|
this.$timeout.cancel(this.showTimeout);
|
|
|
|
this.showTimeout = this.$timeout(() => {
|
|
|
|
this.showTimeout = null;
|
2019-10-26 23:30:01 +00:00
|
|
|
classList.add('shown');
|
|
|
|
}, 10);
|
|
|
|
|
|
|
|
this.emit('open');
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-05-08 11:23:06 +00:00
|
|
|
* Hides the popup.
|
2019-10-26 23:30:01 +00:00
|
|
|
*/
|
|
|
|
hide() {
|
|
|
|
if (!this.shown) return;
|
2019-11-12 07:51:50 +00:00
|
|
|
this._shown = false;
|
2019-10-26 23:30:01 +00:00
|
|
|
|
|
|
|
this.document.removeEventListener('keydown', this.keyDownHandler);
|
|
|
|
this.keyDownHandler = null;
|
|
|
|
|
2019-11-10 10:08:44 +00:00
|
|
|
this.deregisterCallback();
|
|
|
|
this.deregisterCallback = null;
|
2019-10-26 23:30:01 +00:00
|
|
|
|
|
|
|
this.popup.classList.remove('shown');
|
|
|
|
|
2019-11-10 10:08:44 +00:00
|
|
|
this.closeTimeout = this.$timeout(
|
2019-10-28 16:31:33 +00:00
|
|
|
() => this.onClose(), 200);
|
2019-10-26 23:30:01 +00:00
|
|
|
|
|
|
|
this.lastEvent = null;
|
|
|
|
this.emit('closeStart');
|
|
|
|
}
|
|
|
|
|
2020-05-08 11:23:06 +00:00
|
|
|
/**
|
|
|
|
* Called when closing transition ends and popup is not visible, it can
|
|
|
|
* be overriden by child classes (calling the super) to perform additional
|
|
|
|
* actions.
|
|
|
|
*/
|
2019-10-28 16:31:33 +00:00
|
|
|
onClose() {
|
2019-11-10 10:08:44 +00:00
|
|
|
this.closeTimeout = null;
|
2019-10-28 16:31:33 +00:00
|
|
|
this.popup.remove();
|
|
|
|
this.popup = null;
|
2019-11-10 13:13:55 +00:00
|
|
|
this.$contentScope.$destroy();
|
2019-11-12 08:24:01 +00:00
|
|
|
this.$contentScope = null;
|
2019-10-28 16:31:33 +00:00
|
|
|
this.windowEl = null;
|
|
|
|
this.emit('close');
|
|
|
|
}
|
|
|
|
|
2019-10-26 23:30:01 +00:00
|
|
|
onWindowMouseDown(event) {
|
|
|
|
this.lastEvent = event;
|
|
|
|
}
|
|
|
|
|
|
|
|
onBgMouseDown(event) {
|
|
|
|
if (!event.defaultPrevented && event != this.lastEvent)
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
onkeyDown(event) {
|
|
|
|
if (!event.defaultPrevented && event.key == 'Escape')
|
|
|
|
this.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Popup.$inject = ['$element', '$scope', '$transclude'];
|
|
|
|
|
|
|
|
ngModule.vnComponent('vnPopup', {
|
|
|
|
controller: Popup,
|
|
|
|
transclude: true,
|
|
|
|
bindings: {
|
|
|
|
shown: '=?'
|
2020-04-25 09:50:04 +00:00
|
|
|
},
|
|
|
|
installClasses: false
|
2019-10-26 23:30:01 +00:00
|
|
|
});
|
2020-05-06 12:38:09 +00:00
|
|
|
|
|
|
|
ngModule.run(['$compile', function($compile) {
|
|
|
|
Popup.prototype.contentLinkFn = $compile(require('./index.html'));
|
|
|
|
}]);
|