Repository: marciolopesjr/HTML-GL Branch: master Commit: 6e58d6adc4d3 Files: 45 Total size: 2.3 MB Directory structure: gitextract_das9wpov/ ├── .gitignore ├── README.md ├── bower.json ├── demo/ │ ├── advanced-content-dom.html │ ├── advanced-content-webgl.html │ ├── assets/ │ │ ├── css/ │ │ │ ├── appstyle.css │ │ │ └── style.css │ │ └── fonts/ │ │ └── README-FONTS.txt │ ├── basic-dom.html │ ├── basic-webgl-jquery.html │ ├── basic-webgl.html │ ├── filters.html │ ├── js/ │ │ ├── slider.js │ │ └── vendor/ │ │ ├── html2canvas.js │ │ └── velocity.js │ ├── nested-content-webgl.html │ └── ripples.html ├── dist/ │ ├── htmlgl-effects.js │ └── htmlgl.js ├── figures/ │ ├── htmlgl-flow-diagram.ep │ └── logo.psd ├── gulpfile.js ├── package.json ├── page/ │ ├── css/ │ │ └── style.css │ ├── index.html │ └── js/ │ ├── basics.js │ ├── dat.gui.js │ ├── effects.js │ └── slider.js └── src/ ├── effects/ │ ├── ascii.js │ ├── bloom.js │ ├── diagonal-blur.js │ ├── dotscreen.js │ ├── invert.js │ ├── noise.js │ ├── pixelate.js │ ├── rgbsplit.js │ ├── ripples.js │ └── twist.js ├── gl-context.js ├── gl-effects-manager.js ├── gl-element-resolver.js ├── gl-element.js ├── images-loaded.js └── util.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ bower_components .idea ================================================ FILE: README.md ================================================ HTML GL 60 FPS and amazing effects by rendering HTML/CSS in WebGL, framework agnostic ======================================================================================= [![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/PixelsCommander/HTML-GL) HTML GL solves "the slow DOM problem" by creating WebGL representations of DOM elements and hiding actual DOM after. This speeds up HTML/CSS animations and transformations by using 3D hardware acceleration and allows to apply OpenGL effects as modern 3D games have. - [Demo](http://pixelscommander.com/polygon/htmlgl/demo/filters.html) - [Project page](http://htmlgl.com) - [Theory behind HTML GL](http://pixelscommander.com/en/web-applications-performance/render-html-css-in-webgl-to-get-highest-performance-possibl/) Using HTML GL you still work with HTML/CSS as you are common to, but DOM elements are just facades to their WebGL representations. These GPU accelerated textures are very effective from resources consuming perspective and are very cheap to transform or animate. Install ------- npm: ```bash npm install --save html-gl ``` Bower: ```bash bower install --save htmlgl ``` Usage ----- As Web Component ```html This element`s content is rendered in

WebGL

was it easy? Feel free to use CSS, images and all you are common to in HTML/CSS world.
``` As jQuery plugin ```js $('.some div').htmlgl(); ``` No DOM + WebGL rendering = highest FPS possible for Web platform ------------------------------------------------------- HTML GL flow diagram Demos ----- - [Filters](http://pixelscommander.com/polygon/htmlgl/demo/filters.html) WebGL is not only about performance. It breaks any HTML/CSS limits in terms of animations and interactivity - [Mobile effects](http://pixelscommander.com/polygon/htmlgl/demo/ripples.html) use attribute `effects` on `` element to specify effects you use, this one is nice for mobile - [Basic HTML GL](http://pixelscommander.com/polygon/htmlgl/demo/basic-webgl.html) demo shows how to use HTML GL and animate GL Elements. It also demonstrate that HTML GL handle content change events and repaints element`s WebGL representation - [Basic DOM](http://pixelscommander.com/polygon/htmlgl/demo/basic-dom.html) this is the same project as previous. The only difference is that htmlgl.js is not included - [Advanced content HTML GL](http://pixelscommander.com/polygon/htmlgl/demo/advanced-content-webgl.html) slider with nested content rendered via WebGL and animated, ability to drag with mouse horizontaly, click event listeners on boxes - [Advanced content DOM](http://pixelscommander.com/polygon/htmlgl/demo/advanced-content-dom.html) How to use? ----------- Include HTMLGL.js into project. Use tag name `` or jQuery plugin `$(myElement).htmlgl()` for elements you are going to animate. These elements will be rendered in WebGL and their CSS Transform properties will be mapped to WebGL representation transformations. So DOM node itself will not be animated or displayed in order to avoid resources consuming. HTML GL is framework agnostic and is easy to inject into existing project which needs performance tweaking. Rasterization API ----------------- In order to improve technology we are trying to promote standardized native Rasterization API for JavaScript. Help us to be better and to add this cool feature to browsers by spreading the [article](http://pixelscommander.com/en/javascript/state-of-html-content-rasterization-draw-html-to-canvas-image/) and [proposal draft](https://gist.github.com/PixelsCommander/a0b5882139cbb8a1781c#file-proposal-md). Fast way to animate ------------------- The most performant way to animate HTML-GL tags is to operate on tag's `styleGL.transform` in the same way you operate on `style.transform`. E.g. `style.transform = 'translateX(100px) translateY(50px)'`. Velocity.js copy from HTML-GL repository (https://github.com/PixelsCommander/HTML-GL/blob/master/demo/js/vendor/velocity.js) have this optimization built-in. Feel free to use it in the way described in official Velocity.js documentation. Animating HTML-GL tag children ------------------------------ Since it is very efficient to make transformations (move, rotate, scale, change opacity) on HTML-GL tags it becomes very slow to animate it's children until they are HTML-GL tags too. This happens because of necessity to rasterize and send HTML-GL tag texture to GPU. Running demos from repository ----------------------------- Please run `bower install` before running demos License ------- MIT: http://mit-license.org/ Copyright 2015 Denis Radin aka [PixelsCommander](http://pixelscommander.com) ================================================ FILE: bower.json ================================================ { "name": "htmlgl", "authors": [ "PixelsCommander " ], "license": "MIT", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "pixi": "~3.0.7", "webcomponents.js": "~0.5.5", "promise-polyfill": "~2.0.0", "jquery": "~2.1.3", "tween.js": "https://github.com/tweenjs/tween.js.git" }, "keywords": ["web-components"] } ================================================ FILE: demo/advanced-content-dom.html ================================================ DOM content

MENU RENDERED IN DOM

DOM SLIDER SINCE HTML GL IS DISABLED FOR THIS DEMO

  • Select me with DevTools

    7.8/10

  • Change me in DevTools

    8.0/10

  • Breaking bad

    9.6/10

  • Quantum of solace

    6.7/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • ================================================ FILE: demo/advanced-content-webgl.html ================================================ HTML GL nested content

    MENU RENDERED IN DOM

    SLIDER BELOW IS RENDERED IN WEBGL, DRAG IT

  • Select me with DevTools

    7.8/10

  • Change me in DevTools

    8.0/10

  • Breaking bad

    9.6/10

  • Quantum of solace

    6.7/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • ================================================ FILE: demo/assets/css/appstyle.css ================================================ /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Bold'; src: url('../fonts/InterstatePro-Bold.eot'); src: local('☺'), url('../fonts/InterstatePro-Bold.woff') format('woff'), url('../fonts/InterstatePro-Bold.ttf') format('truetype'), url('../fonts/InterstatePro-Bold.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Light'; src: url('../fonts/InterstatePro-Light.eot'); src: local('☺'), url('../fonts/InterstatePro-Light.woff') format('woff'), url('../fonts/InterstatePro-Light.ttf') format('truetype'), url('../fonts/InterstatePro-Light.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-ExtraLight'; src: url('../fonts/InterstatePro-ExtraLight.eot'); src: local('☺'), url('../fonts/InterstatePro-ExtraLight.woff') format('woff'), url('../fonts/InterstatePro-ExtraLight.ttf') format('truetype'), url('../fonts/InterstatePro-ExtraLight.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Regular'; src: url('../fonts/InterstatePro-Regular.eot'); src: local('☺'), url('../fonts/InterstatePro-Regular.woff') format('woff'), url('../fonts/InterstatePro-Regular.ttf') format('truetype'), url('../fonts/InterstatePro-Regular.svg') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: "UPCDigital"; src: url(../fonts/DAWN-UPCDiRg.ttf) format("truetype"); font-weight: 400; } @font-face { font-family: 'UPCDigital-bold'; src: url(../fonts/DAWN-UPCDiBd.ttf) format('truetype'); } body { box-sizing: border-box; /* padding: 20px 43px 0 43px; */ margin: 0; font-family: Conv_InterstatePro-Regular; font-weight: normal; font-size: 24px; color: #2c3e50; width: 100%; height: 100%; background-color: #ecf0f1; overflow-x: hidden; } ul { list-style: none; } li { text-align: center; display: inline-block; vertical-align:top; padding: 20px; } p { width: 128px; margin-top: 15px; } ================================================ FILE: demo/assets/css/style.css ================================================ /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Bold'; src: url('../fonts/InterstatePro-Bold.eot'); src: local('☺'), url('../fonts/InterstatePro-Bold.woff') format('woff'), url('../fonts/InterstatePro-Bold.ttf') format('truetype'), url('../fonts/InterstatePro-Bold.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Light'; src: url('../fonts/InterstatePro-Light.eot'); src: local('☺'), url('../fonts/InterstatePro-Light.woff') format('woff'), url('../fonts/InterstatePro-Light.ttf') format('truetype'), url('../fonts/InterstatePro-Light.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-ExtraLight'; src: url('../fonts/InterstatePro-ExtraLight.eot'); src: local('☺'), url('../fonts/InterstatePro-ExtraLight.woff') format('woff'), url('../fonts/InterstatePro-ExtraLight.ttf') format('truetype'), url('../fonts/InterstatePro-ExtraLight.svg') format('svg'); font-weight: normal; font-style: normal; } /** Generated by FG **/ @font-face { font-family: 'Conv_InterstatePro-Regular'; src: url('../fonts/InterstatePro-Regular.eot'); src: local('☺'), url('../fonts/InterstatePro-Regular.woff') format('woff'), url('../fonts/InterstatePro-Regular.ttf') format('truetype'), url('../fonts/InterstatePro-Regular.svg') format('svg'); font-weight: normal; font-style: normal; } @font-face { font-family: "UPCDigital"; src: url(../fonts/DAWN-UPCDiRg.ttf) format("truetype"); font-weight: 400; } @font-face { font-family: 'UPCDigital-bold'; src: url(../fonts/DAWN-UPCDiBd.ttf) format('truetype'); } html { overflow-x: hidden; } body { box-sizing: border-box; padding: 30px 93px 0 93px; margin: 0; font-family: Conv_InterstatePro-Regular; font-weight: normal; color: #ffffff; width: 100%; height: 100%; background: url("../../pic/bgs/Descendants.png") no-repeat #000000; overflow-x: hidden; } html-gl { display: block; } h1 { font-family: verdana, sans-serif; font-size: 16px; margin: 0 0 30px 0; font-weight: 300; color: #858382; } .menu { font-size: 30px; } .menu.expanded { border-bottom: 1px solid #858382; } a { font-family: verdana, sans-serif; margin: 0 0 30px 0; font-weight: 300; color: #ffffff; text-decoration: none; } a:hover { text-decoration: underline; } ul.menu, ul.submenu { list-style: none; margin: 0; padding: 0; line-height: 1em; padding: 0 0 6px 0; } ul.submenu { padding: 6px 0 0 0; } .menu li { display: inline; padding-right: 30px; } .submenu { font-size: 26px; } .submenu li { overflow: hidden; height: 24px; display: inline-block; padding-right: 30px; } .broadcasts_list { margin: 36px 0 0 0; padding: 0 0 36px 0; /* TODO Implement overflow masks in WebGL overflow-x: hidden;*/ } .broadcasts_list h1 { font-family: Conv_InterstatePro-Light; font-size: 22px; font-weight: 300; margin: 0 0 5px 0; line-height: 1em; } .broadcasts_list ul { list-style: none; padding: 0; margin: 0; white-space: nowrap; } .broadcasts_list li { display: inline-block; width: 186px; margin-right: 15px; } .broadcast { position: relative; font-family: "UPCDigital"; font-size: 16px; line-height: 24px; } .image_overlay, .image_background, .broadcast > img { width: 186px; height: 270px; } .image_background { position: absolute; left: 0; top: 0; background-color: #000000; } .broadcast > img { width: 186px; height: 270px; border: 1px solid #858382; box-sizing: border-box; opacity: 0.8; } .image_overlay { position: absolute; left: 0; top: 0; background-color: #000000; opacity: 0.2; } .broadcast p { line-height: 20px; margin: 0 0 3px 0; padding: 0; color: #D2D2D2; } .broadcast p img { width: 52px; height: 24px; display: inline-block; } .broadcast p > span { font-family: UPCDigital-bold; display: inline-block; color: #ffffff; vertical-align: top; font-size: 16px; margin-left: 3px; } .broadcast p > span span { color: #808080; display: inline-block; vertical-align: baseline; font-size: 12px; } ================================================ FILE: demo/assets/fonts/README-FONTS.txt ================================================ we experienced that web apps could reference their own versions of fonts our app uses in some cases this broke DAWN for example, special characters began to display incorrectly in order to avoid this situation, we're namespacing our fonts with the 'DAWN-' prefix the rename function of the Typelite application (http://www.cr8software.net/typex.html) was used to accomplish this initially ================================================ FILE: demo/basic-dom.html ================================================ HTML GL demo

    HTML GL demo

    This layer is rendered as a

    DOM

    because HTML GL is disabled

    TODO

    • Switch to WebGL for more performant animations
    ================================================ FILE: demo/basic-webgl-jquery.html ================================================ HTML GL demo

    HTML GL demo

    This layer is rendered in

    WebGL

    because it have tag name html-gl

    TODO

    • Add retina support in order to avoid blurry content
    ================================================ FILE: demo/basic-webgl.html ================================================ HTML GL demo

    HTML GL demo

    This layer is rendered in

    WebGL

    because it have tag name html-gl

    TODO

    • Add more effects presets
    ================================================ FILE: demo/filters.html ================================================ HTML GL filters demo

    MENU RENDERED IN DOM

    SLIDER BELOW IS RENDERED IN WEBGL, DRAG IT

  • Select me with DevTools

    7.8/10

  • Change me in DevTools

    8.0/10

  • Breaking bad

    9.6/10

  • Quantum of solace

    6.7/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • Quantum of solace

    7.4/10

  • ================================================ FILE: demo/js/slider.js ================================================ //Slider logic, written in HTML / JS. //The only difference between HTML GL and basic HTML is that you should use element.styleGL.transform instead of element.style.transform var images = document.getElementsByTagName('img'), dragStart = false, slider = document.getElementsByTagName('html-gl')[0], startX = 0, startLeft = 0, transformPropertyName = document.body.style.transform !== undefined ? 'transform' : 'WebkitTransform'; for (var i = 0; i < images.length; i++) { images[i].ondragstart = function () { return false; }; } function setSliderX(x) { (slider.styleGL || slider.style)[transformPropertyName] = 'translateZ(0) translateX(' + (startLeft - (startX - (x || 0))) + 'px)'; } function getSliderX() { return parseInt(parseCSSTransform((slider.styleGL || slider.style)[transformPropertyName]).translateX) || 0 } function onDragStart(event) { dragStart = true; startX = (event.pageX || event.x) || event.touches[0].pageX; startLeft = getSliderX(); } function onDragEnd() { dragStart = false; } function onMove(event) { if (dragStart) { var pageX = (event.pageX || event.x) || event.touches[0].pageX, moveTime = new Date(); setSliderX(pageX); } } slider.addEventListener('mousedown', onDragStart); slider.addEventListener('mouseup', onDragEnd); slider.addEventListener('mousemove', onMove); slider.addEventListener('touchstart', onDragStart); slider.addEventListener('touchend', onDragEnd); slider.addEventListener('touchmove', onMove); parseCSSTransform = function (transformString) { return (transformString.match(/([\w]+)\(([^\)]+)\)/g) || []) //make pairs of prop and value .map(function (it) { return it.replace(/\)$/, "").split(/\(/) }) //convert to key-value map/object .reduce(function (m, it) { return m[it[0]] = it[1], m }, {}); } ================================================ FILE: demo/js/vendor/html2canvas.js ================================================ /* html2canvas 0.5.0-alpha2 Copyright (c) 2015 Niklas von Hertzen Released under MIT License */ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.html2canvas = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o postsJSON values[1] // => commentsJSON return values; }); ``` @class Promise @param {function} resolver Useful for tooling. @constructor */ function lib$es6$promise$promise$$Promise(resolver) { this._id = lib$es6$promise$promise$$counter++; this._state = undefined; this._result = undefined; this._subscribers = []; if (lib$es6$promise$$internal$$noop !== resolver) { if (!lib$es6$promise$utils$$isFunction(resolver)) { lib$es6$promise$promise$$needsResolver(); } if (!(this instanceof lib$es6$promise$promise$$Promise)) { lib$es6$promise$promise$$needsNew(); } lib$es6$promise$$internal$$initializePromise(this, resolver); } } lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default; lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default; lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default; lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default; lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler; lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap; lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap; lib$es6$promise$promise$$Promise.prototype = { constructor: lib$es6$promise$promise$$Promise, /** The primary way of interacting with a promise is through its `then` method, which registers callbacks to receive either a promise's eventual value or the reason why the promise cannot be fulfilled. ```js findUser().then(function(user){ // user is available }, function(reason){ // user is unavailable, and you are given the reason why }); ``` Chaining -------- The return value of `then` is itself a promise. This second, 'downstream' promise is resolved with the return value of the first promise's fulfillment or rejection handler, or rejected if the handler throws an exception. ```js findUser().then(function (user) { return user.name; }, function (reason) { return 'default name'; }).then(function (userName) { // If `findUser` fulfilled, `userName` will be the user's name, otherwise it // will be `'default name'` }); findUser().then(function (user) { throw new Error('Found user, but still unhappy'); }, function (reason) { throw new Error('`findUser` rejected and we're unhappy'); }).then(function (value) { // never reached }, function (reason) { // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'. // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'. }); ``` If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream. ```js findUser().then(function (user) { throw new PedagogicalException('Upstream error'); }).then(function (value) { // never reached }).then(function (value) { // never reached }, function (reason) { // The `PedgagocialException` is propagated all the way down to here }); ``` Assimilation ------------ Sometimes the value you want to propagate to a downstream promise can only be retrieved asynchronously. This can be achieved by returning a promise in the fulfillment or rejection handler. The downstream promise will then be pending until the returned promise is settled. This is called *assimilation*. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // The user's comments are now available }); ``` If the assimliated promise rejects, then the downstream promise will also reject. ```js findUser().then(function (user) { return findCommentsByAuthor(user); }).then(function (comments) { // If `findCommentsByAuthor` fulfills, we'll have the value here }, function (reason) { // If `findCommentsByAuthor` rejects, we'll have the reason here }); ``` Simple Example -------------- Synchronous Example ```javascript var result; try { result = findResult(); // success } catch(reason) { // failure } ``` Errback Example ```js findResult(function(result, err){ if (err) { // failure } else { // success } }); ``` Promise Example; ```javascript findResult().then(function(result){ // success }, function(reason){ // failure }); ``` Advanced Example -------------- Synchronous Example ```javascript var author, books; try { author = findAuthor(); books = findBooksByAuthor(author); // success } catch(reason) { // failure } ``` Errback Example ```js function foundBooks(books) { } function failure(reason) { } findAuthor(function(author, err){ if (err) { failure(err); // failure } else { try { findBoooksByAuthor(author, function(books, err) { if (err) { failure(err); } else { try { foundBooks(books); } catch(reason) { failure(reason); } } }); } catch(error) { failure(err); } // success } }); ``` Promise Example; ```javascript findAuthor(). then(findBooksByAuthor). then(function(books){ // found books }).catch(function(reason){ // something went wrong }); ``` @method then @param {Function} onFulfilled @param {Function} onRejected Useful for tooling. @return {Promise} */ then: function(onFulfillment, onRejection) { var parent = this; var state = parent._state; if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) { return this; } var child = new this.constructor(lib$es6$promise$$internal$$noop); var result = parent._result; if (state) { var callback = arguments[state - 1]; lib$es6$promise$asap$$asap(function(){ lib$es6$promise$$internal$$invokeCallback(state, child, callback, result); }); } else { lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection); } return child; }, /** `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same as the catch block of a try/catch statement. ```js function findAuthor(){ throw new Error('couldn't find that author'); } // synchronous try { findAuthor(); } catch(reason) { // something went wrong } // async with promises findAuthor().catch(function(reason){ // something went wrong }); ``` @method catch @param {Function} onRejection Useful for tooling. @return {Promise} */ 'catch': function(onRejection) { return this.then(null, onRejection); } }; function lib$es6$promise$polyfill$$polyfill() { var local; if (typeof global !== 'undefined') { local = global; } else if (typeof self !== 'undefined') { local = self; } else { try { local = Function('return this')(); } catch (e) { throw new Error('polyfill failed because global object is unavailable in this environment'); } } var P = local.Promise; if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) { return; } local.Promise = lib$es6$promise$promise$$default; } var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill; var lib$es6$promise$umd$$ES6Promise = { 'Promise': lib$es6$promise$promise$$default, 'polyfill': lib$es6$promise$polyfill$$default }; /* global define:true module:true window: true */ if (typeof define === 'function' && define['amd']) { define(function() { return lib$es6$promise$umd$$ES6Promise; }); } else if (typeof module !== 'undefined' && module['exports']) { module['exports'] = lib$es6$promise$umd$$ES6Promise; } else if (typeof this !== 'undefined') { this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise; } lib$es6$promise$polyfill$$default(); }).call(this); }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"_process":2}],2:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { currentQueue[queueIndex].run(); } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; clearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { setTimeout(drainQueue, 0); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; // TODO(shtylman) process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],3:[function(require,module,exports){ (function (global){ /*! https://mths.be/punycode v1.3.2 by @mathias */ ;(function(root) { /** Detect free variables */ var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; var freeModule = typeof module == 'object' && module && !module.nodeType && module; var freeGlobal = typeof global == 'object' && global; if ( freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal ) { root = freeGlobal; } /** * The `punycode` object. * @name punycode * @type Object */ var punycode, /** Highest positive signed 32-bit float value */ maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 /** Bootstring parameters */ base = 36, tMin = 1, tMax = 26, skew = 38, damp = 700, initialBias = 72, initialN = 128, // 0x80 delimiter = '-', // '\x2D' /** Regular expressions */ regexPunycode = /^xn--/, regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators /** Error messages */ errors = { 'overflow': 'Overflow: input needs wider integers to process', 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', 'invalid-input': 'Invalid input' }, /** Convenience shortcuts */ baseMinusTMin = base - tMin, floor = Math.floor, stringFromCharCode = String.fromCharCode, /** Temporary variable */ key; /*--------------------------------------------------------------------------*/ /** * A generic error utility function. * @private * @param {String} type The error type. * @returns {Error} Throws a `RangeError` with the applicable error message. */ function error(type) { throw RangeError(errors[type]); } /** * A generic `Array#map` utility function. * @private * @param {Array} array The array to iterate over. * @param {Function} callback The function that gets called for every array * item. * @returns {Array} A new array of values returned by the callback function. */ function map(array, fn) { var length = array.length; var result = []; while (length--) { result[length] = fn(array[length]); } return result; } /** * A simple `Array#map`-like wrapper to work with domain name strings or email * addresses. * @private * @param {String} domain The domain name or email address. * @param {Function} callback The function that gets called for every * character. * @returns {Array} A new string of characters returned by the callback * function. */ function mapDomain(string, fn) { var parts = string.split('@'); var result = ''; if (parts.length > 1) { // In email addresses, only the domain name should be punycoded. Leave // the local part (i.e. everything up to `@`) intact. result = parts[0] + '@'; string = parts[1]; } // Avoid `split(regex)` for IE8 compatibility. See #17. string = string.replace(regexSeparators, '\x2E'); var labels = string.split('.'); var encoded = map(labels, fn).join('.'); return result + encoded; } /** * Creates an array containing the numeric code points of each Unicode * character in the string. While JavaScript uses UCS-2 internally, * this function will convert a pair of surrogate halves (each of which * UCS-2 exposes as separate characters) into a single code point, * matching UTF-16. * @see `punycode.ucs2.encode` * @see * @memberOf punycode.ucs2 * @name decode * @param {String} string The Unicode input string (UCS-2). * @returns {Array} The new array of code points. */ function ucs2decode(string) { var output = [], counter = 0, length = string.length, value, extra; while (counter < length) { value = string.charCodeAt(counter++); if (value >= 0xD800 && value <= 0xDBFF && counter < length) { // high surrogate, and there is a next character extra = string.charCodeAt(counter++); if ((extra & 0xFC00) == 0xDC00) { // low surrogate output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); } else { // unmatched surrogate; only append this code unit, in case the next // code unit is the high surrogate of a surrogate pair output.push(value); counter--; } } else { output.push(value); } } return output; } /** * Creates a string based on an array of numeric code points. * @see `punycode.ucs2.decode` * @memberOf punycode.ucs2 * @name encode * @param {Array} codePoints The array of numeric code points. * @returns {String} The new Unicode string (UCS-2). */ function ucs2encode(array) { return map(array, function(value) { var output = ''; if (value > 0xFFFF) { value -= 0x10000; output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); value = 0xDC00 | value & 0x3FF; } output += stringFromCharCode(value); return output; }).join(''); } /** * Converts a basic code point into a digit/integer. * @see `digitToBasic()` * @private * @param {Number} codePoint The basic numeric code point value. * @returns {Number} The numeric value of a basic code point (for use in * representing integers) in the range `0` to `base - 1`, or `base` if * the code point does not represent a value. */ function basicToDigit(codePoint) { if (codePoint - 48 < 10) { return codePoint - 22; } if (codePoint - 65 < 26) { return codePoint - 65; } if (codePoint - 97 < 26) { return codePoint - 97; } return base; } /** * Converts a digit/integer into a basic code point. * @see `basicToDigit()` * @private * @param {Number} digit The numeric value of a basic code point. * @returns {Number} The basic code point whose value (when used for * representing integers) is `digit`, which needs to be in the range * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is * used; else, the lowercase form is used. The behavior is undefined * if `flag` is non-zero and `digit` has no uppercase form. */ function digitToBasic(digit, flag) { // 0..25 map to ASCII a..z or A..Z // 26..35 map to ASCII 0..9 return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); } /** * Bias adaptation function as per section 3.4 of RFC 3492. * http://tools.ietf.org/html/rfc3492#section-3.4 * @private */ function adapt(delta, numPoints, firstTime) { var k = 0; delta = firstTime ? floor(delta / damp) : delta >> 1; delta += floor(delta / numPoints); for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { delta = floor(delta / baseMinusTMin); } return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); } /** * Converts a Punycode string of ASCII-only symbols to a string of Unicode * symbols. * @memberOf punycode * @param {String} input The Punycode string of ASCII-only symbols. * @returns {String} The resulting string of Unicode symbols. */ function decode(input) { // Don't use UCS-2 var output = [], inputLength = input.length, out, i = 0, n = initialN, bias = initialBias, basic, j, index, oldi, w, k, digit, t, /** Cached calculation results */ baseMinusT; // Handle the basic code points: let `basic` be the number of input code // points before the last delimiter, or `0` if there is none, then copy // the first basic code points to the output. basic = input.lastIndexOf(delimiter); if (basic < 0) { basic = 0; } for (j = 0; j < basic; ++j) { // if it's not a basic code point if (input.charCodeAt(j) >= 0x80) { error('not-basic'); } output.push(input.charCodeAt(j)); } // Main decoding loop: start just after the last delimiter if any basic code // points were copied; start at the beginning otherwise. for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { // `index` is the index of the next character to be consumed. // Decode a generalized variable-length integer into `delta`, // which gets added to `i`. The overflow checking is easier // if we increase `i` as we go, then subtract off its starting // value at the end to obtain `delta`. for (oldi = i, w = 1, k = base; /* no condition */; k += base) { if (index >= inputLength) { error('invalid-input'); } digit = basicToDigit(input.charCodeAt(index++)); if (digit >= base || digit > floor((maxInt - i) / w)) { error('overflow'); } i += digit * w; t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (digit < t) { break; } baseMinusT = base - t; if (w > floor(maxInt / baseMinusT)) { error('overflow'); } w *= baseMinusT; } out = output.length + 1; bias = adapt(i - oldi, out, oldi == 0); // `i` was supposed to wrap around from `out` to `0`, // incrementing `n` each time, so we'll fix that now: if (floor(i / out) > maxInt - n) { error('overflow'); } n += floor(i / out); i %= out; // Insert `n` at position `i` of the output output.splice(i++, 0, n); } return ucs2encode(output); } /** * Converts a string of Unicode symbols (e.g. a domain name label) to a * Punycode string of ASCII-only symbols. * @memberOf punycode * @param {String} input The string of Unicode symbols. * @returns {String} The resulting Punycode string of ASCII-only symbols. */ function encode(input) { var n, delta, handledCPCount, basicLength, bias, j, m, q, k, t, currentValue, output = [], /** `inputLength` will hold the number of code points in `input`. */ inputLength, /** Cached calculation results */ handledCPCountPlusOne, baseMinusT, qMinusT; // Convert the input in UCS-2 to Unicode input = ucs2decode(input); // Cache the length inputLength = input.length; // Initialize the state n = initialN; delta = 0; bias = initialBias; // Handle the basic code points for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < 0x80) { output.push(stringFromCharCode(currentValue)); } } handledCPCount = basicLength = output.length; // `handledCPCount` is the number of code points that have been handled; // `basicLength` is the number of basic code points. // Finish the basic string - if it is not empty - with a delimiter if (basicLength) { output.push(delimiter); } // Main encoding loop: while (handledCPCount < inputLength) { // All non-basic code points < n have been handled already. Find the next // larger one: for (m = maxInt, j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue >= n && currentValue < m) { m = currentValue; } } // Increase `delta` enough to advance the decoder's state to , // but guard against overflow handledCPCountPlusOne = handledCPCount + 1; if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { error('overflow'); } delta += (m - n) * handledCPCountPlusOne; n = m; for (j = 0; j < inputLength; ++j) { currentValue = input[j]; if (currentValue < n && ++delta > maxInt) { error('overflow'); } if (currentValue == n) { // Represent delta as a generalized variable-length integer for (q = delta, k = base; /* no condition */; k += base) { t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); if (q < t) { break; } qMinusT = q - t; baseMinusT = base - t; output.push( stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) ); q = floor(qMinusT / baseMinusT); } output.push(stringFromCharCode(digitToBasic(q, 0))); bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); delta = 0; ++handledCPCount; } } ++delta; ++n; } return output.join(''); } /** * Converts a Punycode string representing a domain name or an email address * to Unicode. Only the Punycoded parts of the input will be converted, i.e. * it doesn't matter if you call it on a string that has already been * converted to Unicode. * @memberOf punycode * @param {String} input The Punycoded domain name or email address to * convert to Unicode. * @returns {String} The Unicode representation of the given Punycode * string. */ function toUnicode(input) { return mapDomain(input, function(string) { return regexPunycode.test(string) ? decode(string.slice(4).toLowerCase()) : string; }); } /** * Converts a Unicode string representing a domain name or an email address to * Punycode. Only the non-ASCII parts of the domain name will be converted, * i.e. it doesn't matter if you call it with a domain that's already in * ASCII. * @memberOf punycode * @param {String} input The domain name or email address to convert, as a * Unicode string. * @returns {String} The Punycode representation of the given domain name or * email address. */ function toASCII(input) { return mapDomain(input, function(string) { return regexNonASCII.test(string) ? 'xn--' + encode(string) : string; }); } /*--------------------------------------------------------------------------*/ /** Define the public API */ punycode = { /** * A string representing the current Punycode.js version number. * @memberOf punycode * @type String */ 'version': '1.3.2', /** * An object of methods to convert from JavaScript's internal character * representation (UCS-2) to Unicode code points, and back. * @see * @memberOf punycode * @type Object */ 'ucs2': { 'decode': ucs2decode, 'encode': ucs2encode }, 'decode': decode, 'encode': encode, 'toASCII': toASCII, 'toUnicode': toUnicode }; /** Expose `punycode` */ // Some AMD build optimizers, like r.js, check for specific condition patterns // like the following: if ( typeof define == 'function' && typeof define.amd == 'object' && define.amd ) { define('punycode', function() { return punycode; }); } else if (freeExports && freeModule) { if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+ freeModule.exports = punycode; } else { // in Narwhal or RingoJS v0.7.0- for (key in punycode) { punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); } } } else { // in Rhino or a web browser root.punycode = punycode; } }(this)); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],4:[function(require,module,exports){ var log = require('./log'); var Promise = require('./promise'); function restoreOwnerScroll(ownerDocument, x, y) { if (ownerDocument.defaultView && (x !== ownerDocument.defaultView.pageXOffset || y !== ownerDocument.defaultView.pageYOffset)) { ownerDocument.defaultView.scrollTo(x, y); } } function cloneCanvasContents(canvas, clonedCanvas) { try { if (clonedCanvas) { clonedCanvas.width = canvas.width; clonedCanvas.height = canvas.height; clonedCanvas.getContext("2d").putImageData(canvas.getContext("2d").getImageData(0, 0, canvas.width, canvas.height), 0, 0); } } catch(e) { log("Unable to copy canvas content from", canvas, e); } } function cloneNode(node, javascriptEnabled) { var clone = node.nodeType === 3 ? document.createTextNode(node.nodeValue) : node.cloneNode(false); var child = node.firstChild; while(child) { if (javascriptEnabled === true || child.nodeType !== 1 || child.nodeName !== 'SCRIPT') { clone.appendChild(cloneNode(child, javascriptEnabled)); } child = child.nextSibling; } if (node.nodeType === 1 && node.tagName !== 'BODY') { clone._scrollTop = node.scrollTop; clone._scrollLeft = node.scrollLeft; if (node.nodeName === "CANVAS") { cloneCanvasContents(node, clone); } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") { clone.value = node.value; } } return clone; } function initNode(node) { if (node.nodeType === 1) { node.scrollTop = node._scrollTop; node.scrollLeft = node._scrollLeft; var child = node.firstChild; while(child) { initNode(child); child = child.nextSibling; } } } module.exports = function(ownerDocument, containerDocument, width, height, options, x ,y) { var documentElement = cloneNode(ownerDocument.documentElement, options.javascriptEnabled); var container = containerDocument.createElement("iframe"); container.className = "html2canvas-container"; container.style.visibility = "hidden"; container.style.position = "fixed"; container.style.left = "-10000px"; container.style.top = "0px"; container.style.border = "0"; container.style.border = "0"; container.width = width; container.height = height; container.scrolling = "no"; // ios won't scroll without it containerDocument.body.appendChild(container); return new Promise(function(resolve) { var documentClone = container.contentWindow.document; /* Chrome doesn't detect relative background-images assigned in inline