-
Notifications
You must be signed in to change notification settings - Fork 7
/
base-modal-dialog.js
122 lines (96 loc) · 3.3 KB
/
base-modal-dialog.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/**
* BaseModalDialog creates a dialog and handles esc key to close it. It also
* includes open/close animation.
* The template is shown below:
* <smart-dialog class="modal-dialog">
* <div class="outer-container">
* <div class="container"></div>
* </div>
* </smart-dialog>
*/
(function(exports) {
'use strict';
function BaseModalDialog(container) {
// Determine whether this dialog is opened or not
this.isOpened = false;
// smart-dialog helps us to handle ESC key to close the dialog.
this.element = document.createElement('smart-dialog');
this.element.classList.add('modal-dialog');
this.element.setAttribute('role', 'dialog');
// make dialog focusable in order to catch focus from mouse click or touch
// event.
this.element.setAttribute('tabIndex', '-1');
// in order to make vertical align, we need additional container
this.outerContainer = document.createElement('div');
this.outerContainer.classList.add('outer-container');
this.innerContainer = document.createElement('div');
this.innerContainer.classList.add('container');
this.outerContainer.appendChild(this.innerContainer);
this.element.appendChild(this.outerContainer);
this.container = container || document.body;
this.container.appendChild(this.element);
this._init();
}
var proto = Object.create(SmartDialog.prototype);
proto._render = function() {
// implement rendering here.
};
proto._init = function(container, options) {
// Put your custom init code here.
};
proto._setL10n = function(element, l10n) {
if ((typeof l10n) === 'string') {
element.setAttribute('data-l10n-id', l10n);
} else if (navigator.mozL10n) {
navigator.mozL10n.setAttributes(element, l10n.id, l10n.args);
}
};
proto._open = function(options) {
// If you want to override this, please call this at function at the end of
// yours.
// onCancel is triggered when ESC key is pressed.
this.onCancel = options.onCancel || function() {};
this.element.classList.add('visible');
this.element.open();
this.element.focus();
};
proto.open = function(options) {
if (this.isOpened) {
return;
}
this.isOpened = true;
// We should wait two frames for reflow.
window.requestAnimationFrame(function() {
window.requestAnimationFrame(this._open.bind(this, options));
}.bind(this));
};
proto.close = function() {
this.element.close();
this.element.focus();
};
proto.remove = function() {
this.container.removeChild(this.element);
};
proto._focusContent = function() {};
proto._blurContent = function() {};
proto.focus = function() {
if (this.element.classList.contains('opening') ||
this.element.classList.contains('closing')) {
this.element.focus();
} else {
this._focusContent();
}
};
proto.blur = function() {
this._blurContent();
};
proto.fireEvent = function smd_fireEvent(event, detail) {
var evtObject = new CustomEvent(event, {
bubbles: true,
detail: detail || this
});
this.container.dispatchEvent(evtObject);
};
BaseModalDialog.prototype = proto;
exports.BaseModalDialog = BaseModalDialog;
})(window);