From 4392d43d7c7013a53c1cbaf270f27d2aeab14f54 Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 2 Dec 2013 14:12:46 +0200 Subject: [PATCH 1/3] Update holder.js to v2.2. --- docs-assets/js/holder.js | 464 +++++++++++++++++++++++---------------- 1 file changed, 280 insertions(+), 184 deletions(-) diff --git a/docs-assets/js/holder.js b/docs-assets/js/holder.js index ebeb3c5296..85f0441b0e 100644 --- a/docs-assets/js/holder.js +++ b/docs-assets/js/holder.js @@ -1,6 +1,6 @@ /* -Holder - 2.1 - client side image placeholders +Holder - 2.2 - client side image placeholders (c) 2012-2013 Ivan Malopinsky / http://imsky.co Provided under the MIT License. @@ -14,6 +14,8 @@ var Holder = Holder || {}; var preempted = false, fallback = false, canvas = document.createElement('canvas'); +var dpr = 1, bsr = 1; +var resizable_images = []; if (!canvas.getContext) { fallback = true; @@ -27,8 +29,6 @@ if (!canvas.getContext) { } } -var dpr = 1, bsr = 1; - if(!fallback){ dpr = window.devicePixelRatio || 1, bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; @@ -36,181 +36,6 @@ if(!fallback){ var ratio = dpr / bsr; -//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= 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.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); - el.setAttribute("data-src", src); - theme.literalText = dimensions_caption; - holder.originalTheme = holder.theme; - holder.theme = theme; - - if (mode == "image") { - 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) { - el.style.backgroundColor = theme.background; - } else { - el.setAttribute("src", draw(ctx, dimensions, theme, ratio)); - } - } else if (mode == "background") { - if (!fallback) { - el.style.backgroundImage = "url(" + draw(ctx, dimensions, theme, ratio) + ")"; - el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px"; - } - } else if (mode == "fluid") { - el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); - if (dimensions.height.slice(-1) == "%") { - el.style.height = dimensions.height - } else { - el.style.height = dimensions.height + "px" - } - if (dimensions.width.slice(-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_update(element) { - var images; - if (element.nodeType == null) { - images = fluid_images; - } else { - images = [element] - } - for (var 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, !! holder.literal)); - } - } -} - -function parse_flags(flags, options) { - var ret = { - theme: settings.themes.gray - }; - var render = false; - for (sl = flags.length, j = 0; j < sl; j++) { - var flag = flags[j]; - if (app.flags.dimensions.match(flag)) { - render = true; - ret.dimensions = app.flags.dimensions.output(flag); - } else if (app.flags.fluid.match(flag)) { - render = true; - ret.dimensions = app.flags.fluid.output(flag); - ret.fluid = true; - } else if (app.flags.literal.match(flag)) { - ret.literal = 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 - ret.theme = options.themes[flag]; - } else if (app.flags.font.match(flag)) { - ret.font = app.flags.font.output(flag); - } else if (app.flags.auto.match(flag)) { - ret.auto = true; - } else if (app.flags.text.match(flag)) { - ret.text = app.flags.text.output(flag); - } - } - return render ? ret : false; -} -var fluid_images = []; var settings = { domain: "holder.js", images: "img", @@ -230,6 +55,21 @@ var settings = { 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: "" @@ -281,10 +121,264 @@ app.flags = { auto: { regex: /^auto$/ }, - literal: { - regex: /^literal$/ + textmode: { + regex: /textmode\:(.*)/, + output: function(val){ + return this.regex.exec(val)[1]; + } } } + +//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= 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.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); + el.setAttribute("data-src", src); + holder.theme = theme; + el.holder_data = holder; + + if (mode == "image") { + 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) { + el.style.backgroundColor = theme.background; + } else { + 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") { + if (!fallback) { + el.style.backgroundImage = "url(" + draw({ctx:ctx, dimensions: dimensions, template: theme, ratio: ratio, holder: holder}) + ")"; + el.style.backgroundSize = dimensions.width + "px " + dimensions.height + "px"; + } + } else if (mode == "fluid") { + el.setAttribute("alt", text ? text : theme.text ? theme.text + " [" + dimensions_caption + "]" : dimensions_caption); + if (dimensions.height.slice(-1) == "%") { + el.style.height = dimensions.height + } else { + el.style.height = dimensions.height + "px" + } + if (dimensions.width.slice(-1) == "%") { + el.style.width = dimensions.width + } else { + el.style.width = dimensions.width + "px" + } + if (el.style.display == "inline" || el.style.display === "" || el.style.display == "none") { + el.style.display = "block"; + } + if (fallback) { + el.style.backgroundColor = theme.background; + } else { + resizable_images.push(el); + resizable_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 resizable_update(element) { + var images; + if (element.nodeType == null) { + images = resizable_images; + } else { + images = [element] + } + for (var i in images) { + if (!images.hasOwnProperty(i)) { + continue; + } + var el = images[i] + if (el.holder_data) { + var holder = el.holder_data; + var dimensions = dimension_check(el, resizable_update) + if(dimensions){ + if(holder.fluid){ + 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) { + var ret = { + theme: extend(settings.themes.gray, {}) + }; + var render = false; + for (sl = flags.length, j = 0; j < sl; j++) { + var flag = flags[j]; + if (app.flags.dimensions.match(flag)) { + render = true; + ret.dimensions = app.flags.dimensions.output(flag); + } else if (app.flags.fluid.match(flag)) { + render = true; + ret.dimensions = app.flags.fluid.output(flag); + ret.fluid = true; + } else if (app.flags.textmode.match(flag)) { + ret.textmode = app.flags.textmode.output(flag) + } 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(options.themes.hasOwnProperty(flag)){ + ret.theme = extend(options.themes[flag], {}); + } + } else if (app.flags.font.match(flag)) { + ret.font = app.flags.font.output(flag); + } else if (app.flags.auto.match(flag)) { + ret.auto = true; + } else if (app.flags.text.match(flag)) { + ret.text = app.flags.text.output(flag); + } + } + return render ? ret : false; +} + for (var flag in app.flags) { if (!app.flags.hasOwnProperty(flag)) continue; app.flags[flag].match = function (val) { @@ -307,6 +401,8 @@ app.add_image = function (src, el) { return app; }; app.run = function (o) { + preempted = true; + var options = extend(settings, o), images = [], imageNodes = [], @@ -318,6 +414,7 @@ app.run = function (o) { } else if (window.Node && options.images instanceof window.Node) { imageNodes = [options.images]; } + if (typeof (options.bgnodes) == "string") { bgnodes = selector(options.bgnodes); } else if (window.NodeList && options.elements instanceof window.NodeList) { @@ -325,7 +422,6 @@ app.run = function (o) { } 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) { @@ -388,10 +484,10 @@ app.run = function (o) { }; contentLoaded(win, function () { if (window.addEventListener) { - window.addEventListener("resize", fluid_update, false); - window.addEventListener("orientationchange", fluid_update, false); + window.addEventListener("resize", resizable_update, false); + window.addEventListener("orientationchange", resizable_update, false); } else { - window.attachEvent("onresize", fluid_update) + window.attachEvent("onresize", resizable_update) } preempted || app.run(); }); From c56e63e967f8a55b25b35e7bcd8edde4aa936c6f Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 2 Dec 2013 14:13:10 +0200 Subject: [PATCH 2/3] Update jszip.js to the latest git. --- docs-assets/js/jszip.js | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/docs-assets/js/jszip.js b/docs-assets/js/jszip.js index 79a7654a4d..52d35d914d 100644 --- a/docs-assets/js/jszip.js +++ b/docs-assets/js/jszip.js @@ -16,7 +16,9 @@ Usage: base64zip = zip.generate(); **/ -"use strict"; +// We use strict, but it should not be placed outside of a function because +// the environment is shared inside the browser. +// "use strict"; /** * Representation a of zip file in js @@ -93,8 +95,8 @@ JSZip.support = { catch(e) {} try { - var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || - window.MozBlobBuilder || window.MSBlobBuilder)(); + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new BlobBuilder(); builder.append(buffer); return builder.getBlob('application/zip').size === 0; } @@ -161,7 +163,7 @@ JSZip.prototype = (function () { return file.asBinary(); } return result; - } + }; /** * Transform this._data into a string. @@ -287,9 +289,11 @@ JSZip.prototype = (function () { */ var prepareFileAttrs = function (o) { o = o || {}; + /*jshint -W041 */ if (o.base64 === true && o.binary == null) { o.binary = true; } + /*jshint +W041 */ o = extend(o, JSZip.defaults); o.date = o.date || new Date(); if (o.compression !== null) o.compression = o.compression.toUpperCase(); @@ -341,7 +345,9 @@ JSZip.prototype = (function () { } } - return this.files[name] = new ZipObject(name, data, o); + var object = new ZipObject(name, data, o); + this.files[name] = object; + return object; }; @@ -399,7 +405,7 @@ JSZip.prototype = (function () { } else if (file._data.compressionMethod === compression.magic) { result.compressedContent = file._data.getCompressedContent(); } else { - content = file._data.getContent() + content = file._data.getContent(); // need to decompress / recompress result.compressedContent = compression.compress(JSZip.utils.transformTo(compression.compressInputType, content)); } @@ -756,8 +762,9 @@ JSZip.prototype = (function () { case "nodebuffer" : writer = new Uint8ArrayWriter(localDirLength + centralDirLength + dirEnd.length); break; - case "base64" : - default : // case "string" : + // case "base64" : + // case "string" : + default : writer = new StringWriter(localDirLength + centralDirLength + dirEnd.length); break; } @@ -1066,8 +1073,8 @@ JSZip.compressions = { try { // deprecated, browser only, old way - var builder = new (window.BlobBuilder || window.WebKitBlobBuilder || - window.MozBlobBuilder || window.MSBlobBuilder)(); + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder; + var builder = new BlobBuilder(); builder.append(buffer); return builder.getBlob('application/zip'); } @@ -1095,7 +1102,7 @@ JSZip.compressions = { */ function identity(input) { return input; - }; + } /** * Fill in an array with a string. @@ -1108,7 +1115,7 @@ JSZip.compressions = { array[i] = str.charCodeAt(i) & 0xFF; } return array; - }; + } /** * Transform an array-like object to a string. @@ -1165,7 +1172,7 @@ JSZip.compressions = { } } return result.join(""); - }; + } /** * Copy the data from an array-like to an other array-like. @@ -1178,7 +1185,7 @@ JSZip.compressions = { arrayTo[i] = arrayFrom[i]; } return arrayTo; - }; + } // a matrix containing functions to transform everything into everything. var transform = {}; From b8928340f4ef26f788dbf362076105adceb1fa1a Mon Sep 17 00:00:00 2001 From: XhmikosR Date: Mon, 2 Dec 2013 14:15:57 +0200 Subject: [PATCH 3/3] Update filesaver.js to the latest git. --- docs-assets/js/filesaver.js | 522 ++++++++++++++++++++++++++---------- 1 file changed, 376 insertions(+), 146 deletions(-) diff --git a/docs-assets/js/filesaver.js b/docs-assets/js/filesaver.js index adecc88ecb..e7127dba0e 100644 --- a/docs-assets/js/filesaver.js +++ b/docs-assets/js/filesaver.js @@ -14,156 +14,386 @@ /*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */ -if (typeof Blob !== "function" || typeof URL === "undefined") -if (typeof Blob === "function" && typeof webkitURL !== "undefined") self.URL = webkitURL; +if (!(typeof Blob === "function" || typeof Blob === "object") || typeof URL === "undefined") +if ((typeof Blob === "function" || typeof Blob === "object") && typeof webkitURL !== "undefined") self.URL = webkitURL; else var Blob = (function (view) { - "use strict"; + "use strict"; - var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) { - var - get_class = function(object) { - return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; - } - , FakeBlobBuilder = function BlobBuilder() { - this.data = []; - } - , FakeBlob = function Blob(data, type, encoding) { - this.data = data; - this.size = data.length; - this.type = type; - this.encoding = encoding; - } - , FBB_proto = FakeBlobBuilder.prototype - , FB_proto = FakeBlob.prototype - , FileReaderSync = view.FileReaderSync - , FileException = function(type) { - this.code = this[this.name = type]; - } - , file_ex_codes = ( - "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " - + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" - ).split(" ") - , file_ex_code = file_ex_codes.length - , real_URL = view.URL || view.webkitURL || view - , real_create_object_URL = real_URL.createObjectURL - , real_revoke_object_URL = real_URL.revokeObjectURL - , URL = real_URL - , btoa = view.btoa - , atob = view.atob + var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || view.MSBlobBuilder || (function(view) { + var + get_class = function(object) { + return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1]; + } + , FakeBlobBuilder = function BlobBuilder() { + this.data = []; + } + , FakeBlob = function Blob(data, type, encoding) { + this.data = data; + this.size = data.length; + this.type = type; + this.encoding = encoding; + } + , FBB_proto = FakeBlobBuilder.prototype + , FB_proto = FakeBlob.prototype + , FileReaderSync = view.FileReaderSync + , FileException = function(type) { + this.code = this[this.name = type]; + } + , file_ex_codes = ( + "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " + + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR" + ).split(" ") + , file_ex_code = file_ex_codes.length + , real_URL = view.URL || view.webkitURL || view + , real_create_object_URL = real_URL.createObjectURL + , real_revoke_object_URL = real_URL.revokeObjectURL + , URL = real_URL + , btoa = view.btoa + , atob = view.atob - , ArrayBuffer = view.ArrayBuffer - , Uint8Array = view.Uint8Array - ; - FakeBlob.fake = FB_proto.fake = true; - while (file_ex_code--) { - FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; - } - if (!real_URL.createObjectURL) { - URL = view.URL = {}; - } - URL.createObjectURL = function(blob) { - var - type = blob.type - , data_URI_header - ; - if (type === null) { - type = "application/octet-stream"; - } - if (blob instanceof FakeBlob) { - data_URI_header = "data:" + type; - if (blob.encoding === "base64") { - return data_URI_header + ";base64," + blob.data; - } else if (blob.encoding === "URI") { - return data_URI_header + "," + decodeURIComponent(blob.data); - } if (btoa) { - return data_URI_header + ";base64," + btoa(blob.data); - } else { - return data_URI_header + "," + encodeURIComponent(blob.data); - } - } else if (real_create_object_URL) { - return real_create_object_URL.call(real_URL, blob); - } - }; - URL.revokeObjectURL = function(object_URL) { - if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { - real_revoke_object_URL.call(real_URL, object_URL); - } - }; - FBB_proto.append = function(data/*, endings*/) { - var bb = this.data; - // decode data to a binary string - if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { - var - str = "" - , buf = new Uint8Array(data) - , i = 0 - , buf_len = buf.length - ; - for (; i < buf_len; i++) { - str += String.fromCharCode(buf[i]); - } - bb.push(str); - } else if (get_class(data) === "Blob" || get_class(data) === "File") { - if (FileReaderSync) { - var fr = new FileReaderSync; - bb.push(fr.readAsBinaryString(data)); - } else { - // async FileReader won't work as BlobBuilder is sync - throw new FileException("NOT_READABLE_ERR"); - } - } else if (data instanceof FakeBlob) { - if (data.encoding === "base64" && atob) { - bb.push(atob(data.data)); - } else if (data.encoding === "URI") { - bb.push(decodeURIComponent(data.data)); - } else if (data.encoding === "raw") { - bb.push(data.data); - } - } else { - if (typeof data !== "string") { - data += ""; // convert unsupported types to strings - } - // decode UTF-16 to binary string - bb.push(unescape(encodeURIComponent(data))); - } - }; - FBB_proto.getBlob = function(type) { - if (!arguments.length) { - type = null; - } - return new FakeBlob(this.data.join(""), type, "raw"); - }; - FBB_proto.toString = function() { - return "[object BlobBuilder]"; - }; - FB_proto.slice = function(start, end, type) { - var args = arguments.length; - if (args < 3) { - type = null; - } - return new FakeBlob( - this.data.slice(start, args > 1 ? end : this.data.length) - , type - , this.encoding - ); - }; - FB_proto.toString = function() { - return "[object Blob]"; - }; - return FakeBlobBuilder; - }(view)); + , ArrayBuffer = view.ArrayBuffer + , Uint8Array = view.Uint8Array + ; + FakeBlob.fake = FB_proto.fake = true; + while (file_ex_code--) { + FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1; + } + if (!real_URL.createObjectURL) { + URL = view.URL = {}; + } + URL.createObjectURL = function(blob) { + var + type = blob.type + , data_URI_header + ; + if (type === null) { + type = "application/octet-stream"; + } + if (blob instanceof FakeBlob) { + data_URI_header = "data:" + type; + if (blob.encoding === "base64") { + return data_URI_header + ";base64," + blob.data; + } else if (blob.encoding === "URI") { + return data_URI_header + "," + decodeURIComponent(blob.data); + } if (btoa) { + return data_URI_header + ";base64," + btoa(blob.data); + } else { + return data_URI_header + "," + encodeURIComponent(blob.data); + } + } else if (real_create_object_URL) { + return real_create_object_URL.call(real_URL, blob); + } + }; + URL.revokeObjectURL = function(object_URL) { + if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) { + real_revoke_object_URL.call(real_URL, object_URL); + } + }; + FBB_proto.append = function(data/*, endings*/) { + var bb = this.data; + // decode data to a binary string + if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) { + var + str = "" + , buf = new Uint8Array(data) + , i = 0 + , buf_len = buf.length + ; + for (; i < buf_len; i++) { + str += String.fromCharCode(buf[i]); + } + bb.push(str); + } else if (get_class(data) === "Blob" || get_class(data) === "File") { + if (FileReaderSync) { + var fr = new FileReaderSync; + bb.push(fr.readAsBinaryString(data)); + } else { + // async FileReader won't work as BlobBuilder is sync + throw new FileException("NOT_READABLE_ERR"); + } + } else if (data instanceof FakeBlob) { + if (data.encoding === "base64" && atob) { + bb.push(atob(data.data)); + } else if (data.encoding === "URI") { + bb.push(decodeURIComponent(data.data)); + } else if (data.encoding === "raw") { + bb.push(data.data); + } + } else { + if (typeof data !== "string") { + data += ""; // convert unsupported types to strings + } + // decode UTF-16 to binary string + bb.push(unescape(encodeURIComponent(data))); + } + }; + FBB_proto.getBlob = function(type) { + if (!arguments.length) { + type = null; + } + return new FakeBlob(this.data.join(""), type, "raw"); + }; + FBB_proto.toString = function() { + return "[object BlobBuilder]"; + }; + FB_proto.slice = function(start, end, type) { + var args = arguments.length; + if (args < 3) { + type = null; + } + return new FakeBlob( + this.data.slice(start, args > 1 ? end : this.data.length) + , type + , this.encoding + ); + }; + FB_proto.toString = function() { + return "[object Blob]"; + }; + return FakeBlobBuilder; + }(view)); - return function Blob(blobParts, options) { - var type = options ? (options.type || "") : ""; - var builder = new BlobBuilder(); - if (blobParts) { - for (var i = 0, len = blobParts.length; i < len; i++) { - builder.append(blobParts[i]); - } - } - return builder.getBlob(type); - }; + return function Blob(blobParts, options) { + var type = options ? (options.type || "") : ""; + var builder = new BlobBuilder(); + if (blobParts) { + for (var i = 0, len = blobParts.length; i < len; i++) { + builder.append(blobParts[i]); + } + } + return builder.getBlob(type); + }; }(self)); +/* FileSaver.js + * A saveAs() FileSaver implementation. + * 2013-10-21 + * + * By Eli Grey, http://eligrey.com + * License: X11/MIT + * See LICENSE.md + */ + +/*global self */ +/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, + plusplus: true */ + /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ -var saveAs=saveAs||(navigator.msSaveOrOpenBlob&&navigator.msSaveOrOpenBlob.bind(navigator))||(function(h){"use strict";var r=h.document,l=function(){return h.URL||h.webkitURL||h},e=h.URL||h.webkitURL||h,n=r.createElementNS("http://www.w3.org/1999/xhtml","a"),g=!h.externalHost&&"download" in n,j=function(t){var s=r.createEvent("MouseEvents");s.initMouseEvent("click",true,false,h,0,0,0,0,0,false,false,false,false,0,null);t.dispatchEvent(s)},o=h.webkitRequestFileSystem,p=h.requestFileSystem||o||h.mozRequestFileSystem,m=function(s){(h.setImmediate||h.setTimeout)(function(){throw s},0)},c="application/octet-stream",k=0,b=[],i=function(){var t=b.length;while(t--){var s=b[t];if(typeof s==="string"){e.revokeObjectURL(s)}else{s.remove()}}b.length=0},q=function(t,s,w){s=[].concat(s);var v=s.length;while(v--){var x=t["on"+s[v]];if(typeof x==="function"){try{x.call(t,w||t)}catch(u){m(u)}}}},f=function(t,u){var v=this,B=t.type,E=false,x,w,s=function(){var F=l().createObjectURL(t);b.push(F);return F},A=function(){q(v,"writestart progress write writeend".split(" "))},D=function(){if(E||!x){x=s(t)}if(w){w.location.href=x}else{window.open(x,"_blank")}v.readyState=v.DONE;A()},z=function(F){return function(){if(v.readyState!==v.DONE){return F.apply(this,arguments)}}},y={create:true,exclusive:false},C;v.readyState=v.INIT;if(!u){u="download"}if(g){x=s(t);n.href=x;n.download=u;j(n);v.readyState=v.DONE;A();return}if(h.chrome&&B&&B!==c){C=t.slice||t.webkitSlice;t=C.call(t,0,t.size,c);E=true}if(o&&u!=="download"){u+=".download"}if(B===c||o){w=h}if(!p){D();return}k+=t.size;p(h.TEMPORARY,k,z(function(F){F.root.getDirectory("saved",y,z(function(G){var H=function(){G.getFile(u,y,z(function(I){I.createWriter(z(function(J){J.onwriteend=function(K){w.location.href=I.toURL();b.push(I);v.readyState=v.DONE;q(v,"writeend",K)};J.onerror=function(){var K=J.error;if(K.code!==K.ABORT_ERR){D()}};"writestart progress write abort".split(" ").forEach(function(K){J["on"+K]=v["on"+K]});J.write(t);v.abort=function(){J.abort();v.readyState=v.DONE};v.readyState=v.WRITING}),D)}),D)};G.getFile(u,{create:false},z(function(I){I.remove();H()}),z(function(I){if(I.code===I.NOT_FOUND_ERR){H()}else{D()}}))}),D)}),D)},d=f.prototype,a=function(s,t){return new f(s,t)};d.abort=function(){var s=this;s.readyState=s.DONE;q(s,"abort")};d.readyState=d.INIT=0;d.WRITING=1;d.DONE=2;d.error=d.onwritestart=d.onprogress=d.onwrite=d.onabort=d.onerror=d.onwriteend=null;h.addEventListener("unload",i,false);return a}(self)); \ No newline at end of file + +var saveAs = saveAs + || (typeof navigator !== 'undefined' && navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) + || (function(view) { + "use strict"; + var + doc = view.document + // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet + , get_URL = function() { + return view.URL || view.webkitURL || view; + } + , URL = view.URL || view.webkitURL || view + , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") + , can_use_save_link = !view.externalHost && "download" in save_link + , click = function(node) { + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + node.dispatchEvent(event); + } + , webkit_req_fs = view.webkitRequestFileSystem + , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem + , throw_outside = function (ex) { + (view.setImmediate || view.setTimeout)(function() { + throw ex; + }, 0); + } + , force_saveable_type = "application/octet-stream" + , fs_min_size = 0 + , deletion_queue = [] + , process_deletion_queue = function() { + var i = deletion_queue.length; + while (i--) { + var file = deletion_queue[i]; + if (typeof file === "string") { // file is an object URL + URL.revokeObjectURL(file); + } else { // file is a File + file.remove(); + } + } + deletion_queue.length = 0; // clear queue + } + , dispatch = function(filesaver, event_types, event) { + event_types = [].concat(event_types); + var i = event_types.length; + while (i--) { + var listener = filesaver["on" + event_types[i]]; + if (typeof listener === "function") { + try { + listener.call(filesaver, event || filesaver); + } catch (ex) { + throw_outside(ex); + } + } + } + } + , FileSaver = function(blob, name) { + // First try a.download, then web filesystem, then object URLs + var + filesaver = this + , type = blob.type + , blob_changed = false + , object_url + , target_view + , get_object_url = function() { + var object_url = get_URL().createObjectURL(blob); + deletion_queue.push(object_url); + return object_url; + } + , dispatch_all = function() { + dispatch(filesaver, "writestart progress write writeend".split(" ")); + } + // on any filesys errors revert to saving with object URLs + , fs_error = function() { + // don't create more object URLs than needed + if (blob_changed || !object_url) { + object_url = get_object_url(blob); + } + if (target_view) { + target_view.location.href = object_url; + } else { + window.open(object_url, "_blank"); + } + filesaver.readyState = filesaver.DONE; + dispatch_all(); + } + , abortable = function(func) { + return function() { + if (filesaver.readyState !== filesaver.DONE) { + return func.apply(this, arguments); + } + }; + } + , create_if_not_found = {create: true, exclusive: false} + , slice + ; + filesaver.readyState = filesaver.INIT; + if (!name) { + name = "download"; + } + if (can_use_save_link) { + object_url = get_object_url(blob); + // FF for Android has a nasty garbage collection mechanism + // that turns all objects that are not pure javascript into 'deadObject' + // this means `doc` and `save_link` are unusable and need to be recreated + // `view` is usable though: + doc = view.document; + save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a"); + save_link.href = object_url; + save_link.download = name; + var event = doc.createEvent("MouseEvents"); + event.initMouseEvent( + "click", true, false, view, 0, 0, 0, 0, 0 + , false, false, false, false, 0, null + ); + save_link.dispatchEvent(event); + filesaver.readyState = filesaver.DONE; + dispatch_all(); + return; + } + // Object and web filesystem URLs have a problem saving in Google Chrome when + // viewed in a tab, so I force save with application/octet-stream + // http://code.google.com/p/chromium/issues/detail?id=91158 + if (view.chrome && type && type !== force_saveable_type) { + slice = blob.slice || blob.webkitSlice; + blob = slice.call(blob, 0, blob.size, force_saveable_type); + blob_changed = true; + } + // Since I can't be sure that the guessed media type will trigger a download + // in WebKit, I append .download to the filename. + // https://bugs.webkit.org/show_bug.cgi?id=65440 + if (webkit_req_fs && name !== "download") { + name += ".download"; + } + if (type === force_saveable_type || webkit_req_fs) { + target_view = view; + } + if (!req_fs) { + fs_error(); + return; + } + fs_min_size += blob.size; + req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { + fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { + var save = function() { + dir.getFile(name, create_if_not_found, abortable(function(file) { + file.createWriter(abortable(function(writer) { + writer.onwriteend = function(event) { + target_view.location.href = file.toURL(); + deletion_queue.push(file); + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "writeend", event); + }; + writer.onerror = function() { + var error = writer.error; + if (error.code !== error.ABORT_ERR) { + fs_error(); + } + }; + "writestart progress write abort".split(" ").forEach(function(event) { + writer["on" + event] = filesaver["on" + event]; + }); + writer.write(blob); + filesaver.abort = function() { + writer.abort(); + filesaver.readyState = filesaver.DONE; + }; + filesaver.readyState = filesaver.WRITING; + }), fs_error); + }), fs_error); + }; + dir.getFile(name, {create: false}, abortable(function(file) { + // delete file if it already exists + file.remove(); + save(); + }), abortable(function(ex) { + if (ex.code === ex.NOT_FOUND_ERR) { + save(); + } else { + fs_error(); + } + })); + }), fs_error); + }), fs_error); + } + , FS_proto = FileSaver.prototype + , saveAs = function(blob, name) { + return new FileSaver(blob, name); + } + ; + FS_proto.abort = function() { + var filesaver = this; + filesaver.readyState = filesaver.DONE; + dispatch(filesaver, "abort"); + }; + FS_proto.readyState = FS_proto.INIT = 0; + FS_proto.WRITING = 1; + FS_proto.DONE = 2; + + FS_proto.error = + FS_proto.onwritestart = + FS_proto.onprogress = + FS_proto.onwrite = + FS_proto.onabort = + FS_proto.onerror = + FS_proto.onwriteend = + null; + + view.addEventListener("unload", process_deletion_queue, false); + return saveAs; +}(this.self || this.window || this.content)); +// `self` is undefined in Firefox for Android content script context +// while `this` is nsIContentFrameMessageManager +// with an attribute `content` that corresponds to the window + +if (typeof module !== 'undefined') module.exports = saveAs;