1
0
mirror of https://github.com/twbs/bootstrap.git synced 2025-08-16 02:24:19 +02:00

upgrade to holder 1.6

This commit is contained in:
Mark Otto
2012-11-29 21:35:45 -08:00
parent acc037de15
commit 38c546c785

View File

@@ -1,6 +1,6 @@
/* /*
Holder - 1.4 - client side image placeholders Holder - 1.6 - client side image placeholders
(c) 2012 Ivan Malopinsky / http://imsky.co (c) 2012 Ivan Malopinsky / http://imsky.co
Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0 Provided under the Apache 2.0 License: http://www.apache.org/licenses/LICENSE-2.0
@@ -33,63 +33,125 @@ 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 d in a)c[d]=a[d];for(var e in b)c[e]=b[e];return c}
function draw(ctx, dimensions, template) { function text_size(width, height, template) {
var dimension_arr = [dimensions.height, dimensions.width].sort(); var dimension_arr = [height, width].sort();
var maxFactor = Math.round(dimension_arr[1] / 16), var maxFactor = Math.round(dimension_arr[1] / 16),
minFactor = Math.round(dimension_arr[0] / 16); minFactor = Math.round(dimension_arr[0] / 16);
var text_height = Math.max(template.size, maxFactor); var text_height = Math.max(template.size, maxFactor);
canvas.width = dimensions.width; return {
canvas.height = dimensions.height; height: text_height
}
}
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;
canvas.width = width;
canvas.height = height;
ctx.textAlign = "center"; ctx.textAlign = "center";
ctx.textBaseline = "middle"; ctx.textBaseline = "middle";
ctx.fillStyle = template.background; ctx.fillStyle = template.background;
ctx.fillRect(0, 0, dimensions.width, dimensions.height); ctx.fillRect(0, 0, width, height);
ctx.fillStyle = template.foreground; ctx.fillStyle = template.foreground;
ctx.font = "bold " + text_height + "px sans-serif"; ctx.font = "bold " + text_height + "px sans-serif";
var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height); var text = template.text ? template.text : (dimensions.width + "x" + dimensions.height);
if (Math.round(ctx.measureText(text).width) / dimensions.width > 1) { if (ctx.measureText(text).width / width > 1) {
text_height = Math.max(minFactor, template.size); text_height = template.size / (ctx.measureText(text).width / width);
} }
ctx.font = "bold " + text_height + "px sans-serif"; ctx.font = "bold " + (text_height * ratio) + "px sans-serif";
ctx.fillText(text, (dimensions.width / 2), (dimensions.height / 2), dimensions.width); ctx.fillText(text, (width / 2), (height / 2), width);
return canvas.toDataURL("image/png"); return canvas.toDataURL("image/png");
} }
if (!canvas.getContext) {
fallback = true;
} else {
if (canvas.toDataURL("image/png").indexOf("data:image/png") < 0) {
//Android doesn't support data URI
fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
function render(mode, el, holder, src) { function render(mode, el, holder, src) {
var dimensions = holder.dimensions, theme = holder.theme, text = holder.text; var dimensions = holder.dimensions,
theme = holder.theme,
text = holder.text;
var dimensions_caption = dimensions.width + "x" + dimensions.height; var dimensions_caption = dimensions.width + "x" + dimensions.height;
theme = (text ? extend(theme, { text: text }) : theme); theme = (text ? extend(theme, {
text: text
}) : theme);
var ratio = 1;
if(window.devicePixelRatio && window.devicePixelRatio > 1){
ratio = window.devicePixelRatio;
}
if (mode == "image") { if (mode == "image") {
el.setAttribute("data-src", src); el.setAttribute("data-src", src);
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);
el.style.width = dimensions.width + "px"; el.style.width = dimensions.width + "px";
el.style.height = dimensions.height + "px"; el.style.height = dimensions.height + "px";
el.style.backgroundColor = theme.background;
if(!fallback){ if (fallback) {
el.setAttribute("src", draw(ctx, dimensions, theme)); el.style.backgroundColor = theme.background;
}
} }
else{ else{
if(!fallback){ el.setAttribute("src", draw(ctx, dimensions, theme, ratio));
el.style.backgroundImage = "url("+draw(ctx, dimensions, theme)+")";
} }
} else {
if (!fallback) {
el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")";
el.style.backgroundSize = dimensions.width+"px "+dimensions.height+"px";
}
}
};
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("table");
fluid.setAttribute("cellspacing",0)
fluid.setAttribute("cellpadding",0)
fluid.setAttribute("border",0)
var row = document.createElement("tr")
.appendChild(document.createElement("td")
.appendChild(document.createTextNode(theme.text)));
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;
var frag = document.createDocumentFragment(),
tbody = document.createElement("tbody"),
tr = document.createElement("tr"),
td = document.createElement("td");
tr.appendChild(td);
tbody.appendChild(tr);
frag.appendChild(tbody);
if (theme.text) {
td.appendChild(document.createTextNode(theme.text))
fluid.appendChild(frag);
} else {
td.appendChild(document.createTextNode(dimensions_caption))
fluid.appendChild(frag);
fluid_images.push(fluid);
setTimeout(fluid_update, 0);
} }
}; el.parentNode.replaceChild(fluid, el);
}
function fluid_update() {
for (i in fluid_images) {
var el = fluid_images[i];
var label = el.getElementsByTagName("td")[0].firstChild;
label.data = el.offsetWidth + "x" + el.offsetHeight;
}
}
function parse_flags(flags, options) { function parse_flags(flags, options) {
@@ -98,16 +160,21 @@ function parse_flags(flags, options){
}, render = false; }, render = false;
for (sl = flags.length, j = 0; j < sl; j++) { for (sl = flags.length, j = 0; j < sl; j++) {
if (app.flags.dimensions.match(flags[j])) { var flag = flags[j];
if (app.flags.dimensions.match(flag)) {
render = true; render = true;
ret.dimensions = app.flags.dimensions.output(flags[j]); ret.dimensions = app.flags.dimensions.output(flag);
} else if (app.flags.colors.match(flags[j])) { } else if (app.flags.fluid.match(flag)) {
ret.theme = app.flags.colors.output(flags[j]); render = true;
} else if (options.themes[flags[j]]) { ret.dimensions = app.flags.fluid.output(flag);
ret.fluid = true;
} else if (app.flags.colors.match(flag)) {
ret.theme = app.flags.colors.output(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[flags[j]]; ret.theme = options.themes[flag];
} else if (app.flags.text.match(flags[j])) { } else if (app.flags.text.match(flag)) {
ret.text = app.flags.text.output(flags[j]); ret.text = app.flags.text.output(flag);
} }
} }
@@ -115,6 +182,20 @@ function parse_flags(flags, options){
}; };
if (!canvas.getContext) {
fallback = true;
} else {
if (canvas.toDataURL("image/png")
.indexOf("data:image/png") < 0) {
//Android doesn't support data URI
fallback = true;
} else {
var ctx = canvas.getContext("2d");
}
}
var fluid_images = [];
var settings = { var settings = {
domain: "holder.js", domain: "holder.js",
images: "img", images: "img",
@@ -135,13 +216,14 @@ var settings = {
foreground: "#C2F200", foreground: "#C2F200",
size: 12 size: 12
} }
} },
stylesheet: ".holderjs-fluid {font-size:16px;font-weight:bold;text-align:center;font-family:sans-serif;border-collapse:collapse;border:0;vertical-align:middle;margin:0}"
}; };
app.flags = { app.flags = {
dimensions: { dimensions: {
regex: /([0-9]+)x([0-9]+)/, regex: /(\d+)x(\d+)/,
output: function (val) { output: function (val) {
var exec = this.regex.exec(val); var exec = this.regex.exec(val);
return { return {
@@ -150,6 +232,16 @@ app.flags = {
} }
} }
}, },
fluid: {
regex: /([0-9%]+)x([0-9%]+)/,
output: function (val) {
var exec = this.regex.exec(val);
return {
width: exec[1],
height: exec[2]
}
}
},
colors: { colors: {
regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i, regex: /#([0-9a-f]{3,})\:#([0-9a-f]{3,})/i,
output: function (val) { output: function (val) {
@@ -194,14 +286,23 @@ app.add_image = function (src, el) {
app.run = function (o) { app.run = function (o) {
var options = extend(settings, o), var options = extend(settings, o),
images = selector(options.images), images_nodes = selector(options.images),
elements = selector(options.elements), elements = selector(options.elements),
preempted = true; preempted = true,
images = [];
for (i = 0, l = images_nodes.length; i < l; i++) images.push(images_nodes[i]);
var holdercss = document.createElement("style");
holdercss.type = "text/css";
holdercss.styleSheet ? holdercss.styleSheet.cssText = options.stylesheet : holdercss.textContent = options.stylesheet;
document.getElementsByTagName("head")[0].appendChild(holdercss);
var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)"); var cssregex = new RegExp(options.domain + "\/(.*?)\"?\\)");
for (var l = elements.length, i = 0; i < l; i++) { for (var l = elements.length, i = 0; i < l; i++) {
var src = window.getComputedStyle(elements[i],null).getPropertyValue("background-image"); var src = window.getComputedStyle(elements[i], null)
.getPropertyValue("background-image");
var flags = src.match(cssregex); var flags = src.match(cssregex);
if (flags) { if (flags) {
var holder = parse_flags(flags[1].split("/"), options); var holder = parse_flags(flags[1].split("/"), options);
@@ -212,19 +313,30 @@ app.run = function (o) {
} }
for (var l = images.length, i = 0; i < l; i++) { for (var l = images.length, i = 0; i < l; i++) {
var src = images[i].getAttribute("data-src") || images[i].getAttribute("src"); var src = images[i].getAttribute("src") || images[i].getAttribute("data-src");
if (src.indexOf(options.domain)>=0) { if (src != null && src.indexOf(options.domain) >= 0) {
var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1).split("/"), options); var holder = parse_flags(src.substr(src.lastIndexOf(options.domain) + options.domain.length + 1)
.split("/"), options);
if (holder) { if (holder) {
if (holder.fluid) {
fluid(images[i], holder, src);
} else {
render("image", images[i], holder, src); render("image", images[i], holder, src);
} }
} }
} }
}
return app; return app;
}; };
contentLoaded(win, function () { contentLoaded(win, function () {
preempted || app.run() if (window.addEventListener) {
window.addEventListener("resize", fluid_update, false);
window.addEventListener("orientationchange", fluid_update, false);
} else {
window.attachEvent("onresize", fluid_update)
}
preempted || app.run();
}); });
})(Holder, window); })(Holder, window);