-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathakyral-element-query.html
209 lines (178 loc) · 5.54 KB
/
akyral-element-query.html
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
<link rel="import" href="../polymer/polymer.html">
<!--
A utility element that implements element queries to its parent node.
## Using the element
`akyral-element-query` requires a `query` attribute to be defined. You can define
single query or a JSON array of multiple queries (note the use of a single quote
in the queries attribute)
####Example:
<akyral-element-query
query="(min-width:320px) and (max-width:480px)">
</akyral-element-query>
####Example:
<akyral-element-query
queries="['(min-width:320px) and (max-width:480px)',
'(min-width:481px) and (max-width:720px)',
'(min-width:721px) and (max-width:944px)',
'(min-width:945px) and (max-width:1264px)']">
</akyral-element-query>
@element akyral-element-query
@blurb Element that implements element queries to its parent node.
@demo http://filaraujo.github.io/akyral.io/element-query/index.html
@homepage https://github.com/filaraujo/akyral-element-query
-->
<!--
Fired when an element query changes, also fired on element load. Passes the
`media` value within the event details. The akyral-element-query also has
`media` property defining the current selected query.
@event element-query-change
-->
<polymer-element name="akyral-element-query">
<template>
<style>
: host {
bottom: 0;
display: block;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
top: 0;
z-index: -1;
}
object {
width: 100%;
height: 100%;
}
</style>
<template if="[[queries]]">
<object id="obj" type="text/html" on-load="{{loaded}}"></object>
</template>
</template>
<script>
(function() {
var baseStyles = [,
'html, body { margin: 0; padding: 0 }',
'div { transition: opacity 0.01s; opacity: 0;}'
],
authors = ['Filipe Araujo'];
/**
* The `buildDOM` method contructs the media query nodes and styles to
* test against.
*
* @method buildDOM
* @returns object
* @private
*/
function buildDOM() {
var nodes = [],
styles = [].concat(baseStyles);
// convert to array
this.queries = [].concat.apply([], [this.queries]);
this.queries.forEach(function(v, index) {
nodes.push('<div query="' + v + '"></div>');
styles.push('@media ' + v + ' { [query="' + v + '"] { opacity: 1; }}');
});
return {
styles: styles,
nodes: nodes
};
}
// define polymer component
Polymer('akyral-element-query', {
publish: {
/**
* `media` attribute is set by the element when a query changes.
* This attribute is reflected.
*
* @attribute media
* @type string
* @default undefined
*/
media: {
reflect: true,
value: undefined
},
/**
* `queries` attribute defines the media queries to test against.
*
* @attribute queries
* @type array or string
* @default []
*/
queries: []
},
/**
* The `author` attribute defines the initial author, setting
* this value will add another author
*
* @attribute author
* @type string
* @default 'Filipe Araujo'
*/
set author(name) {
if (authors.indexOf(name) > 0) {
return;
}
authors = [].concat.apply(authors, [name]);
},
get author() {
return authors;
},
/**
* The `loaded` method handles object dom creation. This method will
* inject the styles and node into the document as well as bind the
* handlers.
*
* @method loaded
*/
loaded: function(e) {
var doc = this.$.obj.contentDocument,
dom = buildDOM.bind(this)(),
style = doc.createElement('style');
style.innerHTML = dom.styles.join('');
doc.head.appendChild(style);
doc.body.innerHTML = dom.nodes.join('');
doc.addEventListener('transitionend', this.update.bind(this));
this.async(this.update);
},
/**
* The `update` method will set the media attribute and fire the
* `element-query-change` event.
*
* @method update
*/
update: function(e) {
var objWindow = this.$.obj.contentDocument.defaultView.window,
viewport = this.queries.filter(function(view) {
return objWindow.matchMedia(view).matches;
});
viewport = viewport[0] || '';
this.job('event', function() {
this.fire('element-query-change', {
media: viewport
});
}, 250);
this.job('attribute', function() {
this.media = viewport;
}, 150);
},
/**
* The `<polymer-element>` has been fully prepared (e.g. Shadow DOM
* created, property observers setup, event listeners attached, etc).
*
* @method ready
*/
ready: function() {
/*
* IE doesn't handle object tag with data attribute well
* needs to be defined after the fact
*/
this.async(function() {
this.$.obj.data = 'about:blank';
}, 100);
}
});
}());
</script>
</polymer-element>