Remove LOAD_SUB_FRAME load flag.
[chromium-blink-merge.git] / third_party / polymer / components / core-layout-grid / core-layout-grid.html
blobb74b84c66cea098e36b7d87ebed0e902990e43e3
1 <!--
2 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
4 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
5 The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
6 Code distributed by Google as part of the polymer project is also
7 subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
8 -->
11 <!--
12 @group Polymer Core Elements
14 @element core-layout-grid
15 @status beta
16 @homepage github.io
18 TODO
19 -->
20 <link rel="import" href="../polymer/polymer.html">
22 <polymer-element name="core-layout-grid" attributes="nodes layout auto">
23 <script>
24 (function() {
26 Polymer('core-layout-grid', {
28 nodes: null,
29 layout: null,
30 auto: false,
32 created: function() {
33 this.layout = [];
36 nodesChanged: function() {
37 this.invalidate();
40 layoutChanged: function() {
41 this.invalidate();
44 autoNodes: function() {
45 this.nodes = this.parentNode.children.array().filter(
46 function(node) {
47 switch(node.localName) {
48 case 'core-layout-grid':
49 case 'style':
50 return false;
52 return true;
57 invalidate: function() {
58 if (this.layout && this.layout.length) {
59 // job debounces layout, only letting it occur every N ms
60 this.layoutJob = this.job(this.layoutJob, this.relayout);
64 relayout: function() {
65 if (!this.nodes || this.auto) {
66 this.autoNodes();
68 layout(this.layout, this.nodes);
69 this.asyncFire('core-layout');
72 });
76 var lineParent;
78 function line(axis, p, d) {
79 var l = document.createElement('line');
80 var extent = (axis === 'left' ? 'width' :
81 (axis === 'top' ? 'height' : axis));
82 l.setAttribute('extent', extent);
83 if (d < 0) {
84 axis = (axis === 'left' ? 'right' :
85 (axis === 'top' ? 'bottom' : axis));
87 p = Math.abs(p);
88 l.style[axis] = p + 'px';
89 l.style[extent] = '0px';
90 lineParent.appendChild(l);
93 var colCount, colOwners, rowCount, rowOwners;
95 function matrixillate(matrix) {
96 // mesaure the matrix, must be rectangular
97 rowCount = matrix.length;
98 colCount = rowCount && matrix[0].length || 0;
99 // transpose matrix
100 var transpose = [];
101 for (var i=0; i<colCount; i++) {
102 var c = [];
103 for (var j=0; j<rowCount; j++) {
104 c.push(matrix[j][i]);
106 transpose.push(c);
108 // assign sizing control
109 colOwners = findOwners(matrix);
110 rowOwners = findOwners(transpose);
111 //console.log('colOwners', colOwners);
112 //console.log('rowOwners', rowOwners);
115 function findOwners(matrix) {
116 var majCount = matrix.length;
117 var minCount = majCount && matrix[0].length || 0;
118 var owners = [];
119 // for each column (e.g.)
120 for (var i=0; i<minCount; i++) {
121 // array of contained areas
122 var contained = {};
123 // look at each row to find a containing area
124 for (var j=0; j<majCount; j++) {
125 // get the row vector
126 var vector = matrix[j]
127 // node index at [i,j]
128 var nodei = vector[i];
129 // if a node is there
130 if (nodei) {
131 // determine if it bounds this column
132 var owns = false;
133 if (i === 0) {
134 owns = (i === minCount-1) || (nodei !== vector[i+1]);
135 } else if (i === minCount - 1) {
136 owns = (i === 0) || (nodei !== vector[i-1]);
137 } else {
138 owns = nodei !== vector[i-1] && nodei !== vector[i+1];
140 if (owns) {
141 contained[nodei] = 1;
144 // store the owners for this column
145 owners[i] = contained;
148 return owners;
151 var nodes;
153 function colWidth(i) {
154 for (var col in colOwners[i]) {
155 col = Number(col);
156 if (col === 0) {
157 return 96;
159 var node = nodes[col - 1];
160 if (node.hasAttribute('h-flex') || node.hasAttribute('flex')) {
161 return -1;
163 var w = node.offsetWidth;
164 //console.log('colWidth(' + i + ') ==', w);
165 return w;
167 return -1;
170 function rowHeight(i) {
171 for (var row in rowOwners[i]) {
172 row = Number(row);
173 if (row === 0) {
174 return 96;
176 var node = nodes[row - 1];
177 if (node.hasAttribute('v-flex') || node.hasAttribute('flex')) {
178 return -1;
180 var h = node.offsetHeight;
181 //console.log('rowHeight(' + i + ') ==', h);
182 return h;
184 return -1;
187 var m = 0;
189 function railize(count, sizeFn) {
191 // create rails for `count` tracks using
192 // sizing function `sizeFn(trackNo)`
194 // for n tracks there are (n+1) rails
196 // |track|track|track|
197 // 0|->sz0|->sz1|<-sz2|0
199 // |track|track|track|
200 // 0|->sz0| |<-sz2|0
202 // there can be one elastic track per set
204 // |track|track|track|track|
205 // 0|-->s0|-->s1|<--s1|<--s2|0
207 // sz1 spans multiple tracks which makes
208 // it elastic (it's underconstrained)
210 var rails = [];
211 var a = 0;
212 for (var i=0, x; i<count; i++) {
213 rails[i] = {p: a, s: 1};
214 x = sizeFn(i) + m + m;
215 if (x == -1) {
216 break;
218 a += x;
220 if (i === count) {
221 rails[i] = {p: 0, s: -1};
223 var b = 0;
224 for (var ii=count, x; ii>i; ii--) {
225 rails[ii] = {p: b, s: -1};
226 x = sizeFn(ii - 1) + m + m;
227 if (x !== -1) {
228 b += x;
231 return rails;
234 // TODO(sjmiles): this code tries to preserve actual position,
235 // so 'unposition' is really 'naturalize' or something
236 function unposition(box) {
237 var style = box.style;
238 //style.right = style.bottom = style.width = style.height = '';
239 style.position = 'absolute';
240 style.display = 'inline-block';
241 style.boxSizing = style.mozBoxSizing = 'border-box';
244 function _position(style, maj, min, ext, a, b) {
245 style[maj] = style[min] = '';
246 style[ext] = 'auto';
247 if (a.s < 0 && b.s < 0) {
248 var siz = a.p - b.p - m - m;
249 style[ext] = siz + 'px';
250 var c = 'calc(100% - ' + (b.p + siz + m) + 'px' + ')';
251 style[maj] = '-webkit-' + c;
252 style[maj] = c;
253 } else if (b.s < 0) {
254 style[maj] = a.p + m + 'px';
255 style[min] = b.p + m + 'px';
256 } else {
257 style[maj] = a.p + m + 'px';
258 style[ext] = b.p - a.p - m - m + 'px';
262 function position(elt, left, right, top, bottom) {
263 _position(elt.style, 'top', 'bottom', 'height', rows[top],
264 rows[bottom]);
265 _position(elt.style, 'left', 'right', 'width', columns[left],
266 columns[right]);
269 function layout(matrix, anodes, alineParent) {
270 //console.group('layout');
272 lineParent = alineParent;
273 nodes = anodes;
274 matrixillate(matrix);
276 nodes.forEach(unposition);
278 columns = railize(colCount, colWidth);
279 rows = railize(rowCount, rowHeight);
281 if (alineParent) {
282 //console.group('column rails');
283 columns.forEach(function(c) {
284 //console.log(c.p, c.s);
285 line('left', c.p, c.s);
287 //console.groupEnd();
289 //console.group('row rails');
290 rows.forEach(function(r) {
291 //console.log(r.p, r.s);
292 line('top', r.p, r.s);
294 //console.groupEnd();
297 //console.group('rail boundaries');
298 nodes.forEach(function(node, i) {
299 // node indices are 1-based
300 var n = i + 1;
301 // boundary rails
302 var l, r, t = 1e10, b = -1e10;
303 matrix.forEach(function(vector, i) {
304 var f = vector.indexOf(n);
305 if (f > -1) {
306 l = f;
307 r = vector.lastIndexOf(n) + 1;
308 t = Math.min(t, i);
309 b = Math.max(b, i) + 1;
312 if (l == undefined) {
313 //console.log('unused');
314 node.style.position = 'absolute';
315 var offscreen = node.getAttribute('offscreen');
316 switch (offscreen) {
317 case 'basement':
318 node.style.zIndex = 0;
319 break;
320 case 'left':
321 case 'top':
322 node.style[offscreen] = node.offsetWidth * -2 + 'px';
323 break;
324 case 'right':
325 node.style.left = node.offsetParent.offsetWidth
326 + node.offsetWidth + 'px';
327 break;
328 case 'bottom':
329 node.style.top = node.parentNode.offsetHeight
330 + node.offsetHeight + 'px';
331 break;
332 default:
333 node.style[Math.random() >= 0.5 ? 'left' : 'top'] = '-110%';
335 //node.style.opacity = 0;
336 node.style.pointerEvents = 'none';
337 } else {
338 node.style.pointerEvents = '';
339 //node.style.opacity = '';
340 //console.log(l, r, t, b);
341 position(node, l, r, t, b);
344 //console.groupEnd();
345 //console.groupEnd();
348 })();
349 </script>
350 </polymer-element>