-
Notifications
You must be signed in to change notification settings - Fork 2
/
script.js
178 lines (160 loc) · 4.77 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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
(function(define){'use strict';define(function(require,exports,module){
/*globals define*//*jshint node:true*/
/**
* Locals
*/
var baseComponents = window.COMPONENTS_BASE_URL || 'bower_components/';
var base = window.GAIA_DRAWER_BASE_URL || baseComponents + 'gaia-drawer/';
// Extend from the HTMLElement prototype
var proto = Object.create(HTMLElement.prototype);
/**
* Runs when an instance of the
* element is first created.
*
* When use this moment to create the
* shadow-dom, inject our template
* content, setup event listeners
* and set the draw state to match
* the initial `open` attribute.
*
* @private
*/
proto.createdCallback = function() {
var root = this.createShadowRoot();
var html = template.content.cloneNode(true);
// Fetch some els
this.els = {};
this.els.background = html.querySelector('.background');
this.els.content = html.querySelector('.main');
this.els.inner = html.querySelector('.inner');
this.attachEvents();
this.toggle(this.hasAttribute('open'));
// Put content in the shadow-dom
root.appendChild(html);
this.styleHack();
};
/**
* Load in the the component's styles.
*
* We're working around a few platform bugs
* here related to @import in the shadow-dom
* stylesheet. When HTML-Imports are ready
* we won't have to use @import anymore.
*
* @private
*/
proto.styleHack = function() {
var style = document.createElement('style');
var self = this;
this.style.visibility = 'hidden';
style.innerHTML = '@import url(' + base + 'style.css);';
style.setAttribute('scoped', '');
this.classList.add('content', 'host');
this.appendChild(style);
// There are platform issues around using
// @import inside shadow root. Ensuring the
// stylesheet has loaded before putting it in
// the shadow root seems to work around this.
style.addEventListener('load', function() {
self.shadowRoot.appendChild(style.cloneNode(true));
self.style.visibility = '';
self.styled = true;
self.dispatchEvent(new CustomEvent('styled'));
});
};
/**
* Runs when any attribute changes
* on the element.
*
* We only support the `open` attribute,
* so we ignore all others. We then toggle,
* opening the drawer for all values other
* than `null` (which means the attribute
* was removed).
*
* @param {String} attr
* @param {String|null} oldVal
* @param {String|null} newVal
* @private
*/
proto.attributeChangedCallback = function(attr, oldVal, newVal) {
if (attr !== 'open') { return; }
this.toggle(newVal !== null);
};
proto.attachEvents = function() {
this.els.background.addEventListener('click', this.close.bind(this));
this.els.content.addEventListener('click', function(e) {
e.stopPropagation();
});
};
/**
* Toggle the drawer open/closed.
*
* If a value is passed, we ignore the
* current `open` value and just derive
* the state from the value given (similar
* to how `classList.toggle` works).
*
* @param {Boolean} value
* @public
*/
proto.toggle = function(value) {
value = arguments.length ? value : !this.hasAttribute('open');
if (value) { this.open(); }
else { this.close(); }
};
/**
* Open the drawer.
*
* We have to also duplicate the
* attribute on the `.inner` element
* inside the shadow-root as we are
* currently missing the `:host`
* selector from the platform.
*
* @public
*/
proto.open = function() {
this.setAttribute('open', '');
this.els.inner.setAttribute('open', '');
};
/**
* Close the drawer.
*
* We have to also duplicate the
* attribute on the `.inner` element
* inside the shadow-root as we are
* currently missing the `:host`
* selector from the platform.
*
* @public
*/
proto.close = function() {
this.removeAttribute('open');
this.els.inner.removeAttribute('open');
};
// HACK: Create a <template> in memory at runtime.
// When the custom-element is created we clone
// this template and inject into the shadow-root.
// Prior to this we would have had to copy/paste
// the template into the <head> of every app that
// wanted to use <gaia-header>, this would make
// markup changes complicated, and could lead to
// things getting out of sync. This is a short-term
// hack until we can import entire custom-elements
// using HTML Imports (bug 877072).
var template = document.createElement('template');
template.innerHTML = [
'<div class="inner">',
'<div class="background"></div>',
'<div class="main">',
'<content></content>',
'</div>',
'</div>'
].join('');
// Register and return the constructor
module.exports = document.registerElement('gaia-drawer', { prototype: proto });
});})((function(n,w){'use strict';return typeof define=='function'&&define.amd?
define:typeof module=='object'?function(c){c(require,exports,module);}:
function(c){var m={exports:{}},r=function(n){return w[n];};
w[n]=c(r,m.exports,m)||m.exports;};})('gaia-drawer',this));