OLD | NEW |
(Empty) | |
| 1 <!-- |
| 2 Copyright 2013 The Polymer Authors. All rights reserved. |
| 3 Use of this source code is governed by a BSD-style |
| 4 license that can be found in the LICENSE file. |
| 5 --> |
| 6 <!-- |
| 7 /** |
| 8 * @module Polymer Elements |
| 9 */ |
| 10 /** |
| 11 * `<polymer-layout>` arranges nodes horizontally via absolution positioning. |
| 12 * Set the `vertical` attribute (boolean) to arrange vertically instead. |
| 13 * |
| 14 * `<polymer-layout>` arranges it's <b>sibling elements</b>, not |
| 15 * it's children. |
| 16 * |
| 17 * One arranged node may be marked as elastic by giving it a `flex` |
| 18 * attribute (boolean). |
| 19 * |
| 20 * You may remove a node from layout by giving it a `nolayout` |
| 21 * attribute (boolean). |
| 22 * |
| 23 * CSS Notes: |
| 24 * |
| 25 * * `padding` is ignored on the parent node. |
| 26 * * `margin` is ignored on arranged nodes. |
| 27 * * `min-width` is ignored on arranged nodes, use `min-width` on the parent no
de |
| 28 * instead. |
| 29 * |
| 30 * Example: |
| 31 * |
| 32 * Arrange three `div` into columns. `flex` attribute on Column Two makes that |
| 33 * column elastic. |
| 34 * |
| 35 * <polymer-layout></polymer-layout> |
| 36 * <div>Column One</div> |
| 37 * <div flex>Column Two</div> |
| 38 * <div>Column Three</div> |
| 39 * |
| 40 * Remember that `<polymer-layout>` arranges it's sibling elements, not it's ch
ildren. |
| 41 * |
| 42 * If body has width 52 device pixels (in this case, ascii characters), call tha
t 52px. |
| 43 * Column One has it's natural width of 12px (including border), Column Three ha
s it's |
| 44 * natural width of 14px, body border uses 2px, and Column Two automatically use
s the |
| 45 * remaining space: 24px. |
| 46 * |
| 47 * |- 52px -| |
| 48 * ---------------------------------------------------- |
| 49 * ||Column One|| Column Two ||Column Three|| |
| 50 * ---------------------------------------------------- |
| 51 * |- 12px -||- (24px) -|| 14px -| |
| 52 * |
| 53 * As the parent node resizes, the elastic column reacts via CSS to adjust it's
size. |
| 54 * No javascript is used during parent resizing, for best performance. |
| 55 * |
| 56 * Changes in content or sibling size is not handled automatically. |
| 57 * |
| 58 * ---------------------------------------------------------------- |
| 59 * ||Column One| Column Two |Column Three|| |
| 60 * ---------------------------------------------------------------- |
| 61 * |
| 62 * -------------------------------------- |
| 63 * ||Column One|Column Two|Column Three|| |
| 64 * -------------------------------------- |
| 65 * |
| 66 * Arrange in rows by adding the `vertical` attribute. |
| 67 * |
| 68 * Example: |
| 69 * |
| 70 * <polymer-layout vertical></polymer-layout> |
| 71 * <div>Row One</div> |
| 72 * <div flex>Row Two</div> |
| 73 * <div>Row Three</div> |
| 74 * |
| 75 * This setup will cause Row Two to stretch to fill the container. |
| 76 * |
| 77 * ----------- ----------- |
| 78 * |---------| |---------| |
| 79 * | | | | |
| 80 * |Row One | |Row One | |
| 81 * | | | | |
| 82 * |---------| |---------| |
| 83 * | | | | |
| 84 * |Row Two | |Row Two | |
| 85 * | | | | |
| 86 * |---------| | | |
| 87 * | | | | |
| 88 * |Row Three| | | |
| 89 * | | |---------| |
| 90 * |---------| | | |
| 91 * ----------- |Row Three| |
| 92 * | | |
| 93 * |---------| |
| 94 * |---------| |
| 95 * |
| 96 * Layouts can be nested arbitrarily. |
| 97 * |
| 98 * <polymer-layout></polymer-layout> |
| 99 * <div>Menu</div> |
| 100 * <div flex> |
| 101 * <polymer-layout vertical></polymer-layout> |
| 102 * <div>Title</div> |
| 103 * <div>Toolbar</div> |
| 104 * <div flex>Main</div> |
| 105 * <div>Footer</div> |
| 106 * </div> |
| 107 * |
| 108 * Renders something like this |
| 109 * |
| 110 * -------------------------------- |
| 111 * ||Menu ||Title || |
| 112 * || ||-----------------|| |
| 113 * || ||Toolbar || |
| 114 * || ||-----------------|| |
| 115 * || ||Main || |
| 116 * || || || |
| 117 * || ||-----------------|| |
| 118 * || ||Footer || |
| 119 * -------------------------------- |
| 120 * |
| 121 * @class polymer-layout |
| 122 * |
| 123 */ |
| 124 --> |
| 125 <link rel="import" href="../polymer/polymer.html"> |
| 126 |
| 127 <polymer-element name="polymer-layout" attributes="vertical"> |
| 128 <template> |
| 129 <style> |
| 130 :host { |
| 131 display: none; |
| 132 } |
| 133 </style> |
| 134 </template> |
| 135 <script> |
| 136 Polymer('polymer-layout', { |
| 137 vertical: false, |
| 138 ready: function() { |
| 139 this.setAttribute('nolayout', ''); |
| 140 }, |
| 141 enteredView: function() { |
| 142 this.asyncMethod(function() { |
| 143 this.prepare(); |
| 144 this.layout(); |
| 145 }); |
| 146 }, |
| 147 prepare: function() { |
| 148 var parent = this.parentNode.host || this.parentNode; |
| 149 // explicit position harmful on <body> |
| 150 if (parent.localName !== 'body') { |
| 151 // may recalc |
| 152 var cs = window.getComputedStyle(parent); |
| 153 if (cs.position === 'static') { |
| 154 parent.style.position = 'relative'; |
| 155 } |
| 156 //parent.style.overflow = 'hidden'; |
| 157 } |
| 158 // changes will cause another recalc at next validation step |
| 159 var vertical; |
| 160 this.parentNode.childNodes.array().forEach(function(c, i) { |
| 161 if (c.nodeType === Node.ELEMENT_NODE && !c.hasAttribute('nolayout')) { |
| 162 stylize(c, { |
| 163 position: 'absolute', |
| 164 boxSizing: 'border-box', |
| 165 MozBoxSizing: 'border-box', |
| 166 }); |
| 167 // test for auto-vertical |
| 168 if (vertical === undefined) { |
| 169 vertical = (c.offsetWidth == 0 && c.offsetHeight !== 0); |
| 170 } |
| 171 } |
| 172 }); |
| 173 this.vertical = this.vertical || vertical; |
| 174 }, |
| 175 /** |
| 176 * Arrange sibling nodes end-to-end in one dimension. |
| 177 * |
| 178 * Arrangement is horizontal unless the `vertical` |
| 179 * attribute is applied on this node. |
| 180 * |
| 181 * @method layout |
| 182 */ |
| 183 layout: function() { |
| 184 var parent = this.parentNode.host || this.parentNode; |
| 185 var vertical = this.vertical; |
| 186 var ww = 0, hh = 0, pre = [], fit, post = []; |
| 187 var list = pre; |
| 188 // gather element information (at most one recalc) |
| 189 this.parentNode.childNodes.array().forEach(function(c, i) { |
| 190 if (c.nodeType===Node.ELEMENT_NODE && !c.hasAttribute('nolayout')) { |
| 191 var info = { |
| 192 element: c, |
| 193 w: c.offsetWidth, |
| 194 h: c.offsetHeight |
| 195 }; |
| 196 if (!c.hasAttribute('fit') && !c.hasAttribute('flex')) { |
| 197 ww += c.offsetWidth; |
| 198 hh += c.offsetHeight; |
| 199 list.push(info); |
| 200 } else { |
| 201 fit = c; |
| 202 list = post; |
| 203 ww = hh = 0; |
| 204 } |
| 205 } |
| 206 }); |
| 207 // update layout styles (invalidate, no recalc) |
| 208 var v = 0; |
| 209 var mxp = 0, myp = 0; |
| 210 pre.forEach(function(info) { |
| 211 if (vertical) { |
| 212 stylize(info.element, { |
| 213 top: v + 'px', right: mxp, height: info.h + 'px', left: mxp |
| 214 }); |
| 215 } else { |
| 216 stylize(info.element, { |
| 217 top: myp, width: info.w + 'px', bottom: myp, left: v + 'px' |
| 218 }); |
| 219 } |
| 220 v += vertical ? info.h : info.w; |
| 221 }); |
| 222 if (fit) { |
| 223 if (vertical) { |
| 224 stylize(fit, { |
| 225 top: v + 'px', right: mxp, bottom: hh + 'px', left: mxp |
| 226 }); |
| 227 } else { |
| 228 stylize(fit, { |
| 229 top: myp, right: ww + 'px', bottom: myp, left: v + 'px' |
| 230 }); |
| 231 } |
| 232 v = vertical ? hh : ww; |
| 233 post.forEach(function(info) { |
| 234 v -= vertical ? info.h : info.w; |
| 235 if (vertical) { |
| 236 stylize(info.element, { |
| 237 height: info.h + 'px', right: mxp, bottom: v + 'px', left: mxp |
| 238 }); |
| 239 } else { |
| 240 stylize(info.element, { |
| 241 top: myp, right: v + 'px', bottom: myp, width: info.w + 'px' |
| 242 }); |
| 243 } |
| 244 }); |
| 245 } |
| 246 } |
| 247 }); |
| 248 function stylize(element, styles) { |
| 249 var style = element.style; |
| 250 Object.keys(styles).forEach(function(k){ |
| 251 style[k] = styles[k]; |
| 252 }); |
| 253 } |
| 254 </script> |
| 255 </polymer-element> |
OLD | NEW |