element-resize-detector
Advanced tools
Comparing version 1.1.14 to 1.2.0
/*! | ||
* element-resize-detector 1.1.14 | ||
* element-resize-detector 1.2.0 | ||
* Copyright (c) 2016 Lucas Wiener | ||
@@ -8,2 +8,2 @@ * https://github.com/wnr/element-resize-detector | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.elementResizeDetectorMaker=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";function d(){function a(a,b){b||(b=a,a=0),a>f?f=a:a<g&&(g=a),d[a]||(d[a]=[]),d[a].push(b),e++}function b(){for(var a=g;a<=f;a++)for(var b=d[a],c=0;c<b.length;c++){var e=b[c];e()}}function c(){return e}var d={},e=0,f=0,g=0;return{add:a,process:b,size:c}}var e=a("./utils");b.exports=function(a){function b(a,b){!o&&l&&k&&0===n.size()&&g(),n.add(a,b)}function c(){for(o=!0;n.size();){var a=n;n=d(),a.process()}o=!1}function f(a){o||(void 0===a&&(a=k),m&&(h(m),m=null),a?g():c())}function g(){m=i(c)}function h(a){return clearTimeout(a)}function i(a){return function(a){return setTimeout(a,0)}(a)}a=a||{};var j=a.reporter,k=e.getOption(a,"async",!0),l=e.getOption(a,"auto",!0);l&&!k&&(j&&j.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true."),k=!0);var m,n=d(),o=!1;return{add:b,force:f}}},{"./utils":2}],2:[function(a,b,c){"use strict";function d(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}(b.exports={}).getOption=d},{}],3:[function(a,b,c){"use strict";var d=b.exports={};d.isIE=function(a){return!!function(){var a=navigator.userAgent.toLowerCase();return-1!==a.indexOf("msie")||-1!==a.indexOf("trident")||-1!==a.indexOf(" edge/")}()&&(!a||a===function(){var a=3,b=document.createElement("div"),c=b.getElementsByTagName("i");do{b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e"}while(c[0]);return a>4?a:void 0}())},d.isLegacyOpera=function(){return!!window.opera}},{}],4:[function(a,b,c){"use strict";(b.exports={}).forEach=function(a,b){for(var c=0;c<a.length;c++){var d=b(a[c]);if(d)return d}}},{}],5:[function(a,b,c){"use strict";var d=a("../browser-detector");b.exports=function(a){function b(a,b){function c(){b(a)}if(!e(a))throw new Error("Element is not detectable by this strategy.");if(d.isIE(8))i(a).object={proxy:c},a.attachEvent("onresize",c);else{e(a).contentDocument.defaultView.addEventListener("resize",c)}}function c(a,b,c){c||(c=b,b=a,a=null),a=a||{};a.debug;d.isIE(8)?c(b):function(a,b){function c(){function c(){if("static"===j.position){a.style.position="relative";var b=function(a,b,c,d){var e=c[d];"auto"!==e&&"0"!==function(a){return a.replace(/[^-\d\.]/g,"")}(e)&&(a.warn("An element that is positioned static has style."+d+"="+e+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+d+" will be set to 0. Element: ",b),b.style[d]=0)};b(g,a,j,"top"),b(g,a,j,"right"),b(g,a,j,"bottom"),b(g,a,j,"left")}}function h(){function d(a,b){if(!a.contentDocument)return void setTimeout(function(){d(a,b)},100);b(a.contentDocument)}f||c(),d(this,function(c){b(a)})}""!==j.position&&(c(j),f=!0);var k=document.createElement("object");k.style.cssText=e,k.tabIndex=-1,k.type="text/html",k.onload=h,d.isIE()||(k.data="about:blank"),a.appendChild(k),i(a).object=k,d.isIE()&&(k.data="about:blank")}var e="display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;",f=!1,j=window.getComputedStyle(a),k=a.offsetWidth,l=a.offsetHeight;i(a).startSize={width:k,height:l},h?h.add(c):c()}(b,c)}function e(a){return i(a).object}function f(a){d.isIE(8)?a.detachEvent("onresize",i(a).object.proxy):a.removeChild(e(a)),delete i(a).object}a=a||{};var g=a.reporter,h=a.batchProcessor,i=a.stateHandler.getState;if(!g)throw new Error("Missing required dependency: reporter.");return{makeDetectable:c,addListener:b,uninstall:f}}},{"../browser-detector":3}],6:[function(a,b,c){"use strict";var d=a("../collection-utils").forEach;b.exports=function(a){function b(a){a.className+=" "+p+"_animation_active"}function c(a,b,c){if(a.addEventListener)a.addEventListener(b,c);else{if(!a.attachEvent)return k.error("[scroll] Don't know how to add event listeners.");a.attachEvent("on"+b,c)}}function e(a,b,c){if(a.removeEventListener)a.removeEventListener(b,c);else{if(!a.detachEvent)return k.error("[scroll] Don't know how to remove event listeners.");a.detachEvent("on"+b,c)}}function f(a){return m(a).container.childNodes[0].childNodes[0].childNodes[0]}function g(a){return m(a).container.childNodes[0].childNodes[0].childNodes[1]}function h(a,b){if(!m(a).listeners.push)throw new Error("Cannot add listener to an element that is not detectable.");m(a).listeners.push(b)}function i(a,e,h){function i(){if(a.debug){var b=Array.prototype.slice.call(arguments);if(b.unshift(n.get(e),"Scroll: "),k.log.apply)k.log.apply(null,b);else for(var c=0;c<b.length;c++)k.log(b[c])}}function j(a){var b=m(a).container.childNodes[0],c=window.getComputedStyle(b);return!c.width||-1===c.width.indexOf("px")}function q(){var a=window.getComputedStyle(e),b={};return b.position=a.position,b.width=e.offsetWidth,b.height=e.offsetHeight,b.top=a.top,b.right=a.right,b.bottom=a.bottom,b.left=a.left,b.widthCSS=a.width,b.heightCSS=a.height,b}function r(){var a=q();m(e).startSize={width:a.width,height:a.height},i("Element start size",m(e).startSize)}function s(){m(e).listeners=[]}function t(){if(i("storeStyle invoked."),!m(e))return void i("Aborting because element has been uninstalled");var a=q();m(e).style=a}function u(a,b,c){m(a).lastWidth=b,m(a).lastHeight=c}function v(a){return f(a).childNodes[0]}function w(){return 2*o.width+1}function x(){return 2*o.height+1}function y(a){return a+10+w()}function z(a){return a+10+x()}function A(a){return 2*a+w()}function B(a){return 2*a+x()}function C(a,b,c){var d=f(a),e=g(a),h=y(b),i=z(c),j=A(b),k=B(c);d.scrollLeft=h,d.scrollTop=i,e.scrollLeft=j,e.scrollTop=k}function D(){var a=m(e).container;if(!a){a=document.createElement("div"),a.className=p,a.style.cssText="visibility: hidden; display: inline; width: 0px; height: 0px; z-index: -1; overflow: hidden; margin: 0; padding: 0;",m(e).container=a,b(a),e.appendChild(a);var d=function(){m(e).onRendered&&m(e).onRendered()};c(a,"animationstart",d),m(e).onAnimationStart=d}return a}function E(){function a(){m(e).onExpand&&m(e).onExpand()}function b(){m(e).onShrink&&m(e).onShrink()}if(i("Injecting elements"),!m(e))return void i("Aborting because element has been uninstalled");!function(){var a=m(e).style;if("static"===a.position){e.style.position="relative";var b=function(a,b,c,d){var e=c[d];"auto"!==e&&"0"!==function(a){return a.replace(/[^-\d\.]/g,"")}(e)&&(a.warn("An element that is positioned static has style."+d+"="+e+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+d+" will be set to 0. Element: ",b),b.style[d]=0)};b(k,e,a,"top"),b(k,e,a,"right"),b(k,e,a,"bottom"),b(k,e,a,"left")}}();var d=m(e).container;d||(d=D());var f=o.width,g=o.height,h="position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; "+function(a,b,c,d){return a=a?a+"px":"0",b=b?b+"px":"0",c=c?c+"px":"0",d=d?d+"px":"0","left: "+a+"; top: "+b+"; right: "+d+"; bottom: "+c+";"}(-(1+f),-(1+g),-g,-f),j=document.createElement("div"),l=document.createElement("div"),n=document.createElement("div"),q=document.createElement("div"),r=document.createElement("div"),s=document.createElement("div");j.dir="ltr",j.style.cssText="position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;",j.className=p,l.className=p,l.style.cssText=h,n.style.cssText="position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;",q.style.cssText="position: absolute; left: 0; top: 0;",r.style.cssText="position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;",s.style.cssText="position: absolute; width: 200%; height: 200%;",n.appendChild(q),r.appendChild(s),l.appendChild(n),l.appendChild(r),j.appendChild(l),d.appendChild(j),c(n,"scroll",a),c(r,"scroll",b),m(e).onExpandScroll=a,m(e).onShrinkScroll=b}function F(){function b(a,b,c){var d=v(a),e=y(b),f=z(c);d.style.width=e+"px",d.style.height=f+"px"}function c(c){var d=e.offsetWidth,f=e.offsetHeight;i("Storing current size",d,f),u(e,d,f),l.add(0,function(){if(!m(e))return void i("Aborting because element has been uninstalled");if(!h())return void i("Aborting because element container has not been initialized");if(a.debug){var c=e.offsetWidth,g=e.offsetHeight;c===d&&g===f||k.warn(n.get(e),"Scroll: Size changed before updating detector elements.")}b(e,d,f)}),l.add(1,function(){return m(e)?h()?void C(e,d,f):void i("Aborting because element container has not been initialized"):void i("Aborting because element has been uninstalled")}),c&&l.add(2,function(){return m(e)?h()?void c():void i("Aborting because element container has not been initialized"):void i("Aborting because element has been uninstalled")})}function h(){return!!m(e).container}function o(){i("notifyListenersIfNeeded invoked");var a=m(e);return function(){return void 0===m(e).lastNotifiedWidth}()&&a.lastWidth===a.startSize.width&&a.lastHeight===a.startSize.height?i("Not notifying: Size is the same as the start size, and there has been no notification yet."):a.lastWidth===a.lastNotifiedWidth&&a.lastHeight===a.lastNotifiedHeight?i("Not notifying: Size already notified"):(i("Current size not notified, notifying..."),a.lastNotifiedWidth=a.lastWidth,a.lastNotifiedHeight=a.lastHeight,void d(m(e).listeners,function(a){a(e)}))}function p(){if(i("startanimation triggered."),j(e))return void i("Ignoring since element is still unrendered...");i("Element rendered.");var a=f(e),b=g(e);0!==a.scrollLeft&&0!==a.scrollTop&&0!==b.scrollLeft&&0!==b.scrollTop||(i("Scrollbars out of sync. Updating detector elements..."),c(o))}function q(){if(i("Scroll detected."),j(e))return void i("Scroll event fired while unrendered. Ignoring...");var a=e.offsetWidth,b=e.offsetHeight;a!==m(e).lastWidth||b!==m(e).lastHeight?(i("Element size changed."),c(o)):i("Element size has not changed ("+a+"x"+b+").")}if(i("registerListenersAndPositionElements invoked."),!m(e))return void i("Aborting because element has been uninstalled");m(e).onRendered=p,m(e).onExpand=q,m(e).onShrink=q;var r=m(e).style;b(e,r.width,r.height)}function G(){if(i("finalizeDomMutation invoked."),!m(e))return void i("Aborting because element has been uninstalled");var a=m(e).style;u(e,a.width,a.height),C(e,a.width,a.height)}function H(){h(e)}function I(){i("Installing..."),s(),r(),l.add(0,t),l.add(1,E),l.add(2,F),l.add(3,G),l.add(4,H)}h||(h=e,e=a,a=null),a=a||{},i("Making detectable..."),!function(a){return!function(a){return a===a.ownerDocument.body||a.ownerDocument.body.contains(a)}(a)||null===window.getComputedStyle(a)}(e)?I():(i("Element is detached"),D(),i("Waiting until element is attached..."),m(e).onRendered=function(){i("Element is now attached"),I()})}function j(a){var b=m(a);b&&(b.onExpandScroll&&e(f(a),"scroll",b.onExpandScroll),b.onShrinkScroll&&e(g(a),"scroll",b.onShrinkScroll),b.onAnimationStart&&e(b.container,"animationstart",b.onAnimationStart),b.container&&a.removeChild(b.container))}a=a||{};var k=a.reporter,l=a.batchProcessor,m=a.stateHandler.getState,n=(a.stateHandler.hasState,a.idHandler);if(!l)throw new Error("Missing required dependency: batchProcessor");if(!k)throw new Error("Missing required dependency: reporter.");var o=function(){var a=document.createElement("div");a.style.cssText="position: absolute; width: 1000px; height: 1000px; visibility: hidden; margin: 0; padding: 0;";var b=document.createElement("div");b.style.cssText="position: absolute; width: 500px; height: 500px; overflow: scroll; visibility: none; top: -1500px; left: -1500px; visibility: hidden; margin: 0; padding: 0;",b.appendChild(a),document.body.insertBefore(b,document.body.firstChild);var c=500-b.clientWidth,d=500-b.clientHeight;return document.body.removeChild(b),{width:c,height:d}}(),p="erd_scroll_detection_container";return function(a,b){if(!document.getElementById(a)){var c=b+"_animation",d=b+"_animation_active",e="/* Created by the element-resize-detector library. */\n";e+="."+b+" > div::-webkit-scrollbar { display: none; }\n\n",e+="."+d+" { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: "+c+"; animation-name: "+c+"; }\n",e+="@-webkit-keyframes "+c+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",e+="@keyframes "+c+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }",function(b,c){c=c||function(a){document.head.appendChild(a)};var d=document.createElement("style");d.innerHTML=b,d.id=a,c(d)}(e)}}("erd_scroll_detection_scrollbar_style",p),{makeDetectable:i,addListener:h,uninstall:j}}},{"../collection-utils":4}],7:[function(a,b,c){"use strict";function d(a){return Array.isArray(a)||void 0!==a.length}function e(a){if(Array.isArray(a))return a;var b=[];return h(a,function(a){b.push(a)}),b}function f(a){return a&&1===a.nodeType}function g(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}var h=a("./collection-utils").forEach,i=a("./element-utils"),j=a("./listener-handler"),k=a("./id-generator"),l=a("./id-handler"),m=a("./reporter"),n=a("./browser-detector"),o=a("batch-processor"),p=a("./state-handler"),q=a("./detection-strategy/object.js"),r=a("./detection-strategy/scroll.js");b.exports=function(a){function b(a,b,c){function i(a){var b=z.get(a);h(b,function(b){b(a)})}function j(a,b,c){z.add(b,c),a&&c(b)}if(c||(c=b,b=a,a={}),!b)throw new Error("At least one element required.");if(!c)throw new Error("Listener required.");if(f(b))b=[b];else{if(!d(b))return v.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");b=e(b)}var k=0,l=g(a,"callOnAdd",x.callOnAdd),m=g(a,"onReady",function(){}),n=g(a,"debug",x.debug);h(b,function(a){p.getState(a)||(p.initState(a),s.set(a));var d=s.get(a);if(n&&v.log("Attaching listener to element",d,a),!A.isDetectable(a))return n&&v.log(d,"Not detectable."),A.isBusy(a)?(n&&v.log(d,"System busy making it detectable"),j(l,a,c),D[d]=D[d]||[],void D[d].push(function(){++k===b.length&&m()})):(n&&v.log(d,"Making detectable..."),A.markBusy(a,!0),y.makeDetectable({debug:n},a,function(a){if(n&&v.log(d,"onElementDetectable"),p.getState(a)){A.markAsDetectable(a),A.markBusy(a,!1),y.addListener(a,i),j(l,a,c);var e=p.getState(a);if(e&&e.startSize){var f=a.offsetWidth,g=a.offsetHeight;e.startSize.width===f&&e.startSize.height===g||i(a)}D[d]&&h(D[d],function(a){a()})}else n&&v.log(d,"Element uninstalled before being detectable.");delete D[d],++k===b.length&&m()}));n&&v.log(d,"Already detecable, adding listener."),j(l,a,c),k++}),k===b.length&&m()}function c(a){if(!a)return v.error("At least one element is required.");if(f(a))a=[a];else{if(!d(a))return v.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");a=e(a)}h(a,function(a){z.removeAllListeners(a),y.uninstall(a),p.cleanState(a)})}a=a||{};var s;if(a.idHandler)s={get:function(b){return a.idHandler.get(b,!0)},set:a.idHandler.set};else{var t=k(),u=l({idGenerator:t,stateHandler:p});s=u}var v=a.reporter;if(!v){v=m(!1===v)}var w=g(a,"batchProcessor",o({reporter:v})),x={};x.callOnAdd=!!g(a,"callOnAdd",!0),x.debug=!!g(a,"debug",!1);var y,z=j(s),A=i({stateHandler:p}),B=g(a,"strategy","object"),C={reporter:v,batchProcessor:w,stateHandler:p,idHandler:s};if("scroll"===B&&(n.isLegacyOpera()?(v.warn("Scroll strategy is not supported on legacy Opera. Changing to object strategy."),B="object"):n.isIE(9)&&(v.warn("Scroll strategy is not supported on IE9. Changing to object strategy."),B="object")),"scroll"===B)y=r(C);else{if("object"!==B)throw new Error("Invalid strategy name: "+B);y=q(C)}var D={};return{listenTo:b,removeListener:z.removeListener,removeAllListeners:z.removeAllListeners,uninstall:c}}},{"./browser-detector":3,"./collection-utils":4,"./detection-strategy/object.js":5,"./detection-strategy/scroll.js":6,"./element-utils":8,"./id-generator":9,"./id-handler":10,"./listener-handler":11,"./reporter":12,"./state-handler":13,"batch-processor":1}],8:[function(a,b,c){"use strict";b.exports=function(a){function b(a){var b=f(a);return b&&!!b.isDetectable}function c(a){f(a).isDetectable=!0}function d(a){return!!f(a).busy}function e(a,b){f(a).busy=!!b}var f=a.stateHandler.getState;return{isDetectable:b,markAsDetectable:c,isBusy:d,markBusy:e}}},{}],9:[function(a,b,c){"use strict";b.exports=function(){function a(){return b++}var b=1;return{generate:a}}},{}],10:[function(a,b,c){"use strict";b.exports=function(a){function b(a){var b=e(a);return b&&void 0!==b.id?b.id:null}function c(a){var b=e(a);if(!b)throw new Error("setId required the element to have a resize detection state.");var c=d.generate();return b.id=c,c}var d=a.idGenerator,e=a.stateHandler.getState;return{get:b,set:c}}},{}],11:[function(a,b,c){"use strict";b.exports=function(a){function b(b){var c=a.get(b);return void 0===c?[]:f[c]||[]}function c(b,c){var d=a.get(b);f[d]||(f[d]=[]),f[d].push(c)}function d(a,c){for(var d=b(a),e=0,f=d.length;e<f;++e)if(d[e]===c){d.splice(e,1);break}}function e(a){var c=b(a);c&&(c.length=0)}var f={};return{get:b,add:c,removeListener:d,removeAllListeners:e}}},{}],12:[function(a,b,c){"use strict";b.exports=function(a){function b(){}var c={log:b,warn:b,error:b};if(!a&&window.console){var d=function(a,b){a[b]=function(){var a=console[b];if(a.apply)a.apply(console,arguments);else for(var c=0;c<arguments.length;c++)a(arguments[c])}};d(c,"log"),d(c,"warn"),d(c,"error")}return c}},{}],13:[function(a,b,c){"use strict";function d(a){return a[g]={},e(a)}function e(a){return a[g]}function f(a){delete a[g]}var g="_erd";b.exports={initState:d,getState:e,cleanState:f}},{}]},{},[7])(7)}); | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.elementResizeDetectorMaker=a()}}(function(){return function(){function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){return e(b[g][1][a]||a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}return a}()({1:[function(a,b,c){"use strict";function d(){function a(a,b){b||(b=a,a=0),a>f?f=a:a<g&&(g=a),d[a]||(d[a]=[]),d[a].push(b),e++}function b(){for(var a=g;a<=f;a++)for(var b=d[a],c=0;c<b.length;c++){var e=b[c];e()}}function c(){return e}var d={},e=0,f=0,g=0;return{add:a,process:b,size:c}}var e=a("./utils");b.exports=function(a){function b(a,b){!o&&l&&k&&0===n.size()&&g(),n.add(a,b)}function c(){for(o=!0;n.size();){var a=n;n=d(),a.process()}o=!1}function f(a){o||(void 0===a&&(a=k),m&&(h(m),m=null),a?g():c())}function g(){m=i(c)}function h(a){return clearTimeout(a)}function i(a){return function(a){return setTimeout(a,0)}(a)}a=a||{};var j=a.reporter,k=e.getOption(a,"async",!0),l=e.getOption(a,"auto",!0);l&&!k&&(j&&j.warn("Invalid options combination. auto=true and async=false is invalid. Setting async=true."),k=!0);var m,n=d(),o=!1;return{add:b,force:f}}},{"./utils":2}],2:[function(a,b,c){"use strict";function d(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}(b.exports={}).getOption=d},{}],3:[function(a,b,c){"use strict";var d=b.exports={};d.isIE=function(a){return!!function(){var a=navigator.userAgent.toLowerCase();return-1!==a.indexOf("msie")||-1!==a.indexOf("trident")||-1!==a.indexOf(" edge/")}()&&(!a||a===function(){var a=3,b=document.createElement("div"),c=b.getElementsByTagName("i");do{b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e"}while(c[0]);return a>4?a:void 0}())},d.isLegacyOpera=function(){return!!window.opera}},{}],4:[function(a,b,c){"use strict";(b.exports={}).forEach=function(a,b){for(var c=0;c<a.length;c++){var d=b(a[c]);if(d)return d}}},{}],5:[function(a,b,c){"use strict";var d=a("../browser-detector");b.exports=function(a){function b(a,b){function c(){b(a)}if(d.isIE(8))j(a).object={proxy:c},a.attachEvent("onresize",c);else{var e=f(a);if(!e)throw new Error("Element is not detectable by this strategy.");e.contentDocument.defaultView.addEventListener("resize",c)}}function c(b){var c=a.important?" !important; ":"; ";return(b.join(c)+c).trim()}function e(a,b,e){e||(e=b,b=a,a=null),a=a||{};a.debug;d.isIE(8)?e(b):function(b,e){function f(){function c(){if("static"===l.position){b.style.setProperty("position","relative",a.important?"important":"");var c=function(b,c,d,e){var f=d[e];"auto"!==f&&"0"!==function(a){return a.replace(/[^-\d\.]/g,"")}(f)&&(b.warn("An element that is positioned static has style."+e+"="+f+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+e+" will be set to 0. Element: ",c),c.style.setProperty(e,"0",a.important?"important":""))};c(h,b,l,"top"),c(h,b,l,"right"),c(h,b,l,"bottom"),c(h,b,l,"left")}}function f(){function a(b,c){if(!b.contentDocument)return void setTimeout(function(){a(b,c)},100);c(b.contentDocument)}k||c(),a(this,function(a){e(b)})}""!==l.position&&(c(l),k=!0);var i=document.createElement("object");i.style.cssText=g,i.tabIndex=-1,i.type="text/html",i.onload=f,d.isIE()||(i.data="about:blank"),j(b)&&(b.appendChild(i),j(b).object=i,d.isIE()&&(i.data="about:blank"))}var g=c(["display: block","position: absolute","top: 0","left: 0","width: 100%","height: 100%","border: none","padding: 0","margin: 0","opacity: 0","z-index: -1000","pointer-events: none"]),k=!1,l=window.getComputedStyle(b),m=b.offsetWidth,n=b.offsetHeight;j(b).startSize={width:m,height:n},i?i.add(f):f()}(b,e)}function f(a){return j(a).object}function g(a){if(j(a)){var b=f(a);b&&(d.isIE(8)?a.detachEvent("onresize",b.proxy):a.removeChild(b),delete j(a).object)}}a=a||{};var h=a.reporter,i=a.batchProcessor,j=a.stateHandler.getState;if(!h)throw new Error("Missing required dependency: reporter.");return{makeDetectable:e,addListener:b,uninstall:g}}},{"../browser-detector":3}],6:[function(a,b,c){"use strict";var d=a("../collection-utils").forEach;b.exports=function(a){function b(a){e(a,s,t)}function c(b){var c=a.important?" !important; ":"; ";return(b.join(c)+c).trim()}function e(a,b,d){if(!a.getElementById(b)){var e=d+"_animation",f=d+"_animation_active",g="/* Created by the element-resize-detector library. */\n";g+="."+d+" > div::-webkit-scrollbar { "+c(["display: none"])+" }\n\n",g+="."+f+" { "+c(["-webkit-animation-duration: 0.1s","animation-duration: 0.1s","-webkit-animation-name: "+e,"animation-name: "+e])+" }\n",g+="@-webkit-keyframes "+e+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n",g+="@keyframes "+e+" { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }",function(c,d){d=d||function(b){a.head.appendChild(b)};var e=a.createElement("style");e.innerHTML=c,e.id=b,d(e)}(g)}}function f(a){a.className+=" "+t+"_animation_active"}function g(a,b,c){if(a.addEventListener)a.addEventListener(b,c);else{if(!a.attachEvent)return n.error("[scroll] Don't know how to add event listeners.");a.attachEvent("on"+b,c)}}function h(a,b,c){if(a.removeEventListener)a.removeEventListener(b,c);else{if(!a.detachEvent)return n.error("[scroll] Don't know how to remove event listeners.");a.detachEvent("on"+b,c)}}function i(a){return p(a).container.childNodes[0].childNodes[0].childNodes[0]}function j(a){return p(a).container.childNodes[0].childNodes[0].childNodes[1]}function k(a,b){if(!p(a).listeners.push)throw new Error("Cannot add listener to an element that is not detectable.");p(a).listeners.push(b)}function l(a,b,e){function h(){if(a.debug){var c=Array.prototype.slice.call(arguments);if(c.unshift(q.get(b),"Scroll: "),n.log.apply)n.log.apply(null,c);else for(var d=0;d<c.length;d++)n.log(c[d])}}function k(a){var b=p(a).container.childNodes[0],c=window.getComputedStyle(b);return!c.width||-1===c.width.indexOf("px")}function l(){var a=window.getComputedStyle(b),c={};return c.position=a.position,c.width=b.offsetWidth,c.height=b.offsetHeight,c.top=a.top,c.right=a.right,c.bottom=a.bottom,c.left=a.left,c.widthCSS=a.width,c.heightCSS=a.height,c}function m(){var a=l();p(b).startSize={width:a.width,height:a.height},h("Element start size",p(b).startSize)}function s(){p(b).listeners=[]}function u(){if(h("storeStyle invoked."),!p(b))return void h("Aborting because element has been uninstalled");var a=l();p(b).style=a}function v(a,b,c){p(a).lastWidth=b,p(a).lastHeight=c}function w(a){return i(a).childNodes[0]}function x(){return 2*r.width+1}function y(){return 2*r.height+1}function z(a){return a+10+x()}function A(a){return a+10+y()}function B(a){return 2*a+x()}function C(a){return 2*a+y()}function D(a,b,c){var d=i(a),e=j(a),f=z(b),g=A(c),h=B(b),k=C(c);d.scrollLeft=f,d.scrollTop=g,e.scrollLeft=h,e.scrollTop=k}function E(){var a=p(b).container;if(!a){a=document.createElement("div"),a.className=t,a.style.cssText=c(["visibility: hidden","display: inline","width: 0px","height: 0px","z-index: -1","overflow: hidden","margin: 0","padding: 0"]),p(b).container=a,f(a),b.appendChild(a);var d=function(){p(b).onRendered&&p(b).onRendered()};g(a,"animationstart",d),p(b).onAnimationStart=d}return a}function F(){function d(){p(b).onExpand&&p(b).onExpand()}function e(){p(b).onShrink&&p(b).onShrink()}if(h("Injecting elements"),!p(b))return void h("Aborting because element has been uninstalled");!function(){var c=p(b).style;if("static"===c.position){b.style.setProperty("position","relative",a.important?"important":"");var d=function(a,b,c,d){var e=c[d];"auto"!==e&&"0"!==function(a){return a.replace(/[^-\d\.]/g,"")}(e)&&(a.warn("An element that is positioned static has style."+d+"="+e+" which is ignored due to the static positioning. The element will need to be positioned relative, so the style."+d+" will be set to 0. Element: ",b),b.style[d]=0)};d(n,b,c,"top"),d(n,b,c,"right"),d(n,b,c,"bottom"),d(n,b,c,"left")}}();var f=p(b).container;f||(f=E());var i=r.width,j=r.height,k=c(["position: absolute","flex: none","overflow: hidden","z-index: -1","visibility: hidden","width: 100%","height: 100%","left: 0px","top: 0px"]),l=c(["position: absolute","flex: none","overflow: hidden","z-index: -1","visibility: hidden"].concat(function(a,b,c,d){return a=a?a+"px":"0",b=b?b+"px":"0",c=c?c+"px":"0",d=d?d+"px":"0",["left: "+a,"top: "+b,"right: "+d,"bottom: "+c]}(-(1+i),-(1+j),-j,-i))),m=c(["position: absolute","flex: none","overflow: scroll","z-index: -1","visibility: hidden","width: 100%","height: 100%"]),o=c(["position: absolute","flex: none","overflow: scroll","z-index: -1","visibility: hidden","width: 100%","height: 100%"]),q=c(["position: absolute","left: 0","top: 0"]),s=c(["position: absolute","width: 200%","height: 200%"]),u=document.createElement("div"),v=document.createElement("div"),w=document.createElement("div"),x=document.createElement("div"),y=document.createElement("div"),z=document.createElement("div");u.dir="ltr",u.style.cssText=k,u.className=t,v.className=t,v.style.cssText=l,w.style.cssText=m,x.style.cssText=q,y.style.cssText=o,z.style.cssText=s,w.appendChild(x),y.appendChild(z),v.appendChild(w),v.appendChild(y),u.appendChild(v),f.appendChild(u),g(w,"scroll",d),g(y,"scroll",e),p(b).onExpandScroll=d,p(b).onShrinkScroll=e}function G(){function c(b,c,d){var e=w(b),f=z(c),g=A(d);e.style.setProperty("width",f+"px",a.important?"important":""),e.style.setProperty("height",g+"px",a.important?"important":"")}function e(d){var e=b.offsetWidth,g=b.offsetHeight,i=e!==p(b).lastWidth||g!==p(b).lastHeight;h("Storing current size",e,g),v(b,e,g),o.add(0,function(){if(i){if(!p(b))return void h("Aborting because element has been uninstalled");if(!f())return void h("Aborting because element container has not been initialized");if(a.debug){var d=b.offsetWidth,j=b.offsetHeight;d===e&&j===g||n.warn(q.get(b),"Scroll: Size changed before updating detector elements.")}c(b,e,g)}}),o.add(1,function(){return p(b)?f()?void D(b,e,g):void h("Aborting because element container has not been initialized"):void h("Aborting because element has been uninstalled")}),i&&d&&o.add(2,function(){return p(b)?f()?void d():void h("Aborting because element container has not been initialized"):void h("Aborting because element has been uninstalled")})}function f(){return!!p(b).container}function g(){h("notifyListenersIfNeeded invoked");var a=p(b);return function(){return void 0===p(b).lastNotifiedWidth}()&&a.lastWidth===a.startSize.width&&a.lastHeight===a.startSize.height?h("Not notifying: Size is the same as the start size, and there has been no notification yet."):a.lastWidth===a.lastNotifiedWidth&&a.lastHeight===a.lastNotifiedHeight?h("Not notifying: Size already notified"):(h("Current size not notified, notifying..."),a.lastNotifiedWidth=a.lastWidth,a.lastNotifiedHeight=a.lastHeight,void d(p(b).listeners,function(a){a(b)}))}function l(){if(h("startanimation triggered."),k(b))return void h("Ignoring since element is still unrendered...");h("Element rendered.");var a=i(b),c=j(b);0!==a.scrollLeft&&0!==a.scrollTop&&0!==c.scrollLeft&&0!==c.scrollTop||(h("Scrollbars out of sync. Updating detector elements..."),e(g))}function m(){if(h("Scroll detected."),k(b))return void h("Scroll event fired while unrendered. Ignoring...");e(g)}if(h("registerListenersAndPositionElements invoked."),!p(b))return void h("Aborting because element has been uninstalled");p(b).onRendered=l,p(b).onExpand=m,p(b).onShrink=m;var r=p(b).style;c(b,r.width,r.height)}function H(){if(h("finalizeDomMutation invoked."),!p(b))return void h("Aborting because element has been uninstalled");var a=p(b).style;v(b,a.width,a.height),D(b,a.width,a.height)}function I(){e(b)}function J(){h("Installing..."),s(),m(),o.add(0,u),o.add(1,F),o.add(2,G),o.add(3,H),o.add(4,I)}e||(e=b,b=a,a=null),a=a||{},h("Making detectable..."),!function(a){return!function(a){return a===a.ownerDocument.body||a.ownerDocument.body.contains(a)}(a)||null===window.getComputedStyle(a)}(b)?J():(h("Element is detached"),E(),h("Waiting until element is attached..."),p(b).onRendered=function(){h("Element is now attached"),J()})}function m(a){var b=p(a);b&&(b.onExpandScroll&&h(i(a),"scroll",b.onExpandScroll),b.onShrinkScroll&&h(j(a),"scroll",b.onShrinkScroll),b.onAnimationStart&&h(b.container,"animationstart",b.onAnimationStart),b.container&&a.removeChild(b.container))}a=a||{};var n=a.reporter,o=a.batchProcessor,p=a.stateHandler.getState,q=(a.stateHandler.hasState,a.idHandler);if(!o)throw new Error("Missing required dependency: batchProcessor");if(!n)throw new Error("Missing required dependency: reporter.");var r=function(){var a=document.createElement("div");a.style.cssText=c(["position: absolute","width: 1000px","height: 1000px","visibility: hidden","margin: 0","padding: 0"]);var b=document.createElement("div");b.style.cssText=c(["position: absolute","width: 500px","height: 500px","overflow: scroll","visibility: none","top: -1500px","left: -1500px","visibility: hidden","margin: 0","padding: 0"]),b.appendChild(a),document.body.insertBefore(b,document.body.firstChild);var d=500-b.clientWidth,e=500-b.clientHeight;return document.body.removeChild(b),{width:d,height:e}}(),s="erd_scroll_detection_scrollbar_style",t="erd_scroll_detection_container";return b(window.document),{makeDetectable:l,addListener:k,uninstall:m,initDocument:b}}},{"../collection-utils":4}],7:[function(a,b,c){"use strict";function d(a){return Array.isArray(a)||void 0!==a.length}function e(a){if(Array.isArray(a))return a;var b=[];return h(a,function(a){b.push(a)}),b}function f(a){return a&&1===a.nodeType}function g(a,b,c){var d=a[b];return void 0!==d&&null!==d||void 0===c?d:c}var h=a("./collection-utils").forEach,i=a("./element-utils"),j=a("./listener-handler"),k=a("./id-generator"),l=a("./id-handler"),m=a("./reporter"),n=a("./browser-detector"),o=a("batch-processor"),p=a("./state-handler"),q=a("./detection-strategy/object.js"),r=a("./detection-strategy/scroll.js");b.exports=function(a){function b(a,b,c){function i(a){var b=A.get(a);h(b,function(b){b(a)})}function j(a,b,c){A.add(b,c),a&&c(b)}if(c||(c=b,b=a,a={}),!b)throw new Error("At least one element required.");if(!c)throw new Error("Listener required.");if(f(b))b=[b];else{if(!d(b))return w.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");b=e(b)}var k=0,l=g(a,"callOnAdd",y.callOnAdd),m=g(a,"onReady",function(){}),n=g(a,"debug",y.debug);h(b,function(a){p.getState(a)||(p.initState(a),t.set(a));var d=t.get(a);if(n&&w.log("Attaching listener to element",d,a),!B.isDetectable(a))return n&&w.log(d,"Not detectable."),B.isBusy(a)?(n&&w.log(d,"System busy making it detectable"),j(l,a,c),F[d]=F[d]||[],void F[d].push(function(){++k===b.length&&m()})):(n&&w.log(d,"Making detectable..."),B.markBusy(a,!0),z.makeDetectable({debug:n,important:D},a,function(a){if(n&&w.log(d,"onElementDetectable"),p.getState(a)){B.markAsDetectable(a),B.markBusy(a,!1),z.addListener(a,i),j(l,a,c);var e=p.getState(a);if(e&&e.startSize){var f=a.offsetWidth,g=a.offsetHeight;e.startSize.width===f&&e.startSize.height===g||i(a)}F[d]&&h(F[d],function(a){a()})}else n&&w.log(d,"Element uninstalled before being detectable.");delete F[d],++k===b.length&&m()}));n&&w.log(d,"Already detecable, adding listener."),j(l,a,c),k++}),k===b.length&&m()}function c(a){if(!a)return w.error("At least one element is required.");if(f(a))a=[a];else{if(!d(a))return w.error("Invalid arguments. Must be a DOM element or a collection of DOM elements.");a=e(a)}h(a,function(a){A.removeAllListeners(a),z.uninstall(a),p.cleanState(a)})}function s(a){z.initDocument&&z.initDocument(a)}a=a||{};var t;if(a.idHandler)t={get:function(b){return a.idHandler.get(b,!0)},set:a.idHandler.set};else{var u=k(),v=l({idGenerator:u,stateHandler:p});t=v}var w=a.reporter;if(!w){w=m(!1===w)}var x=g(a,"batchProcessor",o({reporter:w})),y={};y.callOnAdd=!!g(a,"callOnAdd",!0),y.debug=!!g(a,"debug",!1);var z,A=j(t),B=i({stateHandler:p}),C=g(a,"strategy","object"),D=g(a,"important",!1),E={reporter:w,batchProcessor:x,stateHandler:p,idHandler:t,important:D};if("scroll"===C&&(n.isLegacyOpera()?(w.warn("Scroll strategy is not supported on legacy Opera. Changing to object strategy."),C="object"):n.isIE(9)&&(w.warn("Scroll strategy is not supported on IE9. Changing to object strategy."),C="object")),"scroll"===C)z=r(E);else{if("object"!==C)throw new Error("Invalid strategy name: "+C);z=q(E)}var F={};return{listenTo:b,removeListener:A.removeListener,removeAllListeners:A.removeAllListeners,uninstall:c,initDocument:s}}},{"./browser-detector":3,"./collection-utils":4,"./detection-strategy/object.js":5,"./detection-strategy/scroll.js":6,"./element-utils":8,"./id-generator":9,"./id-handler":10,"./listener-handler":11,"./reporter":12,"./state-handler":13,"batch-processor":1}],8:[function(a,b,c){"use strict";b.exports=function(a){function b(a){var b=f(a);return b&&!!b.isDetectable}function c(a){f(a).isDetectable=!0}function d(a){return!!f(a).busy}function e(a,b){f(a).busy=!!b}var f=a.stateHandler.getState;return{isDetectable:b,markAsDetectable:c,isBusy:d,markBusy:e}}},{}],9:[function(a,b,c){"use strict";b.exports=function(){function a(){return b++}var b=1;return{generate:a}}},{}],10:[function(a,b,c){"use strict";b.exports=function(a){function b(a){var b=e(a);return b&&void 0!==b.id?b.id:null}function c(a){var b=e(a);if(!b)throw new Error("setId required the element to have a resize detection state.");var c=d.generate();return b.id=c,c}var d=a.idGenerator,e=a.stateHandler.getState;return{get:b,set:c}}},{}],11:[function(a,b,c){"use strict";b.exports=function(a){function b(b){var c=a.get(b);return void 0===c?[]:f[c]||[]}function c(b,c){var d=a.get(b);f[d]||(f[d]=[]),f[d].push(c)}function d(a,c){for(var d=b(a),e=0,f=d.length;e<f;++e)if(d[e]===c){d.splice(e,1);break}}function e(a){var c=b(a);c&&(c.length=0)}var f={};return{get:b,add:c,removeListener:d,removeAllListeners:e}}},{}],12:[function(a,b,c){"use strict";b.exports=function(a){function b(){}var c={log:b,warn:b,error:b};if(!a&&window.console){var d=function(a,b){a[b]=function(){var a=console[b];if(a.apply)a.apply(console,arguments);else for(var c=0;c<arguments.length;c++)a(arguments[c])}};d(c,"log"),d(c,"warn"),d(c,"error")}return c}},{}],13:[function(a,b,c){"use strict";function d(a){return a[g]={},e(a)}function e(a){return a[g]}function f(a){delete a[g]}var g="_erd";b.exports={initState:d,getState:e,cleanState:f}},{}]},{},[7])(7)}); |
{ | ||
"name": "element-resize-detector", | ||
"version": "1.1.14", | ||
"version": "1.2.0", | ||
"description": "Resize event emitter for elements.", | ||
@@ -14,20 +14,20 @@ "homepage": "https://github.com/wnr/element-resize-detector", | ||
"dependencies": { | ||
"batch-processor": "^1.0.0" | ||
"batch-processor": "1.0.0" | ||
}, | ||
"devDependencies": { | ||
"grunt": "^1.0.1", | ||
"grunt-banner": "^0.6.0", | ||
"grunt-browserify": "^5.0.0", | ||
"grunt-contrib-jshint": "^1.1.0", | ||
"grunt-contrib-uglify": "^2.1.0", | ||
"grunt-karma": "^2.0.0", | ||
"jasmine-core": "^2.2.0", | ||
"jquery": "^3.1.1", | ||
"karma": "^1.5.0", | ||
"karma-chrome-launcher": "^2.0.0", | ||
"karma-firefox-launcher": "^1.0.0", | ||
"karma-jasmine": "^1.1.0", | ||
"karma-safari-launcher": "^1.0.0", | ||
"load-grunt-tasks": "^3.0.0", | ||
"lodash": "^4.17.4" | ||
"grunt": "1.0.1", | ||
"grunt-banner": "0.6.0", | ||
"grunt-browserify": "5.2.0", | ||
"grunt-contrib-jshint": "1.1.0", | ||
"grunt-contrib-uglify": "2.3.0", | ||
"grunt-karma": "2.0.0", | ||
"jasmine-core": "2.9.0", | ||
"jquery": "3.1.1", | ||
"karma": "1.7.1", | ||
"karma-chrome-launcher": "2.2.0", | ||
"karma-firefox-launcher": "1.1.0", | ||
"karma-jasmine": "1.1.1", | ||
"karma-safari-launcher": "1.0.0", | ||
"load-grunt-tasks": "3.5.2", | ||
"lodash": "4.17.4" | ||
}, | ||
@@ -34,0 +34,0 @@ "scripts": { |
@@ -57,2 +57,5 @@ # element-resize-detector | ||
### initDocument(document) | ||
If you need to listen to elements inside another document (such as an iframe), you need to init that document with this function. Otherwise the library won't be able to detect when elements are attached to the document. So for an iframe, simpy invoke ``erd.initDocument(iframe.contentDocument);`` when the iframe is mounted on the DOM for the first time. The document from which the element resize detector instance is created will be initialized automatically. Notice that a new document is created when an iframe loads its content. So for iframes, be sure you invoke this function for each `onLoad` iframe event. | ||
## Caveats | ||
@@ -74,2 +77,10 @@ | ||
#### 1.2.0 | ||
* Add new method ``initDocument(document)`` which is needed when listening to detached elements in other documents, such as iframes. | ||
* Add a new optional option that adds `important!` to most style properties, to avoid CSS overriding. Disabled by default. | ||
* Fix an issue with the object approach in IE8. See #95. | ||
* Fix uninstall issue with object approach. See #102. | ||
* Fixed errornous optimization that prevented scrollbar repositioning for really fast x -> y -> x resizes. | ||
#### 1.1.14 | ||
@@ -76,0 +87,0 @@ |
@@ -27,6 +27,2 @@ /** | ||
function addListener(element, listener) { | ||
if(!getObject(element)) { | ||
throw new Error("Element is not detectable by this strategy."); | ||
} | ||
function listenerProxy() { | ||
@@ -44,2 +40,7 @@ listener(element); | ||
var object = getObject(element); | ||
if(!object) { | ||
throw new Error("Element is not detectable by this strategy."); | ||
} | ||
object.contentDocument.defaultView.addEventListener("resize", listenerProxy); | ||
@@ -49,2 +50,8 @@ } | ||
function buildCssTextString(rules) { | ||
var seperator = options.important ? " !important; " : "; "; | ||
return (rules.join(seperator) + seperator).trim(); | ||
} | ||
/** | ||
@@ -68,3 +75,3 @@ * Makes an element detectable and ready to be listened for resize events. Will call the callback when the element is ready to be listened for resize changes. | ||
function injectObject(element, callback) { | ||
var OBJECT_STYLE = "display: block; position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; padding: 0; margin: 0; opacity: 0; z-index: -1000; pointer-events: none;"; | ||
var OBJECT_STYLE = buildCssTextString(["display: block", "position: absolute", "top: 0", "left: 0", "width: 100%", "height: 100%", "border: none", "padding: 0", "margin: 0", "opacity: 0", "z-index: -1000", "pointer-events: none"]); | ||
@@ -90,3 +97,3 @@ //The target element needs to be positioned (everything except static) so the absolute positioned object will be positioned relative to the target element. | ||
if(style.position === "static") { | ||
element.style.position = "relative"; | ||
element.style.setProperty("position", "relative", options.important ? "important" : ""); | ||
@@ -102,3 +109,3 @@ var removeRelativeStyles = function(reporter, element, style, property) { | ||
reporter.warn("An element that is positioned static has style." + property + "=" + value + " which is ignored due to the static positioning. The element will need to be positioned relative, so the style." + property + " will be set to 0. Element: ", element); | ||
element.style[property] = 0; | ||
element.style.setProperty(property, "0", options.important ? "important" : ""); | ||
} | ||
@@ -170,2 +177,7 @@ }; | ||
if (!getState(element)) { | ||
// The element has been uninstalled before the actual loading happened. | ||
return; | ||
} | ||
element.appendChild(object); | ||
@@ -208,6 +220,16 @@ getState(element).object = object; | ||
function uninstall(element) { | ||
if(browserDetector.isIE(8)) { | ||
element.detachEvent("onresize", getState(element).object.proxy); | ||
if (!getState(element)) { | ||
return; | ||
} | ||
var object = getObject(element); | ||
if (!object) { | ||
return; | ||
} | ||
if (browserDetector.isIE(8)) { | ||
element.detachEvent("onresize", object.proxy); | ||
} else { | ||
element.removeChild(getObject(element)); | ||
element.removeChild(object); | ||
} | ||
@@ -214,0 +236,0 @@ delete getState(element).object; |
@@ -29,8 +29,19 @@ /** | ||
// Inject the scrollbar styling that prevents them from appearing sometimes in Chrome. | ||
// The injected container needs to have a class, so that it may be styled with CSS (pseudo elements). | ||
var styleId = "erd_scroll_detection_scrollbar_style"; | ||
var detectionContainerClass = "erd_scroll_detection_container"; | ||
injectScrollStyle(styleId, detectionContainerClass); | ||
function initDocument(targetDocument) { | ||
// Inject the scrollbar styling that prevents them from appearing sometimes in Chrome. | ||
// The injected container needs to have a class, so that it may be styled with CSS (pseudo elements). | ||
injectScrollStyle(targetDocument, styleId, detectionContainerClass); | ||
} | ||
initDocument(window.document); | ||
function buildCssTextString(rules) { | ||
var seperator = options.important ? " !important; " : "; "; | ||
return (rules.join(seperator) + seperator).trim(); | ||
} | ||
function getScrollbarSizes() { | ||
@@ -41,6 +52,6 @@ var width = 500; | ||
var child = document.createElement("div"); | ||
child.style.cssText = "position: absolute; width: " + width*2 + "px; height: " + height*2 + "px; visibility: hidden; margin: 0; padding: 0;"; | ||
child.style.cssText = buildCssTextString(["position: absolute", "width: " + width*2 + "px", "height: " + height*2 + "px", "visibility: hidden", "margin: 0", "padding: 0"]); | ||
var container = document.createElement("div"); | ||
container.style.cssText = "position: absolute; width: " + width + "px; height: " + height + "px; overflow: scroll; visibility: none; top: " + -width*3 + "px; left: " + -height*3 + "px; visibility: hidden; margin: 0; padding: 0;"; | ||
container.style.cssText = buildCssTextString(["position: absolute", "width: " + width + "px", "height: " + height + "px", "overflow: scroll", "visibility: none", "top: " + -width*3 + "px", "left: " + -height*3 + "px", "visibility: hidden", "margin: 0", "padding: 0"]); | ||
@@ -62,9 +73,9 @@ container.appendChild(child); | ||
function injectScrollStyle(styleId, containerClass) { | ||
function injectScrollStyle(targetDocument, styleId, containerClass) { | ||
function injectStyle(style, method) { | ||
method = method || function (element) { | ||
document.head.appendChild(element); | ||
targetDocument.head.appendChild(element); | ||
}; | ||
var styleElement = document.createElement("style"); | ||
var styleElement = targetDocument.createElement("style"); | ||
styleElement.innerHTML = style; | ||
@@ -76,8 +87,8 @@ styleElement.id = styleId; | ||
if (!document.getElementById(styleId)) { | ||
if (!targetDocument.getElementById(styleId)) { | ||
var containerAnimationClass = containerClass + "_animation"; | ||
var containerAnimationActiveClass = containerClass + "_animation_active"; | ||
var style = "/* Created by the element-resize-detector library. */\n"; | ||
style += "." + containerClass + " > div::-webkit-scrollbar { display: none; }\n\n"; | ||
style += "." + containerAnimationActiveClass + " { -webkit-animation-duration: 0.1s; animation-duration: 0.1s; -webkit-animation-name: " + containerAnimationClass + "; animation-name: " + containerAnimationClass + "; }\n"; | ||
style += "." + containerClass + " > div::-webkit-scrollbar { " + buildCssTextString(["display: none"]) + " }\n\n"; | ||
style += "." + containerAnimationActiveClass + " { " + buildCssTextString(["-webkit-animation-duration: 0.1s", "animation-duration: 0.1s", "-webkit-animation-name: " + containerAnimationClass, "animation-name: " + containerAnimationClass]) + " }\n"; | ||
style += "@-webkit-keyframes " + containerAnimationClass + " { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }\n"; | ||
@@ -284,3 +295,3 @@ style += "@keyframes " + containerAnimationClass + " { 0% { opacity: 1; } 50% { opacity: 0; } 100% { opacity: 1; } }"; | ||
container.className = detectionContainerClass; | ||
container.style.cssText = "visibility: hidden; display: inline; width: 0px; height: 0px; z-index: -1; overflow: hidden; margin: 0; padding: 0;"; | ||
container.style.cssText = buildCssTextString(["visibility: hidden", "display: inline", "width: 0px", "height: 0px", "z-index: -1", "overflow: hidden", "margin: 0", "padding: 0"]); | ||
getState(element).container = container; | ||
@@ -309,3 +320,3 @@ addAnimationClass(container); | ||
if(style.position === "static") { | ||
element.style.position = "relative"; | ||
element.style.setProperty("position", "relative",options.important ? "important" : ""); | ||
@@ -340,3 +351,3 @@ var removeRelativeStyles = function(reporter, element, style, property) { | ||
return "left: " + left + "; top: " + top + "; right: " + right + "; bottom: " + bottom + ";"; | ||
return ["left: " + left, "top: " + top, "right: " + right, "bottom: " + bottom]; | ||
} | ||
@@ -369,8 +380,8 @@ | ||
var scrollbarHeight = scrollbarSizes.height; | ||
var containerContainerStyle = "position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; width: 100%; height: 100%; left: 0px; top: 0px;"; | ||
var containerStyle = "position: absolute; flex: none; overflow: hidden; z-index: -1; visibility: hidden; " + getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth); | ||
var expandStyle = "position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;"; | ||
var shrinkStyle = "position: absolute; flex: none; overflow: scroll; z-index: -1; visibility: hidden; width: 100%; height: 100%;"; | ||
var expandChildStyle = "position: absolute; left: 0; top: 0;"; | ||
var shrinkChildStyle = "position: absolute; width: 200%; height: 200%;"; | ||
var containerContainerStyle = buildCssTextString(["position: absolute", "flex: none", "overflow: hidden", "z-index: -1", "visibility: hidden", "width: 100%", "height: 100%", "left: 0px", "top: 0px"]); | ||
var containerStyle = buildCssTextString(["position: absolute", "flex: none", "overflow: hidden", "z-index: -1", "visibility: hidden"].concat(getLeftTopBottomRightCssText(-(1 + scrollbarWidth), -(1 + scrollbarHeight), -scrollbarHeight, -scrollbarWidth))); | ||
var expandStyle = buildCssTextString(["position: absolute", "flex: none", "overflow: scroll", "z-index: -1", "visibility: hidden", "width: 100%", "height: 100%"]); | ||
var shrinkStyle = buildCssTextString(["position: absolute", "flex: none", "overflow: scroll", "z-index: -1", "visibility: hidden", "width: 100%", "height: 100%"]); | ||
var expandChildStyle = buildCssTextString(["position: absolute", "left: 0", "top: 0"]); | ||
var shrinkChildStyle = buildCssTextString(["position: absolute", "width: 200%", "height: 200%"]); | ||
@@ -426,4 +437,4 @@ var containerContainer = document.createElement("div"); | ||
var expandHeight = getExpandHeight(height); | ||
expandChild.style.width = expandWidth + "px"; | ||
expandChild.style.height = expandHeight + "px"; | ||
expandChild.style.setProperty("width", expandWidth + "px", options.important ? "important" : ""); | ||
expandChild.style.setProperty("height", expandHeight + "px", options.important ? "important" : ""); | ||
} | ||
@@ -435,2 +446,5 @@ | ||
// Check whether the size has actually changed since last time the algorithm ran. If not, some steps may be skipped. | ||
var sizeChanged = width !== getState(element).lastWidth || height !== getState(element).lastHeight; | ||
debug("Storing current size", width, height); | ||
@@ -446,2 +460,6 @@ | ||
batchProcessor.add(0, function performUpdateChildSizes() { | ||
if (!sizeChanged) { | ||
return; | ||
} | ||
if (!getState(element)) { | ||
@@ -470,2 +488,5 @@ debug("Aborting because element has been uninstalled"); | ||
batchProcessor.add(1, function updateScrollbars() { | ||
// This function needs to be invoked event though the size is unchanged. The element could have been resized very quickly and then | ||
// been restored to the original size, which will have changed the scrollbar positions. | ||
if (!getState(element)) { | ||
@@ -484,3 +505,3 @@ debug("Aborting because element has been uninstalled"); | ||
if (done) { | ||
if (sizeChanged && done) { | ||
batchProcessor.add(2, function () { | ||
@@ -515,3 +536,3 @@ if (!getState(element)) { | ||
// Don't notify the if the current size is the start size, and this is the first notification. | ||
// Don't notify if the current size is the start size, and this is the first notification. | ||
if (isFirstNotify() && state.lastWidth === state.startSize.width && state.lastHeight === state.startSize.height) { | ||
@@ -561,11 +582,3 @@ return debug("Not notifying: Size is the same as the start size, and there has been no notification yet."); | ||
var width = element.offsetWidth; | ||
var height = element.offsetHeight; | ||
if (width !== getState(element).lastWidth || height !== getState(element).lastHeight) { | ||
debug("Element size changed."); | ||
updateDetectorElements(notifyListenersIfNeeded); | ||
} else { | ||
debug("Element size has not changed (" + width + "x" + height + ")."); | ||
} | ||
updateDetectorElements(notifyListenersIfNeeded); | ||
} | ||
@@ -660,4 +673,5 @@ | ||
addListener: addListener, | ||
uninstall: uninstall | ||
uninstall: uninstall, | ||
initDocument: initDocument | ||
}; | ||
}; |
@@ -110,2 +110,3 @@ "use strict"; | ||
var desiredStrategy = getOption(options, "strategy", "object"); | ||
var importantCssRules = getOption(options, "important", false); | ||
var strategyOptions = { | ||
@@ -115,3 +116,4 @@ reporter: reporter, | ||
stateHandler: stateHandler, | ||
idHandler: idHandler | ||
idHandler: idHandler, | ||
important: importantCssRules | ||
}; | ||
@@ -231,3 +233,3 @@ | ||
elementUtils.markBusy(element, true); | ||
return detectionStrategy.makeDetectable({ debug: debug }, element, function onElementDetectable(element) { | ||
return detectionStrategy.makeDetectable({ debug: debug, important: importantCssRules }, element, function onElementDetectable(element) { | ||
debug && reporter.log(id, "onElementDetectable"); | ||
@@ -308,2 +310,6 @@ | ||
function initDocument(targetDocument) { | ||
detectionStrategy.initDocument && detectionStrategy.initDocument(targetDocument); | ||
} | ||
return { | ||
@@ -313,3 +319,4 @@ listenTo: listenTo, | ||
removeAllListeners: eventListenerHandler.removeAllListeners, | ||
uninstall: uninstall | ||
uninstall: uninstall, | ||
initDocument: initDocument | ||
}; | ||
@@ -316,0 +323,0 @@ }; |
@@ -11,3 +11,3 @@ /* global describe:false, it:false, beforeEach:false, expect:false, elementResizeDetectorMaker:false, _:false, $:false, jasmine:false */ | ||
var diffValueKeys = _.filter(unionKeys, function(key) { | ||
var diffValueKeys = _.filter(unionKeys, function (key) { | ||
var beforeValue = before[key]; | ||
@@ -18,7 +18,7 @@ var afterValue = after[key]; | ||
if(diffValueKeys.length) { | ||
if (diffValueKeys.length) { | ||
var beforeDiffObject = {}; | ||
var afterDiffObject = {}; | ||
_.forEach(diffValueKeys, function(key) { | ||
_.forEach(diffValueKeys, function (key) { | ||
beforeDiffObject[key] = before[key]; | ||
@@ -35,7 +35,7 @@ afterDiffObject[key] = after[key]; | ||
var clonedTarget = {}; | ||
_.forEach(styleObject.cssText.split(";").slice(0, -1), function(declaration){ | ||
_.forEach(styleObject.cssText.split(";").slice(0, -1), function (declaration) { | ||
var colonPos = declaration.indexOf(":"); | ||
var attr = declaration.slice(0, colonPos).trim(); | ||
if(attr.indexOf("-") === -1){ // Remove attributes like "background-image", leaving "backgroundImage" | ||
clonedTarget[attr] = declaration.slice(colonPos+2); | ||
if (attr.indexOf("-") === -1) { // Remove attributes like "background-image", leaving "backgroundImage" | ||
clonedTarget[attr] = declaration.slice(colonPos + 2); | ||
} | ||
@@ -52,3 +52,3 @@ }); | ||
var attrs = {}; | ||
_.forEach(element.attributes, function(attr) { | ||
_.forEach(element.attributes, function (attr) { | ||
attrs[attr.nodeName] = attr.value; | ||
@@ -62,9 +62,9 @@ }); | ||
var reporter = { | ||
log: function() { | ||
log: function () { | ||
throw new Error("Reporter.log should not be called"); | ||
}, | ||
warn: function() { | ||
warn: function () { | ||
throw new Error("Reporter.warn should not be called"); | ||
}, | ||
error: function() { | ||
error: function () { | ||
throw new Error("Reporter.error should not be called"); | ||
@@ -77,4 +77,4 @@ } | ||
function listenToTest(strategy) { | ||
describe("[" + strategy + "] listenTo", function() { | ||
it("should be able to attach a listener to an element", function(done) { | ||
describe("[" + strategy + "] listenTo", function () { | ||
it("should be able to attach a listener to an element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -90,7 +90,7 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -101,3 +101,3 @@ done(); | ||
it("should throw on invalid parameters", function() { | ||
it("should throw on invalid parameters", function () { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -114,4 +114,4 @@ callOnAdd: false, | ||
describe("option.onReady", function() { | ||
it("should be called when installing a listener to an element", function(done) { | ||
describe("option.onReady", function () { | ||
it("should be called when installing a listener to an element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -126,5 +126,5 @@ callOnAdd: false, | ||
erd.listenTo({ | ||
onReady: function() { | ||
onReady: function () { | ||
$("#test").width(200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -137,3 +137,3 @@ done(); | ||
it("should be called when all elements are ready", function(done) { | ||
it("should be called when all elements are ready", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -148,6 +148,6 @@ callOnAdd: false, | ||
erd.listenTo({ | ||
onReady: function() { | ||
onReady: function () { | ||
$("#test").width(200); | ||
$("#test2").width(300); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -161,3 +161,3 @@ expect(listener).toHaveBeenCalledWith($("#test2")[0]); | ||
it("should be able to handle listeners for the same element but different calls", function(done) { | ||
it("should be able to handle listeners for the same element but different calls", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -174,8 +174,10 @@ callOnAdd: false, | ||
onReady: onReady1 | ||
}, $("#test"), function noop() {}); | ||
}, $("#test"), function noop() { | ||
}); | ||
erd.listenTo({ | ||
onReady: onReady2 | ||
}, $("#test"), function noop() {}); | ||
}, $("#test"), function noop() { | ||
}); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(onReady1.calls.count()).toBe(1); | ||
@@ -187,3 +189,3 @@ expect(onReady2.calls.count()).toBe(1); | ||
it("should be able to handle when elements occur multiple times in the same call (and other calls)", function(done) { | ||
it("should be able to handle when elements occur multiple times in the same call (and other calls)", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -200,8 +202,10 @@ callOnAdd: false, | ||
onReady: onReady1 | ||
}, [$("#test")[0], $("#test")[0]], function noop() {}); | ||
}, [$("#test")[0], $("#test")[0]], function noop() { | ||
}); | ||
erd.listenTo({ | ||
onReady: onReady2 | ||
}, $("#test"), function noop() {}); | ||
}, $("#test"), function noop() { | ||
}); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(onReady1.calls.count()).toBe(1); | ||
@@ -214,3 +218,3 @@ expect(onReady2.calls.count()).toBe(1); | ||
it("should be able to attach multiple listeners to an element", function(done) { | ||
it("should be able to attach multiple listeners to an element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -228,7 +232,7 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -240,3 +244,3 @@ expect(listener2).toHaveBeenCalledWith($("#test")[0]); | ||
it("should be able to attach a listener to an element multiple times within the same call", function(done) { | ||
it("should be able to attach a listener to an element multiple times within the same call", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -252,7 +256,7 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -264,3 +268,3 @@ expect(listener1.calls.count()).toBe(2); | ||
it("should be able to attach listeners to multiple elements", function(done) { | ||
it("should be able to attach listeners to multiple elements", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -276,17 +280,17 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(200); | ||
}, 200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
}, 400); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test2").width(500); | ||
}, 600); | ||
setTimeout(function() { | ||
expect(listener1).toHaveBeenCalledWith($("#test2")[0]); | ||
done(); | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test2")[0]); | ||
done(); | ||
}, 800); | ||
@@ -297,4 +301,4 @@ }); | ||
//Only IE8 is lacking the getComputedStyle method. | ||
if(window.getComputedStyle) { | ||
it("should keep the style of the element intact", function(done) { | ||
if (window.getComputedStyle) { | ||
it("should keep the style of the element intact", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -307,4 +311,4 @@ callOnAdd: false, | ||
function ignoreStyleChange(key, before, after) { | ||
return (key === "position" && before === "static" && after === "relative") || | ||
(/^(top|right|bottom|left)$/.test(key) && before === "auto" && after === "0px"); | ||
return (key === "position" && before === "static" && after === "relative") || | ||
(/^(top|right|bottom|left)$/.test(key) && before === "auto" && after === "0px"); | ||
} | ||
@@ -318,3 +322,3 @@ | ||
//Test styles async since making an element listenable is async. | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
var afterComputedStyleAsync = getStyle($("#test")[0]); | ||
@@ -328,4 +332,4 @@ ensureMapEqual(beforeComputedStyle, afterComputedStyleAsync, ignoreStyleChange); | ||
describe("options.callOnAdd", function() { | ||
it("should be true default and call all functions when listenTo succeeds", function(done) { | ||
describe("options.callOnAdd", function () { | ||
it("should be true default and call all functions when listenTo succeeds", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -342,3 +346,3 @@ reporter: reporter, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -351,3 +355,3 @@ expect(listener2).toHaveBeenCalledWith($("#test")[0]); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -359,3 +363,3 @@ expect(listener2).toHaveBeenCalledWith($("#test")[0]); | ||
it("should call listener multiple times when listening to multiple elements", function(done) { | ||
it("should call listener multiple times when listening to multiple elements", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -369,3 +373,3 @@ reporter: reporter, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -378,3 +382,3 @@ expect(listener1).toHaveBeenCalledWith($("#test2")[0]); | ||
it("should call listener if the element is changed synchronously after listenTo", function(done) { | ||
it("should call listener if the element is changed synchronously after listenTo", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -390,3 +394,3 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -407,3 +411,3 @@ done(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).not.toHaveBeenCalledWith($("#test")[0]); | ||
@@ -425,3 +429,3 @@ done(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).not.toHaveBeenCalledWith($("#test")[0]); | ||
@@ -432,3 +436,3 @@ listener.calls.reset(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -439,3 +443,3 @@ listener.calls.reset(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -446,8 +450,8 @@ done(); | ||
it("should use the option.idHandler if present", function(done) { | ||
it("should use the option.idHandler if present", function (done) { | ||
var ID_ATTR = "some-fancy-id-attr"; | ||
var idHandler = { | ||
get: function(element, readonly) { | ||
if(element[ID_ATTR] === undefined) { | ||
get: function (element, readonly) { | ||
if (element[ID_ATTR] === undefined) { | ||
if (readonly) { | ||
@@ -465,5 +469,5 @@ return null; | ||
if($(element).attr("id") === "test") { | ||
if ($(element).attr("id") === "test") { | ||
id = "test+1"; | ||
} else if($(element).attr("id") === "test2") { | ||
} else if ($(element).attr("id") === "test2") { | ||
id = "test2+2"; | ||
@@ -497,3 +501,3 @@ } | ||
var ignoreValidIdAttrAndStyle = function(key) { | ||
var ignoreValidIdAttrAndStyle = function (key) { | ||
return key === ID_ATTR || key === "style"; | ||
@@ -508,3 +512,3 @@ }; | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
@@ -514,11 +518,11 @@ $("#test2").width(500); | ||
setTimeout(function() { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
expect(listener2).toHaveBeenCalledWith($("#test")[0]); | ||
expect(listener2).toHaveBeenCalledWith($("#test2")[0]); | ||
done(); | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith($("#test")[0]); | ||
expect(listener2).toHaveBeenCalledWith($("#test")[0]); | ||
expect(listener2).toHaveBeenCalledWith($("#test2")[0]); | ||
done(); | ||
}, 600); | ||
}); | ||
it("should be able to install into elements that are detached from the DOM", function(done) { | ||
it("should be able to install into elements that are detached from the DOM", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -544,3 +548,3 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith(div); | ||
@@ -551,2 +555,36 @@ done(); | ||
it("should handle iframes, by using initDocument", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: false, | ||
strategy: strategy, | ||
reporter: reporter | ||
}); | ||
var listener1 = jasmine.createSpy("listener1"); | ||
var iframe = document.createElement("iframe"); | ||
$("#test")[0].appendChild(iframe); | ||
erd.initDocument(iframe.contentDocument); | ||
var div = iframe.contentDocument.createElement("div"); | ||
div.style.width = "100%"; | ||
div.style.height = "100%"; | ||
div.id = "target"; | ||
erd.listenTo(div, listener1); | ||
setTimeout(function () { | ||
// FireFox triggers the onload state of the iframe and wipes its content. | ||
iframe.contentDocument.body.appendChild(div); | ||
erd.initDocument(iframe.contentDocument); | ||
}, 10); | ||
setTimeout(function () { | ||
div.style.width = "100px"; | ||
}, 200); | ||
setTimeout(function () { | ||
expect(listener1).toHaveBeenCalledWith(div); | ||
done(); | ||
}, 400); | ||
}); | ||
it("should detect resizes caused by padding and font-size changes", function (done) { | ||
@@ -568,3 +606,3 @@ var erd = elementResizeDetectorMaker({ | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -575,3 +613,3 @@ listener.calls.reset(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -707,7 +745,7 @@ done(); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 200); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
@@ -717,2 +755,49 @@ done(); | ||
}); | ||
it("should handle fast consecutive resizes", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: false, | ||
strategy: strategy, | ||
reporter: reporter | ||
}); | ||
var listener = jasmine.createSpy("listener"); | ||
$("#test").width(100); | ||
erd.listenTo($("#test")[0], listener); | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 50); | ||
setTimeout(function () { | ||
expect(listener.calls.count()).toEqual(1); | ||
$("#test").width(500); | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 0); | ||
}, 100); | ||
// Some browsers skip the 300 -> 500 -> 300 resize, and some actually processes it. | ||
// So the resize events may be 1 or 3 at this point. | ||
setTimeout(function () { | ||
var count = listener.calls.count(); | ||
expect(count === 1 || count === 3).toEqual(true); | ||
}, 150); | ||
setTimeout(function () { | ||
var count = listener.calls.count(); | ||
expect(count === 1 || count === 3).toEqual(true); | ||
$("#test").width(800); | ||
}, 200); | ||
setTimeout(function () { | ||
var count = listener.calls.count(); | ||
expect(count === 2 || count === 4).toEqual(true); | ||
done(); | ||
}, 250); | ||
}); | ||
}); | ||
@@ -722,4 +807,4 @@ } | ||
function removalTest(strategy) { | ||
describe("[" + strategy + "] resizeDetector.removeListener", function() { | ||
it("should remove listener from element", function(done) { | ||
describe("[" + strategy + "] resizeDetector.removeListener", function () { | ||
it("should remove listener from element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -732,3 +817,3 @@ callOnAdd: false, | ||
var listenerCall = jasmine.createSpy("listener"); | ||
var listenerCall = jasmine.createSpy("listener"); | ||
var listenerNotCall = jasmine.createSpy("listener"); | ||
@@ -739,3 +824,3 @@ | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
erd.removeListener($testElem[0], listenerNotCall); | ||
@@ -745,3 +830,3 @@ $testElem.width(300); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listenerCall).toHaveBeenCalled(); | ||
@@ -754,4 +839,4 @@ expect(listenerNotCall).not.toHaveBeenCalled(); | ||
describe("[" + strategy + "] resizeDetector.removeAllListeners", function() { | ||
it("should remove all listeners from element", function(done) { | ||
describe("[" + strategy + "] resizeDetector.removeAllListeners", function () { | ||
it("should remove all listeners from element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -770,3 +855,3 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
erd.removeAllListeners($testElem[0]); | ||
@@ -776,3 +861,3 @@ $testElem.width(300); | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener1).not.toHaveBeenCalled(); | ||
@@ -784,3 +869,3 @@ expect(listener2).not.toHaveBeenCalled(); | ||
it("should work for elements that don't have the detector installed", function() { | ||
it("should work for elements that don't have the detector installed", function () { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -794,5 +879,78 @@ strategy: strategy | ||
describe("[" + strategy + "] resizeDetector.uninstall", function() { | ||
it("should completely remove detector from element", function(done) { | ||
describe("[scroll] Specific scenarios", function () { | ||
it("should be able to call uninstall in the middle of a resize", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
strategy: "scroll" | ||
}); | ||
var $testElem = $("#test"); | ||
var testElem = $testElem[0]; | ||
var listener = jasmine.createSpy("listener"); | ||
erd.listenTo(testElem, listener); | ||
setTimeout(function () { | ||
// We want the uninstall to happen exactly when a scroll event occured before the delayed batched is going to be processed. | ||
// So we intercept the erd shrink/expand functions in the state so that we may call uninstall after the handling of the event. | ||
var uninstalled = false; | ||
function wrapOnScrollEvent(oldFn) { | ||
return function () { | ||
oldFn(); | ||
if (!uninstalled) { | ||
expect(erd.uninstall.bind(erd, testElem)).not.toThrow(); | ||
uninstalled = true; | ||
done(); | ||
} | ||
}; | ||
} | ||
var state = testElem._erd; | ||
state.onExpand = wrapOnScrollEvent(state.onExpand); | ||
state.onShrink = wrapOnScrollEvent(state.onShrink); | ||
$("#test").width(300); | ||
}, 50); | ||
}); | ||
it("should be able to call uninstall and then install in the middle of a resize (issue #61)", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
strategy: "scroll", | ||
reporter: reporter | ||
}); | ||
var $testElem = $("#test"); | ||
var testElem = $testElem[0]; | ||
var listener = jasmine.createSpy("listener"); | ||
erd.listenTo(testElem, listener); | ||
setTimeout(function () { | ||
// We want the uninstall to happen exactly when a scroll event occured before the delayed batched is going to be processed. | ||
// So we intercept the erd shrink/expand functions in the state so that we may call uninstall after the handling of the event. | ||
var uninstalled = false; | ||
function wrapOnScrollEvent(oldFn) { | ||
return function () { | ||
oldFn(); | ||
if (!uninstalled) { | ||
expect(erd.uninstall.bind(erd, testElem)).not.toThrow(); | ||
uninstalled = true; | ||
var listener2 = jasmine.createSpy("listener"); | ||
expect(erd.listenTo.bind(erd, testElem, listener2)).not.toThrow(); | ||
setTimeout(function () { | ||
done(); | ||
}, 0); | ||
} | ||
}; | ||
} | ||
var state = testElem._erd; | ||
state.onExpand = wrapOnScrollEvent(state.onExpand); | ||
state.onShrink = wrapOnScrollEvent(state.onShrink); | ||
$("#test").width(300); | ||
}, 50); | ||
}); | ||
}); | ||
describe("[" + strategy + "] resizeDetector.uninstall", function () { | ||
it("should completely remove detector from element", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: false, | ||
@@ -808,3 +966,3 @@ strategy: strategy | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
erd.uninstall($testElem[0]); | ||
@@ -816,3 +974,3 @@ // detector element should be removed | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).not.toHaveBeenCalled(); | ||
@@ -823,3 +981,3 @@ done(); | ||
it("should completely remove detector from multiple elements", function(done) { | ||
it("should completely remove detector from multiple elements", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
@@ -834,3 +992,3 @@ callOnAdd: false, | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
erd.uninstall($("#test, #test2")); | ||
@@ -843,3 +1001,3 @@ // detector element should be removed | ||
setTimeout(function() { | ||
setTimeout(function () { | ||
expect(listener).not.toHaveBeenCalled(); | ||
@@ -877,69 +1035,2 @@ done(); | ||
it("should be able to call uninstall in the middle of a resize", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
strategy: strategy | ||
}); | ||
var $testElem = $("#test"); | ||
var testElem = $testElem[0]; | ||
var listener = jasmine.createSpy("listener"); | ||
erd.listenTo(testElem, listener); | ||
setTimeout(function () { | ||
// We want the uninstall to happen exactly when a scroll event occured before the delayed batched is going to be processed. | ||
// So we intercept the erd shrink/expand functions in the state so that we may call uninstall after the handling of the event. | ||
var uninstalled = false; | ||
function wrapOnScrollEvent(oldFn) { | ||
return function () { | ||
oldFn(); | ||
if (!uninstalled) { | ||
expect(erd.uninstall.bind(erd, testElem)).not.toThrow(); | ||
uninstalled = true; | ||
done(); | ||
} | ||
}; | ||
} | ||
var state = testElem._erd; | ||
state.onExpand = wrapOnScrollEvent(state.onExpand); | ||
state.onShrink = wrapOnScrollEvent(state.onShrink); | ||
$("#test").width(300); | ||
}, 50); | ||
}); | ||
it("should be able to call uninstall and then install in the middle of a resize (issue #61)", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
strategy: strategy, | ||
debug: true | ||
}); | ||
var $testElem = $("#test"); | ||
var testElem = $testElem[0]; | ||
var listener = jasmine.createSpy("listener"); | ||
erd.listenTo(testElem, listener); | ||
setTimeout(function () { | ||
// We want the uninstall to happen exactly when a scroll event occured before the delayed batched is going to be processed. | ||
// So we intercept the erd shrink/expand functions in the state so that we may call uninstall after the handling of the event. | ||
var uninstalled = false; | ||
function wrapOnScrollEvent(oldFn) { | ||
return function () { | ||
oldFn(); | ||
if (!uninstalled) { | ||
expect(erd.uninstall.bind(erd, testElem)).not.toThrow(); | ||
uninstalled = true; | ||
var listener2 = jasmine.createSpy("listener"); | ||
expect(erd.listenTo.bind(erd, testElem, listener2)).not.toThrow(); | ||
setTimeout(function () { | ||
done(); | ||
}, 0); | ||
} | ||
}; | ||
} | ||
var state = testElem._erd; | ||
state.onExpand = wrapOnScrollEvent(state.onExpand); | ||
state.onShrink = wrapOnScrollEvent(state.onShrink); | ||
$("#test").width(300); | ||
}, 50); | ||
}); | ||
it("should be able to call uninstall in callOnAdd callback", function (done) { | ||
@@ -1014,4 +1105,64 @@ var error = false; | ||
describe("element-resize-detector", function() { | ||
beforeEach(function() { | ||
function importantRuleTest(strategy) { | ||
describe("[" + strategy + "] resizeDetector.important", function () { | ||
it("should add all rules with important", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: true, | ||
strategy: strategy, | ||
important: true | ||
}); | ||
var testElem = $("#test"); | ||
var listenerCall = jasmine.createSpy("listener"); | ||
erd.listenTo(testElem[0], listenerCall); | ||
setTimeout(function () { | ||
if (strategy === "scroll") { | ||
expect(testElem[0].style.cssText).toMatch(/!important;$/); | ||
} | ||
testElem.find("*").toArray().forEach(function (element) { | ||
var rules = element.style.cssText.split(";").filter(function (rule) { | ||
return !!rule; | ||
}); | ||
rules.forEach(function (rule) { | ||
expect(rule).toMatch(/!important$/); | ||
}); | ||
}); | ||
done(); | ||
}, 50); | ||
}); | ||
it("Overrides important CSS", function (done) { | ||
var erd = elementResizeDetectorMaker({ | ||
callOnAdd: false, | ||
strategy: strategy, | ||
important: true | ||
}); | ||
var listener = jasmine.createSpy("listener"); | ||
var testElem = $("#test"); | ||
var style = document.createElement("style"); | ||
style.appendChild(document.createTextNode("#test { position: static !important; }")); | ||
document.head.appendChild(style); | ||
erd.listenTo(testElem[0], listener); | ||
setTimeout(function () { | ||
$("#test").width(300); | ||
}, 100); | ||
setTimeout(function () { | ||
expect(listener).toHaveBeenCalledWith($("#test")[0]); | ||
done(); | ||
}, 200); | ||
}); | ||
}); | ||
} | ||
describe("element-resize-detector", function () { | ||
beforeEach(function () { | ||
//This messed with tests in IE8. | ||
@@ -1023,8 +1174,8 @@ //TODO: Investigate why, because it would be nice to have instead of the current solution. | ||
describe("elementResizeDetectorMaker", function() { | ||
it("should be globally defined", function() { | ||
describe("elementResizeDetectorMaker", function () { | ||
it("should be globally defined", function () { | ||
expect(elementResizeDetectorMaker).toBeDefined(); | ||
}); | ||
it("should create an element-resize-detector instance", function() { | ||
it("should create an element-resize-detector instance", function () { | ||
var erd = elementResizeDetectorMaker(); | ||
@@ -1039,11 +1190,6 @@ | ||
// removalTest("object"); | ||
// | ||
// //Scroll only supported on non-opera browsers. | ||
// if(!window.opera) { | ||
// listenToTest("scroll"); | ||
// removalTest("scroll"); | ||
// } | ||
// importantRuleTest("object"); | ||
listenToTest("scroll"); | ||
removalTest("scroll"); | ||
importantRuleTest("scroll"); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
3713
153
247141
35
Updatedbatch-processor@1.0.0