Skip to content

Commit

Permalink
Use iframes for sizeresponsible
Browse files Browse the repository at this point in the history
	- makes item-recycler's extent obsolite
	- handles hidden state better
  • Loading branch information
Justin Moore committed Jun 11, 2016
1 parent 252bf8b commit 2c467ea
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 172 deletions.
161 changes: 32 additions & 129 deletions src/shared/behaviors/sizeresponsible.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,103 +3,9 @@
Copyright (c) 2015 MediaMath Inc. All rights reserved.
This code may only be used under the BSD style license found at http://mediamath.github.io/strand/LICENSE.txt
-->

<script type="text/javascript">
// adapted from https://github.com/sdecima/javascript-detect-element-resize/blob/3d9563692e169eb54f7c4fb96f4866aebc17cb4e/detect-element-resize.js
/**
* Detect Element Resize
*
* https://github.com/sdecima/javascript-detect-element-resize
* Sebastian Decima
*
* version: 0.5.3
**/

(function (scope) {

var attachEvent = document.attachEvent,
stylesCreated = false;

if (!attachEvent) {
var requestFrame = (function(){
var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
function(fn){ return window.setTimeout(fn, 20); };
return function(fn){ return raf(fn); };
})();

var cancelFrame = (function(){
var cancel = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame ||
window.clearTimeout;
return function(id){ return cancel(id); };
})();

function resetTriggers(element){
if (!element.__resizeTriggers__) { return; } // diverges from 3d9563692e169eb54f7c4fb96f4866aebc17cb4e
var triggers = element.__resizeTriggers__,
expand = triggers.firstElementChild,
contract = triggers.lastElementChild,
expandChild = expand.firstElementChild;

contract.scrollLeft = contract.scrollWidth;
contract.scrollTop = contract.scrollHeight;
expandChild.style.width = expand.offsetWidth + 1 + 'px';
expandChild.style.height = expand.offsetHeight + 1 + 'px';
expand.scrollLeft = expand.scrollWidth;
expand.scrollTop = expand.scrollHeight;
};

function checkTriggers(element){
return element.offsetWidth != element.__resizeLast__.width ||
element.offsetHeight != element.__resizeLast__.height;
}

function scrollListener(e){
var element = this;
resetTriggers(this);
if (this.__resizeRAF__) cancelFrame(this.__resizeRAF__);
this.__resizeRAF__ = requestFrame(function(){
if (checkTriggers(element)) {
element.__resizeLast__.width = element.offsetWidth;
element.__resizeLast__.height = element.offsetHeight;
element.__resizeListeners__.forEach(function(fn){
fn.call(element, e);
});
}
});
};

/* Detect CSS Animations support to detect element display/re-attach */
var animation = false,
animationstring = 'animation',
keyframeprefix = '',
animationstartevent = 'animationstart',
domPrefixes = 'Webkit Moz O ms'.split(' '),
startEvents = 'webkitAnimationStart animationstart oAnimationStart MSAnimationStart'.split(' '),
pfx = '';
{

var elm = document.createElement('fakeelement');
if( elm.style.animationName !== undefined ) { animation = true; }
if( animation === false ) {
for( var i = 0; i < domPrefixes.length; i++ ) {
if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
pfx = domPrefixes[ i ];
animationstring = pfx + 'Animation';
keyframeprefix = '-' + pfx.toLowerCase() + '-';
animationstartevent = startEvents[ i ];
animation = true;
break;
}
}
}

}

var animationName = 'resizeanim';
var animationKeyframes = '@' + keyframeprefix + 'keyframes ' + animationName + ' { from { opacity: 0; } to { opacity: 0; } } ';
var animationStyle = keyframeprefix + 'animation: 1ms ' + animationName + '; ';
}

scope.SizeResponsible = {

properties: {
Expand All @@ -111,47 +17,44 @@
},
},

addResizeListener: function(fn, target){
var element = target || this;
var nameSpace = " " + this.tagName.toLocaleLowerCase() + " ";
addResizeListener: function(fn, target) {
this._listeners = this._listeners || [];
var el = target || this;
var element = Polymer.dom(el);

if (attachEvent) {
element.attachEvent('onresize', fn);
} else {
if (!element.__resizeTriggers__) {
if (getComputedStyle(element).position == 'static') element.style.position = 'relative';
element.__resizeLast__ = {};
element.__resizeListeners__ = [];
element.__resizeTriggers__ = document.createElement('div');
element.__resizeTriggers__.className = 'resize-triggers' + nameSpace;
element.__resizeTriggers__.innerHTML = '<div class="expand-trigger' + nameSpace + '"><div></div></div>' + '<div class="contract-trigger' + nameSpace + '"></div>';
Polymer.dom(element).appendChild(element.__resizeTriggers__);
Polymer.dom.flush();
if (el.style.position !== "relative") {
el.style.position = "relative";
}

resetTriggers(element);
var div = document.createElement("div");
div.style.cssText = "position:absolute; width:auto; height:auto; top:0; right:0; bottom:0; left:0; margin:0; padding:0; overflow:hidden; visibility:hidden; z-index:-1";
var iframe = document.createElement("iframe");
iframe.style.cssText = "width:100%; height:100%; border:0; visibility:visible; margin:0";

element.addEventListener('scroll', scrollListener, true);
div.appendChild(iframe);
element.appendChild(div);

/* Listen for a css animation to detect element display/re-attach */
animationstartevent &&
element.__resizeTriggers__.addEventListener(animationstartevent, function(e) {
if(e.animationName == animationName) resetTriggers(element);
});
}
element.__resizeListeners__.push(fn);
}
iframe.cb = fn;
iframe.contentWindow.addEventListener("resize", fn);

this._listeners.push({
div:div,
iframe:iframe,
fn:fn,
target:target
});
},

removeResizeListener: function(fn, target){
var element = target || this;
if (attachEvent) element.detachEvent('onresize', fn);
else if (element.__resizeListeners__) {
element.__resizeListeners__.splice(element.__resizeListeners__.indexOf(fn), 1);
if (!element.__resizeListeners__.length) {
element.removeEventListener('scroll', scrollListener);
element.__resizeTriggers__ = !Polymer.dom(element).removeChild(element.__resizeTriggers__);
}
}
removeResizeListener: function(fn, target) {
var f = this._listeners.filter(function(t) {
return t.fn === fn || t.target === target;
}).map(function(listen) {
listen.target.removeChild(listen.div);
listen.iframe.contentWindow.removeEventListener("resize",listen.fn);
return this._listeners.indexOf(listen);
}).forEach(function(idx) {
this._listeners.splice(idx,1);
});
}

};
Expand Down
1 change: 0 additions & 1 deletion src/strand-item-recycler/strand-item-recycler.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
<div id="footer">
<content select="[recycler=footer]"></content>
</div>
<div id="extent"></div>
</div>
</div>
</template>
Expand Down
40 changes: 5 additions & 35 deletions src/strand-item-recycler/strand-item-recycler.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,6 @@ found here: https://github.com/Polymer/core-list
return [];
},
},
_waiting: {
type: Boolean,
value: false,
},
_initialized: {
type: Boolean,
value: false,
Expand Down Expand Up @@ -152,10 +148,6 @@ found here: https://github.com/Polymer/core-list
type: Number,
value: 0,
},
_extentHeight: {
type: Number,
value: 0,
},
_viewportHeight: {
type: Number,
value: 0,
Expand All @@ -176,7 +168,6 @@ found here: https://github.com/Polymer/core-list
responders.pane = this._paneResponse.bind(this);
responders.header = this._headerResponse.bind(this);
responders.footer = this._footerResponse.bind(this);
responders.extent = this._extentResponse.bind(this);
return responders;
},
},
Expand Down Expand Up @@ -376,29 +367,19 @@ found here: https://github.com/Polymer/core-list
this.addResizeListener(this._responders.pane, this.$.pane);
this.addResizeListener(this._responders.header, this.$.header);
this.addResizeListener(this._responders.footer, this.$.footer);
this.addResizeListener(this._responders.extent, this.$.extent);
},

