forked from smart-components/smart-dialog
-
Notifications
You must be signed in to change notification settings - Fork 1
/
script.js
124 lines (111 loc) · 3.83 KB
/
script.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
123
124
/**
* fxos-tv-dialog
* - Event:
* 1. will-open
* 2. opened
* 3. will-close
* 4. closed
* - API:
* 1. open - open a fxos-tv-dialog: closed -> opening -> opened
* 2. close - close a fxos-tv-dialog: opened -> closing -> closed
* - Attribute:
* 1. title - title of the fxos-tv-dialog
* 2. esc-close - close dialog when ESC key is clicked (default true).
* Default scale: 1920x1080 (2*sqrt(960*960 + 1080*1080) / 20 = 144.5)
*/
window.FxosTvDialog = (function(win) {
'use strict';
// The value of openDuration and closeDuration should be the same as
// transitionDuration in opening and closing css class.
const openDuration = 1000;
const closeDuration = 650;
// Extend from the HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
proto.createdCallback = function sd_createdCallback() {
this.addEventListener('transitionend', this);
document.addEventListener('keyup', this);
this.transitionTimer = null;
this.classList.add('closed');
if (this.hasAttribute('background-color')) {
this.style.backgroundColor = this.getAttribute('background-color');
}
};
proto._onOpened = function sd_onOpened() {
this.classList.remove('opening');
this.classList.add('opened');
this.fireEvent('opened');
};
proto._onClosed = function sd_onClosed() {
this.classList.remove('closing');
this.classList.add('closed');
this.fireEvent('closed');
};
proto.open = function sd_open() {
if (this.classList.contains('opened') ||
this.classList.contains('opening')) {
return;
}
this.fireEvent('will-open');
this.classList.remove('closing');
this.classList.remove('closed');
this.classList.add('opening');
// handle the case when transitionend event is not fired
clearTimeout(this.transitionTimer);
this.transitionTimer = setTimeout(function() {
this._onOpened();
this.transitionTimer = null;
}.bind(this), openDuration);
};
proto.close = function sd_close() {
if (this.classList.contains('closed') ||
this.classList.contains('closing')) {
return;
}
this.fireEvent('will-close');
this.classList.remove('opening');
this.classList.remove('opened');
this.classList.add('closing');
// handle the case when transitionend event is not fired
clearTimeout(this.transitionTimer);
this.transitionTimer = setTimeout(function() {
this._onClosed();
this.transitionTimer = null;
}.bind(this), closeDuration);
};
proto.handleEvent = function sd_handleEvent(evt) {
switch(evt.type) {
case 'transitionend':
if (evt.target === this && this.transitionTimer) {
if (this.classList.contains('opening')) {
this._onOpened();
} else if (this.classList.contains('closing')) {
this._onClosed();
}
clearTimeout(this.transitionTimer);
this.transitionTimer = null;
}
break;
case 'keyup':
// close dialog when Back is triggered
if (this.getAttribute('esc-close') != 'false' &&
(evt.keyCode === 27 || evt.key === 'Esc') &&
(evt.keyCode === window.KeyEvent.DOM_VK_BACK_SPACE ||
evt.key === 'Backspace') &&
this.classList.contains('opened')) {
evt.preventDefault();
evt.stopPropagation();
this.close();
}
break;
}
};
proto.fireEvent = function sd_fireEvent(event, detail) {
var evtObject = new CustomEvent(event, {
bubbles: false,
detail: detail || this
});
this.dispatchEvent(evtObject);
};
// Register and return the constructor
return document.registerElement('fxos-tv-dialog', { prototype: proto });
})(window);