From 4e3e6511ee9392b3ee819cb6dbe8f7c5cb8b2508 Mon Sep 17 00:00:00 2001 From: kenny Date: Sat, 30 Jul 2016 00:12:44 +0800 Subject: [PATCH 1/2] add dom-to-image@2.5.2 w/ npm auto-update close #8589, cc @tsayen --- ajax/libs/dom-to-image/2.5.2/dom-to-image.js | 720 ++++++++++++++++++ .../dom-to-image/2.5.2/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/package.json | 39 + 3 files changed, 761 insertions(+) create mode 100644 ajax/libs/dom-to-image/2.5.2/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.5.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/package.json diff --git a/ajax/libs/dom-to-image/2.5.2/dom-to-image.js b/ajax/libs/dom-to-image/2.5.2/dom-to-image.js new file mode 100644 index 00000000000000..f3ac3a901cf145 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.2/dom-to-image.js @@ -0,0 +1,720 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toJpeg: toJpeg, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value. + * @param {Number} options.width - width to be applied to node before rendering. + * @param {Number} options.height - height to be applied to node before rendering. + * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. + * @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only), + defaults to 1.0. + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(applyOptions) + .then(function (clone) { + return makeSvgDataUri(clone, + options.width || util.width(node), + options.height || util.height(node) + ); + }); + + function applyOptions(clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + + if (options.width) clone.style.width = options.width + 'px'; + if (options.height) clone.style.height = options.height + 'px'; + + if (options.style) + Object.keys(options.style).forEach(function (property) { + clone.style[property] = options.style[property]; + }); + + return clone; + } + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + util.width(node), + util.height(node) + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a JPEG image data URL + * */ + function toJpeg(node, options) { + options = options || {}; + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL('image/jpeg', options.quality || 1.0); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = options.width || util.width(domNode); + canvas.height = options.height || util.height(domNode); + + if (options.bgcolor) { + var ctx = canvas.getContext('2d'); + ctx.fillStyle = options.bgcolor; + ctx.fillRect(0, 0, canvas.width, canvas.height); + } + + return canvas; + } + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage, + width: width, + height: height + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + + function width(node) { + var leftBorder = px(node, 'border-left-width'); + var rightBorder = px(node, 'border-right-width'); + return node.scrollWidth + leftBorder + rightBorder; + } + + function height(node) { + var topBorder = px(node, 'border-top-width'); + var bottomBorder = px(node, 'border-bottom-width'); + return node.scrollHeight + topBorder + bottomBorder; + } + + function px(node, styleProperty) { + var value = window.getComputedStyle(node).getPropertyValue(styleProperty); + return parseFloat(value.replace('px', '')); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.5.2/dom-to-image.min.js b/ajax/libs/dom-to-image/2.5.2/dom-to-image.min.js new file mode 100644 index 00000000000000..9a7d15f299bc42 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 25-09-2016 */ +!function(a){"use strict";function b(a,b){function c(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&(a.style.width=b.width+"px"),b.height&&(a.style.height=b.height+"px"),b.style&&Object.keys(b.style).forEach(function(c){a.style[c]=b.style[c]}),a}return b=b||{},Promise.resolve(a).then(function(a){return h(a,b.filter,!0)}).then(i).then(j).then(c).then(function(c){return k(c,b.width||p.width(a),b.height||p.height(a))})}function c(a,b){return g(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,p.width(a),p.height(a)).data})}function d(a,b){return g(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return b=b||{},g(a,b).then(function(a){return a.toDataURL("image/jpeg",b.quality||1)})}function f(a,b){return g(a,b||{}).then(p.canvasToBlob)}function g(a,c){function d(a){var b=document.createElement("canvas");if(b.width=c.width||p.width(a),b.height=c.height||p.height(a),c.bgcolor){var d=b.getContext("2d");d.fillStyle=c.bgcolor,d.fillRect(0,0,b.width,b.height)}return b}return b(a,c).then(p.makeImage).then(p.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function h(a,b,c){function d(a){return a instanceof HTMLCanvasElement?p.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return h(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,p.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){p.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return p.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=p.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function i(a){return r.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function j(a){return s.inlineAll(a).then(function(){return a})}function k(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(p.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function l(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return a.search(/^(data:)/)!==-1}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;f Date: Mon, 8 Aug 2016 22:47:01 +0800 Subject: [PATCH 2/2] add old versions of dom-to-image Manually add the other versions from git repo because npm auto-update can't get some of the old versions, cc #8589 --- .../dom-to-image/0.0.2/dom-to-image.min.js | 2 + .../dom-to-image/0.0.3/dom-to-image.min.js | 2 + .../dom-to-image/0.0.4/dom-to-image.min.js | 2 + .../dom-to-image/0.0.5/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.1.0/dom-to-image.js | 114 +++ .../dom-to-image/0.1.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.1.1/dom-to-image.js | 113 +++ .../dom-to-image/0.1.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.2.0/dom-to-image.js | 136 ++++ .../dom-to-image/0.2.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.3.0/dom-to-image.js | 146 ++++ .../dom-to-image/0.3.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.3.1/dom-to-image.js | 146 ++++ .../dom-to-image/0.3.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.4.0/dom-to-image.js | 595 +++++++++++++++ .../dom-to-image/0.4.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.4.1/dom-to-image.js | 606 +++++++++++++++ .../dom-to-image/0.4.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/0.4.2/dom-to-image.js | 607 +++++++++++++++ .../dom-to-image/0.4.2/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.0/dom-to-image.js | 617 +++++++++++++++ .../dom-to-image/1.0.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.1/dom-to-image.js | 609 +++++++++++++++ .../dom-to-image/1.0.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.2/dom-to-image.js | 609 +++++++++++++++ .../dom-to-image/1.0.2/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.3/dom-to-image.js | 609 +++++++++++++++ .../dom-to-image/1.0.3/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.4/dom-to-image.js | 605 +++++++++++++++ .../dom-to-image/1.0.4/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.0.5/dom-to-image.js | 609 +++++++++++++++ .../dom-to-image/1.0.5/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.1.0/dom-to-image.js | 618 +++++++++++++++ .../dom-to-image/1.1.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.1.1/dom-to-image.js | 618 +++++++++++++++ .../dom-to-image/1.1.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.1.2/dom-to-image.js | 618 +++++++++++++++ .../dom-to-image/1.1.2/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/1.1.3/dom-to-image.js | 621 ++++++++++++++++ .../dom-to-image/1.1.3/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.0.0/dom-to-image.js | 622 ++++++++++++++++ .../dom-to-image/2.0.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.0.1/dom-to-image.js | 623 ++++++++++++++++ .../dom-to-image/2.0.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.0.2/dom-to-image.js | 633 ++++++++++++++++ .../dom-to-image/2.0.2/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.1.0/dom-to-image.js | 633 ++++++++++++++++ .../dom-to-image/2.1.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.1.1/dom-to-image.js | 637 ++++++++++++++++ .../dom-to-image/2.1.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.2.0/dom-to-image.js | 654 ++++++++++++++++ .../dom-to-image/2.2.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.2.1/dom-to-image.js | 661 +++++++++++++++++ .../dom-to-image/2.2.1/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.3.0/dom-to-image.js | 665 +++++++++++++++++ .../dom-to-image/2.3.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.4.0/dom-to-image.js | 678 +++++++++++++++++ .../dom-to-image/2.4.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.5.0/dom-to-image.js | 694 +++++++++++++++++ .../dom-to-image/2.5.0/dom-to-image.min.js | 2 + ajax/libs/dom-to-image/2.5.1/dom-to-image.js | 701 ++++++++++++++++++ .../dom-to-image/2.5.1/dom-to-image.min.js | 2 + 62 files changed, 15863 insertions(+) create mode 100644 ajax/libs/dom-to-image/0.0.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.0.3/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.0.4/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.0.5/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.1.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.1.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.1.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.1.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.2.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.2.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.3.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.3.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.3.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.3.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.4.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.4.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.4.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.4.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/0.4.2/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/0.4.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.2/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.3/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.3/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.4/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.4/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.0.5/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.0.5/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.1.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.1.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.1.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.1.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.1.2/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.1.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/1.1.3/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/1.1.3/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.0.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.0.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.0.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.0.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.0.2/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.0.2/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.1.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.1.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.1.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.1.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.2.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.2.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.2.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.2.1/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.3.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.3.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.4.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.4.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.5.0/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.5.0/dom-to-image.min.js create mode 100644 ajax/libs/dom-to-image/2.5.1/dom-to-image.js create mode 100644 ajax/libs/dom-to-image/2.5.1/dom-to-image.min.js diff --git a/ajax/libs/dom-to-image/0.0.2/dom-to-image.min.js b/ajax/libs/dom-to-image/0.0.2/dom-to-image.min.js new file mode 100644 index 00000000000000..ded7a4895edd6c --- /dev/null +++ b/ajax/libs/dom-to-image/0.0.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 20-04-2015 */ +"use strict";!function(){function a(a,b,d){var e=getComputedStyle(b);if(c)a.style.cssText=e.cssText;else for(var f in e)isNaN(parseInt(f,10))&&"function"!=typeof e[f]&&!/^(cssText|length|parentRule)$/.test(f)&&(a.style[f]=e[f])}function b(b,c){var d=b.querySelectorAll("*"),e=c.querySelectorAll("*");a(b,c,1),Array.prototype.forEach.call(d,function(b,c){a(b,e[c])}),b.style.margin=b.style.marginLeft=b.style.marginTop=b.style.marginBottom=b.style.marginRight=""}var c=""!==getComputedStyle(document.body).cssText;window.domvas={toImage:function(a,c,d,e,f,g){f=f||0,g=g||0;var h=a.cloneNode(!0);b(h,a),h.setAttribute("xmlns","http://www.w3.org/1999/xhtml");var i=(new XMLSerializer).serializeToString(h),j="data:image/svg+xml,"+i+"",k=new Image;k.src=j,k.onload=function(){c&&c.call(this,this)}}}}(); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.0.3/dom-to-image.min.js b/ajax/libs/dom-to-image/0.0.3/dom-to-image.min.js new file mode 100644 index 00000000000000..907a47ce5f09ac --- /dev/null +++ b/ajax/libs/dom-to-image/0.0.3/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 23-04-2015 */ +!function(a){"use strict";function b(b,c){var d=a.window.getComputedStyle(b);if(d.cssText)return void(c.style.cssText=d.cssText);for(var e=0;e"+i+"",k=new Image;k.src=j,k.onload=function(){b&&b.call(k,k)}}}}a.domvas=d()}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.0.4/dom-to-image.min.js b/ajax/libs/dom-to-image/0.0.4/dom-to-image.min.js new file mode 100644 index 00000000000000..907a47ce5f09ac --- /dev/null +++ b/ajax/libs/dom-to-image/0.0.4/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 23-04-2015 */ +!function(a){"use strict";function b(b,c){var d=a.window.getComputedStyle(b);if(d.cssText)return void(c.style.cssText=d.cssText);for(var e=0;e"+i+"",k=new Image;k.src=j,k.onload=function(){b&&b.call(k,k)}}}}a.domvas=d()}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.0.5/dom-to-image.min.js b/ajax/libs/dom-to-image/0.0.5/dom-to-image.min.js new file mode 100644 index 00000000000000..907a47ce5f09ac --- /dev/null +++ b/ajax/libs/dom-to-image/0.0.5/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 23-04-2015 */ +!function(a){"use strict";function b(b,c){var d=a.window.getComputedStyle(b);if(d.cssText)return void(c.style.cssText=d.cssText);for(var e=0;e"+i+"",k=new Image;k.src=j,k.onload=function(){b&&b.call(k,k)}}}}a.domvas=d()}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.1.0/dom-to-image.js b/ajax/libs/dom-to-image/0.1.0/dom-to-image.js new file mode 100644 index 00000000000000..1c3f12eadc18ba --- /dev/null +++ b/ajax/libs/dom-to-image/0.1.0/dom-to-image.js @@ -0,0 +1,114 @@ +(function (global) { + "use strict"; + + function copyProperties(style, node) { + for (var i = 0; i < style.length; i++) { + var propertyName = style[i]; + node.style.setProperty( + propertyName, + style.getPropertyValue(propertyName), + style.getPropertyPriority(propertyName) + ); + } + } + + function copyStyle(source, target) { + var sourceStyle = global.window.getComputedStyle(source); + if (sourceStyle.cssText) { + target.style.cssText = sourceStyle.cssText; + return; + } + copyProperties(sourceStyle, target); + } + + function fixNamespace(element) { + if (element instanceof SVGElement) + element.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + else + element.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + } + + function processClone(clone, original) { + fixNamespace(clone); + copyStyle(original, clone); + } + + function cloneNode(node, done) { + var clone = node.cloneNode(false); + processClone(clone, node); + + var children = node.children; + if (children.length === 0) done(clone); + + var cloned = 0; + for (var i = 0; i < children.length; i++) { + cloneChild(children[i]); + } + + function cloneChild(child) { + setTimeout(function () { + cloneNode(child, function (childClone) { + clone.appendChild(childClone); + cloned++; + if (cloned === children.length) done(clone); + }); + }, 0); + } + } + + function stripMargin(node) { + var style = node.style; + style.margin = style.marginLeft = style.marginTop = style.marginBottom = style.marginRight = ''; + return node; + } + + function escape(xmlString) { + return xmlString.replace(/#/g, '%23'); + } + + function serialize(element) { + return escape(new XMLSerializer().serializeToString(element)); + } + + function asForeignObject(node) { + return "" + serialize(node) + ""; + } + + function toSvg(node, width, height) { + return "" + + asForeignObject(node) + ""; + } + + function makeDataUri(node, width, height) { + return "data:image/svg+xml;charset=utf-8," + toSvg(node, width, height); + } + + function makeImage(node, width, height, done) { + var image = new Image(); + image.onload = function () { + done(image); + }; + image.src = makeDataUri(stripMargin(node), width, height); + } + + function toImage(domNode, done) { + cloneNode(domNode, function (clone) { + makeImage(clone, domNode.offsetWidth, domNode.offsetHeight, done); + }); + } + + function toDataUrl(domNode, done) { + toImage(domNode, function(image){ + var canvas = document.createElement('canvas'); + canvas.width = domNode.offsetWidth; + canvas.height = domNode.offsetHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + done(canvas.toDataURL()); + }); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.1.0/dom-to-image.min.js b/ajax/libs/dom-to-image/0.1.0/dom-to-image.min.js new file mode 100644 index 00000000000000..1a183bd68cb061 --- /dev/null +++ b/ajax/libs/dom-to-image/0.1.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-05-2015 */ +!function(a){"use strict";function b(a,b){for(var c=0;c"+i(a)+""}function k(a,b,c){return""+j(a)+""}function l(a,b,c){return"data:image/svg+xml;charset=utf-8,"+k(a,b,c)}function m(a,b,c,d){var e=new Image;e.onload=function(){d(e)},e.src=l(g(a),b,c)}function n(a,b){f(a,function(c){m(c,a.offsetWidth,a.offsetHeight,b)})}function o(a,b){n(a,function(c){var d=document.createElement("canvas");d.width=a.offsetWidth,d.height=a.offsetHeight,d.getContext("2d").drawImage(c,0,0),b(d.toDataURL())})}a.domtoimage={toImage:n,toDataUrl:o}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.1.1/dom-to-image.js b/ajax/libs/dom-to-image/0.1.1/dom-to-image.js new file mode 100644 index 00000000000000..0eee5e04cec65b --- /dev/null +++ b/ajax/libs/dom-to-image/0.1.1/dom-to-image.js @@ -0,0 +1,113 @@ +(function (global) { + "use strict"; + + function copyProperties(style, node) { + for (var i = 0; i < style.length; i++) { + var propertyName = style[i]; + node.style.setProperty( + propertyName, + style.getPropertyValue(propertyName), + style.getPropertyPriority(propertyName) + ); + } + } + + function copyStyle(source, target) { + var sourceStyle = global.window.getComputedStyle(source); + if (sourceStyle.cssText) { + target.style.cssText = sourceStyle.cssText; + return; + } + copyProperties(sourceStyle, target); + } + + function fixNamespace(node) { + if (node instanceof SVGElement) + node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + + function processClone(clone, original) { + fixNamespace(clone); + if (clone instanceof Element) + copyStyle(original, clone); + } + + function cloneNode(node, done) { + var clone = node.cloneNode(false); + + processClone(clone, node); + + var children = node.childNodes; + if (children.length === 0) done(clone); + + var cloned = 0; + for (var i = 0; i < children.length; i++) { + cloneChild(children[i]); + } + + function cloneChild(child) { + cloneNode(child, function (childClone) { + clone.appendChild(childClone); + cloned++; + if (cloned === children.length) done(clone); + }); + } + } + + function stripMargin(node) { + var style = node.style; + style.margin = style.marginLeft = style.marginTop = style.marginBottom = style.marginRight = ''; + return node; + } + + function escape(xmlString) { + return xmlString.replace(/#/g, '%23'); + } + + function serialize(node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return escape(new XMLSerializer().serializeToString(node)); + } + + function asForeignObject(node) { + return "" + serialize(node) + ""; + } + + function toSvg(node, width, height) { + return "" + + asForeignObject(node) + ""; + } + + function makeDataUri(node, width, height) { + return "data:image/svg+xml;charset=utf-8," + toSvg(node, width, height); + } + + function makeImage(node, width, height, done) { + var image = new Image(); + image.onload = function () { + done(image); + }; + image.src = makeDataUri(stripMargin(node), width, height); + } + + function toImage(domNode, done) { + cloneNode(domNode, function (clone) { + makeImage(clone, domNode.offsetWidth, domNode.offsetHeight, done); + }); + } + + function toDataUrl(domNode, done) { + toImage(domNode, function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.offsetWidth; + canvas.height = domNode.offsetHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + done(canvas.toDataURL()); + }); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.1.1/dom-to-image.min.js b/ajax/libs/dom-to-image/0.1.1/dom-to-image.min.js new file mode 100644 index 00000000000000..1a183bd68cb061 --- /dev/null +++ b/ajax/libs/dom-to-image/0.1.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-05-2015 */ +!function(a){"use strict";function b(a,b){for(var c=0;c"+i(a)+""}function k(a,b,c){return""+j(a)+""}function l(a,b,c){return"data:image/svg+xml;charset=utf-8,"+k(a,b,c)}function m(a,b,c,d){var e=new Image;e.onload=function(){d(e)},e.src=l(g(a),b,c)}function n(a,b){f(a,function(c){m(c,a.offsetWidth,a.offsetHeight,b)})}function o(a,b){n(a,function(c){var d=document.createElement("canvas");d.width=a.offsetWidth,d.height=a.offsetHeight,d.getContext("2d").drawImage(c,0,0),b(d.toDataURL())})}a.domtoimage={toImage:n,toDataUrl:o}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.2.0/dom-to-image.js b/ajax/libs/dom-to-image/0.2.0/dom-to-image.js new file mode 100644 index 00000000000000..f56e1b7ed5196d --- /dev/null +++ b/ajax/libs/dom-to-image/0.2.0/dom-to-image.js @@ -0,0 +1,136 @@ +(function (global) { + "use strict"; + + function copyProperties(style, node) { + for (var i = 0; i < style.length; i++) { + var propertyName = style[i]; + node.style.setProperty( + propertyName, + style.getPropertyValue(propertyName), + style.getPropertyPriority(propertyName) + ); + } + } + + function copyStyle(source, target) { + var sourceStyle = global.window.getComputedStyle(source); + if (sourceStyle.cssText) { + target.style.cssText = sourceStyle.cssText; + return; + } + copyProperties(sourceStyle, target); + } + + function fixNamespace(node) { + if (node instanceof SVGElement) + node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + + function processClone(clone, original) { + fixNamespace(clone); + if (clone instanceof Element) + copyStyle(original, clone); + } + + function cloneNode(node, done) { + var clone = node.cloneNode(false); + + processClone(clone, node); + + var children = node.childNodes; + if (children.length === 0) done(clone); + + var cloned = 0; + for (var i = 0; i < children.length; i++) { + cloneChild(children[i]); + } + + function cloneChild(child) { + cloneNode(child, function (childClone) { + clone.appendChild(childClone); + cloned++; + if (cloned === children.length) done(clone); + }); + } + } + + function stripMargin(node) { + var style = node.style; + style.margin = style.marginLeft = style.marginTop = style.marginBottom = style.marginRight = ''; + return node; + } + + function escape(xmlString) { + return xmlString.replace(/#/g, '%23'); + } + + function serialize(node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return escape(new XMLSerializer().serializeToString(node)); + } + + function asForeignObject(node) { + return "" + serialize(node) + ""; + } + + function toSvg(node, width, height) { + return "" + + asForeignObject(node) + ""; + } + + function makeDataUri(node, width, height) { + return "data:image/svg+xml;charset=utf-8," + toSvg(node, width, height); + } + + function makeImage(node, width, height, done) { + var image = new Image(); + image.onload = function () { + done(image); + }; + image.src = makeDataUri(stripMargin(node), width, height); + } + + function toImage(domNode, done) { + cloneNode(domNode, function (clone) { + makeImage(clone, domNode.offsetWidth, domNode.offsetHeight, done); + }); + } + + function drawOffScreen(domNode, done) { + toImage(domNode, function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.offsetWidth; + canvas.height = domNode.offsetHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + done(canvas); + }); + } + + function toBlob(domNode, done) { + drawOffScreen(domNode, function (canvas) { + if (canvas.toBlob) { + canvas.toBlob(done); + return; + } + /* canvas.toBlob() method is not available in Chrome 40 */ + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var binaryArray = new Uint8Array(binaryString.length); + for (var i = 0; i < binaryString.length; i++) { + binaryArray[i] = binaryString.charCodeAt(i); + } + done(new Blob([binaryArray], {type: 'image/png'})); + }); + } + + function toDataUrl(domNode, done) { + drawOffScreen(domNode, function (canvas) { + done(canvas.toDataURL()); + }); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.2.0/dom-to-image.min.js b/ajax/libs/dom-to-image/0.2.0/dom-to-image.min.js new file mode 100644 index 00000000000000..cc95f61c33a25f --- /dev/null +++ b/ajax/libs/dom-to-image/0.2.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-05-2015 */ +!function(a){"use strict";function b(a,b){for(var c=0;c"+i(a)+""}function k(a,b,c){return""+j(a)+""}function l(a,b,c){return"data:image/svg+xml;charset=utf-8,"+k(a,b,c)}function m(a,b,c,d){var e=new Image;e.onload=function(){d(e)},e.src=l(g(a),b,c)}function n(a,b){f(a,function(c){m(c,a.offsetWidth,a.offsetHeight,b)})}function o(a,b){n(a,function(c){var d=document.createElement("canvas");d.width=a.offsetWidth,d.height=a.offsetHeight,d.getContext("2d").drawImage(c,0,0),b(d)})}function p(a,b){o(a,function(a){if(a.toBlob)return void a.toBlob(b);for(var c=window.atob(a.toDataURL().split(",")[1]),d=new Uint8Array(c.length),e=0;e" + serialize(node) + ""; + } + + function toSvg(node, width, height) { + return "" + + asForeignObject(node) + ""; + } + + function makeDataUri(node, width, height) { + return "data:image/svg+xml;charset=utf-8," + toSvg(node, width, height); + } + + function makeImage(node, width, height, done) { + var image = new Image(); + image.onload = function () { + done(image); + }; + image.src = makeDataUri(stripMargin(node), width, height); + } + + function toImage(domNode, done, options) { + options = options || {}; + cloneNode(domNode, function (clone) { + makeImage(clone, domNode.offsetWidth, domNode.offsetHeight, done); + }, options.filter); + } + + function drawOffScreen(domNode, done, options) { + toImage(domNode, function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.offsetWidth; + canvas.height = domNode.offsetHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + done(canvas); + }, options); + } + + function toBlob(domNode, done, options) { + drawOffScreen(domNode, function (canvas) { + if (canvas.toBlob) { + canvas.toBlob(done); + return; + } + /* canvas.toBlob() method is not available in Chrome 40 */ + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var binaryArray = new Uint8Array(binaryString.length); + for (var i = 0; i < binaryString.length; i++) { + binaryArray[i] = binaryString.charCodeAt(i); + } + done(new Blob([binaryArray], {type: 'image/png'})); + }, options); + } + + function toDataUrl(domNode, done, options) { + drawOffScreen(domNode, function (canvas) { + done(canvas.toDataURL()); + }, options); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.3.0/dom-to-image.min.js b/ajax/libs/dom-to-image/0.3.0/dom-to-image.min.js new file mode 100644 index 00000000000000..cc95f61c33a25f --- /dev/null +++ b/ajax/libs/dom-to-image/0.3.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-05-2015 */ +!function(a){"use strict";function b(a,b){for(var c=0;c"+i(a)+""}function k(a,b,c){return""+j(a)+""}function l(a,b,c){return"data:image/svg+xml;charset=utf-8,"+k(a,b,c)}function m(a,b,c,d){var e=new Image;e.onload=function(){d(e)},e.src=l(g(a),b,c)}function n(a,b){f(a,function(c){m(c,a.offsetWidth,a.offsetHeight,b)})}function o(a,b){n(a,function(c){var d=document.createElement("canvas");d.width=a.offsetWidth,d.height=a.offsetHeight,d.getContext("2d").drawImage(c,0,0),b(d)})}function p(a,b){o(a,function(a){if(a.toBlob)return void a.toBlob(b);for(var c=window.atob(a.toDataURL().split(",")[1]),d=new Uint8Array(c.length),e=0;e" + serialize(node) + ""; + } + + function toSvg(node, width, height) { + return "" + + asForeignObject(node) + ""; + } + + function makeDataUri(node, width, height) { + return "data:image/svg+xml;charset=utf-8," + toSvg(node, width, height); + } + + function makeImage(node, width, height, done) { + var image = new Image(); + image.onload = function () { + done(image); + }; + image.src = makeDataUri(stripMargin(node), width, height); + } + + function toImage(domNode, done, options) { + options = options || {}; + cloneNode(domNode, function (clone) { + makeImage(clone, domNode.scrollWidth, domNode.scrollHeight, done); + }, options.filter); + } + + function drawOffScreen(domNode, done, options) { + toImage(domNode, function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + done(canvas); + }, options); + } + + function toBlob(domNode, done, options) { + drawOffScreen(domNode, function (canvas) { + if (canvas.toBlob) { + canvas.toBlob(done); + return; + } + /* canvas.toBlob() method is not available in Chrome 40 */ + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var binaryArray = new Uint8Array(binaryString.length); + for (var i = 0; i < binaryString.length; i++) { + binaryArray[i] = binaryString.charCodeAt(i); + } + done(new Blob([binaryArray], {type: 'image/png'})); + }, options); + } + + function toDataUrl(domNode, done, options) { + drawOffScreen(domNode, function (canvas) { + done(canvas.toDataURL()); + }, options); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.3.1/dom-to-image.min.js b/ajax/libs/dom-to-image/0.3.1/dom-to-image.min.js new file mode 100644 index 00000000000000..12664d3e7ff425 --- /dev/null +++ b/ajax/libs/dom-to-image/0.3.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 18-06-2015 */ +!function(a){"use strict";function b(a,b){for(var c=0;c"+i(a)+""}function k(a,b,c){return""+j(a)+""}function l(a,b,c){return"data:image/svg+xml;charset=utf-8,"+k(a,b,c)}function m(a,b,c,d){var e=new Image;e.onload=function(){d(e)},e.src=l(g(a),b,c)}function n(a,b,c){c=c||{},f(a,function(c){m(c,a.scrollWidth,a.scrollHeight,b)},c.filter)}function o(a,b,c){n(a,function(c){var d=document.createElement("canvas");d.width=a.scrollWidth,d.height=a.scrollHeight,d.getContext("2d").drawImage(c,0,0),b(d)},c)}function p(a,b,c){o(a,function(a){if(a.toBlob)return void a.toBlob(b);for(var c=window.atob(a.toDataURL().split(",")[1]),d=new Uint8Array(c.length),e=0;e' + xhtml + ""; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return "data:image/svg+xml;charset=utf-8," + svg; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function draw(domNode, options) { + return toImage(domNode, options) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to SVG image data URL + * */ + function toImage(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeDataUri(clone, node.scrollWidth, node.scrollHeight); + }) + .then(util.makeImage); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image data URL + * */ + function toDataUrl(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.4.0/dom-to-image.min.js b/ajax/libs/dom-to-image/0.4.0/dom-to-image.min.js new file mode 100644 index 00000000000000..72b173845e2368 --- /dev/null +++ b/ajax/libs/dom-to-image/0.4.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 24-09-2015 */ +!function(a){"use strict";function b(a,b){v.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}function c(a,c){a.cssText?c.cssText=a.cssText:b(a,c)}function d(b){var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return v.asArray(a).map(b).join("; ")+";"}function g(b,c,d){var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}function h(b,c){var d=a.window.getComputedStyle(b.source,c),e=d.getPropertyValue("content");if(""===e||"none"===e)return b;var f=v.uid();b.target.className=b.target.className+" "+f;var h=a.document.createElement("style");return h.appendChild(g(f,c,d)),b.target.appendChild(h),b}function i(a){return[":before",":after"].forEach(function(b){h(a,b)}),a}function j(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}function k(a,b){return b instanceof Element?Promise.resolve({source:a,target:b}).then(d).then(i).then(function(a){return a.target}).then(j):b}function l(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return n(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}function m(a,b,c){var d=a.childNodes;return 0===d.length?Promise.resolve(b):l(b,v.asArray(d),c).then(function(){return b})}function n(a,b){return b&&!b(a)?Promise.resolve():Promise.resolve().then(function(){return a.cloneNode(!1)}).then(function(c){return m(a,c,b)}).then(function(b){return k(a,b)})}function o(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(v.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function p(a){return y.inlineAll(a).then(function(){return a})}function q(a){return x.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function r(a,b){return s(a,b).then(v.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function s(a,b){return b=b||{},Promise.resolve(a).then(function(a){return n(a,b.filter)}).then(q).then(p).then(function(b){return o(b,a.scrollWidth,a.scrollHeight)}).then(v.makeImage)}function t(a,b){return r(a,b).then(function(a){return a.toDataURL()})}function u(a,b){return r(a,b).then(v.canvasToBlob)}var v=function(){function b(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function c(a){var c=b(a).toLowerCase();return o[c]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function h(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function i(a){var b=new XMLHttpRequest;return b.open("GET",a,!0),b.responseType="blob",new Promise(function(c,d){b.onload=function(){if(200!==this.status)return void d(new Error('Cannot fetch resource "'+a+'": '+this.status));var e=new FileReader;e.onloadend=function(){var a=e.result.split(/,/)[1];c(a)},e.readAsDataURL(b.response)},b.send()})}function j(a,b){return"data:"+b+";base64,"+a}function k(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function l(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function m(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function n(a){return a.replace(/#/g,"%23")}const o={woff:"application/x-font-woff",woff2:"application/x-font-woff2",truetype:"application/x-font-ttf",ttf:"application/x-font-ttf",opentype:"application/x-font-otf","embedded-opentype":"application/x-font-otf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif"};var p=function(){function a(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}function b(){return"u"+a()+c++}var c=0;return{next:b}}();return{escape:k,parseExtension:b,mimeType:c,dataAsUrl:j,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:i,uid:p.next,delay:l,asArray:m,escapeXhtml:n,makeImage:h}}(),w=function(){function a(a){return new RegExp("(url\\(['\"]?)("+v.escape(a)+")(['\"]?\\))","g")}function b(a){return!c(a)}function c(a){return-1!==a.search(g)}function d(a){for(var b,c=[];null!==(b=g.exec(a));)c.push(b[1]);return c.filter(function(a){return!v.isDataUrl(a)})}function e(b,c,d,e){return Promise.resolve(c).then(function(a){return d?v.resolveUrl(a,d):a}).then(e||v.getAndEncode).then(function(a){return v.dataAsUrl(a,v.mimeType(c))}).then(function(d){return b.replace(a(c),"$1"+d+"$3")})}function f(a,c,f){return b(a)?Promise.resolve(a):Promise.resolve(a).then(d).then(function(b){var d=Promise.resolve(a);return b.forEach(function(a){d=d.then(function(b){return e(b,a,c,f)})}),d})}const g=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:f,shouldProcess:c,impl:{readUrls:d,inline:e}}}(),x=function(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return w.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){v.asArray(a.cssRules).forEach(b.push.bind(b))}),b}function c(){return Promise.resolve(v.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(d)})}function d(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return w.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}function e(){return c(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}return{resolveAll:e,impl:{readAll:c}}}(),y=function(){function a(a){function b(b){return v.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||v.getAndEncode).then(function(b){return v.dataAsUrl(b,v.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(a){var b=a.style.getPropertyValue("background");return b?w.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}function c(d){return d instanceof Element?b(d).then(function(){return d instanceof HTMLImageElement?a(d).inline():Promise.all(v.asArray(d.childNodes).map(function(a){return c(a)}))}):Promise.resolve(d)}return{inlineAll:c,impl:{newImage:a}}}();a.domtoimage={toImage:s,toDataUrl:t,toBlob:u,impl:{fontFaces:x,images:y,util:v,inliner:w}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.4.1/dom-to-image.js b/ajax/libs/dom-to-image/0.4.1/dom-to-image.js new file mode 100644 index 00000000000000..75ed16e3fe9b5a --- /dev/null +++ b/ajax/libs/dom-to-image/0.4.1/dom-to-image.js @@ -0,0 +1,606 @@ +(function (global) { + "use strict"; + + var util = (function () { + + const TIMEOUT = 30000; + + const MIME = { + 'woff': 'application/x-font-woff', + 'woff2': 'application/x-font-woff2', + 'truetype': 'application/x-font-ttf', + 'ttf': 'application/x-font-ttf', + 'opentype': 'application/x-font-otf', + 'embedded-opentype': 'application/x-font-otf', + 'png': 'image/png', + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'gif': 'image/gif' + }; + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return MIME[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + var uid = (function () { + var index = 0; + + function uid() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + + function next() { + return 'u' + uid() + index++; + } + + return { + next: next + }; + })(); + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = function () { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + this.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + }; + + request.ontimeout = function () { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + }; + + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23'); + } + + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid.next, + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + })(); + + var inliner = (function () { + + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + + function nothingToInline(string) { + return !shouldProcess(string); + } + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline(string)) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + } + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + })(); + + var fontFaces = (function () { + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + })(); + + var images = (function () { + + function newImage(element) { + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + + return { + inline: inline + }; + } + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + } + + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + })(); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + } + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + } + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + } + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + } + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + + pair.target.className = pair.target.className + ' ' + className; + + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + } + + function clonePseudoElements(pair) { + [ + ':before', + ':after' + ] + .forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + } + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve() + .then(function () { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + } + + function makeDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ""; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return "data:image/svg+xml;charset=utf-8," + svg; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function draw(domNode, options) { + return toImage(domNode, options) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to SVG image data URL + * */ + function toImage(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeDataUri(clone, node.scrollWidth, node.scrollHeight); + }) + .then(util.makeImage); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image data URL + * */ + function toDataUrl(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.4.1/dom-to-image.min.js b/ajax/libs/dom-to-image/0.4.1/dom-to-image.min.js new file mode 100644 index 00000000000000..8ef61dc4e13a3e --- /dev/null +++ b/ajax/libs/dom-to-image/0.4.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 24-09-2015 */ +!function(a){"use strict";function b(a,b){v.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}function c(a,c){a.cssText?c.cssText=a.cssText:b(a,c)}function d(b){var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return v.asArray(a).map(b).join("; ")+";"}function g(b,c,d){var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}function h(b,c){var d=a.window.getComputedStyle(b.source,c),e=d.getPropertyValue("content");if(""===e||"none"===e)return b;var f=v.uid();b.target.className=b.target.className+" "+f;var h=a.document.createElement("style");return h.appendChild(g(f,c,d)),b.target.appendChild(h),b}function i(a){return[":before",":after"].forEach(function(b){h(a,b)}),a}function j(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}function k(a,b){return b instanceof Element?Promise.resolve({source:a,target:b}).then(d).then(i).then(function(a){return a.target}).then(j):b}function l(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return n(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}function m(a,b,c){var d=a.childNodes;return 0===d.length?Promise.resolve(b):l(b,v.asArray(d),c).then(function(){return b})}function n(a,b){return b&&!b(a)?Promise.resolve():Promise.resolve().then(function(){return a.cloneNode(!1)}).then(function(c){return m(a,c,b)}).then(function(b){return k(a,b)})}function o(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(v.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function p(a){return y.inlineAll(a).then(function(){return a})}function q(a){return x.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function r(a,b){return s(a,b).then(v.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function s(a,b){return b=b||{},Promise.resolve(a).then(function(a){return n(a,b.filter)}).then(q).then(p).then(function(b){return o(b,a.scrollWidth,a.scrollHeight)}).then(v.makeImage)}function t(a,b){return r(a,b).then(function(a){return a.toDataURL()})}function u(a,b){return r(a,b).then(v.canvasToBlob)}var v=function(){function b(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function c(a){var c=b(a).toLowerCase();return p[c]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function h(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function i(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.onreadystatechange=function(){if(4===d.readyState){if(200!==d.status)return void c(new Error("Cannot fetch resource "+a+", status: "+this.status));var e=new FileReader;e.onloadend=function(){var a=e.result.split(/,/)[1];b(a)},e.readAsDataURL(d.response)}},d.ontimeout=function(){c(new Error("Timeout of 30000ms occured while fetching resource: "+a))},d.responseType="blob",d.timeout=o,d.open("GET",a,!0),d.send()})}function j(a,b){return"data:"+b+";base64,"+a}function k(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function l(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function m(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function n(a){return a.replace(/#/g,"%23")}const o=3e4,p={woff:"application/x-font-woff",woff2:"application/x-font-woff2",truetype:"application/x-font-ttf",ttf:"application/x-font-ttf",opentype:"application/x-font-otf","embedded-opentype":"application/x-font-otf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif"};var q=function(){function a(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}function b(){return"u"+a()+c++}var c=0;return{next:b}}();return{escape:k,parseExtension:b,mimeType:c,dataAsUrl:j,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:i,uid:q.next,delay:l,asArray:m,escapeXhtml:n,makeImage:h}}(),w=function(){function a(a){return new RegExp("(url\\(['\"]?)("+v.escape(a)+")(['\"]?\\))","g")}function b(a){return!c(a)}function c(a){return-1!==a.search(g)}function d(a){for(var b,c=[];null!==(b=g.exec(a));)c.push(b[1]);return c.filter(function(a){return!v.isDataUrl(a)})}function e(b,c,d,e){return Promise.resolve(c).then(function(a){return d?v.resolveUrl(a,d):a}).then(e||v.getAndEncode).then(function(a){return v.dataAsUrl(a,v.mimeType(c))}).then(function(d){return b.replace(a(c),"$1"+d+"$3")})}function f(a,c,f){return b(a)?Promise.resolve(a):Promise.resolve(a).then(d).then(function(b){var d=Promise.resolve(a);return b.forEach(function(a){d=d.then(function(b){return e(b,a,c,f)})}),d})}const g=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:f,shouldProcess:c,impl:{readUrls:d,inline:e}}}(),x=function(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return w.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){v.asArray(a.cssRules).forEach(b.push.bind(b))}),b}function c(){return Promise.resolve(v.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(d)})}function d(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return w.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}function e(){return c(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}return{resolveAll:e,impl:{readAll:c}}}(),y=function(){function a(a){function b(b){return v.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||v.getAndEncode).then(function(b){return v.dataAsUrl(b,v.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(a){var b=a.style.getPropertyValue("background");return b?w.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}function c(d){return d instanceof Element?b(d).then(function(){return d instanceof HTMLImageElement?a(d).inline():Promise.all(v.asArray(d.childNodes).map(function(a){return c(a)}))}):Promise.resolve(d)}return{inlineAll:c,impl:{newImage:a}}}();a.domtoimage={toImage:s,toDataUrl:t,toBlob:u,impl:{fontFaces:x,images:y,util:v,inliner:w}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/0.4.2/dom-to-image.js b/ajax/libs/dom-to-image/0.4.2/dom-to-image.js new file mode 100644 index 00000000000000..c6d06102d71b61 --- /dev/null +++ b/ajax/libs/dom-to-image/0.4.2/dom-to-image.js @@ -0,0 +1,607 @@ +(function (global) { + "use strict"; + + var util = (function () { + + const TIMEOUT = 30000; + + const MIME = { + 'woff': 'application/x-font-woff', + 'woff2': 'application/x-font-woff2', + 'truetype': 'application/x-font-ttf', + 'ttf': 'application/x-font-ttf', + 'opentype': 'application/x-font-otf', + 'embedded-opentype': 'application/x-font-otf', + 'eot': 'application/x-font-otf', + 'png': 'image/png', + 'jpg': 'image/jpeg', + 'jpeg': 'image/jpeg', + 'gif': 'image/gif' + }; + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return MIME[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + var uid = (function () { + var index = 0; + + function uid() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ("0000" + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + + function next() { + return 'u' + uid() + index++; + } + + return { + next: next + }; + })(); + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = function () { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + this.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + }; + + request.ontimeout = function () { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + }; + + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, "\\$1"); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23'); + } + + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid.next, + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + })(); + + var inliner = (function () { + + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + + function nothingToInline(string) { + return !shouldProcess(string); + } + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline(string)) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + } + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + })(); + + var fontFaces = (function () { + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + })(); + + var images = (function () { + + function newImage(element) { + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + + return { + inline: inline + }; + } + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + } + + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + })(); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + } + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + } + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + } + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + } + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + + pair.target.className = pair.target.className + ' ' + className; + + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + } + + function clonePseudoElements(pair) { + [ + ':before', + ':after' + ] + .forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + } + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve() + .then(function () { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + } + + function makeDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ""; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return "data:image/svg+xml;charset=utf-8," + svg; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function draw(domNode, options) { + return toImage(domNode, options) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to SVG image data URL + * */ + function toImage(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeDataUri(clone, node.scrollWidth, node.scrollHeight); + }) + .then(util.makeImage); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image data URL + * */ + function toDataUrl(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param node DOM node object to convert + * @param options {Object} + * @return {Promise} promise that resolves to PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + global.domtoimage = { + toImage: toImage, + toDataUrl: toDataUrl, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; +})(this); diff --git a/ajax/libs/dom-to-image/0.4.2/dom-to-image.min.js b/ajax/libs/dom-to-image/0.4.2/dom-to-image.min.js new file mode 100644 index 00000000000000..8ef61dc4e13a3e --- /dev/null +++ b/ajax/libs/dom-to-image/0.4.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 24-09-2015 */ +!function(a){"use strict";function b(a,b){v.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}function c(a,c){a.cssText?c.cssText=a.cssText:b(a,c)}function d(b){var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return v.asArray(a).map(b).join("; ")+";"}function g(b,c,d){var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}function h(b,c){var d=a.window.getComputedStyle(b.source,c),e=d.getPropertyValue("content");if(""===e||"none"===e)return b;var f=v.uid();b.target.className=b.target.className+" "+f;var h=a.document.createElement("style");return h.appendChild(g(f,c,d)),b.target.appendChild(h),b}function i(a){return[":before",":after"].forEach(function(b){h(a,b)}),a}function j(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}function k(a,b){return b instanceof Element?Promise.resolve({source:a,target:b}).then(d).then(i).then(function(a){return a.target}).then(j):b}function l(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return n(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}function m(a,b,c){var d=a.childNodes;return 0===d.length?Promise.resolve(b):l(b,v.asArray(d),c).then(function(){return b})}function n(a,b){return b&&!b(a)?Promise.resolve():Promise.resolve().then(function(){return a.cloneNode(!1)}).then(function(c){return m(a,c,b)}).then(function(b){return k(a,b)})}function o(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(v.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function p(a){return y.inlineAll(a).then(function(){return a})}function q(a){return x.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function r(a,b){return s(a,b).then(v.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function s(a,b){return b=b||{},Promise.resolve(a).then(function(a){return n(a,b.filter)}).then(q).then(p).then(function(b){return o(b,a.scrollWidth,a.scrollHeight)}).then(v.makeImage)}function t(a,b){return r(a,b).then(function(a){return a.toDataURL()})}function u(a,b){return r(a,b).then(v.canvasToBlob)}var v=function(){function b(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function c(a){var c=b(a).toLowerCase();return p[c]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function h(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function i(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.onreadystatechange=function(){if(4===d.readyState){if(200!==d.status)return void c(new Error("Cannot fetch resource "+a+", status: "+this.status));var e=new FileReader;e.onloadend=function(){var a=e.result.split(/,/)[1];b(a)},e.readAsDataURL(d.response)}},d.ontimeout=function(){c(new Error("Timeout of 30000ms occured while fetching resource: "+a))},d.responseType="blob",d.timeout=o,d.open("GET",a,!0),d.send()})}function j(a,b){return"data:"+b+";base64,"+a}function k(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function l(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function m(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function n(a){return a.replace(/#/g,"%23")}const o=3e4,p={woff:"application/x-font-woff",woff2:"application/x-font-woff2",truetype:"application/x-font-ttf",ttf:"application/x-font-ttf",opentype:"application/x-font-otf","embedded-opentype":"application/x-font-otf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif"};var q=function(){function a(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}function b(){return"u"+a()+c++}var c=0;return{next:b}}();return{escape:k,parseExtension:b,mimeType:c,dataAsUrl:j,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:i,uid:q.next,delay:l,asArray:m,escapeXhtml:n,makeImage:h}}(),w=function(){function a(a){return new RegExp("(url\\(['\"]?)("+v.escape(a)+")(['\"]?\\))","g")}function b(a){return!c(a)}function c(a){return-1!==a.search(g)}function d(a){for(var b,c=[];null!==(b=g.exec(a));)c.push(b[1]);return c.filter(function(a){return!v.isDataUrl(a)})}function e(b,c,d,e){return Promise.resolve(c).then(function(a){return d?v.resolveUrl(a,d):a}).then(e||v.getAndEncode).then(function(a){return v.dataAsUrl(a,v.mimeType(c))}).then(function(d){return b.replace(a(c),"$1"+d+"$3")})}function f(a,c,f){return b(a)?Promise.resolve(a):Promise.resolve(a).then(d).then(function(b){var d=Promise.resolve(a);return b.forEach(function(a){d=d.then(function(b){return e(b,a,c,f)})}),d})}const g=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:f,shouldProcess:c,impl:{readUrls:d,inline:e}}}(),x=function(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return w.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){v.asArray(a.cssRules).forEach(b.push.bind(b))}),b}function c(){return Promise.resolve(v.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(d)})}function d(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return w.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}function e(){return c(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}return{resolveAll:e,impl:{readAll:c}}}(),y=function(){function a(a){function b(b){return v.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||v.getAndEncode).then(function(b){return v.dataAsUrl(b,v.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(a){var b=a.style.getPropertyValue("background");return b?w.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}function c(d){return d instanceof Element?b(d).then(function(){return d instanceof HTMLImageElement?a(d).inline():Promise.all(v.asArray(d.childNodes).map(function(a){return c(a)}))}):Promise.resolve(d)}return{inlineAll:c,impl:{newImage:a}}}();a.domtoimage={toImage:s,toDataUrl:t,toBlob:u,impl:{fontFaces:x,images:y,util:v,inliner:w}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.0/dom-to-image.js b/ajax/libs/dom-to-image/1.0.0/dom-to-image.js new file mode 100644 index 00000000000000..1d7d0f7bb8ef31 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.0/dom-to-image.js @@ -0,0 +1,617 @@ +(function (global) { + 'use strict'; + + var util = (function () { + + const TIMEOUT = 30000; + + const MIME = (function () { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + })(); + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return MIME[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + var uid = (function () { + var index = 0; + + function uid() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + + function next() { + return 'u' + uid() + index++; + } + + return { + next: next + }; + })(); + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = function () { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + this.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + }; + + request.ontimeout = function () { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + }; + + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23'); + } + + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid.next, + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + })(); + + var inliner = (function () { + + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + + function nothingToInline(string) { + return !shouldProcess(string); + } + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline(string)) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + } + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + })(); + + var fontFaces = (function () { + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + })(); + + var images = (function () { + + function newImage(element) { + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + + return { + inline: inline + }; + } + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + } + + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + })(); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + } + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + } + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + } + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + } + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + + pair.target.className = pair.target.className + ' ' + className; + + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + } + + function clonePseudoElements(pair) { + [ + ':before', + ':after' + ] + .forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + } + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve() + .then(function () { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; +})(this); diff --git a/ajax/libs/dom-to-image/1.0.0/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.0/dom-to-image.min.js new file mode 100644 index 00000000000000..5bb025fd23ae6f --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 25-09-2015 */ +!function(a){"use strict";function b(a,b){v.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}function c(a,c){a.cssText?c.cssText=a.cssText:b(a,c)}function d(b){var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return v.asArray(a).map(b).join("; ")+";"}function g(b,c,d){var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}function h(b,c){var d=a.window.getComputedStyle(b.source,c),e=d.getPropertyValue("content");if(""===e||"none"===e)return b;var f=v.uid();b.target.className=b.target.className+" "+f;var h=a.document.createElement("style");return h.appendChild(g(f,c,d)),b.target.appendChild(h),b}function i(a){return[":before",":after"].forEach(function(b){h(a,b)}),a}function j(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}function k(a,b){return b instanceof Element?Promise.resolve({source:a,target:b}).then(d).then(i).then(function(a){return a.target}).then(j):b}function l(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return n(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}function m(a,b,c){var d=a.childNodes;return 0===d.length?Promise.resolve(b):l(b,v.asArray(d),c).then(function(){return b})}function n(a,b){return b&&!b(a)?Promise.resolve():Promise.resolve().then(function(){return a.cloneNode(!1)}).then(function(c){return m(a,c,b)}).then(function(b){return k(a,b)})}function o(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(v.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function p(a){return y.inlineAll(a).then(function(){return a})}function q(a){return x.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function r(a,b){return s(a,b).then(v.makeImage).then(v.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function s(a,b){return b=b||{},Promise.resolve(a).then(function(a){return n(a,b.filter)}).then(q).then(p).then(function(b){return o(b,a.scrollWidth,a.scrollHeight)})}function t(a,b){return r(a,b).then(function(a){return a.toDataURL()})}function u(a,b){return r(a,b).then(v.canvasToBlob)}var v=function(){function b(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function c(a){var c=b(a).toLowerCase();return p[c]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function h(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function i(a){return new Promise(function(b,c){var d=new XMLHttpRequest;d.onreadystatechange=function(){if(4===d.readyState){if(200!==d.status)return void c(new Error("Cannot fetch resource "+a+", status: "+this.status));var e=new FileReader;e.onloadend=function(){var a=e.result.split(/,/)[1];b(a)},e.readAsDataURL(d.response)}},d.ontimeout=function(){c(new Error("Timeout of 30000ms occured while fetching resource: "+a))},d.responseType="blob",d.timeout=o,d.open("GET",a,!0),d.send()})}function j(a,b){return"data:"+b+";base64,"+a}function k(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function l(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function m(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function n(a){return a.replace(/#/g,"%23")}const o=3e4,p=function(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}();var q=function(){function a(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}function b(){return"u"+a()+c++}var c=0;return{next:b}}();return{escape:k,parseExtension:b,mimeType:c,dataAsUrl:j,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:i,uid:q.next,delay:l,asArray:m,escapeXhtml:n,makeImage:h}}(),w=function(){function a(a){return new RegExp("(url\\(['\"]?)("+v.escape(a)+")(['\"]?\\))","g")}function b(a){return!c(a)}function c(a){return-1!==a.search(g)}function d(a){for(var b,c=[];null!==(b=g.exec(a));)c.push(b[1]);return c.filter(function(a){return!v.isDataUrl(a)})}function e(b,c,d,e){return Promise.resolve(c).then(function(a){return d?v.resolveUrl(a,d):a}).then(e||v.getAndEncode).then(function(a){return v.dataAsUrl(a,v.mimeType(c))}).then(function(d){return b.replace(a(c),"$1"+d+"$3")})}function f(a,c,f){return b(a)?Promise.resolve(a):Promise.resolve(a).then(d).then(function(b){var d=Promise.resolve(a);return b.forEach(function(a){d=d.then(function(b){return e(b,a,c,f)})}),d})}const g=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:f,shouldProcess:c,impl:{readUrls:d,inline:e}}}(),x=function(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return w.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){v.asArray(a.cssRules).forEach(b.push.bind(b))}),b}function c(){return Promise.resolve(v.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(d)})}function d(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return w.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}function e(){return c(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}return{resolveAll:e,impl:{readAll:c}}}(),y=function(){function a(a){function b(b){return v.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||v.getAndEncode).then(function(b){return v.dataAsUrl(b,v.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(a){var b=a.style.getPropertyValue("background");return b?w.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}function c(d){return d instanceof Element?b(d).then(function(){return d instanceof HTMLImageElement?a(d).inline():Promise.all(v.asArray(d.childNodes).map(function(a){return c(a)}))}):Promise.resolve(d)}return{inlineAll:c,impl:{newImage:a}}}();a.domtoimage={toSvg:s,toPng:t,toBlob:u,impl:{fontFaces:x,images:y,util:v,inliner:w}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.1/dom-to-image.js b/ajax/libs/dom-to-image/1.0.1/dom-to-image.js new file mode 100644 index 00000000000000..a9d31c9dbf2933 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.1/dom-to-image.js @@ -0,0 +1,609 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements(pair) { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + pair.target.className = pair.target.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.0.1/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.1/dom-to-image.min.js new file mode 100644 index 00000000000000..055fbefe30ea22 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 01-10-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(b){function c(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(b){function c(b,c){function d(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var e=a.window.getComputedStyle(b.source,c),f=e.getPropertyValue("content");if(""===f||"none"===f)return b;var g=n.uid();b.target.className=b.target.className+" "+g;var h=a.document.createElement("style");return h.appendChild(d(g,c,e)),b.target.appendChild(h),b}return[":before",":after"].forEach(function(a){c(b,a)}),b}function f(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}return c instanceof Element?Promise.resolve({source:b,target:c}).then(d).then(e).then(function(a){return a.target}).then(f):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){n.asArray(a.cssRules).forEach(b.push.bind(b))}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.2/dom-to-image.js b/ajax/libs/dom-to-image/1.0.2/dom-to-image.js new file mode 100644 index 00000000000000..f042c0371d3372 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.2/dom-to-image.js @@ -0,0 +1,609 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements(pair) { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + pair.target.className = pair.target.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.0.2/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.2/dom-to-image.min.js new file mode 100644 index 00000000000000..60b7440b79d043 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 29-10-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(b){function c(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(b){function c(b,c){function d(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var e=a.window.getComputedStyle(b.source,c),f=e.getPropertyValue("content");if(""===f||"none"===f)return b;var g=n.uid();b.target.className=b.target.className+" "+g;var h=a.document.createElement("style");return h.appendChild(d(g,c,e)),b.target.appendChild(h),b}return[":before",":after"].forEach(function(a){c(b,a)}),b}function f(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}return c instanceof Element?Promise.resolve({source:b,target:c}).then(d).then(e).then(function(a){return a.target}).then(f):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.3/dom-to-image.js b/ajax/libs/dom-to-image/1.0.3/dom-to-image.js new file mode 100644 index 00000000000000..743cc6dfc02478 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.3/dom-to-image.js @@ -0,0 +1,609 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve({ + source: original, + target: clone + }) + .then(cloneStyle) + .then(clonePseudoElements) + .then(function (pair) { + return pair.target; + }) + .then(fixNamespace); + + function cloneStyle(pair) { + var style = global.window.getComputedStyle(pair.source); + copyStyle(style, pair.target.style); + return pair; + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements(pair) { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(pair, element); + }); + return pair; + + function clonePseudoElement(pair, element) { + var style = global.window.getComputedStyle(pair.source, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return pair; + + var className = util.uid(); + pair.target.className = pair.target.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + pair.target.appendChild(styleElement); + + return pair; + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function fixNamespace(node) { + if (node instanceof SVGElement) node.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + return node; + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.0.3/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.3/dom-to-image.min.js new file mode 100644 index 00000000000000..ce662239c04df8 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.3/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-11-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(b){function c(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}var d=a.window.getComputedStyle(b.source);return c(d,b.target.style),b}function e(b){function c(b,c){function d(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var e=a.window.getComputedStyle(b.source,c),f=e.getPropertyValue("content");if(""===f||"none"===f)return b;var g=n.uid();b.target.className=b.target.className+" "+g;var h=a.document.createElement("style");return h.appendChild(d(g,c,e)),b.target.appendChild(h),b}return[":before",":after"].forEach(function(a){c(b,a)}),b}function f(a){return a instanceof SVGElement&&a.setAttribute("xmlns","http://www.w3.org/2000/svg"),a}return c instanceof Element?Promise.resolve({source:b,target:c}).then(d).then(e).then(function(a){return a.target}).then(f):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.4/dom-to-image.js b/ajax/libs/dom-to-image/1.0.4/dom-to-image.js new file mode 100644 index 00000000000000..1bb1057ea5037f --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.4/dom-to-image.js @@ -0,0 +1,605 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.0.4/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.4/dom-to-image.min.js new file mode 100644 index 00000000000000..a1e906fd6a4a9a --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.4/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 29-11-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.0.5/dom-to-image.js b/ajax/libs/dom-to-image/1.0.5/dom-to-image.js new file mode 100644 index 00000000000000..b323cdf07cac14 --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.5/dom-to-image.js @@ -0,0 +1,609 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.0.5/dom-to-image.min.js b/ajax/libs/dom-to-image/1.0.5/dom-to-image.min.js new file mode 100644 index 00000000000000..5aa0cea185635a --- /dev/null +++ b/ajax/libs/dom-to-image/1.0.5/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 29-11-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=document.createElement("canvas");return c.width=a.scrollWidth,c.height=a.scrollHeight,c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.1.0/dom-to-image.js b/ajax/libs/dom-to-image/1.1.0/dom-to-image.js new file mode 100644 index 00000000000000..bf58ea9ca443ed --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.0/dom-to-image.js @@ -0,0 +1,618 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\./]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.1.0/dom-to-image.min.js b/ajax/libs/dom-to-image/1.1.0/dom-to-image.min.js new file mode 100644 index 00000000000000..30395edbdfb541 --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 30-11-2015 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\./]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.1.1/dom-to-image.js b/ajax/libs/dom-to-image/1.1.1/dom-to-image.js new file mode 100644 index 00000000000000..070929c976b536 --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.1/dom-to-image.js @@ -0,0 +1,618 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + const WOFF = 'application/font-woff'; + const JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + const TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + const URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.1.1/dom-to-image.min.js b/ajax/libs/dom-to-image/1.1.1/dom-to-image.min.js new file mode 100644 index 00000000000000..366579baae53c3 --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 05-01-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){const a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){const b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of 30000ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}const e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.1.2/dom-to-image.js b/ajax/libs/dom-to-image/1.1.2/dom-to-image.js new file mode 100644 index 00000000000000..f1c0660ecd32ae --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.2/dom-to-image.js @@ -0,0 +1,618 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(function (node) { + return node.cloneNode(false); + }) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.1.2/dom-to-image.min.js b/ajax/libs/dom-to-image/1.1.2/dom-to-image.min.js new file mode 100644 index 00000000000000..3b161be5a04ba0 --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 30-01-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function f(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(function(a){return a.cloneNode(!1)}).then(function(a){return d(b,a,c)}).then(function(a){return f(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/1.1.3/dom-to-image.js b/ajax/libs/dom-to-image/1.1.3/dom-to-image.js new file mode 100644 index 00000000000000..41e15a0283ecb6 --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.3/dom-to-image.js @@ -0,0 +1,621 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + reject(new Error('Cannot fetch resource ' + url + ', status: ' + request.status)); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/1.1.3/dom-to-image.min.js b/ajax/libs/dom-to-image/1.1.3/dom-to-image.min.js new file mode 100644 index 00000000000000..4e8eca7805d87c --- /dev/null +++ b/ajax/libs/dom-to-image/1.1.3/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 03-02-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function f(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function g(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(d).then(function(a){return f(b,a,c)}).then(function(a){return g(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return void d(new Error("Cannot fetch resource "+a+", status: "+g.status));var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.0.0/dom-to-image.js b/ajax/libs/dom-to-image/2.0.0/dom-to-image.js new file mode 100644 index 00000000000000..02e0e835610158 --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.0/dom-to-image.js @@ -0,0 +1,622 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + console.error('cannot fetch resource ' + url + ', status: ' + request.status); + resolve(''); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.0.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.0.0/dom-to-image.min.js new file mode 100644 index 00000000000000..9fa29938283341 --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 02-03-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function f(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function g(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(d).then(function(a){return f(b,a,c)}).then(function(a){return g(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return console.error("cannot fetch resource "+a+", status: "+g.status),void c("");var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.0.1/dom-to-image.js b/ajax/libs/dom-to-image/2.0.1/dom-to-image.js new file mode 100644 index 00000000000000..8d8c7bdd72994f --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.1/dom-to-image.js @@ -0,0 +1,623 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixNamespace) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixNamespace() { + if (clone instanceof SVGElement) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + console.error('cannot fetch resource ' + url + ', status: ' + request.status); + resolve(''); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.0.1/dom-to-image.min.js b/ajax/libs/dom-to-image/2.0.1/dom-to-image.min.js new file mode 100644 index 00000000000000..cc032c91ffc76c --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 11-03-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function f(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function g(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value),b instanceof HTMLInputElement&&c.setAttribute("value",b.value)}function g(){c instanceof SVGElement&&c.setAttribute("xmlns","http://www.w3.org/2000/svg")}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(d).then(function(a){return f(b,a,c)}).then(function(a){return g(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return console.error("cannot fetch resource "+a+", status: "+g.status),void c("");var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.0.2/dom-to-image.js b/ajax/libs/dom-to-image/2.0.2/dom-to-image.js new file mode 100644 index 00000000000000..13f69a7e55e1f5 --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.2/dom-to-image.js @@ -0,0 +1,633 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well) + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter) { + if (filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + console.error('cannot fetch resource ' + url + ', status: ' + request.status); + resolve(''); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.0.2/dom-to-image.min.js b/ajax/libs/dom-to-image/2.0.2/dom-to-image.min.js new file mode 100644 index 00000000000000..5ffd01051adc4d --- /dev/null +++ b/ajax/libs/dom-to-image/2.0.2/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 28-03-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c){function d(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function f(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function g(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value),b instanceof HTMLInputElement&&c.setAttribute("value",b.value)}function g(){c instanceof SVGElement&&(c.setAttribute("xmlns","http://www.w3.org/2000/svg"),c instanceof SVGRectElement&&["width","height"].forEach(function(a){var b=c.getAttribute(a);b&&c.style.setProperty(a,b)}))}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return c&&!c(b)?Promise.resolve():Promise.resolve(b).then(d).then(function(a){return f(b,a,c)}).then(function(a){return g(b,a)})}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return console.error("cannot fetch resource "+a+", status: "+g.status),void c("");var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.1.0/dom-to-image.js b/ajax/libs/dom-to-image/2.1.0/dom-to-image.js new file mode 100644 index 00000000000000..7aea7cf861ea5a --- /dev/null +++ b/ajax/libs/dom-to-image/2.1.0/dom-to-image.js @@ -0,0 +1,633 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Filter is not applied to the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve, reject) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + console.error('cannot fetch resource ' + url + ', status: ' + request.status); + resolve(''); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + reject(new Error('Timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url)); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.1.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.1.0/dom-to-image.min.js new file mode 100644 index 00000000000000..6426c1ddc14a2a --- /dev/null +++ b/ajax/libs/dom-to-image/2.1.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 28-03-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter,!0)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c,d){function f(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function g(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function h(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value),b instanceof HTMLInputElement&&c.setAttribute("value",b.value)}function g(){c instanceof SVGElement&&(c.setAttribute("xmlns","http://www.w3.org/2000/svg"),c instanceof SVGRectElement&&["width","height"].forEach(function(a){var b=c.getAttribute(a);b&&c.style.setProperty(a,b)}))}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return d||!c||c(b)?Promise.resolve(b).then(f).then(function(a){return g(b,a,c)}).then(function(a){return h(b,a)}):Promise.resolve()}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c,d){function e(){if(4===g.readyState){if(200!==g.status)return console.error("cannot fetch resource "+a+", status: "+g.status),void c("");var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function f(){d(new Error("Timeout of "+b+"ms occured while fetching resource: "+a))}var g=new XMLHttpRequest;g.onreadystatechange=e,g.ontimeout=f,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.1.1/dom-to-image.js b/ajax/libs/dom-to-image/2.1.1/dom-to-image.js new file mode 100644 index 00000000000000..46bbf00410c7b5 --- /dev/null +++ b/ajax/libs/dom-to-image/2.1.1/dom-to-image.js @@ -0,0 +1,637 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Filter is not applied to the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message){ + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.1.1/dom-to-image.min.js b/ajax/libs/dom-to-image/2.1.1/dom-to-image.min.js new file mode 100644 index 00000000000000..a869a54382317a --- /dev/null +++ b/ajax/libs/dom-to-image/2.1.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 30-03-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return e(a,b.filter,!0)}).then(f).then(g).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return h(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return i(a,b||{}).then(function(a){return a.toDataURL()})}function d(a,b){return i(a,b||{}).then(n.canvasToBlob)}function e(b,c,d){function f(a){return a instanceof HTMLCanvasElement?n.makeImage(a.toDataURL()):a.cloneNode(!1)}function g(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return e(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var f=a.childNodes;return 0===f.length?Promise.resolve(b):d(b,n.asArray(f),c).then(function(){return b})}function h(b,c){function d(){function d(a,b){function c(a,b){n.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return n.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=n.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value),b instanceof HTMLInputElement&&c.setAttribute("value",b.value)}function g(){c instanceof SVGElement&&(c.setAttribute("xmlns","http://www.w3.org/2000/svg"),c instanceof SVGRectElement&&["width","height"].forEach(function(a){var b=c.getAttribute(a);b&&c.style.setProperty(a,b)}))}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return d||!c||c(b)?Promise.resolve(b).then(f).then(function(a){return g(b,a,c)}).then(function(a){return h(b,a)}):Promise.resolve()}function f(a){return p.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function g(a){return q.inlineAll(a).then(function(){return a})}function h(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(n.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function i(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(n.makeImage).then(n.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function j(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function k(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!n.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+n.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?n.resolveUrl(a,c):a}).then(d||n.getAndEncode).then(function(a){return n.dataAsUrl(a,n.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function l(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return o.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{n.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return o.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(n.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function m(){function a(a){function b(b){return n.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||n.getAndEncode).then(function(b){return n.dataAsUrl(b,n.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?o.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(n.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var n=j(),o=k(),p=l(),q=m();a.domtoimage={toSvg:b,toPng:c,toBlob:d,impl:{fontFaces:p,images:q,util:n,inliner:o}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.2.0/dom-to-image.js b/ajax/libs/dom-to-image/2.2.0/dom-to-image.js new file mode 100644 index 00000000000000..9ac9b187cfc217 --- /dev/null +++ b/ajax/libs/dom-to-image/2.2.0/dom-to-image.js @@ -0,0 +1,654 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + global.domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Filter is not applied to the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(global.window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = global.window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = global.document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return global.document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = global.document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message){ + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.2.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.2.0/dom-to-image.min.js new file mode 100644 index 00000000000000..c0ab7173740c4d --- /dev/null +++ b/ajax/libs/dom-to-image/2.2.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 23-04-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return f(a,b.filter,!0)}).then(g).then(h).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return i(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return j(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return j(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return j(a,b||{}).then(o.canvasToBlob)}function f(b,c,d){function e(a){return a instanceof HTMLCanvasElement?o.makeImage(a.toDataURL()):a.cloneNode(!1)}function g(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return f(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,o.asArray(e),c).then(function(){return b})}function h(b,c){function d(){function d(a,b){function c(a,b){o.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}d(a.window.getComputedStyle(b),c.style)}function e(){function d(d){function e(b,c,d){function e(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function f(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return o.asArray(a).map(b).join("; ")+";"}var g="."+b+":"+c,h=d.cssText?e(d):f(d);return a.document.createTextNode(g+"{"+h+"}")}var f=a.window.getComputedStyle(b,d),g=f.getPropertyValue("content");if(""!==g&&"none"!==g){var h=o.uid();c.className=c.className+" "+h;var i=a.document.createElement("style");i.appendChild(e(h,d,f)),c.appendChild(i)}}[":before",":after"].forEach(function(a){d(a)})}function f(){b instanceof HTMLTextAreaElement&&(c.innerHTML=b.value),b instanceof HTMLInputElement&&c.setAttribute("value",b.value)}function g(){c instanceof SVGElement&&(c.setAttribute("xmlns","http://www.w3.org/2000/svg"),c instanceof SVGRectElement&&["width","height"].forEach(function(a){var b=c.getAttribute(a);b&&c.style.setProperty(a,b)}))}return c instanceof Element?Promise.resolve().then(d).then(e).then(f).then(g).then(function(){return c}):c}return d||!c||c(b)?Promise.resolve(b).then(e).then(function(a){return g(b,a,c)}).then(function(a){return h(b,a)}):Promise.resolve()}function g(a){return q.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function h(a){return r.inlineAll(a).then(function(){return a})}function i(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(o.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function j(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(o.makeImage).then(o.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function k(){function b(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function c(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function d(a){var d=c(a).toLowerCase();return b()[d]||""}function e(a){return-1!==a.search(/^(data:)/)}function f(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function g(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):f(a)}function h(b,c){var d=a.document.implementation.createHTMLDocument(),e=d.createElement("base");d.head.appendChild(e);var f=d.createElement("a");return d.body.appendChild(f),e.href=c,f.href=b,f.href}function i(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function j(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function k(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function l(a,b){return"data:"+b+";base64,"+a}function m(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function n(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function o(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function p(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:m,parseExtension:c,mimeType:d,dataAsUrl:l,isDataUrl:e,canvasToBlob:g,resolveUrl:h,getAndEncode:k,uid:i(),delay:n,asArray:o,escapeXhtml:p,makeImage:j}}function l(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!o.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+o.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?o.resolveUrl(a,c):a}).then(d||o.getAndEncode).then(function(a){return o.dataAsUrl(a,o.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function m(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return p.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{o.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return p.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(o.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function n(){function a(a){function b(b){return o.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||o.getAndEncode).then(function(b){return o.dataAsUrl(b,o.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?p.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(o.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var o=k(),p=l(),q=m(),r=n();a.domtoimage={toSvg:b,toPng:d,toBlob:e,toPixelData:c,impl:{fontFaces:q,images:r,util:o,inliner:p}}}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.2.1/dom-to-image.js b/ajax/libs/dom-to-image/2.2.1/dom-to-image.js new file mode 100644 index 00000000000000..4087c0416d6bd9 --- /dev/null +++ b/ajax/libs/dom-to-image/2.2.1/dom-to-image.js @@ -0,0 +1,661 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Filter is not applied to the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, node.scrollWidth, node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = domNode.scrollWidth; + canvas.height = domNode.scrollHeight; + return canvas; + } + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.2.1/dom-to-image.min.js b/ajax/libs/dom-to-image/2.2.1/dom-to-image.min.js new file mode 100644 index 00000000000000..85d3cb13df707e --- /dev/null +++ b/ajax/libs/dom-to-image/2.2.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 23-04-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return f(a,b.filter,!0)}).then(g).then(h).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),a}).then(function(b){return i(b,a.scrollWidth,a.scrollHeight)})}function c(a,b){return j(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return j(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return j(a,b||{}).then(o.canvasToBlob)}function f(a,b,c){function d(a){return a instanceof HTMLCanvasElement?o.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return f(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,o.asArray(e),c).then(function(){return b})}function g(a,b){function c(){function c(a,b){function c(a,b){o.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return o.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=o.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return g(a,b)}):Promise.resolve()}function g(a){return q.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function h(a){return r.inlineAll(a).then(function(){return a})}function i(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(o.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function j(a,c){function d(a){var b=document.createElement("canvas");return b.width=a.scrollWidth,b.height=a.scrollHeight,b}return b(a,c).then(o.makeImage).then(o.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function k(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(a,b){var c=document.implementation.createHTMLDocument(),d=c.createElement("base");c.head.appendChild(d);var e=c.createElement("a");return c.body.appendChild(e),d.href=b,e.href=a,e.href}function h(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function i(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function j(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function k(a,b){return"data:"+b+";base64,"+a}function l(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function m(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function n(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function o(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:l,parseExtension:b,mimeType:c,dataAsUrl:k,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:j,uid:h(),delay:m,asArray:n,escapeXhtml:o,makeImage:i}}function l(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!o.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+o.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?o.resolveUrl(a,c):a}).then(d||o.getAndEncode).then(function(a){return o.dataAsUrl(a,o.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function m(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return p.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{o.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return p.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(o.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function n(){function a(a){function b(b){return o.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||o.getAndEncode).then(function(b){return o.dataAsUrl(b,o.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?p.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(o.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var o=k(),p=l(),q=m(),r=n(),s={toSvg:b,toPng:d,toBlob:e,toPixelData:c,impl:{fontFaces:q,images:r,util:o,inliner:p}};"undefined"!=typeof module?module.exports=s:a.domtoimage=s}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.3.0/dom-to-image.js b/ajax/libs/dom-to-image/2.3.0/dom-to-image.js new file mode 100644 index 00000000000000..effc61433d21af --- /dev/null +++ b/ajax/libs/dom-to-image/2.3.0/dom-to-image.js @@ -0,0 +1,665 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value. + * @param {Number} options.width - width to be applied to node before rendering. + * @param {Number} options.height - height to be applied to node before rendering. + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(function (clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + if (options.width) clone.style.setProperty('width', options.width + 'px'); + if (options.height) clone.style.setProperty('height', options.height + 'px'); + return clone; + }) + .then(function (clone) { + return makeSvgDataUri(clone, options.width || node.scrollWidth, options.height || node.scrollHeight); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = options.width || domNode.scrollWidth; + canvas.height = options.height || domNode.scrollHeight; + return canvas; + } + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.3.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.3.0/dom-to-image.min.js new file mode 100644 index 00000000000000..c9cdb690f06ae2 --- /dev/null +++ b/ajax/libs/dom-to-image/2.3.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 24-04-2016 */ +!function(a){"use strict";function b(a,b){return b=b||{},Promise.resolve(a).then(function(a){return g(a,b.filter,!0)}).then(h).then(i).then(function(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&a.style.setProperty("width",b.width+"px"),b.height&&a.style.setProperty("height",b.height+"px"),a}).then(function(c){return j(c,b.width||a.scrollWidth,b.height||a.scrollHeight)})}function c(a,b){return f(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return f(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return f(a,b||{}).then(o.canvasToBlob)}function f(a,c){function d(a){var b=document.createElement("canvas");return b.width=c.width||a.scrollWidth,b.height=c.height||a.scrollHeight,b}return b(a,c).then(o.makeImage).then(o.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function g(a,b,c){function d(a){return a instanceof HTMLCanvasElement?o.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return g(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,o.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){o.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return o.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=o.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function h(a){return q.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function i(a){return r.inlineAll(a).then(function(){return a})}function j(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(o.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function k(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(a,b){var c=document.implementation.createHTMLDocument(),d=c.createElement("base");c.head.appendChild(d);var e=c.createElement("a");return c.body.appendChild(e),d.href=b,e.href=a,e.href}function h(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function i(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function j(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function k(a,b){return"data:"+b+";base64,"+a}function l(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function m(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function n(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function o(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:l,parseExtension:b,mimeType:c,dataAsUrl:k,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:j,uid:h(),delay:m,asArray:n,escapeXhtml:o,makeImage:i}}function l(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!o.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+o.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?o.resolveUrl(a,c):a}).then(d||o.getAndEncode).then(function(a){return o.dataAsUrl(a,o.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function m(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return p.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{o.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return p.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(o.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function n(){function a(a){function b(b){return o.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||o.getAndEncode).then(function(b){return o.dataAsUrl(b,o.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?p.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(o.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var o=k(),p=l(),q=m(),r=n(),s={toSvg:b,toPng:d,toBlob:e,toPixelData:c,impl:{fontFaces:q,images:r,util:o,inliner:p}};"undefined"!=typeof module?module.exports=s:a.domtoimage=s}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.4.0/dom-to-image.js b/ajax/libs/dom-to-image/2.4.0/dom-to-image.js new file mode 100644 index 00000000000000..3aa061506615ee --- /dev/null +++ b/ajax/libs/dom-to-image/2.4.0/dom-to-image.js @@ -0,0 +1,678 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value. + * @param {Number} options.width - width to be applied to node before rendering. + * @param {Number} options.height - height to be applied to node before rendering. + * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(applyOptions) + .then(function (clone) { + return makeSvgDataUri(clone, + options.width || node.scrollWidth, + options.height || node.scrollHeight + ); + }); + + function applyOptions(clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + + if (options.width) clone.style.width = options.width + 'px'; + if (options.height) clone.style.height = options.height + 'px'; + + if (options.style) + Object.keys(options.style).forEach(function (property) { + clone.style[property] = options.style[property]; + }); + + return clone; + } + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = options.width || domNode.scrollWidth; + canvas.height = options.height || domNode.scrollHeight; + return canvas; + } + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.4.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.4.0/dom-to-image.min.js new file mode 100644 index 00000000000000..e7da9cd2a6519c --- /dev/null +++ b/ajax/libs/dom-to-image/2.4.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 24-04-2016 */ +!function(a){"use strict";function b(a,b){function c(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&(a.style.width=b.width+"px"),b.height&&(a.style.height=b.height+"px"),b.style&&Object.keys(b.style).forEach(function(c){a.style[c]=b.style[c]}),a}return b=b||{},Promise.resolve(a).then(function(a){return g(a,b.filter,!0)}).then(h).then(i).then(c).then(function(c){return j(c,b.width||a.scrollWidth,b.height||a.scrollHeight)})}function c(a,b){return f(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return f(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return f(a,b||{}).then(o.canvasToBlob)}function f(a,c){function d(a){var b=document.createElement("canvas");return b.width=c.width||a.scrollWidth,b.height=c.height||a.scrollHeight,b}return b(a,c).then(o.makeImage).then(o.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function g(a,b,c){function d(a){return a instanceof HTMLCanvasElement?o.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return g(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,o.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){o.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return o.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=o.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function h(a){return q.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function i(a){return r.inlineAll(a).then(function(){return a})}function j(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(o.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function k(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(a,b){var c=document.implementation.createHTMLDocument(),d=c.createElement("base");c.head.appendChild(d);var e=c.createElement("a");return c.body.appendChild(e),d.href=b,e.href=a,e.href}function h(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function i(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function j(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function k(a,b){return"data:"+b+";base64,"+a}function l(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function m(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function n(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function o(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:l,parseExtension:b,mimeType:c,dataAsUrl:k,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:j,uid:h(),delay:m,asArray:n,escapeXhtml:o,makeImage:i}}function l(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!o.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+o.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?o.resolveUrl(a,c):a}).then(d||o.getAndEncode).then(function(a){return o.dataAsUrl(a,o.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function m(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return p.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{o.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return p.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(o.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function n(){function a(a){function b(b){return o.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||o.getAndEncode).then(function(b){return o.dataAsUrl(b,o.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?p.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(o.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var o=k(),p=l(),q=m(),r=n(),s={toSvg:b,toPng:d,toBlob:e,toPixelData:c,impl:{fontFaces:q,images:r,util:o,inliner:p}};"undefined"!=typeof module?module.exports=s:a.domtoimage=s}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.5.0/dom-to-image.js b/ajax/libs/dom-to-image/2.5.0/dom-to-image.js new file mode 100644 index 00000000000000..ab6aba22757e03 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.0/dom-to-image.js @@ -0,0 +1,694 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toJpeg: toJpeg, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value. + * @param {Number} options.width - width to be applied to node before rendering. + * @param {Number} options.height - height to be applied to node before rendering. + * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. + * @param {Object} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only), + defaults to 1.0. + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(applyOptions) + .then(function (clone) { + return makeSvgDataUri(clone, + options.width || node.scrollWidth, + options.height || node.scrollHeight + ); + }); + + function applyOptions(clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + + if (options.width) clone.style.width = options.width + 'px'; + if (options.height) clone.style.height = options.height + 'px'; + + if (options.style) + Object.keys(options.style).forEach(function (property) { + clone.style[property] = options.style[property]; + }); + + return clone; + } + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a JPEG image data URL + * */ + function toJpeg(node, options) { + options = options || {}; + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL('image/jpeg', options.quality || 1.0); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = options.width || domNode.scrollWidth; + canvas.height = options.height || domNode.scrollHeight; + return canvas; + } + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.5.0/dom-to-image.min.js b/ajax/libs/dom-to-image/2.5.0/dom-to-image.min.js new file mode 100644 index 00000000000000..21c771acc1dff0 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.0/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 07-06-2016 */ +!function(a){"use strict";function b(a,b){function c(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&(a.style.width=b.width+"px"),b.height&&(a.style.height=b.height+"px"),b.style&&Object.keys(b.style).forEach(function(c){a.style[c]=b.style[c]}),a}return b=b||{},Promise.resolve(a).then(function(a){return h(a,b.filter,!0)}).then(i).then(j).then(c).then(function(c){return k(c,b.width||a.scrollWidth,b.height||a.scrollHeight)})}function c(a,b){return g(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return g(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return b=b||{},g(a,b).then(function(a){return a.toDataURL("image/jpeg",b.quality||1)})}function f(a,b){return g(a,b||{}).then(p.canvasToBlob)}function g(a,c){function d(a){var b=document.createElement("canvas");return b.width=c.width||a.scrollWidth,b.height=c.height||a.scrollHeight,b}return b(a,c).then(p.makeImage).then(p.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function h(a,b,c){function d(a){return a instanceof HTMLCanvasElement?p.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return h(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,p.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){p.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return p.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=p.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function i(a){return r.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function j(a){return s.inlineAll(a).then(function(){return a})}function k(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(p.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function l(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return-1!==a.search(/^(data:)/)}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;d>f;f++)e[f]=c.charCodeAt(f);b(new Blob([e],{type:"image/png"}))})}function f(a){return a.toBlob?new Promise(function(b){a.toBlob(b)}):e(a)}function g(a,b){var c=document.implementation.createHTMLDocument(),d=c.createElement("base");c.head.appendChild(d);var e=c.createElement("a");return c.body.appendChild(e),d.href=b,e.href=a,e.href}function h(){var a=0;return function(){function b(){return("0000"+(Math.random()*Math.pow(36,4)<<0).toString(36)).slice(-4)}return"u"+b()+a++}}function i(a){return new Promise(function(b,c){var d=new Image;d.onload=function(){b(d)},d.onerror=c,d.src=a})}function j(a){var b=3e4;return new Promise(function(c){function d(){if(4===g.readyState){if(200!==g.status)return void f("cannot fetch resource: "+a+", status: "+g.status);var b=new FileReader;b.onloadend=function(){var a=b.result.split(/,/)[1];c(a)},b.readAsDataURL(g.response)}}function e(){f("timeout of "+b+"ms occured while fetching resource: "+a)}function f(a){console.error(a),c("")}var g=new XMLHttpRequest;g.onreadystatechange=d,g.ontimeout=e,g.responseType="blob",g.timeout=b,g.open("GET",a,!0),g.send()})}function k(a,b){return"data:"+b+";base64,"+a}function l(a){return a.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")}function m(a){return function(b){return new Promise(function(c){setTimeout(function(){c(b)},a)})}}function n(a){for(var b=[],c=a.length,d=0;c>d;d++)b.push(a[d]);return b}function o(a){return a.replace(/#/g,"%23").replace(/\n/g,"%0A")}return{escape:l,parseExtension:b,mimeType:c,dataAsUrl:k,isDataUrl:d,canvasToBlob:f,resolveUrl:g,getAndEncode:j,uid:h(),delay:m,asArray:n,escapeXhtml:o,makeImage:i}}function m(){function a(a){return-1!==a.search(e)}function b(a){for(var b,c=[];null!==(b=e.exec(a));)c.push(b[1]);return c.filter(function(a){return!p.isDataUrl(a)})}function c(a,b,c,d){function e(a){return new RegExp("(url\\(['\"]?)("+p.escape(a)+")(['\"]?\\))","g")}return Promise.resolve(b).then(function(a){return c?p.resolveUrl(a,c):a}).then(d||p.getAndEncode).then(function(a){return p.dataAsUrl(a,p.mimeType(b))}).then(function(c){return a.replace(e(b),"$1"+c+"$3")})}function d(d,e,f){function g(){return!a(d)}return g()?Promise.resolve(d):Promise.resolve(d).then(b).then(function(a){var b=Promise.resolve(d);return a.forEach(function(a){b=b.then(function(b){return c(b,a,e,f)})}),b})}var e=/url\(['"]?([^'"]+?)['"]?\)/g;return{inlineAll:d,shouldProcess:a,impl:{readUrls:b,inline:c}}}function n(){function a(){return b(document).then(function(a){return Promise.all(a.map(function(a){return a.resolve()}))}).then(function(a){return a.join("\n")})}function b(){function a(a){return a.filter(function(a){return a.type===CSSRule.FONT_FACE_RULE}).filter(function(a){return q.shouldProcess(a.style.getPropertyValue("src"))})}function b(a){var b=[];return a.forEach(function(a){try{p.asArray(a.cssRules||[]).forEach(b.push.bind(b))}catch(c){console.log("Error while reading CSS rules from "+a.href,c.toString())}}),b}function c(a){return{resolve:function(){var b=(a.parentStyleSheet||{}).href;return q.inlineAll(a.cssText,b)},src:function(){return a.style.getPropertyValue("src")}}}return Promise.resolve(p.asArray(document.styleSheets)).then(b).then(a).then(function(a){return a.map(c)})}return{resolveAll:a,impl:{readAll:b}}}function o(){function a(a){function b(b){return p.isDataUrl(a.src)?Promise.resolve():Promise.resolve(a.src).then(b||p.getAndEncode).then(function(b){return p.dataAsUrl(b,p.mimeType(a.src))}).then(function(b){return new Promise(function(c,d){a.onload=c,a.onerror=d,a.src=b})})}return{inline:b}}function b(c){function d(a){var b=a.style.getPropertyValue("background");return b?q.inlineAll(b).then(function(b){a.style.setProperty("background",b,a.style.getPropertyPriority("background"))}).then(function(){return a}):Promise.resolve(a)}return c instanceof Element?d(c).then(function(){return c instanceof HTMLImageElement?a(c).inline():Promise.all(p.asArray(c.childNodes).map(function(a){return b(a)}))}):Promise.resolve(c)}return{inlineAll:b,impl:{newImage:a}}}var p=l(),q=m(),r=n(),s=o(),t={toSvg:b,toPng:d,toJpeg:e,toBlob:f,toPixelData:c,impl:{fontFaces:r,images:s,util:p,inliner:q}};"undefined"!=typeof module?module.exports=t:a.domtoimage=t}(this); \ No newline at end of file diff --git a/ajax/libs/dom-to-image/2.5.1/dom-to-image.js b/ajax/libs/dom-to-image/2.5.1/dom-to-image.js new file mode 100644 index 00000000000000..53715a36fb6c01 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.1/dom-to-image.js @@ -0,0 +1,701 @@ +(function (global) { + 'use strict'; + + var util = newUtil(); + var inliner = newInliner(); + var fontFaces = newFontFaces(); + var images = newImages(); + + var domtoimage = { + toSvg: toSvg, + toPng: toPng, + toJpeg: toJpeg, + toBlob: toBlob, + toPixelData: toPixelData, + impl: { + fontFaces: fontFaces, + images: images, + util: util, + inliner: inliner + } + }; + + if (typeof module !== 'undefined') + module.exports = domtoimage; + else + global.domtoimage = domtoimage; + + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options + * @param {Function} options.filter - Should return true if passed node should be included in the output + * (excluding node means excluding it's children as well). Not called on the root node. + * @param {String} options.bgcolor - color for the background, any valid CSS color value. + * @param {Number} options.width - width to be applied to node before rendering. + * @param {Number} options.height - height to be applied to node before rendering. + * @param {Object} options.style - an object whose properties to be copied to node's style before rendering. + * @param {Number} options.quality - a Number between 0 and 1 indicating image quality (applicable to JPEG only), + defaults to 1.0. + * @return {Promise} - A promise that is fulfilled with a SVG image data URL + * */ + function toSvg(node, options) { + options = options || {}; + return Promise.resolve(node) + .then(function (node) { + return cloneNode(node, options.filter, true); + }) + .then(embedFonts) + .then(inlineImages) + .then(applyOptions) + .then(function (clone) { + return makeSvgDataUri(clone, + options.width || node.scrollWidth, + options.height || node.scrollHeight + ); + }); + + function applyOptions(clone) { + if (options.bgcolor) clone.style.backgroundColor = options.bgcolor; + + if (options.width) clone.style.width = options.width + 'px'; + if (options.height) clone.style.height = options.height + 'px'; + + if (options.style) + Object.keys(options.style).forEach(function (property) { + clone.style[property] = options.style[property]; + }); + + return clone; + } + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a Uint8Array containing RGBA pixel data. + * */ + function toPixelData(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.getContext('2d').getImageData( + 0, + 0, + node.scrollWidth, + node.scrollHeight + ).data; + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image data URL + * */ + function toPng(node, options) { + return draw(node, options || {}) + .then(function (canvas) { + return canvas.toDataURL(); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a JPEG image data URL + * */ + function toJpeg(node, options) { + options = options || {}; + return draw(node, options) + .then(function (canvas) { + return canvas.toDataURL('image/jpeg', options.quality || 1.0); + }); + } + + /** + * @param {Node} node - The DOM Node object to render + * @param {Object} options - Rendering options, @see {@link toSvg} + * @return {Promise} - A promise that is fulfilled with a PNG image blob + * */ + function toBlob(node, options) { + return draw(node, options || {}) + .then(util.canvasToBlob); + } + + function draw(domNode, options) { + return toSvg(domNode, options) + .then(util.makeImage) + .then(util.delay(100)) + .then(function (image) { + var canvas = newCanvas(domNode); + canvas.getContext('2d').drawImage(image, 0, 0); + return canvas; + }); + + function newCanvas(domNode) { + var canvas = document.createElement('canvas'); + canvas.width = options.width || domNode.scrollWidth; + canvas.height = options.height || domNode.scrollHeight; + + if (options.bgcolor) { + var ctx = canvas.getContext('2d'); + ctx.fillStyle = options.bgcolor; + ctx.fillRect(0, 0, canvas.width, canvas.height); + } + + return canvas; + } + } + + function cloneNode(node, filter, root) { + if (!root && filter && !filter(node)) return Promise.resolve(); + + return Promise.resolve(node) + .then(makeNodeCopy) + .then(function (clone) { + return cloneChildren(node, clone, filter); + }) + .then(function (clone) { + return processClone(node, clone); + }); + + function makeNodeCopy(node) { + if (node instanceof HTMLCanvasElement) return util.makeImage(node.toDataURL()); + return node.cloneNode(false); + } + + function cloneChildren(original, clone, filter) { + var children = original.childNodes; + if (children.length === 0) return Promise.resolve(clone); + + return cloneChildrenInOrder(clone, util.asArray(children), filter) + .then(function () { + return clone; + }); + + function cloneChildrenInOrder(parent, children, filter) { + var done = Promise.resolve(); + children.forEach(function (child) { + done = done + .then(function () { + return cloneNode(child, filter); + }) + .then(function (childClone) { + if (childClone) parent.appendChild(childClone); + }); + }); + return done; + } + } + + function processClone(original, clone) { + if (!(clone instanceof Element)) return clone; + + return Promise.resolve() + .then(cloneStyle) + .then(clonePseudoElements) + .then(copyUserInput) + .then(fixSvg) + .then(function () { + return clone; + }); + + function cloneStyle() { + copyStyle(window.getComputedStyle(original), clone.style); + + function copyStyle(source, target) { + if (source.cssText) target.cssText = source.cssText; + else copyProperties(source, target); + + function copyProperties(source, target) { + util.asArray(source).forEach(function (name) { + target.setProperty( + name, + source.getPropertyValue(name), + source.getPropertyPriority(name) + ); + }); + } + } + } + + function clonePseudoElements() { + [':before', ':after'].forEach(function (element) { + clonePseudoElement(element); + }); + + function clonePseudoElement(element) { + var style = window.getComputedStyle(original, element); + var content = style.getPropertyValue('content'); + + if (content === '' || content === 'none') return; + + var className = util.uid(); + clone.className = clone.className + ' ' + className; + var styleElement = document.createElement('style'); + styleElement.appendChild(formatPseudoElementStyle(className, element, style)); + clone.appendChild(styleElement); + + function formatPseudoElementStyle(className, element, style) { + var selector = '.' + className + ':' + element; + var cssText = style.cssText ? formatCssText(style) : formatCssProperties(style); + return document.createTextNode(selector + '{' + cssText + '}'); + + function formatCssText(style) { + var content = style.getPropertyValue('content'); + return style.cssText + ' content: ' + content + ';'; + } + + function formatCssProperties(style) { + + return util.asArray(style) + .map(formatProperty) + .join('; ') + ';'; + + function formatProperty(name) { + return name + ': ' + + style.getPropertyValue(name) + + (style.getPropertyPriority(name) ? ' !important' : ''); + } + } + } + } + } + + function copyUserInput() { + if (original instanceof HTMLTextAreaElement) clone.innerHTML = original.value; + if (original instanceof HTMLInputElement) clone.setAttribute("value", original.value); + } + + function fixSvg() { + if (!(clone instanceof SVGElement)) return; + clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg'); + + if (!(clone instanceof SVGRectElement)) return; + ['width', 'height'].forEach(function (attribute) { + var value = clone.getAttribute(attribute); + if (!value) return; + + clone.style.setProperty(attribute, value); + }); + } + } + } + + function embedFonts(node) { + return fontFaces.resolveAll() + .then(function (cssText) { + var styleNode = document.createElement('style'); + node.appendChild(styleNode); + styleNode.appendChild(document.createTextNode(cssText)); + return node; + }); + } + + function inlineImages(node) { + return images.inlineAll(node) + .then(function () { + return node; + }); + } + + function makeSvgDataUri(node, width, height) { + return Promise.resolve(node) + .then(function (node) { + node.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml'); + return new XMLSerializer().serializeToString(node); + }) + .then(util.escapeXhtml) + .then(function (xhtml) { + return '' + xhtml + ''; + }) + .then(function (foreignObject) { + return '' + + foreignObject + ''; + }) + .then(function (svg) { + return 'data:image/svg+xml;charset=utf-8,' + svg; + }); + } + + function newUtil() { + return { + escape: escape, + parseExtension: parseExtension, + mimeType: mimeType, + dataAsUrl: dataAsUrl, + isDataUrl: isDataUrl, + canvasToBlob: canvasToBlob, + resolveUrl: resolveUrl, + getAndEncode: getAndEncode, + uid: uid(), + delay: delay, + asArray: asArray, + escapeXhtml: escapeXhtml, + makeImage: makeImage + }; + + function mimes() { + /* + * Only WOFF and EOT mime types for fonts are 'real' + * see http://www.iana.org/assignments/media-types/media-types.xhtml + */ + var WOFF = 'application/font-woff'; + var JPEG = 'image/jpeg'; + + return { + 'woff': WOFF, + 'woff2': WOFF, + 'ttf': 'application/font-truetype', + 'eot': 'application/vnd.ms-fontobject', + 'png': 'image/png', + 'jpg': JPEG, + 'jpeg': JPEG, + 'gif': 'image/gif', + 'tiff': 'image/tiff', + 'svg': 'image/svg+xml' + }; + } + + function parseExtension(url) { + var match = /\.([^\.\/]*?)$/g.exec(url); + if (match) return match[1]; + else return ''; + } + + function mimeType(url) { + var extension = parseExtension(url).toLowerCase(); + return mimes()[extension] || ''; + } + + function isDataUrl(url) { + return url.search(/^(data:)/) !== -1; + } + + function toBlob(canvas) { + return new Promise(function (resolve) { + var binaryString = window.atob(canvas.toDataURL().split(',')[1]); + var length = binaryString.length; + var binaryArray = new Uint8Array(length); + + for (var i = 0; i < length; i++) + binaryArray[i] = binaryString.charCodeAt(i); + + resolve(new Blob([binaryArray], { + type: 'image/png' + })); + }); + } + + function canvasToBlob(canvas) { + if (canvas.toBlob) + return new Promise(function (resolve) { + canvas.toBlob(resolve); + }); + + return toBlob(canvas); + } + + function resolveUrl(url, baseUrl) { + var doc = document.implementation.createHTMLDocument(); + var base = doc.createElement('base'); + doc.head.appendChild(base); + var a = doc.createElement('a'); + doc.body.appendChild(a); + base.href = baseUrl; + a.href = url; + return a.href; + } + + function uid() { + var index = 0; + + return function () { + return 'u' + fourRandomChars() + index++; + + function fourRandomChars() { + /* see http://stackoverflow.com/a/6248722/2519373 */ + return ('0000' + (Math.random() * Math.pow(36, 4) << 0).toString(36)).slice(-4); + } + }; + } + + function makeImage(uri) { + return new Promise(function (resolve, reject) { + var image = new Image(); + image.onload = function () { + resolve(image); + }; + image.onerror = reject; + image.src = uri; + }); + } + + function getAndEncode(url) { + var TIMEOUT = 30000; + + return new Promise(function (resolve) { + var request = new XMLHttpRequest(); + + request.onreadystatechange = done; + request.ontimeout = timeout; + request.responseType = 'blob'; + request.timeout = TIMEOUT; + request.open('GET', url, true); + request.send(); + + function done() { + if (request.readyState !== 4) return; + + if (request.status !== 200) { + fail('cannot fetch resource: ' + url + ', status: ' + request.status); + return; + } + + var encoder = new FileReader(); + encoder.onloadend = function () { + var content = encoder.result.split(/,/)[1]; + resolve(content); + }; + encoder.readAsDataURL(request.response); + } + + function timeout() { + fail('timeout of ' + TIMEOUT + 'ms occured while fetching resource: ' + url); + } + + function fail(message) { + console.error(message); + resolve(''); + } + }); + } + + function dataAsUrl(content, type) { + return 'data:' + type + ';base64,' + content; + } + + function escape(string) { + return string.replace(/([.*+?^${}()|\[\]\/\\])/g, '\\$1'); + } + + function delay(ms) { + return function (arg) { + return new Promise(function (resolve) { + setTimeout(function () { + resolve(arg); + }, ms); + }); + }; + } + + function asArray(arrayLike) { + var array = []; + var length = arrayLike.length; + for (var i = 0; i < length; i++) array.push(arrayLike[i]); + return array; + } + + function escapeXhtml(string) { + return string.replace(/#/g, '%23').replace(/\n/g, '%0A'); + } + } + + function newInliner() { + var URL_REGEX = /url\(['"]?([^'"]+?)['"]?\)/g; + + return { + inlineAll: inlineAll, + shouldProcess: shouldProcess, + impl: { + readUrls: readUrls, + inline: inline + } + }; + + function shouldProcess(string) { + return string.search(URL_REGEX) !== -1; + } + + function readUrls(string) { + var result = []; + var match; + while ((match = URL_REGEX.exec(string)) !== null) { + result.push(match[1]); + } + return result.filter(function (url) { + return !util.isDataUrl(url); + }); + } + + function inline(string, url, baseUrl, get) { + return Promise.resolve(url) + .then(function (url) { + return baseUrl ? util.resolveUrl(url, baseUrl) : url; + }) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(url)); + }) + .then(function (dataUrl) { + return string.replace(urlAsRegex(url), '$1' + dataUrl + '$3'); + }); + + function urlAsRegex(url) { + return new RegExp('(url\\([\'"]?)(' + util.escape(url) + ')([\'"]?\\))', 'g'); + } + } + + function inlineAll(string, baseUrl, get) { + if (nothingToInline()) return Promise.resolve(string); + + return Promise.resolve(string) + .then(readUrls) + .then(function (urls) { + var done = Promise.resolve(string); + urls.forEach(function (url) { + done = done.then(function (string) { + return inline(string, url, baseUrl, get); + }); + }); + return done; + }); + + function nothingToInline() { + return !shouldProcess(string); + } + } + } + + function newFontFaces() { + return { + resolveAll: resolveAll, + impl: { + readAll: readAll + } + }; + + function resolveAll() { + return readAll(document) + .then(function (webFonts) { + return Promise.all( + webFonts.map(function (webFont) { + return webFont.resolve(); + }) + ); + }) + .then(function (cssStrings) { + return cssStrings.join('\n'); + }); + } + + function readAll() { + return Promise.resolve(util.asArray(document.styleSheets)) + .then(getCssRules) + .then(selectWebFontRules) + .then(function (rules) { + return rules.map(newWebFont); + }); + + function selectWebFontRules(cssRules) { + return cssRules + .filter(function (rule) { + return rule.type === CSSRule.FONT_FACE_RULE; + }) + .filter(function (rule) { + return inliner.shouldProcess(rule.style.getPropertyValue('src')); + }); + } + + function getCssRules(styleSheets) { + var cssRules = []; + styleSheets.forEach(function (sheet) { + try { + util.asArray(sheet.cssRules || []).forEach(cssRules.push.bind(cssRules)); + } catch (e) { + console.log('Error while reading CSS rules from ' + sheet.href, e.toString()); + } + }); + return cssRules; + } + + function newWebFont(webFontRule) { + return { + resolve: function resolve() { + var baseUrl = (webFontRule.parentStyleSheet || {}).href; + return inliner.inlineAll(webFontRule.cssText, baseUrl); + }, + src: function () { + return webFontRule.style.getPropertyValue('src'); + } + }; + } + } + } + + function newImages() { + return { + inlineAll: inlineAll, + impl: { + newImage: newImage + } + }; + + function newImage(element) { + return { + inline: inline + }; + + function inline(get) { + if (util.isDataUrl(element.src)) return Promise.resolve(); + + return Promise.resolve(element.src) + .then(get || util.getAndEncode) + .then(function (data) { + return util.dataAsUrl(data, util.mimeType(element.src)); + }) + .then(function (dataUrl) { + return new Promise(function (resolve, reject) { + element.onload = resolve; + element.onerror = reject; + element.src = dataUrl; + }); + }); + } + } + + function inlineAll(node) { + if (!(node instanceof Element)) return Promise.resolve(node); + + return inlineBackground(node) + .then(function () { + if (node instanceof HTMLImageElement) + return newImage(node).inline(); + else + return Promise.all( + util.asArray(node.childNodes).map(function (child) { + return inlineAll(child); + }) + ); + }); + + function inlineBackground(node) { + var background = node.style.getPropertyValue('background'); + + if (!background) return Promise.resolve(node); + + return inliner.inlineAll(background) + .then(function (inlined) { + node.style.setProperty( + 'background', + inlined, + node.style.getPropertyPriority('background') + ); + }) + .then(function () { + return node; + }); + } + } + } +})(this); diff --git a/ajax/libs/dom-to-image/2.5.1/dom-to-image.min.js b/ajax/libs/dom-to-image/2.5.1/dom-to-image.min.js new file mode 100644 index 00000000000000..29ab33b472b810 --- /dev/null +++ b/ajax/libs/dom-to-image/2.5.1/dom-to-image.min.js @@ -0,0 +1,2 @@ +/*! dom-to-image 31-07-2016 */ +!function(a){"use strict";function b(a,b){function c(a){return b.bgcolor&&(a.style.backgroundColor=b.bgcolor),b.width&&(a.style.width=b.width+"px"),b.height&&(a.style.height=b.height+"px"),b.style&&Object.keys(b.style).forEach(function(c){a.style[c]=b.style[c]}),a}return b=b||{},Promise.resolve(a).then(function(a){return h(a,b.filter,!0)}).then(i).then(j).then(c).then(function(c){return k(c,b.width||a.scrollWidth,b.height||a.scrollHeight)})}function c(a,b){return g(a,b||{}).then(function(b){return b.getContext("2d").getImageData(0,0,a.scrollWidth,a.scrollHeight).data})}function d(a,b){return g(a,b||{}).then(function(a){return a.toDataURL()})}function e(a,b){return b=b||{},g(a,b).then(function(a){return a.toDataURL("image/jpeg",b.quality||1)})}function f(a,b){return g(a,b||{}).then(p.canvasToBlob)}function g(a,c){function d(a){var b=document.createElement("canvas");if(b.width=c.width||a.scrollWidth,b.height=c.height||a.scrollHeight,c.bgcolor){var d=b.getContext("2d");d.fillStyle=c.bgcolor,d.fillRect(0,0,b.width,b.height)}return b}return b(a,c).then(p.makeImage).then(p.delay(100)).then(function(b){var c=d(a);return c.getContext("2d").drawImage(b,0,0),c})}function h(a,b,c){function d(a){return a instanceof HTMLCanvasElement?p.makeImage(a.toDataURL()):a.cloneNode(!1)}function e(a,b,c){function d(a,b,c){var d=Promise.resolve();return b.forEach(function(b){d=d.then(function(){return h(b,c)}).then(function(b){b&&a.appendChild(b)})}),d}var e=a.childNodes;return 0===e.length?Promise.resolve(b):d(b,p.asArray(e),c).then(function(){return b})}function f(a,b){function c(){function c(a,b){function c(a,b){p.asArray(a).forEach(function(c){b.setProperty(c,a.getPropertyValue(c),a.getPropertyPriority(c))})}a.cssText?b.cssText=a.cssText:c(a,b)}c(window.getComputedStyle(a),b.style)}function d(){function c(c){function d(a,b,c){function d(a){var b=a.getPropertyValue("content");return a.cssText+" content: "+b+";"}function e(a){function b(b){return b+": "+a.getPropertyValue(b)+(a.getPropertyPriority(b)?" !important":"")}return p.asArray(a).map(b).join("; ")+";"}var f="."+a+":"+b,g=c.cssText?d(c):e(c);return document.createTextNode(f+"{"+g+"}")}var e=window.getComputedStyle(a,c),f=e.getPropertyValue("content");if(""!==f&&"none"!==f){var g=p.uid();b.className=b.className+" "+g;var h=document.createElement("style");h.appendChild(d(g,c,e)),b.appendChild(h)}}[":before",":after"].forEach(function(a){c(a)})}function e(){a instanceof HTMLTextAreaElement&&(b.innerHTML=a.value),a instanceof HTMLInputElement&&b.setAttribute("value",a.value)}function f(){b instanceof SVGElement&&(b.setAttribute("xmlns","http://www.w3.org/2000/svg"),b instanceof SVGRectElement&&["width","height"].forEach(function(a){var c=b.getAttribute(a);c&&b.style.setProperty(a,c)}))}return b instanceof Element?Promise.resolve().then(c).then(d).then(e).then(f).then(function(){return b}):b}return c||!b||b(a)?Promise.resolve(a).then(d).then(function(c){return e(a,c,b)}).then(function(b){return f(a,b)}):Promise.resolve()}function i(a){return r.resolveAll().then(function(b){var c=document.createElement("style");return a.appendChild(c),c.appendChild(document.createTextNode(b)),a})}function j(a){return s.inlineAll(a).then(function(){return a})}function k(a,b,c){return Promise.resolve(a).then(function(a){return a.setAttribute("xmlns","http://www.w3.org/1999/xhtml"),(new XMLSerializer).serializeToString(a)}).then(p.escapeXhtml).then(function(a){return''+a+""}).then(function(a){return''+a+""}).then(function(a){return"data:image/svg+xml;charset=utf-8,"+a})}function l(){function a(){var a="application/font-woff",b="image/jpeg";return{woff:a,woff2:a,ttf:"application/font-truetype",eot:"application/vnd.ms-fontobject",png:"image/png",jpg:b,jpeg:b,gif:"image/gif",tiff:"image/tiff",svg:"image/svg+xml"}}function b(a){var b=/\.([^\.\/]*?)$/g.exec(a);return b?b[1]:""}function c(c){var d=b(c).toLowerCase();return a()[d]||""}function d(a){return a.search(/^(data:)/)!==-1}function e(a){return new Promise(function(b){for(var c=window.atob(a.toDataURL().split(",")[1]),d=c.length,e=new Uint8Array(d),f=0;f