vendor/assets/javascripts/holder.js in holder_rails-1.9.0 vs vendor/assets/javascripts/holder.js in holder_rails-2.0.0

- old
+ new

@@ -1,8 +1,8 @@ /* -Holder - 1.9 - client side image placeholders +Holder - 2.0 - client side image placeholders (c) 2012-2013 Ivan Malopinsky / http://imsky.co Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0 Commercial use requires attribution. @@ -39,133 +39,119 @@ var proto = this.__proto__ || this.constructor.prototype; return (prop in this) && (!(prop in proto) || proto[prop] !== this[prop]); } function text_size(width, height, template) { - var dimension_arr = [height, width].sort(); - var maxFactor = Math.round(dimension_arr[1] / 16), - minFactor = Math.round(dimension_arr[0] / 16); - var text_height = Math.max(template.size, maxFactor); + height = parseInt(height,10); + width = parseInt(width,10); + var bigSide = Math.max(height, width) + var smallSide = Math.min(height, width) + var scale = 1 / 12; + var newHeight = Math.min(smallSide * 0.75, 0.75 * bigSide * scale); return { - height: text_height + height: Math.round(Math.max(template.size, newHeight)) } } function draw(ctx, dimensions, template, ratio) { var ts = text_size(dimensions.width, dimensions.height, template); var text_height = ts.height; - var width = dimensions.width * ratio, height = dimensions.height * ratio; + var width = dimensions.width * ratio, + height = dimensions.height * ratio; var font = template.font ? template.font : "sans-serif"; canvas.width = width; canvas.height = height; ctx.textAlign = "center"; ctx.textBaseline = "middle"; ctx.fillStyle = template.background; ctx.fillRect(0, 0, width, height); ctx.fillStyle = template.foreground; - ctx.font = "bold " + text_height + "px "+font; - var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height); - if (ctx.measureText(text).width / width > 1) { - text_height = template.size / (ctx.measureText(text).width / width); + ctx.font = "bold " + text_height + "px " + font; + var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height)); + var text_width = ctx.measureText(text).width; + if (text_width / width >= 0.75) { + text_height = Math.floor(text_height * 0.75 * (width/text_width)); } //Resetting font size if necessary - ctx.font = "bold " + (text_height * ratio) + "px "+font; + ctx.font = "bold " + (text_height * ratio) + "px " + font; ctx.fillText(text, (width / 2), (height / 2), width); return canvas.toDataURL("image/png"); } function render(mode, el, holder, src) { var dimensions = holder.dimensions, theme = holder.theme, text = holder.text ? decodeURIComponent(holder.text) : holder.text; var dimensions_caption = dimensions.width + "x" + dimensions.height; - theme = (text ? extend(theme, { text: text }) : theme); - theme = (holder.font ? extend(theme, {font: holder.font}) : theme); - - var ratio = 1; - if(window.devicePixelRatio && window.devicePixelRatio > 1){ - ratio = window.devicePixelRatio; - } - + theme = (text ? extend(theme, { + text: text + }) : theme); + theme = (holder.font ? extend(theme, { + font: holder.font + }) : theme); if (mode == "image") { el.setAttribute("data-src", src); el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); - - if(fallback || !holder.auto){ - el.style.width = dimensions.width + "px"; - el.style.height = dimensions.height + "px"; + if (fallback || !holder.auto) { + el.style.width = dimensions.width + "px"; + el.style.height = dimensions.height + "px"; } - if (fallback) { el.style.backgroundColor = theme.background; - - } - else{ + } else { el.setAttribute("src", draw(ctx, dimensions, theme, ratio)); } - } else { + } else if (mode == "background") { if (!fallback) { el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")"; - el.style.backgroundSize = dimensions.width+"px "+dimensions.height+"px"; + el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px"; } + } else if (mode == "fluid") { + el.setAttribute("data-src", src); + el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); + if (dimensions.height.substr(-1) == "%") { + el.style.height = dimensions.height + } else { + el.style.height = dimensions.height + "px" + } + if (dimensions.width.substr(-1) == "%") { + el.style.width = dimensions.width + } else { + el.style.width = dimensions.width + "px" + } + if (el.style.display == "inline" || el.style.display == "") { + el.style.display = "block"; + } + if (fallback) { + el.style.backgroundColor = theme.background; + } else { + el.holderData = holder; + fluid_images.push(el); + fluid_update(el); + } } }; -function fluid(el, holder, src) { - var dimensions = holder.dimensions, - theme = holder.theme, - text = holder.text; - var dimensions_caption = dimensions.width + "x" + dimensions.height; - theme = (text ? extend(theme, { - text: text - }) : theme); - - var fluid = document.createElement("div"); - - fluid.style.backgroundColor = theme.background; - fluid.style.color = theme.foreground; - fluid.className = el.className + " holderjs-fluid"; - fluid.style.width = holder.dimensions.width + (holder.dimensions.width.indexOf("%")>0?"":"px"); - fluid.style.height = holder.dimensions.height + (holder.dimensions.height.indexOf("%")>0?"":"px"); - fluid.id = el.id; - - el.style.width=0; - el.style.height=0; - - if (theme.text) { - fluid.appendChild(document.createTextNode(theme.text)) +function fluid_update(element) { + var images; + if (element.nodeType == null) { + images = fluid_images; } else { - fluid.appendChild(document.createTextNode(dimensions_caption)) - fluid_images.push(fluid); - setTimeout(fluid_update, 0); + images = [element] } - - el.parentNode.insertBefore(fluid, el.nextSibling) - - if(window.jQuery){ - jQuery(function($){ - $(el).on("load", function(){ - el.style.width = fluid.style.width; - el.style.height = fluid.style.height; - $(el).show(); - $(fluid).remove(); - }); - }) + for (i in images) { + var el = images[i] + if (el.holderData) { + var holder = el.holderData; + el.setAttribute("src", draw(ctx, { + height: el.clientHeight, + width: el.clientWidth + }, holder.theme, ratio)); + } } } -function fluid_update() { - for (i in fluid_images) { - if(!fluid_images.hasOwnProperty(i)) continue; - var el = fluid_images[i], - label = el.firstChild; - - el.style.lineHeight = el.offsetHeight+"px"; - label.data = el.offsetWidth + "x" + el.offsetHeight; - } -} - function parse_flags(flags, options) { var ret = { theme: settings.themes.gray }, render = false; @@ -184,22 +170,23 @@ } else if (options.themes[flag]) { //If a theme is specified, it will override custom colors ret.theme = options.themes[flag]; } else if (app.flags.text.match(flag)) { ret.text = app.flags.text.output(flag); - } else if(app.flags.font.match(flag)){ + } else if (app.flags.font.match(flag)) { ret.font = app.flags.font.output(flag); - } - else if(app.flags.auto.match(flag)){ + } else if (app.flags.auto.match(flag)) { ret.auto = true; } } return render ? ret : false; }; + + if (!canvas.getContext) { fallback = true; } else { if (canvas.toDataURL("image/png") .indexOf("data:image/png") < 0) { @@ -208,10 +195,19 @@ } else { var ctx = canvas.getContext("2d"); } } +var dpr = 1, bsr = 1; + +if(!fallback){ + dpr = window.devicePixelRatio || 1, + bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; +} + +var ratio = dpr / bsr; + var fluid_images = []; var settings = { domain: "holder.js", images: "img", @@ -220,22 +216,22 @@ "gray": { background: "#eee", foreground: "#aaa", size: 12 }, - "social": { + "social": { background: "#3a5a97", foreground: "#fff", size: 12 }, - "industrial": { + "industrial": { background: "#434A52", foreground: "#C2F200", size: 12 } }, - stylesheet: ".holderjs-fluid {font-size:16px;font-weight:bold;text-align:center;font-family:sans-serif;margin:0}" + stylesheet: "" }; app.flags = { dimensions: { @@ -274,22 +270,22 @@ output: function (val) { return this.regex.exec(val)[1]; } }, font: { - regex: /font\:(.*)/, - output: function(val){ - return this.regex.exec(val)[1]; - } + regex: /font\:(.*)/, + output: function (val) { + return this.regex.exec(val)[1]; + } }, auto: { - regex: /^auto$/ + regex: /^auto$/ } } for (var flag in app.flags) { - if(!app.flags.hasOwnProperty(flag)) continue; + if (!app.flags.hasOwnProperty(flag)) continue; app.flags[flag].match = function (val) { return val.match(this.regex) } } @@ -309,74 +305,94 @@ } return app; }; app.run = function (o) { - var options = extend(settings, o), images = []; + var options = extend(settings, o), + images = [], imageNodes = [], bgnodes = []; - if(options.images instanceof window.NodeList){ - imageNodes = options.images; - } - else if(options.images instanceof window.Node){ - imageNodes = [options.images]; - } - else{ + if(typeof(options.images) == "string"){ imageNodes = selector(options.images); } - - if(options.elements instanceof window.NodeList){ - bgnodes = options.bgnodes; + else if (window.NodeList && options.images instanceof window.NodeList) { + imageNodes = options.images; + } else if (window.Node && options.images instanceof window.Node) { + imageNodes = [options.images]; } - else if(options.bgnodes instanceof window.Node){ - bgnodes = [options.bgnodes]; - } - else{ + + if(typeof(options.bgnodes) == "string"){ bgnodes = selector(options.bgnodes); + } else if (window.NodeList && options.elements instanceof window.NodeList) { + bgnodes = options.bgnodes; + } else if (window.Node && options.bgnodes instanceof window.Node) { + bgnodes = [options.bgnodes]; } - + preempted = true; - + for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]); - + var holdercss = document.getElementById("holderjs-style"); + if (!holdercss) { + holdercss = document.createElement("style"); + holdercss.setAttribute("id", "holderjs-style"); + holdercss.type = "text/css"; + document.getElementsByTagName("head")[0].appendChild(holdercss); + } - if(!holdercss){ - holdercss = document.createElement("style"); - holdercss.setAttribute("id", "holderjs-style"); - holdercss.type = "text/css"; - document.getElementsByTagName("head")[0].appendChild(holdercss); + if (!options.nocss) { + if (holdercss.styleSheet) { + holdercss.styleSheet.cssText += options.stylesheet; + } else { + holdercss.appendChild(document.createTextNode(options.stylesheet)); + } } - if(holdercss.styleSheet){ - holdercss.styleSheet += options.stylesheet; - } - else{ - holdercss.textContent+= options.stylesheet; - } - var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)"); for (var l = bgnodes.length, i = 0; i < l; i++) { var src = window.getComputedStyle(bgnodes[i], null) .getPropertyValue("background-image"); var flags = src.match(cssregex); + var bgsrc = bgnodes[i].getAttribute("data-background-src"); + if (flags) { var holder = parse_flags(flags[1].split("/"), options); if (holder) { render("background", bgnodes[i], holder, src); } } + else if(bgsrc != null){ + var holder = parse_flags(bgsrc.substr(bgsrc.lastIndexOf(options.domain) + options.domain.length + 1) + .split("/"), options); + if(holder){ + render("background", bgnodes[i], holder, src); + } + } } - for (var l = images.length, i = 0; i < l; i++) { - var src = images[i].getAttribute("src") || images[i].getAttribute("data-src"); - if (src != null && src.indexOf(options.domain) >= 0) { + for (l = images.length, i = 0; i < l; i++) { + + var attr_src = attr_data_src = src = null; + + try{ + attr_src = images[i].getAttribute("src"); + attr_datasrc = images[i].getAttribute("data-src"); + }catch(e){} + + if (attr_datasrc == null && !! attr_src && attr_src.indexOf(options.domain) >= 0) { + src = attr_src; + } else if ( !! attr_datasrc && attr_datasrc.indexOf(options.domain) >= 0) { + src = attr_datasrc; + } + + if (src) { var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1) .split("/"), options); if (holder) { if (holder.fluid) { - fluid(images[i], holder, src); + render("fluid", images[i], holder, src) } else { render("image", images[i], holder, src); } } } @@ -392,10 +408,12 @@ window.attachEvent("onresize", fluid_update) } preempted || app.run(); }); -if ( typeof define === "function" && define.amd ) { - define( "Holder", [], function () { return app; } ); +if (typeof define === "function" && define.amd) { + define("Holder", [], function () { + return app; + }); } })(Holder, window);