detached: function () {
this.$.pane.removeEventListener("scroll", this._responders.scroll);
this.removeResizeListener(this._responders.pane, this.$.pane);
this.removeResizeListener(this._responders.header, this.$.header);
this.removeResizeListener(this._responders.footer, this.$.footer);
this.removeResizeListener(this._responders.extent, this.$.extent);
},

_settleDown: function () {
this.fire("presentation-settled");
},

_extentResponse: function (e) {
if (this._waiting &&
elementHeight(this.$.extent) > 0) {
this._waiting = false;
this.initialize();
}
},

_paneResponse: function (e) {
var itemRecycler = this;
var delta = +(elementHeight(itemRecycler.$.quad) - itemRecycler._viewportHeight) || 0;
Expand Down Expand Up @@ -457,10 +438,12 @@ found here: https://github.com/Polymer/core-list
var change = 0;
var initialization = true;

bound.height += delta;
itemRecycler._measurements.setHeight(bound.young, bound.height);
if (delta > 0 ||
itemRecycler._itemHeight <= 0 ||
itemRecycler._itemHeight && delta < 0) {
bound.height += delta;
itemRecycler._measurements.setHeight(bound.young, bound.height);

if (delta || itemRecycler._itemHeight <= 0) {
if (bound.height) {
if (!itemRecycler._itemHeight) {
change = itemRecycler._accommodateGlobalHeightAdjustment(0|initialization, bound, delta);
Expand Down Expand Up @@ -575,11 +558,7 @@ found here: https://github.com/Polymer/core-list
return 0|false;
} else if (!this.hasTemplate()) {
return 0|false;
} else if (elementHeight(this.$.extent) < 1) {
this._waiting = true;
return 0|false;
} else {
this._waiting = false;
this.debounce("initializeRecycler", this.initializeRecycler);
return 0|true;
}
Expand All @@ -601,7 +580,6 @@ found here: https://github.com/Polymer/core-list

this._initializable = true;
this._initialized = true;
this._waiting = false;
return 0|true;
} else {
return 0|false;
Expand All @@ -613,7 +591,6 @@ found here: https://github.com/Polymer/core-list

this._headerHeight = elementHeight(this.$.header);
this._footerHeight = elementHeight(this.$.footer);
this._extentHeight = elementHeight(this.$.extent);

viewportHeight -= (this._headerHeight + this._footerHeight);
this._viewportHeight = viewportHeight;
Expand All @@ -622,7 +599,6 @@ found here: https://github.com/Polymer/core-list
this._repositionHeader();
this._repositionFooter();
this._repositionMiddle();
this._repositionExtent();

var padding = roundMaybe(this._itemHeight);

Expand Down Expand Up @@ -1075,7 +1051,6 @@ found here: https://github.com/Polymer/core-list
this._repositionHeader();
this._repositionFooter();
this._repositionMiddle();
this._repositionExtent();
},

_restyleMiddleHeight: function () {
Expand All @@ -1093,11 +1068,6 @@ found here: https://github.com/Polymer/core-list
this._assignMiddleHeight(height);
},

_repositionExtent: function () {
var position = -this._extentHeight + this._transformBaseline;
this._setTranslation(position, this.$.extent);
},

_repositionMiddle: function () {
var position = (this._headerHeight + this._transformBaseline);
this._setTranslation(position, this.$.middle);
Expand Down
8 changes: 1 addition & 7 deletions src/strand-item-recycler/strand-item-recycler.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,9 @@
display: inline-block;
}

#header, #footer, #middle, #extent, #constrainer {
#header, #footer, #middle, #constrainer {
min-width: 100%;
position: relative;
}

#extent {
height: 1px;
margin-top: -1px;
z-index: -1;
}


0 comments on commit 2c467ea

Please sign in to comment.