From cbef0461fc09abaaac45e73f101b6d45ffbfc796 Mon Sep 17 00:00:00 2001 From: joeyvandijk Date: Wed, 8 Jan 2014 15:21:25 +0100 Subject: [PATCH] v1.5.0 add files --- ajax/libs/rimg/1.5.0/rimg.js | 596 +++++++++++++++++++++++++++++++ ajax/libs/rimg/1.5.0/rimg.min.js | 2 + 2 files changed, 598 insertions(+) create mode 100644 ajax/libs/rimg/1.5.0/rimg.js create mode 100644 ajax/libs/rimg/1.5.0/rimg.min.js diff --git a/ajax/libs/rimg/1.5.0/rimg.js b/ajax/libs/rimg/1.5.0/rimg.js new file mode 100644 index 000000000..ea2d8b2b9 --- /dev/null +++ b/ajax/libs/rimg/1.5.0/rimg.js @@ -0,0 +1,596 @@ +'use strict'; + +!function(){ + if(!console){ + console = { + log: function(){}, + error: function(){} + } + } + + ////////// IE8 ///////////// + if (!Object.create) { + Object.create = (function(){ + function F(){} + + return function(o){ + if (arguments.length != 1) { + throw new Error('Object.create implementation only accepts one parameter.'); + } + F.prototype = o; + return new F(); + } + })() + } + if (!Function.prototype.bind) { + Function.prototype.bind = function (oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function () {}, + fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; + } + ////////// END IE8 ///////////// + + var Rimg = function() { + var hidden = { + status : 'init', + observer : null, + breakpoints : [], + images: [], + offset:{x:100,y:100}, + resizeInfo:{wait:null,time:null}, + resizeDimensions: {width:0,height:0}, + disableIntrospection: false, + disableLazyLoading: false, + isIE8: false + }; + + if(window.addEventListener === undefined){ + hidden.isIE8 = true; + } + + function parseBreakpoints(value){ + //custom: (once) -small 640w 1x, -retina-small 640w 2x, -medium 1280w 1x, -retina-medium 1280w 2x + //custom: (per image) data-src="image.jpg" + if(typeof value === 'string'){ + var breakpoints = value.split(','); + if(breakpoints.length === 0){ + //invalid + hidden.status = 'error'; + console.error('Rimg: your breakpoint-definition '+ value +' is invalid, check the documentation.'); + return null; + } + var definition = []; + var i = 0; + var il = breakpoints.length; + while(i 0){ + return definition; + }else{ + hidden.status = 'error'; + console.error('Rimg: your breakpoint-definition misses valid breakpoints, check the documentation.'); + return null; + } + }else{ + //invalid + hidden.status = 'error'; + console.error('Rimg: your breakpoint-definition is not a String, check the documentation.'); + return null; + } + } + + //discover initial settings + if(typeof window.RimgOptions !== 'undefined'){ + //validate + var bpts = parseBreakpoints(window.RimgOptions.breakpoint); + if(bpts !== null){ + hidden.breakpoints = bpts; + } + if(window.RimgOptions.disableIntrospection === true){ + hidden.disableIntrospection = true; + } + if(window.RimgOptions.disableLazyLoading === true){ + hidden.disableLazyLoading = true; + } + if(window.RimgOptions.offset != null && typeof window.RimgOptions.offset.x === 'number' && typeof window.RimgOptions.offset.y === 'number'){ + hidden.offset.x = window.RimgOptions.offset.x; + hidden.offset.y = window.RimgOptions.offset.y; + } + //clean reference + window.RimgOptions = undefined; + }else{ + console.log('(remark) Rimg: no breakpoints defined (yet), check the documentation or manually adjust it.'); + } + + function event(type,evt,func,target){ + //add/remote event listeners + if(target === undefined){ + target = document; + } + if(evt === 'resize'){ + target = window; + } + if(hidden.isIE8){ + //switch events to add correct responsive support + if(evt === 'DOMContentLoaded'){ + evt = 'onreadystatechange'; + } + if(evt === 'resize'){ + evt = 'onresize'; + } + if(type === 'add'){ + target.attachEvent(evt,func); + }else{ + target.detachEvent(evt,func); + } + }else{ + if(type === 'add'){ + target.addEventListener(evt,func,false); + }else{ + target.removeEventListener(evt,func,false); + } + } + } + + function addImage(value){ + //add an image but check if it already is saved + var i = 0; + var il = hidden.images.length; + var found = false; + while(i (-hidden.offset.y + hidden.resizeDimensions.height + hidden.offset.y)) || + ((rect.left + rect.width) < -hidden.offset.x) || + (rect.left > (-hidden.offset.x + hidden.resizeDimensions.width + hidden.offset.x)) + ); + } + //change src property when appropriate + var ratio = window.devicePixelRatio || 1; + var data = value.getAttribute('data-src'); + if(data !== null && visible){ + //only adjust images with data-src property + var file = data.substr(0,data.lastIndexOf('.')); + var extension = data.substr(data.lastIndexOf('.')); + var size = {x:value.width,y:value.height}; + //firefox presents width/height with 0, so check getComputedStyle if necessary: + if(value.width === 0){ + size.x = window.getComputedStyle(value,null).maxWidth; + size.x = size.x.replace('px',''); + size.x = Number(size.x); + } + if(value.height === 0){ + size.y = window.getComputedStyle(value,null).maxHeight; + size.y = size.y.replace('px',''); + size.y = Number(size.y); + } + var i = 0; + var il = hidden.breakpoints.length; + var breakpoint; + while(i 1){ + //find html node + var html; + if(target.childNodes[1].nodeName !== 'HTML'){ + //needed to skip HTML comments which are detected as nodes + var i = 0; + var il = target.childNodes.length; + while(i + html = target.childNodes[1]; + } + //find body node + if(html.childNodes[1].nodeName !== 'BODY'){ + var i = 0; + var il = html.childNodes.length; + while(i + inspect(html.childNodes[1]); + } + }else{ + console.error('Rimg.execute(): not a valid DOM representation, check your code.'); + } + }else{ + if(target !== undefined && target.nodeName !== undefined && target.nodeName.toLowerCase() === 'img'){ + //direct reference + inspect(target); + }else if(target[0] !== undefined && target[0].nodeName.toLowerCase() === 'img'){ + //child reference (after add) + inspect(target[0]); + }else{ + //no element found + } + } + }, + configure: function(value){ + if(!(value instanceof Object)){ + console.error('Rimg: your definition is not an object, check the documentation.'); + return; + } + if(value.breakpoint){ + var breakpoints = parseBreakpoints(value.breakpoint); + if(breakpoints !== null){ + hidden.breakpoints = breakpoints; + } + } + if(value.disableIntrospection === true){ + hidden.disableIntrospection = true; + } + if(value.disableLazyLoading === true){ + hidden.disableLazyLoading = true; + } + if(value.offset != null && typeof value.offset.x === 'number' && typeof value.offset.y === 'number'){ + hidden.offset.x = value.offset.x; + hidden.offset.y = value.offset.y; + } + + if(hidden.status === 'ready' && !hidden.disableIntrospection){ + //save dimensions + checkDimensions(); + + //if DOM loaded, execute right away + this.execute(document); + } + }, + resized: function(e){ + if(hidden.status !== 'ready'){ + //not available anymore + return; + } + + //cleanup + if(hidden.resizeInfo.wait !== null){ + clearTimeout(hidden.resizeInfo.wait); + } + + //TODO (clear)timeout more useful? + if(hidden.resizeInfo.time === null || new Date().getTime() - hidden.resizeInfo.time > 1000){ + //first time || long ago + resize.bind(this)(); + }else{ + //wait 100ms to ensure performant and not a blocking script execution + hidden.resizeInfo.wait = setTimeout(resize.bind(this),100); + } + }, + scrolled: function(e){ + if(!hidden.disableLazyLoading){ + //execute directly for best performance / feel = "skip" will be done at adjustment check + adjustImages(); + } + }, + loaded: function(e){ + if(hidden.status !== 'progress'){ + //not available anymore + return; + } + if(hidden.isIE8 && document.readyState != 'complete'){ + return; + } + + //cleanup listener + event('remove','DOMContentLoaded',this.loaded); + + //save dimensions + checkDimensions(); + + //initial DOM checkup + if(!hidden.disableIntrospection){ + // DOM content loaded + if (hidden.observer === null) { + //check the whole page before any changes happen + this.execute(document); + }else{ + hidden.observer.observe(document.body, { + attributes: true, + childList: true, + characterData: false, + subtree: true, + attributeFilter: ['data-src'] + }); + //check full DOM + this.execute(document); + } + + //listen for browser resize + event('add','resize',this.resized.bind(this)); + } + + //initial scrolling listener + if(!hidden.disableLazyLoading){ + event('add','scroll',this.scrolled.bind(this)); + } + hidden.status = 'ready'; + }, + disableLazyLoading: function(){ + hidden.disableLazyLoading = true; + }, + disableIntrospection: function(){ + hidden.disableIntrospection = true; + + //remove mutation listeners + if(hidden.observer){ + hidden.observer.disconnect(); + }else{ + event('remove','DOMNodeInserted',nodeInserted); + } + }, + initialize: function(){ + if(hidden.status !== 'init'){ + if(hidden.status !== 'error'){ + console.error('Rimg.initialize(): Already initialized. No forced initialization supported, check your code.'); + } + return; + } + + //listen for DOM & change events + var base = this; + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + if (MutationObserver === undefined || hidden.isIE8) { + event('add','DOMAttrModified',function(e){ + //DOM attribute modified, not supported in webkit (will use MutationObserver there) + base.execute(e.target); + }); + //TODO issues with IE9 - http://help.dottoro.com/ljmcxjla.php + event('add','DOMNodeInserted',nodeInserted.bind(base)); + //ignore DOMSubtreeModified while DOMAttrModified is used, while performance does not allow 2 listeners + }else{ + hidden.observer = new MutationObserver(function(mutations) { + mutations.forEach(function(mutation) { + if(mutation.addedNodes.length > 0){ + base.execute(mutation.addedNodes); + }else if(mutation.attributeName === 'data-src'){ + base.execute(mutation.target); + } + }); + }); + } + hidden.status = 'progress'; + + //check current DOM status (already loaded?) = async support + if((document.readyState === 'interactive' || document.readyState === 'complete') && document.body){ + this.loaded.bind(this)(); + }else{ + // wait until DOM is loaded + event('add','DOMContentLoaded',this.loaded.bind(this)); + } + } + }; + }; + + // browser + window.Rimg = Object.create(Rimg()); + + // start listening + window.Rimg.initialize(); +}(); \ No newline at end of file diff --git a/ajax/libs/rimg/1.5.0/rimg.min.js b/ajax/libs/rimg/1.5.0/rimg.min.js new file mode 100644 index 000000000..c0d8c4ce4 --- /dev/null +++ b/ajax/libs/rimg/1.5.0/rimg.min.js @@ -0,0 +1,2 @@ +/*! http://github.com/joeyvandijk/rimg/ - 2014-01-08 */ +"use strict";!function(){console||(console={log:function(){},error:function(){}}),Object.create||(Object.create=function(){function F(){}return function(o){if(1!=arguments.length)throw new Error("Object.create implementation only accepts one parameter.");return F.prototype=o,new F}}()),Function.prototype.bind||(Function.prototype.bind=function(oThis){if("function"!=typeof this)throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");var aArgs=Array.prototype.slice.call(arguments,1),fToBind=this,fNOP=function(){},fBound=function(){return fToBind.apply(this instanceof fNOP&&oThis?this:oThis,aArgs.concat(Array.prototype.slice.call(arguments)))};return fNOP.prototype=this.prototype,fBound.prototype=new fNOP,fBound});var Rimg=function(){function parseBreakpoints(value){if("string"==typeof value){var breakpoints=value.split(",");if(0===breakpoints.length)return hidden.status="error",console.error("Rimg: your breakpoint-definition "+value+" is invalid, check the documentation."),null;for(var definition=[],i=0,il=breakpoints.length;il>i;){for(var bp=breakpoints[i],bpDefinition={src:[],width:-1,height:-1,pixelRatio:[],getSrc:function(value){var ratios=this.pixelRatio.length;if(0===ratios)return hidden.status="error",console.error("Rimg: missing a pixelRatio definition, check the documentation."),"";if(1===ratios)return this.src[0];if(2===ratios)return 1>=value?this.src[0]:this.src[1];for(var s=0,sl=this.pixelRatio.length;sl>s;){if(value===this.pixelRatio[s]||Math.round(value)===this.pixelRatio[s])return this.src[s];s++}return this.src[ratios-1]}},parts=bp.split(" "),p=0,pl=parts.length;pl>p;){var part=parts[p];""===part.replace(" ","")||(null!==part.match(/^[0-9]{0,4}w/gi)?bpDefinition.width=Number(part.substr(0,part.length-1)):null!==part.match(/^[0-9]{0,4}h/gi)?bpDefinition.height=Number(part.substr(0,part.length-1)):null!==part.match(/[0-9]{1}x/gi)?bpDefinition.pixelRatio.push(Number(part.substr(0,part.length-1))):bpDefinition.src.push(part)),p++}for(var d=0,dl=definition.length,found=!1;dl>d;){var def=definition[d];if(def.width===bpDefinition.width&&-1!==def.width||def.height===bpDefinition.height&&-1!==def.height){def.pixelRatio.push(bpDefinition.pixelRatio[0]),def.src.push(bpDefinition.src[0]),found=!0;break}d++}found||definition.push(bpDefinition),i++}return definition.length>0?definition:(hidden.status="error",console.error("Rimg: your breakpoint-definition misses valid breakpoints, check the documentation."),null)}return hidden.status="error",console.error("Rimg: your breakpoint-definition is not a String, check the documentation."),null}function event(type,evt,func,target){void 0===target&&(target=document),"resize"===evt&&(target=window),hidden.isIE8?("DOMContentLoaded"===evt&&(evt="onreadystatechange"),"resize"===evt&&(evt="onresize"),"add"===type?target.attachEvent(evt,func):target.detachEvent(evt,func)):"add"===type?target.addEventListener(evt,func,!1):target.removeEventListener(evt,func,!1)}function addImage(value){for(var i=0,il=hidden.images.length,found=!1;il>i;){if(hidden.images[i]===value){found=!0;break}i++}found||hidden.images.push(value)}function adjust(value){var visible=!0;if(!hidden.disableLazyLoading){var rect=value.getBoundingClientRect();visible=!(rect.top+rect.height<-hidden.offset.y||rect.top>-hidden.offset.y+hidden.resizeDimensions.height+hidden.offset.y||rect.left+rect.width<-hidden.offset.x||rect.left>-hidden.offset.x+hidden.resizeDimensions.width+hidden.offset.x)}var ratio=window.devicePixelRatio||1,data=value.getAttribute("data-src");if(null!==data&&visible){var file=data.substr(0,data.lastIndexOf(".")),extension=data.substr(data.lastIndexOf(".")),size={x:value.width,y:value.height};0===value.width&&(size.x=window.getComputedStyle(value,null).maxWidth,size.x=size.x.replace("px",""),size.x=Number(size.x)),0===value.height&&(size.y=window.getComputedStyle(value,null).maxHeight,size.y=size.y.replace("px",""),size.y=Number(size.y));for(var breakpoint,i=0,il=hidden.breakpoints.length;il>i;){var bp=hidden.breakpoints[i],wd=size.x;if(size.xi;){var item=value.children[i];inspect(item),i++}}function adjustImages(){for(var i=0,il=hidden.images.length;il>i;)adjust(hidden.images[i]),i++}function checkDimensions(){var wd,hg;hidden.isIE8?(wd=document.body.clientWidth,hg=document.body.clientHeight):(wd=window.innerWidth,hg=window.innerHeight);var changed=!1;return(hidden.resizeDimensions.width!==wd||hidden.resizeDimensions.height!==hg)&&(hidden.resizeDimensions.width=wd,hidden.resizeDimensions.height=hg,changed=!0),changed}function resize(){clearTimeout(hidden.resizeInfo.wait),checkDimensions()&&adjustImages(),hidden.resizeInfo.time=(new Date).getTime()}function nodeInserted(e){this.execute(e.target)}var hidden={status:"init",observer:null,breakpoints:[],images:[],offset:{x:100,y:100},resizeInfo:{wait:null,time:null},resizeDimensions:{width:0,height:0},disableIntrospection:!1,disableLazyLoading:!1,isIE8:!1};if(void 0===window.addEventListener&&(hidden.isIE8=!0),"undefined"!=typeof window.RimgOptions){var bpts=parseBreakpoints(window.RimgOptions.breakpoint);null!==bpts&&(hidden.breakpoints=bpts),window.RimgOptions.disableIntrospection===!0&&(hidden.disableIntrospection=!0),window.RimgOptions.disableLazyLoading===!0&&(hidden.disableLazyLoading=!0),null!=window.RimgOptions.offset&&"number"==typeof window.RimgOptions.offset.x&&"number"==typeof window.RimgOptions.offset.y&&(hidden.offset.x=window.RimgOptions.offset.x,hidden.offset.y=window.RimgOptions.offset.y),window.RimgOptions=void 0}else console.log("(remark) Rimg: no breakpoints defined (yet), check the documentation or manually adjust it.");return{version:"1.5.0",execute:function(target){if("error"===hidden.status)return console.error("Rimg.execute(): error-status so no actions can be executed, check your code."),void 0;if(void 0===target)return console.error("Rimg.execute(): undefined value, check your code to add a valid DOM element to this function."),void 0;if(0===hidden.breakpoints.length)return console.log("(remark) Rimg.execute(): no breakpoints defined (yet), probably because of manual control."),void 0;if("#document"===target.nodeName)if(hidden.images.splice(0,hidden.images.length),target.childNodes.length>1){var html;if("HTML"!==target.childNodes[1].nodeName)for(var i=0,il=target.childNodes.length;il>i;){if("HTML"===target.childNodes[i].nodeName){html=target.childNodes[i];break}i++}else html=target.childNodes[1];if("BODY"!==html.childNodes[1].nodeName)for(var i=0,il=html.childNodes.length;il>i;){if("BODY"===html.childNodes[i].nodeName){inspect(html.childNodes[i]);break}i++}else inspect(html.childNodes[1])}else console.error("Rimg.execute(): not a valid DOM representation, check your code.");else void 0!==target&&void 0!==target.nodeName&&"img"===target.nodeName.toLowerCase()?inspect(target):void 0!==target[0]&&"img"===target[0].nodeName.toLowerCase()&&inspect(target[0])},configure:function(value){if(!(value instanceof Object))return console.error("Rimg: your definition is not an object, check the documentation."),void 0;if(value.breakpoint){var breakpoints=parseBreakpoints(value.breakpoint);null!==breakpoints&&(hidden.breakpoints=breakpoints)}value.disableIntrospection===!0&&(hidden.disableIntrospection=!0),value.disableLazyLoading===!0&&(hidden.disableLazyLoading=!0),null!=value.offset&&"number"==typeof value.offset.x&&"number"==typeof value.offset.y&&(hidden.offset.x=value.offset.x,hidden.offset.y=value.offset.y),"ready"!==hidden.status||hidden.disableIntrospection||(checkDimensions(),this.execute(document))},resized:function(){"ready"===hidden.status&&(null!==hidden.resizeInfo.wait&&clearTimeout(hidden.resizeInfo.wait),null===hidden.resizeInfo.time||(new Date).getTime()-hidden.resizeInfo.time>1e3?resize.bind(this)():hidden.resizeInfo.wait=setTimeout(resize.bind(this),100))},scrolled:function(){hidden.disableLazyLoading||adjustImages()},loaded:function(){"progress"===hidden.status&&(hidden.isIE8&&"complete"!=document.readyState||(event("remove","DOMContentLoaded",this.loaded),checkDimensions(),hidden.disableIntrospection||(null===hidden.observer?this.execute(document):(hidden.observer.observe(document.body,{attributes:!0,childList:!0,characterData:!1,subtree:!0,attributeFilter:["data-src"]}),this.execute(document)),event("add","resize",this.resized.bind(this))),hidden.disableLazyLoading||event("add","scroll",this.scrolled.bind(this)),hidden.status="ready"))},disableLazyLoading:function(){hidden.disableLazyLoading=!0},disableIntrospection:function(){hidden.disableIntrospection=!0,hidden.observer?hidden.observer.disconnect():event("remove","DOMNodeInserted",nodeInserted)},initialize:function(){if("init"!==hidden.status)return"error"!==hidden.status&&console.error("Rimg.initialize(): Already initialized. No forced initialization supported, check your code."),void 0;var base=this,MutationObserver=window.MutationObserver||window.WebKitMutationObserver||window.MozMutationObserver;void 0===MutationObserver||hidden.isIE8?(event("add","DOMAttrModified",function(e){base.execute(e.target)}),event("add","DOMNodeInserted",nodeInserted.bind(base))):hidden.observer=new MutationObserver(function(mutations){mutations.forEach(function(mutation){mutation.addedNodes.length>0?base.execute(mutation.addedNodes):"data-src"===mutation.attributeName&&base.execute(mutation.target)})}),hidden.status="progress","interactive"!==document.readyState&&"complete"!==document.readyState||!document.body?event("add","DOMContentLoaded",this.loaded.bind(this)):this.loaded.bind(this)()}}};window.Rimg=Object.create(Rimg()),window.Rimg.initialize()}(); \ No newline at end of file