1 2 3 Polymer('core-slide', { 4 5 closed: false, 6 open: true, 7 vertical: false, 8 targetId: '', 9 target: null, 10 11 ready: function() { 12 this.setAttribute('nolayout', ''); 13 }, 14 15 attached: function() { 16 this.target = this.parentNode; 17 }, 18 19 targetIdChanged: function() { 20 var p = this.parentNode; 21 while (p.parentNode) {p = p.parentNode;}; 22 this.target = p.querySelector('#' + this.targetId); 23 }, 24 25 targetChanged: function() { 26 if (this.closed) { 27 this.asyncMethod(this.update); 28 } 29 }, 30 31 toggle: function() { 32 this.open = !this.open; 33 }, 34 35 closedChanged: function() { 36 this.open = !this.closed; 37 }, 38 39 openChanged: function() { 40 this.asyncMethod(this.update); 41 }, 42 43 update: function() { 44 this.closed = !this.open; 45 if (this.target) { 46 if (this.vertical) { 47 if (this.target.style.top !== '') { 48 this.updateTop(); 49 } else { 50 this.updateBottom(); 51 } 52 } else { 53 if (this.target.style.left !== '') { 54 this.updateLeft(); 55 } else { 56 this.updateRight(); 57 } 58 } 59 } 60 }, 61 62 updateLeft: function() { 63 var w = this.target.offsetWidth; 64 var l = this.open ? 0 : -w; 65 this.target.style.left = l + 'px'; 66 var s = this.target.nextElementSibling; 67 while (s) { 68 if (!s.hasAttribute('nolayout')) { 69 if (s.style.left === '' && s.style.right !== '') { 70 break; 71 } 72 l += w; 73 s.style.left = l + 'px'; 74 w = s.offsetWidth; 75 } 76 s = s.nextElementSibling; 77 } 78 }, 79 80 updateRight: function() { 81 var w = this.target.offsetWidth; 82 var r = this.open ? 0 : -w; 83 this.target.style.right = r + 'px'; 84 //var s = this.target.previousElementSibling; 85 var s = previousElementSibling(this.target); 86 while (s) { 87 if (!s.hasAttribute('nolayout')) { 88 if (s.style.right === '' && s.style.left !== '') { 89 break; 90 } 91 r += w; 92 s.style.right = r + 'px'; 93 w = s.offsetWidth; 94 } 95 //if (s == s.previousElementSibling) { 96 // console.error(s.localName + ' is its own sibling', s); 97 // break; 98 //} 99 //s = s.previousElementSibling; 100 s = previousElementSibling(s); 101 } 102 }, 103 104 updateTop: function() { 105 var h = this.target.offsetHeight; 106 var t = this.open ? 0 : -h; 107 this.target.style.top = t + 'px'; 108 var s = this.target.nextElementSibling; 109 while (s) { 110 if (!s.hasAttribute('nolayout')) { 111 if (s.style.top === '' && s.style.bottom !== '') { 112 break; 113 } 114 t += h; 115 s.style.top = t + 'px'; 116 h = s.offsetHeight; 117 } 118 s = s.nextElementSibling; 119 } 120 }, 121 122 updateBottom: function() { 123 var h = this.target.offsetHeight; 124 var b = this.open ? 0 : -h; 125 this.target.style.bottom = b + 'px'; 126 //var s = this.target.previousElementSibling; 127 var s = previousElementSibling(this.target); 128 while (s) { 129 if (!s.hasAttribute('nolayout')) { 130 if (s.style.bottom === '' && s.style.top !== '') { 131 break; 132 } 133 b = b + h; 134 s.style.bottom = b + 'px'; 135 h = s.offsetHeight; 136 } 137 //if (s == s.previousElementSibling) { 138 // console.error(s.localName + ' is its own sibling', s); 139 // break; 140 //} 141 //s = s.previousElementSibling; 142 s = previousElementSibling(s); 143 } 144 } 145 146 }); 147 148 // TODO(sjmiles): temporary workaround for b0rked property in ShadowDOMPolyfill 149 function previousElementSibling(e) { 150 do { 151 e = e.previousSibling; 152 } while (e && e.nodeType !== Node.ELEMENT_NODE); 153 return e; 154 }; 155 156