Commit 4392d43d authored by XhmikosR's avatar XhmikosR

Update holder.js to v2.2.

parent cc6951fa
/* /*
Holder - 2.1 - client side image placeholders Holder - 2.2 - client side image placeholders
(c) 2012-2013 Ivan Malopinsky / http://imsky.co (c) 2012-2013 Ivan Malopinsky / http://imsky.co
Provided under the MIT License. Provided under the MIT License.
...@@ -14,6 +14,8 @@ var Holder = Holder || {}; ...@@ -14,6 +14,8 @@ var Holder = Holder || {};
var preempted = false, var preempted = false,
fallback = false, fallback = false,
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
var dpr = 1, bsr = 1;
var resizable_images = [];
if (!canvas.getContext) { if (!canvas.getContext) {
fallback = true; fallback = true;
...@@ -27,8 +29,6 @@ if (!canvas.getContext) { ...@@ -27,8 +29,6 @@ if (!canvas.getContext) {
} }
} }
var dpr = 1, bsr = 1;
if(!fallback){ if(!fallback){
dpr = window.devicePixelRatio || 1, dpr = window.devicePixelRatio || 1,
bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1;
...@@ -36,6 +36,99 @@ if(!fallback){ ...@@ -36,6 +36,99 @@ if(!fallback){
var ratio = dpr / bsr; var ratio = dpr / bsr;
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
},
"sky": {
background: "#0D8FDB",
foreground: "#fff",
size: 12
},
"vine": {
background: "#39DBAC",
foreground: "#1E292C",
size: 12
},
"lava": {
background: "#F8591A",
foreground: "#1C2846",
size: 12
}
},
stylesheet: ""
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
},
textmode: {
regex: /textmode\:(.*)/,
output: function(val){
return this.regex.exec(val)[1];
}
}
}
//getElementsByClassName polyfill //getElementsByClassName polyfill
document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s}) document.getElementsByClassName||(document.getElementsByClassName=function(e){var t=document,n,r,i,s=[];if(t.querySelectorAll)return t.querySelectorAll("."+e);if(t.evaluate){r=".//*[contains(concat(' ', @class, ' '), ' "+e+" ')]",n=t.evaluate(r,t,null,0,null);while(i=n.iterateNext())s.push(i)}else{n=t.getElementsByTagName("*"),r=new RegExp("(^|\\s)"+e+"(\\s|$)");for(i=0;i<n.length;i++)r.test(n[i].className)&&s.push(n[i])}return s})
...@@ -52,7 +145,20 @@ function selector(a){ ...@@ -52,7 +145,20 @@ function selector(a){
} }
//shallow object property extend //shallow object property extend
function extend(a,b){var c={};for(var d in a)c[d]=a[d];for(var e in b)c[e]=b[e];return c} function extend(a,b){
var c={};
for(var i in a){
if(a.hasOwnProperty(i)){
c[i]=a[i];
}
}
for(var i in b){
if(b.hasOwnProperty(i)){
c[i]=b[i];
}
}
return c
}
//hasOwnProperty polyfill //hasOwnProperty polyfill
if (!Object.prototype.hasOwnProperty) if (!Object.prototype.hasOwnProperty)
...@@ -75,7 +181,15 @@ function text_size(width, height, template) { ...@@ -75,7 +181,15 @@ function text_size(width, height, template) {
} }
} }
function draw(ctx, dimensions, template, ratio, literal) { function draw(args) {
var ctx = args.ctx;
var dimensions = args.dimensions;
var template = args.template;
var ratio = args.ratio;
var holder = args.holder;
var literal = holder.textmode == "literal";
var exact = holder.textmode == "exact";
var ts = text_size(dimensions.width, dimensions.height, template); var ts = text_size(dimensions.width, dimensions.height, template);
var text_height = ts.height; var text_height = ts.height;
var width = dimensions.width * ratio, var width = dimensions.width * ratio,
...@@ -91,7 +205,12 @@ function draw(ctx, dimensions, template, ratio, literal) { ...@@ -91,7 +205,12 @@ function draw(ctx, dimensions, template, ratio, literal) {
ctx.font = "bold " + text_height + "px " + font; ctx.font = "bold " + text_height + "px " + font;
var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height)); var text = template.text ? template.text : (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
if (literal) { if (literal) {
text = template.literalText; var dimensions = holder.dimensions;
text = dimensions.width + "x" + dimensions.height;
}
else if(exact && holder.exact_dimensions){
var dimensions = holder.exact_dimensions;
text = (Math.floor(dimensions.width) + "x" + Math.floor(dimensions.height));
} }
var text_width = ctx.measureText(text).width; var text_width = ctx.measureText(text).width;
if (text_width / width >= 0.75) { if (text_width / width >= 0.75) {
...@@ -104,6 +223,7 @@ function draw(ctx, dimensions, template, ratio, literal) { ...@@ -104,6 +223,7 @@ function draw(ctx, dimensions, template, ratio, literal) {
} }
function render(mode, el, holder, src) { function render(mode, el, holder, src) {
var dimensions = holder.dimensions, var dimensions = holder.dimensions,
theme = holder.theme, theme = holder.theme,
text = holder.text ? decodeURIComponent(holder.text) : holder.text; text = holder.text ? decodeURIComponent(holder.text) : holder.text;
...@@ -115,10 +235,9 @@ function render(mode, el, holder, src) { ...@@ -115,10 +235,9 @@ function render(mode, el, holder, src) {
font: holder.font font: holder.font
}) : theme); }) : theme);
el.setAttribute("data-src", src); el.setAttribute("data-src", src);
theme.literalText = dimensions_caption;
holder.originalTheme = holder.theme;
holder.theme = theme; holder.theme = theme;
el.holder_data = holder;
if (mode == "image") { if (mode == "image") {
el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption);
if (fallback || !holder.auto) { if (fallback || !holder.auto) {
...@@ -128,11 +247,17 @@ function render(mode, el, holder, src) { ...@@ -128,11 +247,17 @@ function render(mode, el, holder, src) {
if (fallback) { if (fallback) {
el.style.backgroundColor = theme.background; el.style.backgroundColor = theme.background;
} else { } else {
el.setAttribute("src", draw(ctx, dimensions, theme, ratio)); el.setAttribute("src", draw({ctx: ctx, dimensions: dimensions, template: theme, ratio:ratio, holder: holder}));
if(holder.textmode && holder.textmode == "exact"){
resizable_images.push(el);
resizable_update(el);
}
} }
} else if (mode == "background") { } else if (mode == "background") {
if (!fallback) { if (!fallback) {
el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")"; el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")";
el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px"; el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px";
} }
} else if (mode == "fluid") { } else if (mode == "fluid") {
...@@ -147,41 +272,82 @@ function render(mode, el, holder, src) { ...@@ -147,41 +272,82 @@ function render(mode, el, holder, src) {
} else { } else {
el.style.width = dimensions.width + "px" el.style.width = dimensions.width + "px"
} }
if (el.style.display == "inline" || el.style.display === "") { if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") {
el.style.display = "block"; el.style.display = "block";
} }
if (fallback) { if (fallback) {
el.style.backgroundColor = theme.background; el.style.backgroundColor = theme.background;
} else { } else {
el.holderData = holder; resizable_images.push(el);
fluid_images.push(el); resizable_update(el);
fluid_update(el); }
}
}
function dimension_check(el, callback) {
var dimensions = {
height: el.clientHeight,
width: el.clientWidth
};
if (!dimensions.height && !dimensions.width) {
if (el.hasAttribute("data-holder-invisible")) {
throw new Error("Holder: placeholder is not visible");
} else {
el.setAttribute("data-holder-invisible", true)
setTimeout(function () {
callback.call(this, el)
}, 1)
return null;
} }
} else {
el.removeAttribute("data-holder-invisible")
} }
return dimensions;
} }
function fluid_update(element) { function resizable_update(element) {
var images; var images;
if (element.nodeType == null) { if (element.nodeType == null) {
images = fluid_images; images = resizable_images;
} else { } else {
images = [element] images = [element]
} }
for (var i in images) { for (var i in images) {
if (!images.hasOwnProperty(i)) {
continue;
}
var el = images[i] var el = images[i]
if (el.holderData) { if (el.holder_data) {
var holder = el.holderData; var holder = el.holder_data;
el.setAttribute("src", draw(ctx, { var dimensions = dimension_check(el, resizable_update)
height: el.clientHeight, if(dimensions){
width: el.clientWidth if(holder.fluid){
}, holder.theme, ratio, !! holder.literal)); el.setAttribute("src", draw({
ctx: ctx,
dimensions: dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
if(holder.textmode && holder.textmode == "exact"){
holder.exact_dimensions = dimensions;
el.setAttribute("src", draw({
ctx: ctx,
dimensions: holder.dimensions,
template: holder.theme,
ratio: ratio,
holder: holder
}))
}
}
} }
} }
} }
function parse_flags(flags, options) { function parse_flags(flags, options) {
var ret = { var ret = {
theme: settings.themes.gray theme: extend(settings.themes.gray, {})
}; };
var render = false; var render = false;
for (sl = flags.length, j = 0; j < sl; j++) { for (sl = flags.length, j = 0; j < sl; j++) {
...@@ -193,13 +359,15 @@ function parse_flags(flags, options) { ...@@ -193,13 +359,15 @@ function parse_flags(flags, options) {
render = true; render = true;
ret.dimensions = app.flags.fluid.output(flag); ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true; ret.fluid = true;
} else if (app.flags.literal.match(flag)) { } else if (app.flags.textmode.match(flag)) {
ret.literal = true; ret.textmode = app.flags.textmode.output(flag)
} else if (app.flags.colors.match(flag)) { } else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(flag); ret.theme = app.flags.colors.output(flag);
} else if (options.themes[flag]) { } else if (options.themes[flag]) {
//If a theme is specified, it will override custom colors //If a theme is specified, it will override custom colors
ret.theme = options.themes[flag]; if(options.themes.hasOwnProperty(flag)){
ret.theme = extend(options.themes[flag], {});
}
} else if (app.flags.font.match(flag)) { } else if (app.flags.font.match(flag)) {
ret.font = app.flags.font.output(flag); ret.font = app.flags.font.output(flag);
} else if (app.flags.auto.match(flag)) { } else if (app.flags.auto.match(flag)) {
...@@ -210,81 +378,7 @@ function parse_flags(flags, options) { ...@@ -210,81 +378,7 @@ function parse_flags(flags, options) {
} }
return render ? ret : false; return render ? ret : false;
} }
var fluid_images = [];
var settings = {
domain: "holder.js",
images: "img",
bgnodes: ".holderjs",
themes: {
"gray": {
background: "#eee",
foreground: "#aaa",
size: 12
},
"social": {
background: "#3a5a97",
foreground: "#fff",
size: 12
},
"industrial": {
background: "#434A52",
foreground: "#C2F200",
size: 12
}
},
stylesheet: ""
};
app.flags = {
dimensions: {
regex: /^(\d+)x(\d+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: +exec[1],
height: +exec[2]
}
}
},
fluid: {
regex: /^([0-9%]+)x([0-9%]+)$/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) {
var exec = this.regex.exec(val);
return {
size: settings.themes.gray.size,
foreground: "#" + exec[2],
background: "#" + exec[1]
}
}
},
text: {
regex: /text\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
font: {
regex: /font\:(.*)/,
output: function (val) {
return this.regex.exec(val)[1];
}
},
auto: {
regex: /^auto$/
},
literal: {
regex: /^literal$/
}
}
for (var flag in app.flags) { for (var flag in app.flags) {
if (!app.flags.hasOwnProperty(flag)) continue; if (!app.flags.hasOwnProperty(flag)) continue;
app.flags[flag].match = function (val) { app.flags[flag].match = function (val) {
...@@ -307,6 +401,8 @@ app.add_image = function (src, el) { ...@@ -307,6 +401,8 @@ app.add_image = function (src, el) {
return app; return app;
}; };
app.run = function (o) { app.run = function (o) {
preempted = true;
var options = extend(settings, o), var options = extend(settings, o),
images = [], images = [],
imageNodes = [], imageNodes = [],
...@@ -318,6 +414,7 @@ app.run = function (o) { ...@@ -318,6 +414,7 @@ app.run = function (o) {
} else if (window.Node && options.images instanceof window.Node) { } else if (window.Node && options.images instanceof window.Node) {
imageNodes = [options.images]; imageNodes = [options.images];
} }
if (typeof (options.bgnodes) == "string") { if (typeof (options.bgnodes) == "string") {
bgnodes = selector(options.bgnodes); bgnodes = selector(options.bgnodes);
} else if (window.NodeList && options.elements instanceof window.NodeList) { } else if (window.NodeList && options.elements instanceof window.NodeList) {
...@@ -325,7 +422,6 @@ app.run = function (o) { ...@@ -325,7 +422,6 @@ app.run = function (o) {
} else if (window.Node && options.bgnodes instanceof window.Node) { } else if (window.Node && options.bgnodes instanceof window.Node) {
bgnodes = [options.bgnodes]; bgnodes = [options.bgnodes];
} }
preempted = true;
for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]); for (i = 0, l = imageNodes.length; i < l; i++) images.push(imageNodes[i]);
var holdercss = document.getElementById("holderjs-style"); var holdercss = document.getElementById("holderjs-style");
if (!holdercss) { if (!holdercss) {
...@@ -388,10 +484,10 @@ app.run = function (o) { ...@@ -388,10 +484,10 @@ app.run = function (o) {
}; };
contentLoaded(win, function () { contentLoaded(win, function () {
if (window.addEventListener) { if (window.addEventListener) {
window.addEventListener("resize", fluid_update, false); window.addEventListener("resize", resizable_update, false);
window.addEventListener("orientationchange", fluid_update, false); window.addEventListener("orientationchange", resizable_update, false);
} else { } else {
window.attachEvent("onresize", fluid_update) window.attachEvent("onresize", resizable_update)
} }
preempted || app.run(); preempted || app.run();
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment