1 | (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<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
2 | 'use strict';
|
3 |
|
4 | var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
|
5 |
|
6 | var _rasterizehtml = require('rasterizehtml');
|
7 |
|
8 | var _rasterizehtml2 = _interopRequireDefault(_rasterizehtml);
|
9 |
|
10 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
11 |
|
12 | function shadeColor(color, percent) {
|
13 | var f = parseInt(color.slice(1), 16),
|
14 | t = percent < 0 ? 0 : 255,
|
15 | p = percent < 0 ? percent * -1 : percent;
|
16 | var R = f >> 16,
|
17 | G = f >> 8 & 0x00FF,
|
18 | B = f & 0x0000FF;
|
19 | return '#' + (0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B)).toString(16).slice(1);
|
20 | }
|
21 |
|
22 | function collectElements(article, selectors) {
|
23 | var q = '';
|
24 | [
|
25 | ['heading', 'h1,h2,h3,h4,h5,h6'], ['paragraph', 'p']
|
26 |
|
27 | , ['material', 'ul,ol,pre,table,blockquote']].forEach(function (d) {
|
28 | var key = d[0];
|
29 | q += ',' + (selectors[key] || d[1]);
|
30 | });
|
31 | return article.querySelectorAll(q.slice(1));
|
32 | }
|
33 |
|
34 | function fetchResultData(endpointURL, csrfToken, resolveCallback, rejectCallback) {
|
35 | var credentials = { csrfToken: csrfToken };
|
36 | if (!credentials.csrfToken) {
|
37 | credentials.csrfToken = '';
|
38 | }
|
39 | var getJSON = function getJSON(url) {
|
40 | var emptyData = { 'p': [] };
|
41 | return new Promise(function (resolve, reject) {
|
42 | var xhr = new XMLHttpRequest();
|
43 | xhr.open('GET', url, true);
|
44 | xhr.setRequestHeader('Accept', 'application/json');
|
45 | xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
46 | if (credentials.csrfToken !== '') {
|
47 | xhr.setRequestHeader('X-CSRF-Token', credentials.csrfToken);
|
48 | }
|
49 | xhr.responseType = 'text';
|
50 | xhr.onerror = function () {
|
51 | var status = xhr.status;
|
52 | reject(emptyData);
|
53 | };
|
54 | xhr.onload = function () {
|
55 | var status = xhr.status,
|
56 | response = xhr.response;
|
57 | if (status === 200) {
|
58 | response = response.replace(/^\]\)\}while\(1\);<\/x>/, '');
|
59 | resolve(JSON.parse(response));
|
60 | } else {
|
61 | console.error('[ERROR] GET status: ', status);
|
62 | reject(emptyData);
|
63 | }
|
64 | };
|
65 | xhr.send();
|
66 | });
|
67 | };
|
68 | return getJSON(endpointURL).then(function (data) {
|
69 | return resolveCallback(data);
|
70 | }, function (data) {
|
71 | return rejectCallback(data);
|
72 | });
|
73 | }
|
74 |
|
75 | function buildHTML(data, elements, styles) {
|
76 | var html = '<html><head>';
|
77 | html += Array.from(styles).map(function (s) {
|
78 |
|
79 | return s.outerHTML;
|
80 | }).join('');
|
81 | html += '</head><body>';
|
82 |
|
83 | var colors0 = [
|
84 | '#2d96db', '#4aa8a6', '#64b977', '#99c95d', '#c5d062', '#f6d866', '#fab252', '#fd8e3e', '#fe6f43', '#fd515b', '#fb1b2a'];
|
85 |
|
86 | var colors1 = [
|
87 | '#9e0142', '#d0384d', '#ee6445', '#fa9c58', '#fdcd7b', '#fef0a7', '#f3faad', '#d0ec9c', '#98d5a4', '#5cb7a9', '#3582ba', '#5e4fa2'];
|
88 |
|
89 | var colors = colors0
|
90 | ,
|
91 | pIndex = 0;
|
92 | html += Array.from(elements).map(function (e) {
|
93 | var n = document.importNode(e, true);
|
94 | if (n.nodeName !== 'IMG') {
|
95 | if (n.nodeName === 'P' && 'p' in data) {
|
96 |
|
97 | var v = data['p'][String(pIndex)];
|
98 | if (v !== undefined) {
|
99 | var color = '#ffffff';
|
100 | try {
|
101 | var i = Math.round(parseFloat(v) * 10);
|
102 | color = shadeColor(colors[i], 0.55);
|
103 | } catch (_e) {
|
104 | console.error(e);
|
105 | }
|
106 | n.style.background = color;
|
107 | n.style.backgroundColor = 'rgba(' + color + ', 0.9)';
|
108 | }
|
109 | pIndex += 1;
|
110 | }
|
111 | }
|
112 | return n.outerHTML;
|
113 | }).join('');
|
114 | html += '</body></html>';
|
115 | return html;
|
116 | }
|
117 |
|
118 | function makeCanvas(width, height) {
|
119 | var container = document.getElementById('scrolliris_canvas_container'),
|
120 | canvas = document.createElement('canvas');
|
121 | canvas.setAttribute('id', 'scrolliris_canvas');
|
122 | canvas.setAttribute('width', width * 0.5);
|
123 | canvas.setAttribute('height', height * 0.5);
|
124 | container.appendChild(canvas);
|
125 | return canvas;
|
126 | }
|
127 |
|
128 | function drawCanvas(canvas, html, width, height, margin) {
|
129 | _rasterizehtml2.default.drawHTML(html, canvas, {
|
130 | zoom: 0.5,
|
131 | width: width,
|
132 | height: height
|
133 | });
|
134 |
|
135 | var dragging = false,
|
136 | lastY = void 0,
|
137 | marginTop = 0,
|
138 | event = {};
|
139 |
|
140 | canvas.addEventListener('mousedown', function (e) {
|
141 | var evt = e || event;
|
142 | canvas.style.cursor = 'grabbing';
|
143 | dragging = true;
|
144 | lastY = evt.clientY;
|
145 | e.preventDefault();
|
146 | }, false);
|
147 |
|
148 | canvas.addEventListener('mouseup', function (e) {
|
149 | canvas.style.cursor = 'grab';
|
150 | dragging = false;
|
151 | }, false);
|
152 |
|
153 | window.addEventListener('mousemove', function (e) {
|
154 | var evt = e || event;
|
155 | if (dragging) {
|
156 | var delta = evt.clientY - lastY;
|
157 | lastY = evt.clientY;
|
158 | marginTop += delta;
|
159 | if (marginTop > 0) {
|
160 | marginTop = 0;
|
161 | } else if (marginTop < margin) {
|
162 | marginTop = margin;
|
163 | }
|
164 | canvas.style.marginTop = marginTop + 'px';
|
165 | }
|
166 | e.preventDefault();
|
167 | }, false);
|
168 |
|
169 | window.addEventListener('mouseout', function (e) {
|
170 | canvas.style.cursor = 'grab';
|
171 | dragging = false;
|
172 | }, false);
|
173 | }
|
174 |
|
175 | (function (doc, ctx) {
|
176 | var config = {},
|
177 | settings = {},
|
178 | options = {};
|
179 |
|
180 | if (ctx.hasOwnProperty('config') && _typeof(ctx.config) === 'object') {
|
181 | config = ctx['config'];
|
182 |
|
183 | }
|
184 | if (ctx.hasOwnProperty('settings') && _typeof(ctx.options) === 'object') {
|
185 | settings = ctx['settings'];
|
186 | if (!settings.endpointURL) {
|
187 | console.error('endpointURL is required');
|
188 | return false;
|
189 | }
|
190 | }
|
191 | if (ctx.hasOwnProperty('options') && _typeof(ctx.options) === 'object') {
|
192 | options = ctx['options'];
|
193 | }
|
194 |
|
195 | var selectors = options.selectors || {};
|
196 | var article = doc.querySelector(selectors.article || 'body article');
|
197 |
|
198 |
|
199 | var elements = collectElements(article, selectors),
|
200 | styles = doc.querySelectorAll('style') || [];
|
201 |
|
202 |
|
203 |
|
204 | var elm = doc.documentElement;
|
205 | var docWidth = Math.max(doc.body.clientWidth, elm.clientWidth, elm.scrollWidth);
|
206 | var docHeight = Math.max(doc.body.clientHeight, elm.clientHeight, elm.scrollHeight);
|
207 |
|
208 | var draw = function draw(data) {
|
209 | var html = buildHTML(data, elements, styles),
|
210 | canvas = makeCanvas(docWidth, docHeight);
|
211 |
|
212 | var canvasHeight = 290
|
213 | ,
|
214 | headerHeight = 22,
|
215 | footerHeiht = 22,
|
216 | frameMargin = 9
|
217 | ,
|
218 | scale = 0.5;
|
219 | var margin = -1 * (docHeight * scale / canvasHeight * 100) + (headerHeight + footerHeiht + frameMargin);
|
220 | drawCanvas(canvas, html, docWidth, docHeight, margin);
|
221 | };
|
222 |
|
223 | fetchResultData(settings.endpointURL, settings.csrfToken, function (data) {
|
224 |
|
225 | draw(data);
|
226 | }, function (data) {
|
227 |
|
228 |
|
229 | draw(data);
|
230 | });
|
231 | })(window.parent.document, (window.ScrollirisReadabilityReflector || {}).Context);
|
232 |
|
233 | },{"rasterizehtml":39}],2:[function(require,module,exports){
|
234 |
|
235 | (function (root, factory) {
|
236 | if (typeof define === 'function' && define.amd) {
|
237 | define(factory);
|
238 | } else if (typeof exports === 'object') {
|
239 | module.exports = factory();
|
240 | } else {
|
241 | root.ayepromise = factory();
|
242 | }
|
243 | }(this, function () {
|
244 | 'use strict';
|
245 |
|
246 | var ayepromise = {};
|
247 |
|
248 | |
249 |
|
250 | var once = function () {
|
251 | var wasCalled = false;
|
252 |
|
253 | return function wrapper(wrappedFunction) {
|
254 | return function () {
|
255 | if (wasCalled) {
|
256 | return;
|
257 | }
|
258 | wasCalled = true;
|
259 | wrappedFunction.apply(null, arguments);
|
260 | };
|
261 | };
|
262 | };
|
263 |
|
264 | var getThenableIfExists = function (obj) {
|
265 |
|
266 | var then = obj && obj.then;
|
267 |
|
268 | if (typeof obj === "object" && typeof then === "function") {
|
269 |
|
270 | return function() { return then.apply(obj, arguments); };
|
271 | }
|
272 | };
|
273 |
|
274 | var aThenHandler = function (onFulfilled, onRejected) {
|
275 | var defer = ayepromise.defer();
|
276 |
|
277 | var doHandlerCall = function (func, value) {
|
278 | setTimeout(function () {
|
279 | var returnValue;
|
280 | try {
|
281 | returnValue = func(value);
|
282 | } catch (e) {
|
283 | defer.reject(e);
|
284 | return;
|
285 | }
|
286 |
|
287 | if (returnValue === defer.promise) {
|
288 | defer.reject(new TypeError('Cannot resolve promise with itself'));
|
289 | } else {
|
290 | defer.resolve(returnValue);
|
291 | }
|
292 | }, 1);
|
293 | };
|
294 |
|
295 | var callFulfilled = function (value) {
|
296 | if (onFulfilled && onFulfilled.call) {
|
297 | doHandlerCall(onFulfilled, value);
|
298 | } else {
|
299 | defer.resolve(value);
|
300 | }
|
301 | };
|
302 |
|
303 | var callRejected = function (value) {
|
304 | if (onRejected && onRejected.call) {
|
305 | doHandlerCall(onRejected, value);
|
306 | } else {
|
307 | defer.reject(value);
|
308 | }
|
309 | };
|
310 |
|
311 | return {
|
312 | promise: defer.promise,
|
313 | handle: function (state, value) {
|
314 | if (state === FULFILLED) {
|
315 | callFulfilled(value);
|
316 | } else {
|
317 | callRejected(value);
|
318 | }
|
319 | }
|
320 | };
|
321 | };
|
322 |
|
323 |
|
324 | var PENDING = 0,
|
325 | FULFILLED = 1,
|
326 | REJECTED = 2;
|
327 |
|
328 | ayepromise.defer = function () {
|
329 | var state = PENDING,
|
330 | outcome,
|
331 | thenHandlers = [];
|
332 |
|
333 | var doSettle = function (settledState, value) {
|
334 | state = settledState;
|
335 |
|
336 | outcome = value;
|
337 |
|
338 | thenHandlers.forEach(function (then) {
|
339 | then.handle(state, outcome);
|
340 | });
|
341 |
|
342 |
|
343 | thenHandlers = null;
|
344 | };
|
345 |
|
346 | var doFulfill = function (value) {
|
347 | doSettle(FULFILLED, value);
|
348 | };
|
349 |
|
350 | var doReject = function (error) {
|
351 | doSettle(REJECTED, error);
|
352 | };
|
353 |
|
354 | var registerThenHandler = function (onFulfilled, onRejected) {
|
355 | var thenHandler = aThenHandler(onFulfilled, onRejected);
|
356 |
|
357 | if (state === PENDING) {
|
358 | thenHandlers.push(thenHandler);
|
359 | } else {
|
360 | thenHandler.handle(state, outcome);
|
361 | }
|
362 |
|
363 | return thenHandler.promise;
|
364 | };
|
365 |
|
366 | var safelyResolveThenable = function (thenable) {
|
367 |
|
368 | var onceWrapper = once();
|
369 | try {
|
370 | thenable(
|
371 | onceWrapper(transparentlyResolveThenablesAndSettle),
|
372 | onceWrapper(doReject)
|
373 | );
|
374 | } catch (e) {
|
375 | onceWrapper(doReject)(e);
|
376 | }
|
377 | };
|
378 |
|
379 | var transparentlyResolveThenablesAndSettle = function (value) {
|
380 | var thenable;
|
381 |
|
382 | try {
|
383 | thenable = getThenableIfExists(value);
|
384 | } catch (e) {
|
385 | doReject(e);
|
386 | return;
|
387 | }
|
388 |
|
389 | if (thenable) {
|
390 | safelyResolveThenable(thenable);
|
391 | } else {
|
392 | doFulfill(value);
|
393 | }
|
394 | };
|
395 |
|
396 | var onceWrapper = once();
|
397 | return {
|
398 | resolve: onceWrapper(transparentlyResolveThenablesAndSettle),
|
399 | reject: onceWrapper(doReject),
|
400 | promise: {
|
401 | then: registerThenHandler,
|
402 | fail: function (onRejected) {
|
403 | return registerThenHandler(null, onRejected);
|
404 | }
|
405 | }
|
406 | };
|
407 | };
|
408 |
|
409 | return ayepromise;
|
410 | }));
|
411 |
|
412 | },{}],3:[function(require,module,exports){
|
413 |
|
414 |
|
415 |
|
416 |
|
417 |
|
418 |
|
419 |
|
420 |
|
421 |
|
422 |
|
423 |
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 |
|
433 |
|
434 | 'use strict';
|
435 |
|
436 | var punycode = require('punycode');
|
437 | var util = require('./util');
|
438 |
|
439 | exports.parse = urlParse;
|
440 | exports.resolve = urlResolve;
|
441 | exports.resolveObject = urlResolveObject;
|
442 | exports.format = urlFormat;
|
443 |
|
444 | exports.Url = Url;
|
445 |
|
446 | function Url() {
|
447 | this.protocol = null;
|
448 | this.slashes = null;
|
449 | this.auth = null;
|
450 | this.host = null;
|
451 | this.port = null;
|
452 | this.hostname = null;
|
453 | this.hash = null;
|
454 | this.search = null;
|
455 | this.query = null;
|
456 | this.pathname = null;
|
457 | this.path = null;
|
458 | this.href = null;
|
459 | }
|
460 |
|
461 |
|
462 |
|
463 |
|
464 |
|
465 | var protocolPattern = /^([a-z0-9.+-]+:)/i,
|
466 | portPattern = /:[0-9]*$/,
|
467 |
|
468 |
|
469 | simplePathPattern = /^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,
|
470 |
|
471 |
|
472 |
|
473 | delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
|
474 |
|
475 |
|
476 | unwise = ['{', '}', '|', '\\', '^', '`'].concat(delims),
|
477 |
|
478 |
|
479 | autoEscape = ['\''].concat(unwise),
|
480 |
|
481 |
|
482 |
|
483 |
|
484 | nonHostChars = ['%', '/', '?', ';', '#'].concat(autoEscape),
|
485 | hostEndingChars = ['/', '?', '#'],
|
486 | hostnameMaxLen = 255,
|
487 | hostnamePartPattern = /^[+a-z0-9A-Z_-]{0,63}$/,
|
488 | hostnamePartStart = /^([+a-z0-9A-Z_-]{0,63})(.*)$/,
|
489 |
|
490 | unsafeProtocol = {
|
491 | 'javascript': true,
|
492 | 'javascript:': true
|
493 | },
|
494 |
|
495 | hostlessProtocol = {
|
496 | 'javascript': true,
|
497 | 'javascript:': true
|
498 | },
|
499 |
|
500 | slashedProtocol = {
|
501 | 'http': true,
|
502 | 'https': true,
|
503 | 'ftp': true,
|
504 | 'gopher': true,
|
505 | 'file': true,
|
506 | 'http:': true,
|
507 | 'https:': true,
|
508 | 'ftp:': true,
|
509 | 'gopher:': true,
|
510 | 'file:': true
|
511 | },
|
512 | querystring = require('querystring');
|
513 |
|
514 | function urlParse(url, parseQueryString, slashesDenoteHost) {
|
515 | if (url && util.isObject(url) && url instanceof Url) return url;
|
516 |
|
517 | var u = new Url;
|
518 | u.parse(url, parseQueryString, slashesDenoteHost);
|
519 | return u;
|
520 | }
|
521 |
|
522 | Url.prototype.parse = function(url, parseQueryString, slashesDenoteHost) {
|
523 | if (!util.isString(url)) {
|
524 | throw new TypeError("Parameter 'url' must be a string, not " + typeof url);
|
525 | }
|
526 |
|
527 |
|
528 |
|
529 |
|
530 | var queryIndex = url.indexOf('?'),
|
531 | splitter =
|
532 | (queryIndex !== -1 && queryIndex < url.indexOf('#')) ? '?' : '#',
|
533 | uSplit = url.split(splitter),
|
534 | slashRegex = /\\/g;
|
535 | uSplit[0] = uSplit[0].replace(slashRegex, '/');
|
536 | url = uSplit.join(splitter);
|
537 |
|
538 | var rest = url;
|
539 |
|
540 |
|
541 |
|
542 | rest = rest.trim();
|
543 |
|
544 | if (!slashesDenoteHost && url.split('#').length === 1) {
|
545 |
|
546 | var simplePath = simplePathPattern.exec(rest);
|
547 | if (simplePath) {
|
548 | this.path = rest;
|
549 | this.href = rest;
|
550 | this.pathname = simplePath[1];
|
551 | if (simplePath[2]) {
|
552 | this.search = simplePath[2];
|
553 | if (parseQueryString) {
|
554 | this.query = querystring.parse(this.search.substr(1));
|
555 | } else {
|
556 | this.query = this.search.substr(1);
|
557 | }
|
558 | } else if (parseQueryString) {
|
559 | this.search = '';
|
560 | this.query = {};
|
561 | }
|
562 | return this;
|
563 | }
|
564 | }
|
565 |
|
566 | var proto = protocolPattern.exec(rest);
|
567 | if (proto) {
|
568 | proto = proto[0];
|
569 | var lowerProto = proto.toLowerCase();
|
570 | this.protocol = lowerProto;
|
571 | rest = rest.substr(proto.length);
|
572 | }
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 | if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
|
579 | var slashes = rest.substr(0, 2) === '//';
|
580 | if (slashes && !(proto && hostlessProtocol[proto])) {
|
581 | rest = rest.substr(2);
|
582 | this.slashes = true;
|
583 | }
|
584 | }
|
585 |
|
586 | if (!hostlessProtocol[proto] &&
|
587 | (slashes || (proto && !slashedProtocol[proto]))) {
|
588 |
|
589 |
|
590 |
|
591 |
|
592 |
|
593 |
|
594 |
|
595 |
|
596 |
|
597 |
|
598 |
|
599 |
|
600 |
|
601 |
|
602 |
|
603 |
|
604 |
|
605 | var hostEnd = -1;
|
606 | for (var i = 0; i < hostEndingChars.length; i++) {
|
607 | var hec = rest.indexOf(hostEndingChars[i]);
|
608 | if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
|
609 | hostEnd = hec;
|
610 | }
|
611 |
|
612 |
|
613 |
|
614 | var auth, atSign;
|
615 | if (hostEnd === -1) {
|
616 |
|
617 | atSign = rest.lastIndexOf('@');
|
618 | } else {
|
619 |
|
620 |
|
621 | atSign = rest.lastIndexOf('@', hostEnd);
|
622 | }
|
623 |
|
624 |
|
625 |
|
626 | if (atSign !== -1) {
|
627 | auth = rest.slice(0, atSign);
|
628 | rest = rest.slice(atSign + 1);
|
629 | this.auth = decodeURIComponent(auth);
|
630 | }
|
631 |
|
632 |
|
633 | hostEnd = -1;
|
634 | for (var i = 0; i < nonHostChars.length; i++) {
|
635 | var hec = rest.indexOf(nonHostChars[i]);
|
636 | if (hec !== -1 && (hostEnd === -1 || hec < hostEnd))
|
637 | hostEnd = hec;
|
638 | }
|
639 |
|
640 | if (hostEnd === -1)
|
641 | hostEnd = rest.length;
|
642 |
|
643 | this.host = rest.slice(0, hostEnd);
|
644 | rest = rest.slice(hostEnd);
|
645 |
|
646 |
|
647 | this.parseHost();
|
648 |
|
649 |
|
650 |
|
651 | this.hostname = this.hostname || '';
|
652 |
|
653 |
|
654 |
|
655 | var ipv6Hostname = this.hostname[0] === '[' &&
|
656 | this.hostname[this.hostname.length - 1] === ']';
|
657 |
|
658 |
|
659 | if (!ipv6Hostname) {
|
660 | var hostparts = this.hostname.split(/\./);
|
661 | for (var i = 0, l = hostparts.length; i < l; i++) {
|
662 | var part = hostparts[i];
|
663 | if (!part) continue;
|
664 | if (!part.match(hostnamePartPattern)) {
|
665 | var newpart = '';
|
666 | for (var j = 0, k = part.length; j < k; j++) {
|
667 | if (part.charCodeAt(j) > 127) {
|
668 |
|
669 |
|
670 |
|
671 | newpart += 'x';
|
672 | } else {
|
673 | newpart += part[j];
|
674 | }
|
675 | }
|
676 |
|
677 | if (!newpart.match(hostnamePartPattern)) {
|
678 | var validParts = hostparts.slice(0, i);
|
679 | var notHost = hostparts.slice(i + 1);
|
680 | var bit = part.match(hostnamePartStart);
|
681 | if (bit) {
|
682 | validParts.push(bit[1]);
|
683 | notHost.unshift(bit[2]);
|
684 | }
|
685 | if (notHost.length) {
|
686 | rest = '/' + notHost.join('.') + rest;
|
687 | }
|
688 | this.hostname = validParts.join('.');
|
689 | break;
|
690 | }
|
691 | }
|
692 | }
|
693 | }
|
694 |
|
695 | if (this.hostname.length > hostnameMaxLen) {
|
696 | this.hostname = '';
|
697 | } else {
|
698 |
|
699 | this.hostname = this.hostname.toLowerCase();
|
700 | }
|
701 |
|
702 | if (!ipv6Hostname) {
|
703 |
|
704 |
|
705 |
|
706 |
|
707 | this.hostname = punycode.toASCII(this.hostname);
|
708 | }
|
709 |
|
710 | var p = this.port ? ':' + this.port : '';
|
711 | var h = this.hostname || '';
|
712 | this.host = h + p;
|
713 | this.href += this.host;
|
714 |
|
715 |
|
716 |
|
717 | if (ipv6Hostname) {
|
718 | this.hostname = this.hostname.substr(1, this.hostname.length - 2);
|
719 | if (rest[0] !== '/') {
|
720 | rest = '/' + rest;
|
721 | }
|
722 | }
|
723 | }
|
724 |
|
725 |
|
726 |
|
727 | if (!unsafeProtocol[lowerProto]) {
|
728 |
|
729 |
|
730 |
|
731 |
|
732 | for (var i = 0, l = autoEscape.length; i < l; i++) {
|
733 | var ae = autoEscape[i];
|
734 | if (rest.indexOf(ae) === -1)
|
735 | continue;
|
736 | var esc = encodeURIComponent(ae);
|
737 | if (esc === ae) {
|
738 | esc = escape(ae);
|
739 | }
|
740 | rest = rest.split(ae).join(esc);
|
741 | }
|
742 | }
|
743 |
|
744 |
|
745 |
|
746 | var hash = rest.indexOf('#');
|
747 | if (hash !== -1) {
|
748 |
|
749 | this.hash = rest.substr(hash);
|
750 | rest = rest.slice(0, hash);
|
751 | }
|
752 | var qm = rest.indexOf('?');
|
753 | if (qm !== -1) {
|
754 | this.search = rest.substr(qm);
|
755 | this.query = rest.substr(qm + 1);
|
756 | if (parseQueryString) {
|
757 | this.query = querystring.parse(this.query);
|
758 | }
|
759 | rest = rest.slice(0, qm);
|
760 | } else if (parseQueryString) {
|
761 |
|
762 | this.search = '';
|
763 | this.query = {};
|
764 | }
|
765 | if (rest) this.pathname = rest;
|
766 | if (slashedProtocol[lowerProto] &&
|
767 | this.hostname && !this.pathname) {
|
768 | this.pathname = '/';
|
769 | }
|
770 |
|
771 |
|
772 | if (this.pathname || this.search) {
|
773 | var p = this.pathname || '';
|
774 | var s = this.search || '';
|
775 | this.path = p + s;
|
776 | }
|
777 |
|
778 |
|
779 | this.href = this.format();
|
780 | return this;
|
781 | };
|
782 |
|
783 |
|
784 | function urlFormat(obj) {
|
785 |
|
786 |
|
787 |
|
788 |
|
789 | if (util.isString(obj)) obj = urlParse(obj);
|
790 | if (!(obj instanceof Url)) return Url.prototype.format.call(obj);
|
791 | return obj.format();
|
792 | }
|
793 |
|
794 | Url.prototype.format = function() {
|
795 | var auth = this.auth || '';
|
796 | if (auth) {
|
797 | auth = encodeURIComponent(auth);
|
798 | auth = auth.replace(/%3A/i, ':');
|
799 | auth += '@';
|
800 | }
|
801 |
|
802 | var protocol = this.protocol || '',
|
803 | pathname = this.pathname || '',
|
804 | hash = this.hash || '',
|
805 | host = false,
|
806 | query = '';
|
807 |
|
808 | if (this.host) {
|
809 | host = auth + this.host;
|
810 | } else if (this.hostname) {
|
811 | host = auth + (this.hostname.indexOf(':') === -1 ?
|
812 | this.hostname :
|
813 | '[' + this.hostname + ']');
|
814 | if (this.port) {
|
815 | host += ':' + this.port;
|
816 | }
|
817 | }
|
818 |
|
819 | if (this.query &&
|
820 | util.isObject(this.query) &&
|
821 | Object.keys(this.query).length) {
|
822 | query = querystring.stringify(this.query);
|
823 | }
|
824 |
|
825 | var search = this.search || (query && ('?' + query)) || '';
|
826 |
|
827 | if (protocol && protocol.substr(-1) !== ':') protocol += ':';
|
828 |
|
829 |
|
830 |
|
831 | if (this.slashes ||
|
832 | (!protocol || slashedProtocol[protocol]) && host !== false) {
|
833 | host = '//' + (host || '');
|
834 | if (pathname && pathname.charAt(0) !== '/') pathname = '/' + pathname;
|
835 | } else if (!host) {
|
836 | host = '';
|
837 | }
|
838 |
|
839 | if (hash && hash.charAt(0) !== '#') hash = '#' + hash;
|
840 | if (search && search.charAt(0) !== '?') search = '?' + search;
|
841 |
|
842 | pathname = pathname.replace(/[?#]/g, function(match) {
|
843 | return encodeURIComponent(match);
|
844 | });
|
845 | search = search.replace('#', '%23');
|
846 |
|
847 | return protocol + host + pathname + search + hash;
|
848 | };
|
849 |
|
850 | function urlResolve(source, relative) {
|
851 | return urlParse(source, false, true).resolve(relative);
|
852 | }
|
853 |
|
854 | Url.prototype.resolve = function(relative) {
|
855 | return this.resolveObject(urlParse(relative, false, true)).format();
|
856 | };
|
857 |
|
858 | function urlResolveObject(source, relative) {
|
859 | if (!source) return relative;
|
860 | return urlParse(source, false, true).resolveObject(relative);
|
861 | }
|
862 |
|
863 | Url.prototype.resolveObject = function(relative) {
|
864 | if (util.isString(relative)) {
|
865 | var rel = new Url();
|
866 | rel.parse(relative, false, true);
|
867 | relative = rel;
|
868 | }
|
869 |
|
870 | var result = new Url();
|
871 | var tkeys = Object.keys(this);
|
872 | for (var tk = 0; tk < tkeys.length; tk++) {
|
873 | var tkey = tkeys[tk];
|
874 | result[tkey] = this[tkey];
|
875 | }
|
876 |
|
877 |
|
878 |
|
879 | result.hash = relative.hash;
|
880 |
|
881 |
|
882 | if (relative.href === '') {
|
883 | result.href = result.format();
|
884 | return result;
|
885 | }
|
886 |
|
887 |
|
888 | if (relative.slashes && !relative.protocol) {
|
889 |
|
890 | var rkeys = Object.keys(relative);
|
891 | for (var rk = 0; rk < rkeys.length; rk++) {
|
892 | var rkey = rkeys[rk];
|
893 | if (rkey !== 'protocol')
|
894 | result[rkey] = relative[rkey];
|
895 | }
|
896 |
|
897 |
|
898 | if (slashedProtocol[result.protocol] &&
|
899 | result.hostname && !result.pathname) {
|
900 | result.path = result.pathname = '/';
|
901 | }
|
902 |
|
903 | result.href = result.format();
|
904 | return result;
|
905 | }
|
906 |
|
907 | if (relative.protocol && relative.protocol !== result.protocol) {
|
908 |
|
909 |
|
910 |
|
911 |
|
912 |
|
913 |
|
914 |
|
915 |
|
916 | if (!slashedProtocol[relative.protocol]) {
|
917 | var keys = Object.keys(relative);
|
918 | for (var v = 0; v < keys.length; v++) {
|
919 | var k = keys[v];
|
920 | result[k] = relative[k];
|
921 | }
|
922 | result.href = result.format();
|
923 | return result;
|
924 | }
|
925 |
|
926 | result.protocol = relative.protocol;
|
927 | if (!relative.host && !hostlessProtocol[relative.protocol]) {
|
928 | var relPath = (relative.pathname || '').split('/');
|
929 | while (relPath.length && !(relative.host = relPath.shift()));
|
930 | if (!relative.host) relative.host = '';
|
931 | if (!relative.hostname) relative.hostname = '';
|
932 | if (relPath[0] !== '') relPath.unshift('');
|
933 | if (relPath.length < 2) relPath.unshift('');
|
934 | result.pathname = relPath.join('/');
|
935 | } else {
|
936 | result.pathname = relative.pathname;
|
937 | }
|
938 | result.search = relative.search;
|
939 | result.query = relative.query;
|
940 | result.host = relative.host || '';
|
941 | result.auth = relative.auth;
|
942 | result.hostname = relative.hostname || relative.host;
|
943 | result.port = relative.port;
|
944 |
|
945 | if (result.pathname || result.search) {
|
946 | var p = result.pathname || '';
|
947 | var s = result.search || '';
|
948 | result.path = p + s;
|
949 | }
|
950 | result.slashes = result.slashes || relative.slashes;
|
951 | result.href = result.format();
|
952 | return result;
|
953 | }
|
954 |
|
955 | var isSourceAbs = (result.pathname && result.pathname.charAt(0) === '/'),
|
956 | isRelAbs = (
|
957 | relative.host ||
|
958 | relative.pathname && relative.pathname.charAt(0) === '/'
|
959 | ),
|
960 | mustEndAbs = (isRelAbs || isSourceAbs ||
|
961 | (result.host && relative.pathname)),
|
962 | removeAllDots = mustEndAbs,
|
963 | srcPath = result.pathname && result.pathname.split('/') || [],
|
964 | relPath = relative.pathname && relative.pathname.split('/') || [],
|
965 | psychotic = result.protocol && !slashedProtocol[result.protocol];
|
966 |
|
967 |
|
968 |
|
969 |
|
970 |
|
971 |
|
972 | if (psychotic) {
|
973 | result.hostname = '';
|
974 | result.port = null;
|
975 | if (result.host) {
|
976 | if (srcPath[0] === '') srcPath[0] = result.host;
|
977 | else srcPath.unshift(result.host);
|
978 | }
|
979 | result.host = '';
|
980 | if (relative.protocol) {
|
981 | relative.hostname = null;
|
982 | relative.port = null;
|
983 | if (relative.host) {
|
984 | if (relPath[0] === '') relPath[0] = relative.host;
|
985 | else relPath.unshift(relative.host);
|
986 | }
|
987 | relative.host = null;
|
988 | }
|
989 | mustEndAbs = mustEndAbs && (relPath[0] === '' || srcPath[0] === '');
|
990 | }
|
991 |
|
992 | if (isRelAbs) {
|
993 |
|
994 | result.host = (relative.host || relative.host === '') ?
|
995 | relative.host : result.host;
|
996 | result.hostname = (relative.hostname || relative.hostname === '') ?
|
997 | relative.hostname : result.hostname;
|
998 | result.search = relative.search;
|
999 | result.query = relative.query;
|
1000 | srcPath = relPath;
|
1001 |
|
1002 | } else if (relPath.length) {
|
1003 |
|
1004 |
|
1005 | if (!srcPath) srcPath = [];
|
1006 | srcPath.pop();
|
1007 | srcPath = srcPath.concat(relPath);
|
1008 | result.search = relative.search;
|
1009 | result.query = relative.query;
|
1010 | } else if (!util.isNullOrUndefined(relative.search)) {
|
1011 |
|
1012 |
|
1013 |
|
1014 | if (psychotic) {
|
1015 | result.hostname = result.host = srcPath.shift();
|
1016 |
|
1017 |
|
1018 |
|
1019 | var authInHost = result.host && result.host.indexOf('@') > 0 ?
|
1020 | result.host.split('@') : false;
|
1021 | if (authInHost) {
|
1022 | result.auth = authInHost.shift();
|
1023 | result.host = result.hostname = authInHost.shift();
|
1024 | }
|
1025 | }
|
1026 | result.search = relative.search;
|
1027 | result.query = relative.query;
|
1028 |
|
1029 | if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
|
1030 | result.path = (result.pathname ? result.pathname : '') +
|
1031 | (result.search ? result.search : '');
|
1032 | }
|
1033 | result.href = result.format();
|
1034 | return result;
|
1035 | }
|
1036 |
|
1037 | if (!srcPath.length) {
|
1038 |
|
1039 |
|
1040 | result.pathname = null;
|
1041 |
|
1042 | if (result.search) {
|
1043 | result.path = '/' + result.search;
|
1044 | } else {
|
1045 | result.path = null;
|
1046 | }
|
1047 | result.href = result.format();
|
1048 | return result;
|
1049 | }
|
1050 |
|
1051 |
|
1052 |
|
1053 |
|
1054 | var last = srcPath.slice(-1)[0];
|
1055 | var hasTrailingSlash = (
|
1056 | (result.host || relative.host || srcPath.length > 1) &&
|
1057 | (last === '.' || last === '..') || last === '');
|
1058 |
|
1059 |
|
1060 |
|
1061 | var up = 0;
|
1062 | for (var i = srcPath.length; i >= 0; i--) {
|
1063 | last = srcPath[i];
|
1064 | if (last === '.') {
|
1065 | srcPath.splice(i, 1);
|
1066 | } else if (last === '..') {
|
1067 | srcPath.splice(i, 1);
|
1068 | up++;
|
1069 | } else if (up) {
|
1070 | srcPath.splice(i, 1);
|
1071 | up--;
|
1072 | }
|
1073 | }
|
1074 |
|
1075 |
|
1076 | if (!mustEndAbs && !removeAllDots) {
|
1077 | for (; up--; up) {
|
1078 | srcPath.unshift('..');
|
1079 | }
|
1080 | }
|
1081 |
|
1082 | if (mustEndAbs && srcPath[0] !== '' &&
|
1083 | (!srcPath[0] || srcPath[0].charAt(0) !== '/')) {
|
1084 | srcPath.unshift('');
|
1085 | }
|
1086 |
|
1087 | if (hasTrailingSlash && (srcPath.join('/').substr(-1) !== '/')) {
|
1088 | srcPath.push('');
|
1089 | }
|
1090 |
|
1091 | var isAbsolute = srcPath[0] === '' ||
|
1092 | (srcPath[0] && srcPath[0].charAt(0) === '/');
|
1093 |
|
1094 |
|
1095 | if (psychotic) {
|
1096 | result.hostname = result.host = isAbsolute ? '' :
|
1097 | srcPath.length ? srcPath.shift() : '';
|
1098 |
|
1099 |
|
1100 |
|
1101 | var authInHost = result.host && result.host.indexOf('@') > 0 ?
|
1102 | result.host.split('@') : false;
|
1103 | if (authInHost) {
|
1104 | result.auth = authInHost.shift();
|
1105 | result.host = result.hostname = authInHost.shift();
|
1106 | }
|
1107 | }
|
1108 |
|
1109 | mustEndAbs = mustEndAbs || (result.host && srcPath.length);
|
1110 |
|
1111 | if (mustEndAbs && !isAbsolute) {
|
1112 | srcPath.unshift('');
|
1113 | }
|
1114 |
|
1115 | if (!srcPath.length) {
|
1116 | result.pathname = null;
|
1117 | result.path = null;
|
1118 | } else {
|
1119 | result.pathname = srcPath.join('/');
|
1120 | }
|
1121 |
|
1122 |
|
1123 | if (!util.isNull(result.pathname) || !util.isNull(result.search)) {
|
1124 | result.path = (result.pathname ? result.pathname : '') +
|
1125 | (result.search ? result.search : '');
|
1126 | }
|
1127 | result.auth = relative.auth || result.auth;
|
1128 | result.slashes = result.slashes || relative.slashes;
|
1129 | result.href = result.format();
|
1130 | return result;
|
1131 | };
|
1132 |
|
1133 | Url.prototype.parseHost = function() {
|
1134 | var host = this.host;
|
1135 | var port = portPattern.exec(host);
|
1136 | if (port) {
|
1137 | port = port[0];
|
1138 | if (port !== ':') {
|
1139 | this.port = port.substr(1);
|
1140 | }
|
1141 | host = host.substr(0, host.length - port.length);
|
1142 | }
|
1143 | if (host) this.hostname = host;
|
1144 | };
|
1145 |
|
1146 | },{"./util":4,"punycode":35,"querystring":38}],4:[function(require,module,exports){
|
1147 | 'use strict';
|
1148 |
|
1149 | module.exports = {
|
1150 | isString: function(arg) {
|
1151 | return typeof(arg) === 'string';
|
1152 | },
|
1153 | isObject: function(arg) {
|
1154 | return typeof(arg) === 'object' && arg !== null;
|
1155 | },
|
1156 | isNull: function(arg) {
|
1157 | return arg === null;
|
1158 | },
|
1159 | isNullOrUndefined: function(arg) {
|
1160 | return arg == null;
|
1161 | }
|
1162 | };
|
1163 |
|
1164 | },{}],5:[function(require,module,exports){
|
1165 | module.exports = (function() {
|
1166 | |
1167 |
|
1168 |
|
1169 |
|
1170 |
|
1171 |
|
1172 | function peg$subclass(child, parent) {
|
1173 | function ctor() { this.constructor = child; }
|
1174 | ctor.prototype = parent.prototype;
|
1175 | child.prototype = new ctor();
|
1176 | }
|
1177 |
|
1178 | function SyntaxError(message, expected, found, offset, line, column) {
|
1179 | this.message = message;
|
1180 | this.expected = expected;
|
1181 | this.found = found;
|
1182 | this.offset = offset;
|
1183 | this.line = line;
|
1184 | this.column = column;
|
1185 |
|
1186 | this.name = "SyntaxError";
|
1187 | }
|
1188 |
|
1189 | peg$subclass(SyntaxError, Error);
|
1190 |
|
1191 | function parse(input) {
|
1192 | var options = arguments.length > 1 ? arguments[1] : {},
|
1193 |
|
1194 | peg$FAILED = {},
|
1195 |
|
1196 | peg$startRuleFunctions = { start: peg$parsestart },
|
1197 | peg$startRuleFunction = peg$parsestart,
|
1198 |
|
1199 | peg$c0 = [],
|
1200 | peg$c1 = function() { return []},
|
1201 | peg$c2 = peg$FAILED,
|
1202 | peg$c3 = ",",
|
1203 | peg$c4 = { type: "literal", value: ",", description: "\",\"" },
|
1204 | peg$c5 = function(x, xs) { return [x].concat(xs); },
|
1205 | peg$c6 = function(entry) { return [entry]; },
|
1206 | peg$c7 = function(url, format) { return {url: url, format: format}; },
|
1207 | peg$c8 = function(url) { return {url: url}; },
|
1208 | peg$c9 = "url(",
|
1209 | peg$c10 = { type: "literal", value: "url(", description: "\"url(\"" },
|
1210 | peg$c11 = ")",
|
1211 | peg$c12 = { type: "literal", value: ")", description: "\")\"" },
|
1212 | peg$c13 = function(value) { return value; },
|
1213 | peg$c14 = "format(",
|
1214 | peg$c15 = { type: "literal", value: "format(", description: "\"format(\"" },
|
1215 | peg$c16 = "local(",
|
1216 | peg$c17 = { type: "literal", value: "local(", description: "\"local(\"" },
|
1217 | peg$c18 = function(value) { return {local: value}; },
|
1218 | peg$c19 = /^[^)]/,
|
1219 | peg$c20 = { type: "class", value: "[^)]", description: "[^)]" },
|
1220 | peg$c21 = function(chars) { return util.extractValue(chars.join("")); },
|
1221 | peg$c22 = /^[ \t\r\n\f]/,
|
1222 | peg$c23 = { type: "class", value: "[ \\t\\r\\n\\f]", description: "[ \\t\\r\\n\\f]" },
|
1223 |
|
1224 | peg$currPos = 0,
|
1225 | peg$reportedPos = 0,
|
1226 | peg$cachedPos = 0,
|
1227 | peg$cachedPosDetails = { line: 1, column: 1, seenCR: false },
|
1228 | peg$maxFailPos = 0,
|
1229 | peg$maxFailExpected = [],
|
1230 | peg$silentFails = 0,
|
1231 |
|
1232 | peg$result;
|
1233 |
|
1234 | if ("startRule" in options) {
|
1235 | if (!(options.startRule in peg$startRuleFunctions)) {
|
1236 | throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
|
1237 | }
|
1238 |
|
1239 | peg$startRuleFunction = peg$startRuleFunctions[options.startRule];
|
1240 | }
|
1241 |
|
1242 | function text() {
|
1243 | return input.substring(peg$reportedPos, peg$currPos);
|
1244 | }
|
1245 |
|
1246 | function offset() {
|
1247 | return peg$reportedPos;
|
1248 | }
|
1249 |
|
1250 | function line() {
|
1251 | return peg$computePosDetails(peg$reportedPos).line;
|
1252 | }
|
1253 |
|
1254 | function column() {
|
1255 | return peg$computePosDetails(peg$reportedPos).column;
|
1256 | }
|
1257 |
|
1258 | function expected(description) {
|
1259 | throw peg$buildException(
|
1260 | null,
|
1261 | [{ type: "other", description: description }],
|
1262 | peg$reportedPos
|
1263 | );
|
1264 | }
|
1265 |
|
1266 | function error(message) {
|
1267 | throw peg$buildException(message, null, peg$reportedPos);
|
1268 | }
|
1269 |
|
1270 | function peg$computePosDetails(pos) {
|
1271 | function advance(details, startPos, endPos) {
|
1272 | var p, ch;
|
1273 |
|
1274 | for (p = startPos; p < endPos; p++) {
|
1275 | ch = input.charAt(p);
|
1276 | if (ch === "\n") {
|
1277 | if (!details.seenCR) { details.line++; }
|
1278 | details.column = 1;
|
1279 | details.seenCR = false;
|
1280 | } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") {
|
1281 | details.line++;
|
1282 | details.column = 1;
|
1283 | details.seenCR = true;
|
1284 | } else {
|
1285 | details.column++;
|
1286 | details.seenCR = false;
|
1287 | }
|
1288 | }
|
1289 | }
|
1290 |
|
1291 | if (peg$cachedPos !== pos) {
|
1292 | if (peg$cachedPos > pos) {
|
1293 | peg$cachedPos = 0;
|
1294 | peg$cachedPosDetails = { line: 1, column: 1, seenCR: false };
|
1295 | }
|
1296 | advance(peg$cachedPosDetails, peg$cachedPos, pos);
|
1297 | peg$cachedPos = pos;
|
1298 | }
|
1299 |
|
1300 | return peg$cachedPosDetails;
|
1301 | }
|
1302 |
|
1303 | function peg$fail(expected) {
|
1304 | if (peg$currPos < peg$maxFailPos) { return; }
|
1305 |
|
1306 | if (peg$currPos > peg$maxFailPos) {
|
1307 | peg$maxFailPos = peg$currPos;
|
1308 | peg$maxFailExpected = [];
|
1309 | }
|
1310 |
|
1311 | peg$maxFailExpected.push(expected);
|
1312 | }
|
1313 |
|
1314 | function peg$buildException(message, expected, pos) {
|
1315 | function cleanupExpected(expected) {
|
1316 | var i = 1;
|
1317 |
|
1318 | expected.sort(function(a, b) {
|
1319 | if (a.description < b.description) {
|
1320 | return -1;
|
1321 | } else if (a.description > b.description) {
|
1322 | return 1;
|
1323 | } else {
|
1324 | return 0;
|
1325 | }
|
1326 | });
|
1327 |
|
1328 | while (i < expected.length) {
|
1329 | if (expected[i - 1] === expected[i]) {
|
1330 | expected.splice(i, 1);
|
1331 | } else {
|
1332 | i++;
|
1333 | }
|
1334 | }
|
1335 | }
|
1336 |
|
1337 | function buildMessage(expected, found) {
|
1338 | function stringEscape(s) {
|
1339 | function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); }
|
1340 |
|
1341 | return s
|
1342 | .replace(/\\/g, '\\\\')
|
1343 | .replace(/"/g, '\\"')
|
1344 | .replace(/\x08/g, '\\b')
|
1345 | .replace(/\t/g, '\\t')
|
1346 | .replace(/\n/g, '\\n')
|
1347 | .replace(/\f/g, '\\f')
|
1348 | .replace(/\r/g, '\\r')
|
1349 | .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
|
1350 | .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); })
|
1351 | .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); })
|
1352 | .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); });
|
1353 | }
|
1354 |
|
1355 | var expectedDescs = new Array(expected.length),
|
1356 | expectedDesc, foundDesc, i;
|
1357 |
|
1358 | for (i = 0; i < expected.length; i++) {
|
1359 | expectedDescs[i] = expected[i].description;
|
1360 | }
|
1361 |
|
1362 | expectedDesc = expected.length > 1
|
1363 | ? expectedDescs.slice(0, -1).join(", ")
|
1364 | + " or "
|
1365 | + expectedDescs[expected.length - 1]
|
1366 | : expectedDescs[0];
|
1367 |
|
1368 | foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input";
|
1369 |
|
1370 | return "Expected " + expectedDesc + " but " + foundDesc + " found.";
|
1371 | }
|
1372 |
|
1373 | var posDetails = peg$computePosDetails(pos),
|
1374 | found = pos < input.length ? input.charAt(pos) : null;
|
1375 |
|
1376 | if (expected !== null) {
|
1377 | cleanupExpected(expected);
|
1378 | }
|
1379 |
|
1380 | return new SyntaxError(
|
1381 | message !== null ? message : buildMessage(expected, found),
|
1382 | expected,
|
1383 | found,
|
1384 | pos,
|
1385 | posDetails.line,
|
1386 | posDetails.column
|
1387 | );
|
1388 | }
|
1389 |
|
1390 | function peg$parsestart() {
|
1391 | var s0, s1;
|
1392 |
|
1393 | s0 = peg$parsesourceEntries();
|
1394 | if (s0 === peg$FAILED) {
|
1395 | s0 = peg$currPos;
|
1396 | s1 = [];
|
1397 | if (s1 !== peg$FAILED) {
|
1398 | peg$reportedPos = s0;
|
1399 | s1 = peg$c1();
|
1400 | }
|
1401 | s0 = s1;
|
1402 | }
|
1403 |
|
1404 | return s0;
|
1405 | }
|
1406 |
|
1407 | function peg$parsesourceEntries() {
|
1408 | var s0, s1, s2, s3, s4, s5;
|
1409 |
|
1410 | s0 = peg$currPos;
|
1411 | s1 = peg$parsesourceEntry();
|
1412 | if (s1 !== peg$FAILED) {
|
1413 | s2 = [];
|
1414 | s3 = peg$parsewhitespace();
|
1415 | while (s3 !== peg$FAILED) {
|
1416 | s2.push(s3);
|
1417 | s3 = peg$parsewhitespace();
|
1418 | }
|
1419 | if (s2 !== peg$FAILED) {
|
1420 | if (input.charCodeAt(peg$currPos) === 44) {
|
1421 | s3 = peg$c3;
|
1422 | peg$currPos++;
|
1423 | } else {
|
1424 | s3 = peg$FAILED;
|
1425 | if (peg$silentFails === 0) { peg$fail(peg$c4); }
|
1426 | }
|
1427 | if (s3 !== peg$FAILED) {
|
1428 | s4 = [];
|
1429 | s5 = peg$parsewhitespace();
|
1430 | while (s5 !== peg$FAILED) {
|
1431 | s4.push(s5);
|
1432 | s5 = peg$parsewhitespace();
|
1433 | }
|
1434 | if (s4 !== peg$FAILED) {
|
1435 | s5 = peg$parsesourceEntries();
|
1436 | if (s5 !== peg$FAILED) {
|
1437 | peg$reportedPos = s0;
|
1438 | s1 = peg$c5(s1, s5);
|
1439 | s0 = s1;
|
1440 | } else {
|
1441 | peg$currPos = s0;
|
1442 | s0 = peg$c2;
|
1443 | }
|
1444 | } else {
|
1445 | peg$currPos = s0;
|
1446 | s0 = peg$c2;
|
1447 | }
|
1448 | } else {
|
1449 | peg$currPos = s0;
|
1450 | s0 = peg$c2;
|
1451 | }
|
1452 | } else {
|
1453 | peg$currPos = s0;
|
1454 | s0 = peg$c2;
|
1455 | }
|
1456 | } else {
|
1457 | peg$currPos = s0;
|
1458 | s0 = peg$c2;
|
1459 | }
|
1460 | if (s0 === peg$FAILED) {
|
1461 | s0 = peg$currPos;
|
1462 | s1 = peg$parsesourceEntry();
|
1463 | if (s1 !== peg$FAILED) {
|
1464 | peg$reportedPos = s0;
|
1465 | s1 = peg$c6(s1);
|
1466 | }
|
1467 | s0 = s1;
|
1468 | }
|
1469 |
|
1470 | return s0;
|
1471 | }
|
1472 |
|
1473 | function peg$parsesourceEntry() {
|
1474 | var s0;
|
1475 |
|
1476 | s0 = peg$parseurlEntry();
|
1477 | if (s0 === peg$FAILED) {
|
1478 | s0 = peg$parselocalEntry();
|
1479 | }
|
1480 |
|
1481 | return s0;
|
1482 | }
|
1483 |
|
1484 | function peg$parseurlEntry() {
|
1485 | var s0, s1, s2, s3;
|
1486 |
|
1487 | s0 = peg$currPos;
|
1488 | s1 = peg$parseurl();
|
1489 | if (s1 !== peg$FAILED) {
|
1490 | s2 = [];
|
1491 | s3 = peg$parsewhitespace();
|
1492 | if (s3 !== peg$FAILED) {
|
1493 | while (s3 !== peg$FAILED) {
|
1494 | s2.push(s3);
|
1495 | s3 = peg$parsewhitespace();
|
1496 | }
|
1497 | } else {
|
1498 | s2 = peg$c2;
|
1499 | }
|
1500 | if (s2 !== peg$FAILED) {
|
1501 | s3 = peg$parseformat();
|
1502 | if (s3 !== peg$FAILED) {
|
1503 | peg$reportedPos = s0;
|
1504 | s1 = peg$c7(s1, s3);
|
1505 | s0 = s1;
|
1506 | } else {
|
1507 | peg$currPos = s0;
|
1508 | s0 = peg$c2;
|
1509 | }
|
1510 | } else {
|
1511 | peg$currPos = s0;
|
1512 | s0 = peg$c2;
|
1513 | }
|
1514 | } else {
|
1515 | peg$currPos = s0;
|
1516 | s0 = peg$c2;
|
1517 | }
|
1518 | if (s0 === peg$FAILED) {
|
1519 | s0 = peg$currPos;
|
1520 | s1 = peg$parseurl();
|
1521 | if (s1 !== peg$FAILED) {
|
1522 | peg$reportedPos = s0;
|
1523 | s1 = peg$c8(s1);
|
1524 | }
|
1525 | s0 = s1;
|
1526 | }
|
1527 |
|
1528 | return s0;
|
1529 | }
|
1530 |
|
1531 | function peg$parseurl() {
|
1532 | var s0, s1, s2, s3;
|
1533 |
|
1534 | s0 = peg$currPos;
|
1535 | if (input.substr(peg$currPos, 4) === peg$c9) {
|
1536 | s1 = peg$c9;
|
1537 | peg$currPos += 4;
|
1538 | } else {
|
1539 | s1 = peg$FAILED;
|
1540 | if (peg$silentFails === 0) { peg$fail(peg$c10); }
|
1541 | }
|
1542 | if (s1 !== peg$FAILED) {
|
1543 | s2 = peg$parsevalue();
|
1544 | if (s2 !== peg$FAILED) {
|
1545 | if (input.charCodeAt(peg$currPos) === 41) {
|
1546 | s3 = peg$c11;
|
1547 | peg$currPos++;
|
1548 | } else {
|
1549 | s3 = peg$FAILED;
|
1550 | if (peg$silentFails === 0) { peg$fail(peg$c12); }
|
1551 | }
|
1552 | if (s3 !== peg$FAILED) {
|
1553 | peg$reportedPos = s0;
|
1554 | s1 = peg$c13(s2);
|
1555 | s0 = s1;
|
1556 | } else {
|
1557 | peg$currPos = s0;
|
1558 | s0 = peg$c2;
|
1559 | }
|
1560 | } else {
|
1561 | peg$currPos = s0;
|
1562 | s0 = peg$c2;
|
1563 | }
|
1564 | } else {
|
1565 | peg$currPos = s0;
|
1566 | s0 = peg$c2;
|
1567 | }
|
1568 |
|
1569 | return s0;
|
1570 | }
|
1571 |
|
1572 | function peg$parseformat() {
|
1573 | var s0, s1, s2, s3;
|
1574 |
|
1575 | s0 = peg$currPos;
|
1576 | if (input.substr(peg$currPos, 7) === peg$c14) {
|
1577 | s1 = peg$c14;
|
1578 | peg$currPos += 7;
|
1579 | } else {
|
1580 | s1 = peg$FAILED;
|
1581 | if (peg$silentFails === 0) { peg$fail(peg$c15); }
|
1582 | }
|
1583 | if (s1 !== peg$FAILED) {
|
1584 | s2 = peg$parsevalue();
|
1585 | if (s2 !== peg$FAILED) {
|
1586 | if (input.charCodeAt(peg$currPos) === 41) {
|
1587 | s3 = peg$c11;
|
1588 | peg$currPos++;
|
1589 | } else {
|
1590 | s3 = peg$FAILED;
|
1591 | if (peg$silentFails === 0) { peg$fail(peg$c12); }
|
1592 | }
|
1593 | if (s3 !== peg$FAILED) {
|
1594 | peg$reportedPos = s0;
|
1595 | s1 = peg$c13(s2);
|
1596 | s0 = s1;
|
1597 | } else {
|
1598 | peg$currPos = s0;
|
1599 | s0 = peg$c2;
|
1600 | }
|
1601 | } else {
|
1602 | peg$currPos = s0;
|
1603 | s0 = peg$c2;
|
1604 | }
|
1605 | } else {
|
1606 | peg$currPos = s0;
|
1607 | s0 = peg$c2;
|
1608 | }
|
1609 |
|
1610 | return s0;
|
1611 | }
|
1612 |
|
1613 | function peg$parselocalEntry() {
|
1614 | var s0, s1, s2, s3;
|
1615 |
|
1616 | s0 = peg$currPos;
|
1617 | if (input.substr(peg$currPos, 6) === peg$c16) {
|
1618 | s1 = peg$c16;
|
1619 | peg$currPos += 6;
|
1620 | } else {
|
1621 | s1 = peg$FAILED;
|
1622 | if (peg$silentFails === 0) { peg$fail(peg$c17); }
|
1623 | }
|
1624 | if (s1 !== peg$FAILED) {
|
1625 | s2 = peg$parsevalue();
|
1626 | if (s2 !== peg$FAILED) {
|
1627 | if (input.charCodeAt(peg$currPos) === 41) {
|
1628 | s3 = peg$c11;
|
1629 | peg$currPos++;
|
1630 | } else {
|
1631 | s3 = peg$FAILED;
|
1632 | if (peg$silentFails === 0) { peg$fail(peg$c12); }
|
1633 | }
|
1634 | if (s3 !== peg$FAILED) {
|
1635 | peg$reportedPos = s0;
|
1636 | s1 = peg$c18(s2);
|
1637 | s0 = s1;
|
1638 | } else {
|
1639 | peg$currPos = s0;
|
1640 | s0 = peg$c2;
|
1641 | }
|
1642 | } else {
|
1643 | peg$currPos = s0;
|
1644 | s0 = peg$c2;
|
1645 | }
|
1646 | } else {
|
1647 | peg$currPos = s0;
|
1648 | s0 = peg$c2;
|
1649 | }
|
1650 |
|
1651 | return s0;
|
1652 | }
|
1653 |
|
1654 | function peg$parsevalue() {
|
1655 | var s0, s1, s2;
|
1656 |
|
1657 | s0 = peg$currPos;
|
1658 | s1 = [];
|
1659 | if (peg$c19.test(input.charAt(peg$currPos))) {
|
1660 | s2 = input.charAt(peg$currPos);
|
1661 | peg$currPos++;
|
1662 | } else {
|
1663 | s2 = peg$FAILED;
|
1664 | if (peg$silentFails === 0) { peg$fail(peg$c20); }
|
1665 | }
|
1666 | if (s2 !== peg$FAILED) {
|
1667 | while (s2 !== peg$FAILED) {
|
1668 | s1.push(s2);
|
1669 | if (peg$c19.test(input.charAt(peg$currPos))) {
|
1670 | s2 = input.charAt(peg$currPos);
|
1671 | peg$currPos++;
|
1672 | } else {
|
1673 | s2 = peg$FAILED;
|
1674 | if (peg$silentFails === 0) { peg$fail(peg$c20); }
|
1675 | }
|
1676 | }
|
1677 | } else {
|
1678 | s1 = peg$c2;
|
1679 | }
|
1680 | if (s1 !== peg$FAILED) {
|
1681 | peg$reportedPos = s0;
|
1682 | s1 = peg$c21(s1);
|
1683 | }
|
1684 | s0 = s1;
|
1685 |
|
1686 | return s0;
|
1687 | }
|
1688 |
|
1689 | function peg$parsewhitespace() {
|
1690 | var s0;
|
1691 |
|
1692 | if (peg$c22.test(input.charAt(peg$currPos))) {
|
1693 | s0 = input.charAt(peg$currPos);
|
1694 | peg$currPos++;
|
1695 | } else {
|
1696 | s0 = peg$FAILED;
|
1697 | if (peg$silentFails === 0) { peg$fail(peg$c23); }
|
1698 | }
|
1699 |
|
1700 | return s0;
|
1701 | }
|
1702 |
|
1703 |
|
1704 | var util = require('../util');
|
1705 |
|
1706 |
|
1707 | peg$result = peg$startRuleFunction();
|
1708 |
|
1709 | if (peg$result !== peg$FAILED && peg$currPos === input.length) {
|
1710 | return peg$result;
|
1711 | } else {
|
1712 | if (peg$result !== peg$FAILED && peg$currPos < input.length) {
|
1713 | peg$fail({ type: "end", description: "end of input" });
|
1714 | }
|
1715 |
|
1716 | throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos);
|
1717 | }
|
1718 | }
|
1719 |
|
1720 | return {
|
1721 | SyntaxError: SyntaxError,
|
1722 | parse: parse
|
1723 | };
|
1724 | })();
|
1725 |
|
1726 | },{"../util":7}],6:[function(require,module,exports){
|
1727 | var grammar = require('./grammar');
|
1728 |
|
1729 |
|
1730 | exports.SyntaxError = function (message, offset) {
|
1731 | this.message = message;
|
1732 | this.offset = offset;
|
1733 | };
|
1734 |
|
1735 | exports.parse = function (fontFaceSourceValue) {
|
1736 | try {
|
1737 | return grammar.parse(fontFaceSourceValue);
|
1738 | } catch (e) {
|
1739 | throw new exports.SyntaxError(e.message, e.offset);
|
1740 | }
|
1741 | };
|
1742 |
|
1743 | exports.serialize = function (parsedFontFaceSources) {
|
1744 | return parsedFontFaceSources.map(function (sourceItem) {
|
1745 | var itemValue;
|
1746 |
|
1747 | if (sourceItem.url) {
|
1748 | itemValue = 'url("' + sourceItem.url + '")';
|
1749 | if (sourceItem.format) {
|
1750 | itemValue += ' format("' + sourceItem.format + '")';
|
1751 | }
|
1752 | } else {
|
1753 | itemValue = 'local("' + sourceItem.local + '")';
|
1754 | }
|
1755 | return itemValue;
|
1756 | }).join(', ');
|
1757 | };
|
1758 |
|
1759 | },{"./grammar":5}],7:[function(require,module,exports){
|
1760 | var trimCSSWhitespace = function (value) {
|
1761 | var whitespaceRegex = /^[\t\r\f\n ]*(.+?)[\t\r\f\n ]*$/;
|
1762 |
|
1763 | return value.replace(whitespaceRegex, "$1");
|
1764 | };
|
1765 |
|
1766 | var unquoteString = function (quotedUrl) {
|
1767 | var doubleQuoteRegex = /^"(.*)"$/,
|
1768 | singleQuoteRegex = /^'(.*)'$/;
|
1769 |
|
1770 | if (doubleQuoteRegex.test(quotedUrl)) {
|
1771 | return quotedUrl.replace(doubleQuoteRegex, "$1");
|
1772 | } else {
|
1773 | if (singleQuoteRegex.test(quotedUrl)) {
|
1774 | return quotedUrl.replace(singleQuoteRegex, "$1");
|
1775 | } else {
|
1776 | return quotedUrl;
|
1777 | }
|
1778 | }
|
1779 | };
|
1780 |
|
1781 | exports.extractValue = function (value) {
|
1782 | return unquoteString(trimCSSWhitespace(value));
|
1783 | };
|
1784 |
|
1785 | },{}],8:[function(require,module,exports){
|
1786 |
|
1787 |
|
1788 |
|
1789 |
|
1790 |
|
1791 |
|
1792 | 'use strict';
|
1793 |
|
1794 | exports.match = matchQuery;
|
1795 | exports.parse = parseQuery;
|
1796 |
|
1797 |
|
1798 |
|
1799 | var RE_MEDIA_QUERY = /(?:(only|not)?\s*([^\s\(\)]+)(?:\s*and)?\s*)?(.+)?/i,
|
1800 | RE_MQ_EXPRESSION = /\(\s*([^\s\:\)]+)\s*(?:\:\s*([^\s\)]+))?\s*\)/,
|
1801 | RE_MQ_FEATURE = /^(?:(min|max)-)?(.+)/,
|
1802 | RE_LENGTH_UNIT = /(em|rem|px|cm|mm|in|pt|pc)?$/,
|
1803 | RE_RESOLUTION_UNIT = /(dpi|dpcm|dppx)?$/;
|
1804 |
|
1805 | function matchQuery(mediaQuery, values) {
|
1806 | return parseQuery(mediaQuery).some(function (query) {
|
1807 | var inverse = query.inverse;
|
1808 |
|
1809 |
|
1810 |
|
1811 | var typeMatch = query.type === 'all' || values.type === query.type;
|
1812 |
|
1813 |
|
1814 | if ((typeMatch && inverse) || !(typeMatch || inverse)) {
|
1815 | return false;
|
1816 | }
|
1817 |
|
1818 | var expressionsMatch = query.expressions.every(function (expression) {
|
1819 | var feature = expression.feature,
|
1820 | modifier = expression.modifier,
|
1821 | expValue = expression.value,
|
1822 | value = values[feature];
|
1823 |
|
1824 |
|
1825 | if (!value) { return false; }
|
1826 |
|
1827 | switch (feature) {
|
1828 | case 'orientation':
|
1829 | case 'scan':
|
1830 | return value.toLowerCase() === expValue.toLowerCase();
|
1831 |
|
1832 | case 'width':
|
1833 | case 'height':
|
1834 | case 'device-width':
|
1835 | case 'device-height':
|
1836 | expValue = toPx(expValue);
|
1837 | value = toPx(value);
|
1838 | break;
|
1839 |
|
1840 | case 'resolution':
|
1841 | expValue = toDpi(expValue);
|
1842 | value = toDpi(value);
|
1843 | break;
|
1844 |
|
1845 | case 'aspect-ratio':
|
1846 | case 'device-aspect-ratio':
|
1847 | case 'device-pixel-ratio':
|
1848 | expValue = toDecimal(expValue);
|
1849 | value = toDecimal(value);
|
1850 | break;
|
1851 |
|
1852 | case 'grid':
|
1853 | case 'color':
|
1854 | case 'color-index':
|
1855 | case 'monochrome':
|
1856 | expValue = parseInt(expValue, 10) || 1;
|
1857 | value = parseInt(value, 10) || 0;
|
1858 | break;
|
1859 | }
|
1860 |
|
1861 | switch (modifier) {
|
1862 | case 'min': return value >= expValue;
|
1863 | case 'max': return value <= expValue;
|
1864 | default : return value === expValue;
|
1865 | }
|
1866 | });
|
1867 |
|
1868 | return (expressionsMatch && !inverse) || (!expressionsMatch && inverse);
|
1869 | });
|
1870 | }
|
1871 |
|
1872 | function parseQuery(mediaQuery) {
|
1873 | return mediaQuery.split(',').map(function (query) {
|
1874 | query = query.trim();
|
1875 |
|
1876 | var captures = query.match(RE_MEDIA_QUERY),
|
1877 | modifier = captures[1],
|
1878 | type = captures[2],
|
1879 | expressions = captures[3] || '',
|
1880 | parsed = {};
|
1881 |
|
1882 | parsed.inverse = !!modifier && modifier.toLowerCase() === 'not';
|
1883 | parsed.type = type ? type.toLowerCase() : 'all';
|
1884 |
|
1885 |
|
1886 | expressions = expressions.match(/\([^\)]+\)/g) || [];
|
1887 |
|
1888 | parsed.expressions = expressions.map(function (expression) {
|
1889 | var captures = expression.match(RE_MQ_EXPRESSION),
|
1890 | feature = captures[1].toLowerCase().match(RE_MQ_FEATURE);
|
1891 |
|
1892 | return {
|
1893 | modifier: feature[1],
|
1894 | feature : feature[2],
|
1895 | value : captures[2]
|
1896 | };
|
1897 | });
|
1898 |
|
1899 | return parsed;
|
1900 | });
|
1901 | }
|
1902 |
|
1903 |
|
1904 |
|
1905 | function toDecimal(ratio) {
|
1906 | var decimal = Number(ratio),
|
1907 | numbers;
|
1908 |
|
1909 | if (!decimal) {
|
1910 | numbers = ratio.match(/^(\d+)\s*\/\s*(\d+)$/);
|
1911 | decimal = numbers[1] / numbers[2];
|
1912 | }
|
1913 |
|
1914 | return decimal;
|
1915 | }
|
1916 |
|
1917 | function toDpi(resolution) {
|
1918 | var value = parseFloat(resolution),
|
1919 | units = String(resolution).match(RE_RESOLUTION_UNIT)[1];
|
1920 |
|
1921 | switch (units) {
|
1922 | case 'dpcm': return value / 2.54;
|
1923 | case 'dppx': return value * 96;
|
1924 | default : return value;
|
1925 | }
|
1926 | }
|
1927 |
|
1928 | function toPx(length) {
|
1929 | var value = parseFloat(length),
|
1930 | units = String(length).match(RE_LENGTH_UNIT)[1];
|
1931 |
|
1932 | switch (units) {
|
1933 | case 'em' : return value * 16;
|
1934 | case 'rem': return value * 16;
|
1935 | case 'cm' : return value * 96 / 2.54;
|
1936 | case 'mm' : return value * 96 / 2.54 / 10;
|
1937 | case 'in' : return value * 96;
|
1938 | case 'pt' : return value * 72;
|
1939 | case 'pc' : return value * 72 / 12;
|
1940 | default : return value;
|
1941 | }
|
1942 | }
|
1943 |
|
1944 | },{}],9:[function(require,module,exports){
|
1945 |
|
1946 | var CSSOM = {
|
1947 | CSSRule: require("./CSSRule").CSSRule,
|
1948 | MatcherList: require("./MatcherList").MatcherList
|
1949 | };
|
1950 |
|
1951 |
|
1952 |
|
1953 |
|
1954 |
|
1955 |
|
1956 |
|
1957 | CSSOM.CSSDocumentRule = function CSSDocumentRule() {
|
1958 | CSSOM.CSSRule.call(this);
|
1959 | this.matcher = new CSSOM.MatcherList();
|
1960 | this.cssRules = [];
|
1961 | };
|
1962 |
|
1963 | CSSOM.CSSDocumentRule.prototype = new CSSOM.CSSRule();
|
1964 | CSSOM.CSSDocumentRule.prototype.constructor = CSSOM.CSSDocumentRule;
|
1965 | CSSOM.CSSDocumentRule.prototype.type = 10;
|
1966 |
|
1967 |
|
1968 |
|
1969 |
|
1970 | Object.defineProperty(CSSOM.CSSDocumentRule.prototype, "cssText", {
|
1971 | get: function() {
|
1972 | var cssTexts = [];
|
1973 | for (var i=0, length=this.cssRules.length; i < length; i++) {
|
1974 | cssTexts.push(this.cssRules[i].cssText);
|
1975 | }
|
1976 | return "@-moz-document " + this.matcher.matcherText + " {" + cssTexts.join("") + "}";
|
1977 | }
|
1978 | });
|
1979 |
|
1980 |
|
1981 |
|
1982 | exports.CSSDocumentRule = CSSOM.CSSDocumentRule;
|
1983 |
|
1984 |
|
1985 | },{"./CSSRule":16,"./MatcherList":22}],10:[function(require,module,exports){
|
1986 |
|
1987 | var CSSOM = {
|
1988 | CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
|
1989 | CSSRule: require("./CSSRule").CSSRule
|
1990 | };
|
1991 |
|
1992 |
|
1993 |
|
1994 |
|
1995 |
|
1996 |
|
1997 |
|
1998 | CSSOM.CSSFontFaceRule = function CSSFontFaceRule() {
|
1999 | CSSOM.CSSRule.call(this);
|
2000 | this.style = new CSSOM.CSSStyleDeclaration();
|
2001 | this.style.parentRule = this;
|
2002 | };
|
2003 |
|
2004 | CSSOM.CSSFontFaceRule.prototype = new CSSOM.CSSRule();
|
2005 | CSSOM.CSSFontFaceRule.prototype.constructor = CSSOM.CSSFontFaceRule;
|
2006 | CSSOM.CSSFontFaceRule.prototype.type = 5;
|
2007 |
|
2008 |
|
2009 |
|
2010 |
|
2011 |
|
2012 | Object.defineProperty(CSSOM.CSSFontFaceRule.prototype, "cssText", {
|
2013 | get: function() {
|
2014 | return "@font-face {" + this.style.cssText + "}";
|
2015 | }
|
2016 | });
|
2017 |
|
2018 |
|
2019 |
|
2020 | exports.CSSFontFaceRule = CSSOM.CSSFontFaceRule;
|
2021 |
|
2022 |
|
2023 | },{"./CSSRule":16,"./CSSStyleDeclaration":17}],11:[function(require,module,exports){
|
2024 |
|
2025 | var CSSOM = {
|
2026 | CSSRule: require("./CSSRule").CSSRule
|
2027 | };
|
2028 |
|
2029 |
|
2030 |
|
2031 |
|
2032 |
|
2033 |
|
2034 |
|
2035 | CSSOM.CSSHostRule = function CSSHostRule() {
|
2036 | CSSOM.CSSRule.call(this);
|
2037 | this.cssRules = [];
|
2038 | };
|
2039 |
|
2040 | CSSOM.CSSHostRule.prototype = new CSSOM.CSSRule();
|
2041 | CSSOM.CSSHostRule.prototype.constructor = CSSOM.CSSHostRule;
|
2042 | CSSOM.CSSHostRule.prototype.type = 1001;
|
2043 |
|
2044 |
|
2045 |
|
2046 |
|
2047 | Object.defineProperty(CSSOM.CSSHostRule.prototype, "cssText", {
|
2048 | get: function() {
|
2049 | var cssTexts = [];
|
2050 | for (var i=0, length=this.cssRules.length; i < length; i++) {
|
2051 | cssTexts.push(this.cssRules[i].cssText);
|
2052 | }
|
2053 | return "@host {" + cssTexts.join("") + "}";
|
2054 | }
|
2055 | });
|
2056 |
|
2057 |
|
2058 |
|
2059 | exports.CSSHostRule = CSSOM.CSSHostRule;
|
2060 |
|
2061 |
|
2062 | },{"./CSSRule":16}],12:[function(require,module,exports){
|
2063 |
|
2064 | var CSSOM = {
|
2065 | CSSRule: require("./CSSRule").CSSRule,
|
2066 | CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet,
|
2067 | MediaList: require("./MediaList").MediaList
|
2068 | };
|
2069 |
|
2070 |
|
2071 |
|
2072 |
|
2073 |
|
2074 |
|
2075 |
|
2076 |
|
2077 | CSSOM.CSSImportRule = function CSSImportRule() {
|
2078 | CSSOM.CSSRule.call(this);
|
2079 | this.href = "";
|
2080 | this.media = new CSSOM.MediaList();
|
2081 | this.styleSheet = new CSSOM.CSSStyleSheet();
|
2082 | };
|
2083 |
|
2084 | CSSOM.CSSImportRule.prototype = new CSSOM.CSSRule();
|
2085 | CSSOM.CSSImportRule.prototype.constructor = CSSOM.CSSImportRule;
|
2086 | CSSOM.CSSImportRule.prototype.type = 3;
|
2087 |
|
2088 | Object.defineProperty(CSSOM.CSSImportRule.prototype, "cssText", {
|
2089 | get: function() {
|
2090 | var mediaText = this.media.mediaText;
|
2091 | return "@import url(" + this.href + ")" + (mediaText ? " " + mediaText : "") + ";";
|
2092 | },
|
2093 | set: function(cssText) {
|
2094 | var i = 0;
|
2095 |
|
2096 | |
2097 |
|
2098 |
|
2099 |
|
2100 |
|
2101 |
|
2102 |
|
2103 | var state = '';
|
2104 |
|
2105 | var buffer = '';
|
2106 | var index;
|
2107 | for (var character; (character = cssText.charAt(i)); i++) {
|
2108 |
|
2109 | switch (character) {
|
2110 | case ' ':
|
2111 | case '\t':
|
2112 | case '\r':
|
2113 | case '\n':
|
2114 | case '\f':
|
2115 | if (state === 'after-import') {
|
2116 | state = 'url';
|
2117 | } else {
|
2118 | buffer += character;
|
2119 | }
|
2120 | break;
|
2121 |
|
2122 | case '@':
|
2123 | if (!state && cssText.indexOf('@import', i) === i) {
|
2124 | state = 'after-import';
|
2125 | i += 'import'.length;
|
2126 | buffer = '';
|
2127 | }
|
2128 | break;
|
2129 |
|
2130 | case 'u':
|
2131 | if (state === 'url' && cssText.indexOf('url(', i) === i) {
|
2132 | index = cssText.indexOf(')', i + 1);
|
2133 | if (index === -1) {
|
2134 | throw i + ': ")" not found';
|
2135 | }
|
2136 | i += 'url('.length;
|
2137 | var url = cssText.slice(i, index);
|
2138 | if (url[0] === url[url.length - 1]) {
|
2139 | if (url[0] === '"' || url[0] === "'") {
|
2140 | url = url.slice(1, -1);
|
2141 | }
|
2142 | }
|
2143 | this.href = url;
|
2144 | i = index;
|
2145 | state = 'media';
|
2146 | }
|
2147 | break;
|
2148 |
|
2149 | case '"':
|
2150 | if (state === 'url') {
|
2151 | index = cssText.indexOf('"', i + 1);
|
2152 | if (!index) {
|
2153 | throw i + ": '\"' not found";
|
2154 | }
|
2155 | this.href = cssText.slice(i + 1, index);
|
2156 | i = index;
|
2157 | state = 'media';
|
2158 | }
|
2159 | break;
|
2160 |
|
2161 | case "'":
|
2162 | if (state === 'url') {
|
2163 | index = cssText.indexOf("'", i + 1);
|
2164 | if (!index) {
|
2165 | throw i + ': "\'" not found';
|
2166 | }
|
2167 | this.href = cssText.slice(i + 1, index);
|
2168 | i = index;
|
2169 | state = 'media';
|
2170 | }
|
2171 | break;
|
2172 |
|
2173 | case ';':
|
2174 | if (state === 'media') {
|
2175 | if (buffer) {
|
2176 | this.media.mediaText = buffer.trim();
|
2177 | }
|
2178 | }
|
2179 | break;
|
2180 |
|
2181 | default:
|
2182 | if (state === 'media') {
|
2183 | buffer += character;
|
2184 | }
|
2185 | break;
|
2186 | }
|
2187 | }
|
2188 | }
|
2189 | });
|
2190 |
|
2191 |
|
2192 |
|
2193 | exports.CSSImportRule = CSSOM.CSSImportRule;
|
2194 |
|
2195 |
|
2196 | },{"./CSSRule":16,"./CSSStyleSheet":19,"./MediaList":23}],13:[function(require,module,exports){
|
2197 |
|
2198 | var CSSOM = {
|
2199 | CSSRule: require("./CSSRule").CSSRule,
|
2200 | CSSStyleDeclaration: require('./CSSStyleDeclaration').CSSStyleDeclaration
|
2201 | };
|
2202 |
|
2203 |
|
2204 |
|
2205 |
|
2206 |
|
2207 |
|
2208 |
|
2209 | CSSOM.CSSKeyframeRule = function CSSKeyframeRule() {
|
2210 | CSSOM.CSSRule.call(this);
|
2211 | this.keyText = '';
|
2212 | this.style = new CSSOM.CSSStyleDeclaration();
|
2213 | this.style.parentRule = this;
|
2214 | };
|
2215 |
|
2216 | CSSOM.CSSKeyframeRule.prototype = new CSSOM.CSSRule();
|
2217 | CSSOM.CSSKeyframeRule.prototype.constructor = CSSOM.CSSKeyframeRule;
|
2218 | CSSOM.CSSKeyframeRule.prototype.type = 9;
|
2219 |
|
2220 |
|
2221 |
|
2222 |
|
2223 |
|
2224 | Object.defineProperty(CSSOM.CSSKeyframeRule.prototype, "cssText", {
|
2225 | get: function() {
|
2226 | return this.keyText + " {" + this.style.cssText + "} ";
|
2227 | }
|
2228 | });
|
2229 |
|
2230 |
|
2231 |
|
2232 | exports.CSSKeyframeRule = CSSOM.CSSKeyframeRule;
|
2233 |
|
2234 |
|
2235 | },{"./CSSRule":16,"./CSSStyleDeclaration":17}],14:[function(require,module,exports){
|
2236 |
|
2237 | var CSSOM = {
|
2238 | CSSRule: require("./CSSRule").CSSRule
|
2239 | };
|
2240 |
|
2241 |
|
2242 |
|
2243 |
|
2244 |
|
2245 |
|
2246 |
|
2247 | CSSOM.CSSKeyframesRule = function CSSKeyframesRule() {
|
2248 | CSSOM.CSSRule.call(this);
|
2249 | this.name = '';
|
2250 | this.cssRules = [];
|
2251 | };
|
2252 |
|
2253 | CSSOM.CSSKeyframesRule.prototype = new CSSOM.CSSRule();
|
2254 | CSSOM.CSSKeyframesRule.prototype.constructor = CSSOM.CSSKeyframesRule;
|
2255 | CSSOM.CSSKeyframesRule.prototype.type = 8;
|
2256 |
|
2257 |
|
2258 |
|
2259 |
|
2260 |
|
2261 | Object.defineProperty(CSSOM.CSSKeyframesRule.prototype, "cssText", {
|
2262 | get: function() {
|
2263 | var cssTexts = [];
|
2264 | for (var i=0, length=this.cssRules.length; i < length; i++) {
|
2265 | cssTexts.push(" " + this.cssRules[i].cssText);
|
2266 | }
|
2267 | return "@" + (this._vendorPrefix || '') + "keyframes " + this.name + " { \n" + cssTexts.join("\n") + "\n}";
|
2268 | }
|
2269 | });
|
2270 |
|
2271 |
|
2272 |
|
2273 | exports.CSSKeyframesRule = CSSOM.CSSKeyframesRule;
|
2274 |
|
2275 |
|
2276 | },{"./CSSRule":16}],15:[function(require,module,exports){
|
2277 |
|
2278 | var CSSOM = {
|
2279 | CSSRule: require("./CSSRule").CSSRule,
|
2280 | MediaList: require("./MediaList").MediaList
|
2281 | };
|
2282 |
|
2283 |
|
2284 |
|
2285 |
|
2286 |
|
2287 |
|
2288 |
|
2289 |
|
2290 | CSSOM.CSSMediaRule = function CSSMediaRule() {
|
2291 | CSSOM.CSSRule.call(this);
|
2292 | this.media = new CSSOM.MediaList();
|
2293 | this.cssRules = [];
|
2294 | };
|
2295 |
|
2296 | CSSOM.CSSMediaRule.prototype = new CSSOM.CSSRule();
|
2297 | CSSOM.CSSMediaRule.prototype.constructor = CSSOM.CSSMediaRule;
|
2298 | CSSOM.CSSMediaRule.prototype.type = 4;
|
2299 |
|
2300 |
|
2301 |
|
2302 |
|
2303 |
|
2304 | Object.defineProperty(CSSOM.CSSMediaRule.prototype, "cssText", {
|
2305 | get: function() {
|
2306 | var cssTexts = [];
|
2307 | for (var i=0, length=this.cssRules.length; i < length; i++) {
|
2308 | cssTexts.push(this.cssRules[i].cssText);
|
2309 | }
|
2310 | return "@media " + this.media.mediaText + " {" + cssTexts.join("") + "}";
|
2311 | }
|
2312 | });
|
2313 |
|
2314 |
|
2315 |
|
2316 | exports.CSSMediaRule = CSSOM.CSSMediaRule;
|
2317 |
|
2318 |
|
2319 | },{"./CSSRule":16,"./MediaList":23}],16:[function(require,module,exports){
|
2320 |
|
2321 | var CSSOM = {};
|
2322 |
|
2323 |
|
2324 |
|
2325 |
|
2326 |
|
2327 |
|
2328 |
|
2329 |
|
2330 | CSSOM.CSSRule = function CSSRule() {
|
2331 | this.parentRule = null;
|
2332 | this.parentStyleSheet = null;
|
2333 | };
|
2334 |
|
2335 | CSSOM.CSSRule.UNKNOWN_RULE = 0;
|
2336 | CSSOM.CSSRule.STYLE_RULE = 1;
|
2337 | CSSOM.CSSRule.CHARSET_RULE = 2;
|
2338 | CSSOM.CSSRule.IMPORT_RULE = 3;
|
2339 | CSSOM.CSSRule.MEDIA_RULE = 4;
|
2340 | CSSOM.CSSRule.FONT_FACE_RULE = 5;
|
2341 | CSSOM.CSSRule.PAGE_RULE = 6;
|
2342 | CSSOM.CSSRule.KEYFRAMES_RULE = 7;
|
2343 | CSSOM.CSSRule.KEYFRAME_RULE = 8;
|
2344 | CSSOM.CSSRule.MARGIN_RULE = 9;
|
2345 | CSSOM.CSSRule.NAMESPACE_RULE = 10;
|
2346 | CSSOM.CSSRule.COUNTER_STYLE_RULE = 11;
|
2347 | CSSOM.CSSRule.SUPPORTS_RULE = 12;
|
2348 | CSSOM.CSSRule.DOCUMENT_RULE = 13;
|
2349 | CSSOM.CSSRule.FONT_FEATURE_VALUES_RULE = 14;
|
2350 | CSSOM.CSSRule.VIEWPORT_RULE = 15;
|
2351 | CSSOM.CSSRule.REGION_STYLE_RULE = 16;
|
2352 |
|
2353 |
|
2354 | CSSOM.CSSRule.prototype = {
|
2355 | constructor: CSSOM.CSSRule
|
2356 | //FIXME
|
2357 | };
|
2358 |
|
2359 |
|
2360 | //.CommonJS
|
2361 | exports.CSSRule = CSSOM.CSSRule;
|
2362 | ///CommonJS
|
2363 |
|
2364 | },{}],17:[function(require,module,exports){
|
2365 |
|
2366 | var CSSOM = {};
|
2367 |
|
2368 |
|
2369 |
|
2370 |
|
2371 |
|
2372 |
|
2373 |
|
2374 | CSSOM.CSSStyleDeclaration = function CSSStyleDeclaration(){
|
2375 | this.length = 0;
|
2376 | this.parentRule = null;
|
2377 |
|
2378 |
|
2379 | this._importants = {};
|
2380 | };
|
2381 |
|
2382 |
|
2383 | CSSOM.CSSStyleDeclaration.prototype = {
|
2384 |
|
2385 | constructor: CSSOM.CSSStyleDeclaration,
|
2386 |
|
2387 | /**
|
2388 | *
|
2389 | * @param {string} name
|
2390 | * @see http:
|
2391 | * @return {string} the value of the property if it has been explicitly set for this declaration block.
|
2392 | * Returns the empty string if the property has not been set.
|
2393 | */
|
2394 | getPropertyValue: function(name) {
|
2395 | return this[name] || "";
|
2396 | },
|
2397 |
|
2398 | |
2399 |
|
2400 |
|
2401 |
|
2402 |
|
2403 |
|
2404 |
|
2405 | setProperty: function(name, value, priority) {
|
2406 | if (this[name]) {
|
2407 |
|
2408 | var index = Array.prototype.indexOf.call(this, name);
|
2409 | if (index < 0) {
|
2410 | this[this.length] = name;
|
2411 | this.length++;
|
2412 | }
|
2413 | } else {
|
2414 |
|
2415 | this[this.length] = name;
|
2416 | this.length++;
|
2417 | }
|
2418 | this[name] = value + "";
|
2419 | this._importants[name] = priority;
|
2420 | },
|
2421 |
|
2422 | |
2423 |
|
2424 |
|
2425 |
|
2426 |
|
2427 |
|
2428 |
|
2429 | removeProperty: function(name) {
|
2430 | if (!(name in this)) {
|
2431 | return "";
|
2432 | }
|
2433 | var index = Array.prototype.indexOf.call(this, name);
|
2434 | if (index < 0) {
|
2435 | return "";
|
2436 | }
|
2437 | var prevValue = this[name];
|
2438 | this[name] = "";
|
2439 |
|
2440 |
|
2441 | Array.prototype.splice.call(this, index, 1);
|
2442 |
|
2443 |
|
2444 |
|
2445 |
|
2446 | return prevValue;
|
2447 | },
|
2448 |
|
2449 | getPropertyCSSValue: function() {
|
2450 |
|
2451 | },
|
2452 |
|
2453 | |
2454 |
|
2455 |
|
2456 |
|
2457 | getPropertyPriority: function(name) {
|
2458 | return this._importants[name] || "";
|
2459 | },
|
2460 |
|
2461 |
|
2462 | |
2463 |
|
2464 |
|
2465 |
|
2466 |
|
2467 | getPropertyShorthand: function() {
|
2468 |
|
2469 | },
|
2470 |
|
2471 | isPropertyImplicit: function() {
|
2472 |
|
2473 | },
|
2474 |
|
2475 |
|
2476 | get cssText(){
|
2477 | var properties = [];
|
2478 | for (var i=0, length=this.length; i < length; ++i) {
|
2479 | var name = this[i];
|
2480 | var value = this.getPropertyValue(name);
|
2481 | var priority = this.getPropertyPriority(name);
|
2482 | if (priority) {
|
2483 | priority = " !" + priority;
|
2484 | }
|
2485 | properties[i] = name + ": " + value + priority + ";";
|
2486 | }
|
2487 | return properties.join(" ");
|
2488 | },
|
2489 |
|
2490 | set cssText(text){
|
2491 | var i, name;
|
2492 | for (i = this.length; i--;) {
|
2493 | name = this[i];
|
2494 | this[name] = "";
|
2495 | }
|
2496 | Array.prototype.splice.call(this, 0, this.length);
|
2497 | this._importants = {};
|
2498 |
|
2499 | var dummyRule = CSSOM.parse('#bogus{' + text + '}').cssRules[0].style;
|
2500 | var length = dummyRule.length;
|
2501 | for (i = 0; i < length; ++i) {
|
2502 | name = dummyRule[i];
|
2503 | this.setProperty(dummyRule[i], dummyRule.getPropertyValue(name), dummyRule.getPropertyPriority(name));
|
2504 | }
|
2505 | }
|
2506 | };
|
2507 |
|
2508 |
|
2509 |
|
2510 | exports.CSSStyleDeclaration = CSSOM.CSSStyleDeclaration;
|
2511 | CSSOM.parse = require('./parse').parse;
|
2512 |
|
2513 |
|
2514 | },{"./parse":27}],18:[function(require,module,exports){
|
2515 |
|
2516 | var CSSOM = {
|
2517 | CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
|
2518 | CSSRule: require("./CSSRule").CSSRule
|
2519 | };
|
2520 |
|
2521 |
|
2522 |
|
2523 |
|
2524 |
|
2525 |
|
2526 |
|
2527 |
|
2528 | CSSOM.CSSStyleRule = function CSSStyleRule() {
|
2529 | CSSOM.CSSRule.call(this);
|
2530 | this.selectorText = "";
|
2531 | this.style = new CSSOM.CSSStyleDeclaration();
|
2532 | this.style.parentRule = this;
|
2533 | };
|
2534 |
|
2535 | CSSOM.CSSStyleRule.prototype = new CSSOM.CSSRule();
|
2536 | CSSOM.CSSStyleRule.prototype.constructor = CSSOM.CSSStyleRule;
|
2537 | CSSOM.CSSStyleRule.prototype.type = 1;
|
2538 |
|
2539 | Object.defineProperty(CSSOM.CSSStyleRule.prototype, "cssText", {
|
2540 | get: function() {
|
2541 | var text;
|
2542 | if (this.selectorText) {
|
2543 | text = this.selectorText + " {" + this.style.cssText + "}";
|
2544 | } else {
|
2545 | text = "";
|
2546 | }
|
2547 | return text;
|
2548 | },
|
2549 | set: function(cssText) {
|
2550 | var rule = CSSOM.CSSStyleRule.parse(cssText);
|
2551 | this.style = rule.style;
|
2552 | this.selectorText = rule.selectorText;
|
2553 | }
|
2554 | });
|
2555 |
|
2556 |
|
2557 |
|
2558 |
|
2559 |
|
2560 |
|
2561 |
|
2562 |
|
2563 | CSSOM.CSSStyleRule.parse = function(ruleText) {
|
2564 | var i = 0;
|
2565 | var state = "selector";
|
2566 | var index;
|
2567 | var j = i;
|
2568 | var buffer = "";
|
2569 |
|
2570 | var SIGNIFICANT_WHITESPACE = {
|
2571 | "selector": true,
|
2572 | "value": true
|
2573 | };
|
2574 |
|
2575 | var styleRule = new CSSOM.CSSStyleRule();
|
2576 | var name, priority="";
|
2577 |
|
2578 | for (var character; (character = ruleText.charAt(i)); i++) {
|
2579 |
|
2580 | switch (character) {
|
2581 |
|
2582 | case " ":
|
2583 | case "\t":
|
2584 | case "\r":
|
2585 | case "\n":
|
2586 | case "\f":
|
2587 | if (SIGNIFICANT_WHITESPACE[state]) {
|
2588 |
|
2589 | switch (ruleText.charAt(i - 1)) {
|
2590 | case " ":
|
2591 | case "\t":
|
2592 | case "\r":
|
2593 | case "\n":
|
2594 | case "\f":
|
2595 | break;
|
2596 | default:
|
2597 | buffer += " ";
|
2598 | break;
|
2599 | }
|
2600 | }
|
2601 | break;
|
2602 |
|
2603 |
|
2604 | case '"':
|
2605 | j = i + 1;
|
2606 | index = ruleText.indexOf('"', j) + 1;
|
2607 | if (!index) {
|
2608 | throw '" is missing';
|
2609 | }
|
2610 | buffer += ruleText.slice(i, index);
|
2611 | i = index - 1;
|
2612 | break;
|
2613 |
|
2614 | case "'":
|
2615 | j = i + 1;
|
2616 | index = ruleText.indexOf("'", j) + 1;
|
2617 | if (!index) {
|
2618 | throw "' is missing";
|
2619 | }
|
2620 | buffer += ruleText.slice(i, index);
|
2621 | i = index - 1;
|
2622 | break;
|
2623 |
|
2624 |
|
2625 | case "/":
|
2626 | if (ruleText.charAt(i + 1) === "*") {
|
2627 | i += 2;
|
2628 | index = ruleText.indexOf("*/", i);
|
2629 | if (index === -1) {
|
2630 | throw new SyntaxError("Missing */");
|
2631 | } else {
|
2632 | i = index + 1;
|
2633 | }
|
2634 | } else {
|
2635 | buffer += character;
|
2636 | }
|
2637 | break;
|
2638 |
|
2639 | case "{":
|
2640 | if (state === "selector") {
|
2641 | styleRule.selectorText = buffer.trim();
|
2642 | buffer = "";
|
2643 | state = "name";
|
2644 | }
|
2645 | break;
|
2646 |
|
2647 | case ":":
|
2648 | if (state === "name") {
|
2649 | name = buffer.trim();
|
2650 | buffer = "";
|
2651 | state = "value";
|
2652 | } else {
|
2653 | buffer += character;
|
2654 | }
|
2655 | break;
|
2656 |
|
2657 | case "!":
|
2658 | if (state === "value" && ruleText.indexOf("!important", i) === i) {
|
2659 | priority = "important";
|
2660 | i += "important".length;
|
2661 | } else {
|
2662 | buffer += character;
|
2663 | }
|
2664 | break;
|
2665 |
|
2666 | case ";":
|
2667 | if (state === "value") {
|
2668 | styleRule.style.setProperty(name, buffer.trim(), priority);
|
2669 | priority = "";
|
2670 | buffer = "";
|
2671 | state = "name";
|
2672 | } else {
|
2673 | buffer += character;
|
2674 | }
|
2675 | break;
|
2676 |
|
2677 | case "}":
|
2678 | if (state === "value") {
|
2679 | styleRule.style.setProperty(name, buffer.trim(), priority);
|
2680 | priority = "";
|
2681 | buffer = "";
|
2682 | } else if (state === "name") {
|
2683 | break;
|
2684 | } else {
|
2685 | buffer += character;
|
2686 | }
|
2687 | state = "selector";
|
2688 | break;
|
2689 |
|
2690 | default:
|
2691 | buffer += character;
|
2692 | break;
|
2693 |
|
2694 | }
|
2695 | }
|
2696 |
|
2697 | return styleRule;
|
2698 |
|
2699 | };
|
2700 |
|
2701 |
|
2702 |
|
2703 | exports.CSSStyleRule = CSSOM.CSSStyleRule;
|
2704 |
|
2705 |
|
2706 | },{"./CSSRule":16,"./CSSStyleDeclaration":17}],19:[function(require,module,exports){
|
2707 |
|
2708 | var CSSOM = {
|
2709 | StyleSheet: require("./StyleSheet").StyleSheet,
|
2710 | CSSStyleRule: require("./CSSStyleRule").CSSStyleRule
|
2711 | };
|
2712 |
|
2713 |
|
2714 |
|
2715 |
|
2716 |
|
2717 |
|
2718 |
|
2719 | CSSOM.CSSStyleSheet = function CSSStyleSheet() {
|
2720 | CSSOM.StyleSheet.call(this);
|
2721 | this.cssRules = [];
|
2722 | };
|
2723 |
|
2724 |
|
2725 | CSSOM.CSSStyleSheet.prototype = new CSSOM.StyleSheet();
|
2726 | CSSOM.CSSStyleSheet.prototype.constructor = CSSOM.CSSStyleSheet;
|
2727 |
|
2728 |
|
2729 |
|
2730 |
|
2731 |
|
2732 |
|
2733 |
|
2734 |
|
2735 |
|
2736 |
|
2737 |
|
2738 |
|
2739 |
|
2740 |
|
2741 |
|
2742 |
|
2743 |
|
2744 |
|
2745 | CSSOM.CSSStyleSheet.prototype.insertRule = function(rule, index) {
|
2746 | if (index < 0 || index > this.cssRules.length) {
|
2747 | throw new RangeError("INDEX_SIZE_ERR");
|
2748 | }
|
2749 | var cssRule = CSSOM.parse(rule).cssRules[0];
|
2750 | cssRule.parentStyleSheet = this;
|
2751 | this.cssRules.splice(index, 0, cssRule);
|
2752 | return index;
|
2753 | };
|
2754 |
|
2755 |
|
2756 |
|
2757 |
|
2758 |
|
2759 |
|
2760 |
|
2761 |
|
2762 |
|
2763 |
|
2764 |
|
2765 |
|
2766 |
|
2767 |
|
2768 |
|
2769 | CSSOM.CSSStyleSheet.prototype.deleteRule = function(index) {
|
2770 | if (index < 0 || index >= this.cssRules.length) {
|
2771 | throw new RangeError("INDEX_SIZE_ERR");
|
2772 | }
|
2773 | this.cssRules.splice(index, 1);
|
2774 | };
|
2775 |
|
2776 |
|
2777 |
|
2778 |
|
2779 |
|
2780 |
|
2781 | CSSOM.CSSStyleSheet.prototype.toString = function() {
|
2782 | var result = "";
|
2783 | var rules = this.cssRules;
|
2784 | for (var i=0; i<rules.length; i++) {
|
2785 | result += rules[i].cssText + "\n";
|
2786 | }
|
2787 | return result;
|
2788 | };
|
2789 |
|
2790 |
|
2791 |
|
2792 | exports.CSSStyleSheet = CSSOM.CSSStyleSheet;
|
2793 | CSSOM.parse = require('./parse').parse;
|
2794 |
|
2795 |
|
2796 | },{"./CSSStyleRule":18,"./StyleSheet":24,"./parse":27}],20:[function(require,module,exports){
|
2797 |
|
2798 | var CSSOM = {};
|
2799 |
|
2800 |
|
2801 |
|
2802 |
|
2803 |
|
2804 |
|
2805 |
|
2806 |
|
2807 |
|
2808 | CSSOM.CSSValue = function CSSValue() {
|
2809 | };
|
2810 |
|
2811 | CSSOM.CSSValue.prototype = {
|
2812 | constructor: CSSOM.CSSValue,
|
2813 |
|
2814 | // @see: http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSValue
|
2815 | set cssText(text) {
|
2816 | var name = this._getConstructorName();
|
2817 |
|
2818 | throw new Error('DOMException: property "cssText" of "' + name + '" is readonly and can not be replaced with "' + text + '"!');
|
2819 | },
|
2820 |
|
2821 | get cssText() {
|
2822 | var name = this._getConstructorName();
|
2823 |
|
2824 | throw new Error('getter "cssText" of "' + name + '" is not implemented!');
|
2825 | },
|
2826 |
|
2827 | _getConstructorName: function() {
|
2828 | var s = this.constructor.toString(),
|
2829 | c = s.match(/function\s([^\(]+)/),
|
2830 | name = c[1];
|
2831 |
|
2832 | return name;
|
2833 | }
|
2834 | };
|
2835 |
|
2836 |
|
2837 |
|
2838 | exports.CSSValue = CSSOM.CSSValue;
|
2839 |
|
2840 |
|
2841 | },{}],21:[function(require,module,exports){
|
2842 |
|
2843 | var CSSOM = {
|
2844 | CSSValue: require('./CSSValue').CSSValue
|
2845 | };
|
2846 |
|
2847 |
|
2848 |
|
2849 |
|
2850 |
|
2851 |
|
2852 |
|
2853 |
|
2854 | CSSOM.CSSValueExpression = function CSSValueExpression(token, idx) {
|
2855 | this._token = token;
|
2856 | this._idx = idx;
|
2857 | };
|
2858 |
|
2859 | CSSOM.CSSValueExpression.prototype = new CSSOM.CSSValue();
|
2860 | CSSOM.CSSValueExpression.prototype.constructor = CSSOM.CSSValueExpression;
|
2861 |
|
2862 |
|
2863 |
|
2864 |
|
2865 |
|
2866 |
|
2867 |
|
2868 |
|
2869 |
|
2870 |
|
2871 |
|
2872 |
|
2873 |
|
2874 |
|
2875 |
|
2876 |
|
2877 | CSSOM.CSSValueExpression.prototype.parse = function() {
|
2878 | var token = this._token,
|
2879 | idx = this._idx;
|
2880 |
|
2881 | var character = '',
|
2882 | expression = '',
|
2883 | error = '',
|
2884 | info,
|
2885 | paren = [];
|
2886 |
|
2887 |
|
2888 | for (; ; ++idx) {
|
2889 | character = token.charAt(idx);
|
2890 |
|
2891 |
|
2892 | if (character === '') {
|
2893 | error = 'css expression error: unfinished expression!';
|
2894 | break;
|
2895 | }
|
2896 |
|
2897 | switch(character) {
|
2898 | case '(':
|
2899 | paren.push(character);
|
2900 | expression += character;
|
2901 | break;
|
2902 |
|
2903 | case ')':
|
2904 | paren.pop(character);
|
2905 | expression += character;
|
2906 | break;
|
2907 |
|
2908 | case '/':
|
2909 | if ((info = this._parseJSComment(token, idx))) {
|
2910 | if (info.error) {
|
2911 | error = 'css expression error: unfinished comment in expression!';
|
2912 | } else {
|
2913 | idx = info.idx;
|
2914 |
|
2915 | }
|
2916 | } else if ((info = this._parseJSRexExp(token, idx))) {
|
2917 | idx = info.idx;
|
2918 | expression += info.text;
|
2919 | } else {
|
2920 | expression += character;
|
2921 | }
|
2922 | break;
|
2923 |
|
2924 | case "'":
|
2925 | case '"':
|
2926 | info = this._parseJSString(token, idx, character);
|
2927 | if (info) {
|
2928 | idx = info.idx;
|
2929 | expression += info.text;
|
2930 | } else {
|
2931 | expression += character;
|
2932 | }
|
2933 | break;
|
2934 |
|
2935 | default:
|
2936 | expression += character;
|
2937 | break;
|
2938 | }
|
2939 |
|
2940 | if (error) {
|
2941 | break;
|
2942 | }
|
2943 |
|
2944 |
|
2945 | if (paren.length === 0) {
|
2946 | break;
|
2947 | }
|
2948 | }
|
2949 |
|
2950 | var ret;
|
2951 | if (error) {
|
2952 | ret = {
|
2953 | error: error
|
2954 | };
|
2955 | } else {
|
2956 | ret = {
|
2957 | idx: idx,
|
2958 | expression: expression
|
2959 | };
|
2960 | }
|
2961 |
|
2962 | return ret;
|
2963 | };
|
2964 |
|
2965 |
|
2966 |
|
2967 |
|
2968 |
|
2969 |
|
2970 |
|
2971 |
|
2972 |
|
2973 |
|
2974 |
|
2975 |
|
2976 |
|
2977 | CSSOM.CSSValueExpression.prototype._parseJSComment = function(token, idx) {
|
2978 | var nextChar = token.charAt(idx + 1),
|
2979 | text;
|
2980 |
|
2981 | if (nextChar === '/' || nextChar === '*') {
|
2982 | var startIdx = idx,
|
2983 | endIdx,
|
2984 | commentEndChar;
|
2985 |
|
2986 | if (nextChar === '/') {
|
2987 | commentEndChar = '\n';
|
2988 | } else if (nextChar === '*') {
|
2989 | commentEndChar = '*/';
|
2990 | }
|
2991 |
|
2992 | endIdx = token.indexOf(commentEndChar, startIdx + 1 + 1);
|
2993 | if (endIdx !== -1) {
|
2994 | endIdx = endIdx + commentEndChar.length - 1;
|
2995 | text = token.substring(idx, endIdx + 1);
|
2996 | return {
|
2997 | idx: endIdx,
|
2998 | text: text
|
2999 | };
|
3000 | } else {
|
3001 | var error = 'css expression error: unfinished comment in expression!';
|
3002 | return {
|
3003 | error: error
|
3004 | };
|
3005 | }
|
3006 | } else {
|
3007 | return false;
|
3008 | }
|
3009 | };
|
3010 |
|
3011 |
|
3012 |
|
3013 |
|
3014 |
|
3015 |
|
3016 |
|
3017 |
|
3018 |
|
3019 |
|
3020 |
|
3021 | CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
|
3022 | var endIdx = this._findMatchedIdx(token, idx, sep),
|
3023 | text;
|
3024 |
|
3025 | if (endIdx === -1) {
|
3026 | return false;
|
3027 | } else {
|
3028 | text = token.substring(idx, endIdx + sep.length);
|
3029 |
|
3030 | return {
|
3031 | idx: endIdx,
|
3032 | text: text
|
3033 | };
|
3034 | }
|
3035 | };
|
3036 |
|
3037 |
|
3038 |
|
3039 |
|
3040 |
|
3041 |
|
3042 |
|
3043 |
|
3044 |
|
3045 |
|
3046 |
|
3047 |
|
3048 |
|
3049 |
|
3050 |
|
3051 |
|
3052 |
|
3053 |
|
3054 |
|
3055 |
|
3056 |
|
3057 |
|
3058 |
|
3059 |
|
3060 |
|
3061 |
|
3062 |
|
3063 |
|
3064 |
|
3065 |
|
3066 |
|
3067 |
|
3068 |
|
3069 |
|
3070 |
|
3071 |
|
3072 |
|
3073 |
|
3074 |
|
3075 |
|
3076 |
|
3077 |
|
3078 |
|
3079 |
|
3080 |
|
3081 |
|
3082 |
|
3083 |
|
3084 |
|
3085 |
|
3086 |
|
3087 |
|
3088 |
|
3089 |
|
3090 |
|
3091 |
|
3092 |
|
3093 |
|
3094 |
|
3095 |
|
3096 | CSSOM.CSSValueExpression.prototype._parseJSRexExp = function(token, idx) {
|
3097 | var before = token.substring(0, idx).replace(/\s+$/, ""),
|
3098 | legalRegx = [
|
3099 | /^$/,
|
3100 | /\($/,
|
3101 | /\[$/,
|
3102 | /\!$/,
|
3103 | /\+$/,
|
3104 | /\-$/,
|
3105 | /\*$/,
|
3106 | /\/\s+/,
|
3107 | /\%$/,
|
3108 | /\=$/,
|
3109 | /\>$/,
|
3110 | /<$/,
|
3111 | /\&$/,
|
3112 | /\|$/,
|
3113 | /\^$/,
|
3114 | /\~$/,
|
3115 | /\?$/,
|
3116 | /\,$/,
|
3117 | /delete$/,
|
3118 | /in$/,
|
3119 | /instanceof$/,
|
3120 | /new$/,
|
3121 | /typeof$/,
|
3122 | /void$/
|
3123 | ];
|
3124 |
|
3125 | var isLegal = legalRegx.some(function(reg) {
|
3126 | return reg.test(before);
|
3127 | });
|
3128 |
|
3129 | if (!isLegal) {
|
3130 | return false;
|
3131 | } else {
|
3132 | var sep = '/';
|
3133 |
|
3134 | // same logic as string
|
3135 | return this._parseJSString(token, idx, sep);
|
3136 | }
|
3137 | };
|
3138 |
|
3139 |
|
3140 | /**
|
3141 | *
|
3142 | * find next sep(same line) index in `token`
|
3143 | *
|
3144 | * @return {Number}
|
3145 | *
|
3146 | */
|
3147 | CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
|
3148 | var startIdx = idx,
|
3149 | endIdx;
|
3150 |
|
3151 | var NOT_FOUND = -1;
|
3152 |
|
3153 | while(true) {
|
3154 | endIdx = token.indexOf(sep, startIdx + 1);
|
3155 |
|
3156 | if (endIdx === -1) { // not found
|
3157 | endIdx = NOT_FOUND;
|
3158 | break;
|
3159 | } else {
|
3160 | var text = token.substring(idx + 1, endIdx),
|
3161 | matched = text.match(/\\+$/);
|
3162 | if (!matched || matched[0] % 2 === 0) { // not escaped
|
3163 | break;
|
3164 | } else {
|
3165 | startIdx = endIdx;
|
3166 | }
|
3167 | }
|
3168 | }
|
3169 |
|
3170 | // boundary must be in the same line(js sting or regexp)
|
3171 | var nextNewLineIdx = token.indexOf('\n', idx + 1);
|
3172 | if (nextNewLineIdx < endIdx) {
|
3173 | endIdx = NOT_FOUND;
|
3174 | }
|
3175 |
|
3176 |
|
3177 | return endIdx;
|
3178 | };
|
3179 |
|
3180 |
|
3181 |
|
3182 |
|
3183 | //.CommonJS
|
3184 | exports.CSSValueExpression = CSSOM.CSSValueExpression;
|
3185 | ///CommonJS
|
3186 |
|
3187 | },{"./CSSValue":20}],22:[function(require,module,exports){
|
3188 | //.CommonJS
|
3189 | var CSSOM = {};
|
3190 | ///CommonJS
|
3191 |
|
3192 |
|
3193 | /**
|
3194 | * @constructor
|
3195 | * @see https://developer.mozilla.org/en/CSS/@-moz-document
|
3196 | */
|
3197 | CSSOM.MatcherList = function MatcherList(){
|
3198 | this.length = 0;
|
3199 | };
|
3200 |
|
3201 | CSSOM.MatcherList.prototype = {
|
3202 |
|
3203 | constructor: CSSOM.MatcherList,
|
3204 |
|
3205 | /**
|
3206 | * @return {string}
|
3207 | */
|
3208 | get matcherText() {
|
3209 | return Array.prototype.join.call(this, ", ");
|
3210 | },
|
3211 |
|
3212 | /**
|
3213 | * @param {string} value
|
3214 | */
|
3215 | set matcherText(value) {
|
3216 | // just a temporary solution, actually it may be wrong by just split the value with ',', because a url can include ','.
|
3217 | var values = value.split(",");
|
3218 | var length = this.length = values.length;
|
3219 | for (var i=0; i<length; i++) {
|
3220 | this[i] = values[i].trim();
|
3221 | }
|
3222 | },
|
3223 |
|
3224 | /**
|
3225 | * @param {string} matcher
|
3226 | */
|
3227 | appendMatcher: function(matcher) {
|
3228 | if (Array.prototype.indexOf.call(this, matcher) === -1) {
|
3229 | this[this.length] = matcher;
|
3230 | this.length++;
|
3231 | }
|
3232 | },
|
3233 |
|
3234 | /**
|
3235 | * @param {string} matcher
|
3236 | */
|
3237 | deleteMatcher: function(matcher) {
|
3238 | var index = Array.prototype.indexOf.call(this, matcher);
|
3239 | if (index !== -1) {
|
3240 | Array.prototype.splice.call(this, index, 1);
|
3241 | }
|
3242 | }
|
3243 |
|
3244 | };
|
3245 |
|
3246 |
|
3247 | //.CommonJS
|
3248 | exports.MatcherList = CSSOM.MatcherList;
|
3249 | ///CommonJS
|
3250 |
|
3251 | },{}],23:[function(require,module,exports){
|
3252 | //.CommonJS
|
3253 | var CSSOM = {};
|
3254 | ///CommonJS
|
3255 |
|
3256 |
|
3257 | /**
|
3258 | * @constructor
|
3259 | * @see http://dev.w3.org/csswg/cssom/#the-medialist-interface
|
3260 | */
|
3261 | CSSOM.MediaList = function MediaList(){
|
3262 | this.length = 0;
|
3263 | };
|
3264 |
|
3265 | CSSOM.MediaList.prototype = {
|
3266 |
|
3267 | constructor: CSSOM.MediaList,
|
3268 |
|
3269 | /**
|
3270 | * @return {string}
|
3271 | */
|
3272 | get mediaText() {
|
3273 | return Array.prototype.join.call(this, ", ");
|
3274 | },
|
3275 |
|
3276 | /**
|
3277 | * @param {string} value
|
3278 | */
|
3279 | set mediaText(value) {
|
3280 | var values = value.split(",");
|
3281 | var length = this.length = values.length;
|
3282 | for (var i=0; i<length; i++) {
|
3283 | this[i] = values[i].trim();
|
3284 | }
|
3285 | },
|
3286 |
|
3287 | /**
|
3288 | * @param {string} medium
|
3289 | */
|
3290 | appendMedium: function(medium) {
|
3291 | if (Array.prototype.indexOf.call(this, medium) === -1) {
|
3292 | this[this.length] = medium;
|
3293 | this.length++;
|
3294 | }
|
3295 | },
|
3296 |
|
3297 | /**
|
3298 | * @param {string} medium
|
3299 | */
|
3300 | deleteMedium: function(medium) {
|
3301 | var index = Array.prototype.indexOf.call(this, medium);
|
3302 | if (index !== -1) {
|
3303 | Array.prototype.splice.call(this, index, 1);
|
3304 | }
|
3305 | }
|
3306 |
|
3307 | };
|
3308 |
|
3309 |
|
3310 | //.CommonJS
|
3311 | exports.MediaList = CSSOM.MediaList;
|
3312 | ///CommonJS
|
3313 |
|
3314 | },{}],24:[function(require,module,exports){
|
3315 | //.CommonJS
|
3316 | var CSSOM = {};
|
3317 | ///CommonJS
|
3318 |
|
3319 |
|
3320 | /**
|
3321 | * @constructor
|
3322 | * @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface
|
3323 | */
|
3324 | CSSOM.StyleSheet = function StyleSheet() {
|
3325 | this.parentStyleSheet = null;
|
3326 | };
|
3327 |
|
3328 |
|
3329 | //.CommonJS
|
3330 | exports.StyleSheet = CSSOM.StyleSheet;
|
3331 | ///CommonJS
|
3332 |
|
3333 | },{}],25:[function(require,module,exports){
|
3334 | //.CommonJS
|
3335 | var CSSOM = {
|
3336 | CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet,
|
3337 | CSSStyleRule: require("./CSSStyleRule").CSSStyleRule,
|
3338 | CSSMediaRule: require("./CSSMediaRule").CSSMediaRule,
|
3339 | CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
|
3340 | CSSKeyframeRule: require('./CSSKeyframeRule').CSSKeyframeRule,
|
3341 | CSSKeyframesRule: require('./CSSKeyframesRule').CSSKeyframesRule
|
3342 | };
|
3343 | ///CommonJS
|
3344 |
|
3345 |
|
3346 | /**
|
3347 | * Produces a deep copy of stylesheet — the instance variables of stylesheet are copied recursively.
|
3348 | * @param {CSSStyleSheet|CSSOM.CSSStyleSheet} stylesheet
|
3349 | * @nosideeffects
|
3350 | * @return {CSSOM.CSSStyleSheet}
|
3351 | */
|
3352 | CSSOM.clone = function clone(stylesheet) {
|
3353 |
|
3354 | var cloned = new CSSOM.CSSStyleSheet();
|
3355 |
|
3356 | var rules = stylesheet.cssRules;
|
3357 | if (!rules) {
|
3358 | return cloned;
|
3359 | }
|
3360 |
|
3361 | var RULE_TYPES = {
|
3362 | 1: CSSOM.CSSStyleRule,
|
3363 | 4: CSSOM.CSSMediaRule,
|
3364 | //3: CSSOM.CSSImportRule,
|
3365 | //5: CSSOM.CSSFontFaceRule,
|
3366 | //6: CSSOM.CSSPageRule,
|
3367 | 8: CSSOM.CSSKeyframesRule,
|
3368 | 9: CSSOM.CSSKeyframeRule
|
3369 | };
|
3370 |
|
3371 | for (var i=0, rulesLength=rules.length; i < rulesLength; i++) {
|
3372 | var rule = rules[i];
|
3373 | var ruleClone = cloned.cssRules[i] = new RULE_TYPES[rule.type]();
|
3374 |
|
3375 | var style = rule.style;
|
3376 | if (style) {
|
3377 | var styleClone = ruleClone.style = new CSSOM.CSSStyleDeclaration();
|
3378 | for (var j=0, styleLength=style.length; j < styleLength; j++) {
|
3379 | var name = styleClone[j] = style[j];
|
3380 | styleClone[name] = style[name];
|
3381 | styleClone._importants[name] = style.getPropertyPriority(name);
|
3382 | }
|
3383 | styleClone.length = style.length;
|
3384 | }
|
3385 |
|
3386 | if (rule.hasOwnProperty('keyText')) {
|
3387 | ruleClone.keyText = rule.keyText;
|
3388 | }
|
3389 |
|
3390 | if (rule.hasOwnProperty('selectorText')) {
|
3391 | ruleClone.selectorText = rule.selectorText;
|
3392 | }
|
3393 |
|
3394 | if (rule.hasOwnProperty('mediaText')) {
|
3395 | ruleClone.mediaText = rule.mediaText;
|
3396 | }
|
3397 |
|
3398 | if (rule.hasOwnProperty('cssRules')) {
|
3399 | ruleClone.cssRules = clone(rule).cssRules;
|
3400 | }
|
3401 | }
|
3402 |
|
3403 | return cloned;
|
3404 |
|
3405 | };
|
3406 |
|
3407 | //.CommonJS
|
3408 | exports.clone = CSSOM.clone;
|
3409 | ///CommonJS
|
3410 |
|
3411 | },{"./CSSKeyframeRule":13,"./CSSKeyframesRule":14,"./CSSMediaRule":15,"./CSSStyleDeclaration":17,"./CSSStyleRule":18,"./CSSStyleSheet":19}],26:[function(require,module,exports){
|
3412 | exports.CSSStyleDeclaration = require("./CSSStyleDeclaration").CSSStyleDeclaration;
|
3413 | exports.CSSRule = require("./CSSRule").CSSRule;
|
3414 | exports.CSSStyleRule = require("./CSSStyleRule").CSSStyleRule;
|
3415 | exports.CSSImportRule = require("./CSSImportRule").CSSImportRule;
|
3416 | exports.MediaList = require("./MediaList").MediaList;
|
3417 | exports.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule;
|
3418 | exports.StyleSheet = require("./StyleSheet").StyleSheet;
|
3419 | exports.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet;
|
3420 | exports.parse = require("./parse").parse;
|
3421 | exports.clone = require("./clone").clone;
|
3422 |
|
3423 | },{"./CSSImportRule":12,"./CSSMediaRule":15,"./CSSRule":16,"./CSSStyleDeclaration":17,"./CSSStyleRule":18,"./CSSStyleSheet":19,"./MediaList":23,"./StyleSheet":24,"./clone":25,"./parse":27}],27:[function(require,module,exports){
|
3424 | //.CommonJS
|
3425 | var CSSOM = {};
|
3426 | ///CommonJS
|
3427 |
|
3428 |
|
3429 | /**
|
3430 | * @param {string} token
|
3431 | */
|
3432 | CSSOM.parse = function parse(token) {
|
3433 |
|
3434 | var i = 0;
|
3435 |
|
3436 | /**
|
3437 | "before-selector" or
|
3438 | "selector" or
|
3439 | "atRule" or
|
3440 | "atBlock" or
|
3441 | "before-name" or
|
3442 | "name" or
|
3443 | "before-value" or
|
3444 | "value"
|
3445 | */
|
3446 | var state = "before-selector";
|
3447 |
|
3448 | var index;
|
3449 | var buffer = "";
|
3450 | var valueParenthesisDepth = 0;
|
3451 |
|
3452 | var SIGNIFICANT_WHITESPACE = {
|
3453 | "selector": true,
|
3454 | "value": true,
|
3455 | "value-parenthesis": true,
|
3456 | "atRule": true,
|
3457 | "importRule-begin": true,
|
3458 | "importRule": true,
|
3459 | "atBlock": true,
|
3460 | 'documentRule-begin': true
|
3461 | };
|
3462 |
|
3463 | var styleSheet = new CSSOM.CSSStyleSheet();
|
3464 |
|
3465 | // @type CSSStyleSheet|CSSMediaRule|CSSFontFaceRule|CSSKeyframesRule|CSSDocumentRule
|
3466 | var currentScope = styleSheet;
|
3467 |
|
3468 | // @type CSSMediaRule|CSSKeyframesRule|CSSDocumentRule
|
3469 | var parentRule;
|
3470 |
|
3471 | var name, priority="", styleRule, mediaRule, importRule, fontFaceRule, keyframesRule, documentRule, hostRule;
|
3472 |
|
3473 | var atKeyframesRegExp = /@(-(?:\w+-)+)?keyframes/g;
|
3474 |
|
3475 | var parseError = function(message) {
|
3476 | var lines = token.substring(0, i).split('\n');
|
3477 | var lineCount = lines.length;
|
3478 | var charCount = lines.pop().length + 1;
|
3479 | var error = new Error(message + ' (line ' + lineCount + ', char ' + charCount + ')');
|
3480 | error.line = lineCount;
|
3481 | /* jshint sub : true */
|
3482 | error['char'] = charCount;
|
3483 | error.styleSheet = styleSheet;
|
3484 | throw error;
|
3485 | };
|
3486 |
|
3487 | for (var character; (character = token.charAt(i)); i++) {
|
3488 |
|
3489 | switch (character) {
|
3490 |
|
3491 | case " ":
|
3492 | case "\t":
|
3493 | case "\r":
|
3494 | case "\n":
|
3495 | case "\f":
|
3496 | if (SIGNIFICANT_WHITESPACE[state]) {
|
3497 | buffer += character;
|
3498 | }
|
3499 | break;
|
3500 |
|
3501 | // String
|
3502 | case '"':
|
3503 | index = i + 1;
|
3504 | do {
|
3505 | index = token.indexOf('"', index) + 1;
|
3506 | if (!index) {
|
3507 | parseError('Unmatched "');
|
3508 | }
|
3509 | } while (token[index - 2] === '\\');
|
3510 | buffer += token.slice(i, index);
|
3511 | i = index - 1;
|
3512 | switch (state) {
|
3513 | case 'before-value':
|
3514 | state = 'value';
|
3515 | break;
|
3516 | case 'importRule-begin':
|
3517 | state = 'importRule';
|
3518 | break;
|
3519 | }
|
3520 | break;
|
3521 |
|
3522 | case "'":
|
3523 | index = i + 1;
|
3524 | do {
|
3525 | index = token.indexOf("'", index) + 1;
|
3526 | if (!index) {
|
3527 | parseError("Unmatched '");
|
3528 | }
|
3529 | } while (token[index - 2] === '\\');
|
3530 | buffer += token.slice(i, index);
|
3531 | i = index - 1;
|
3532 | switch (state) {
|
3533 | case 'before-value':
|
3534 | state = 'value';
|
3535 | break;
|
3536 | case 'importRule-begin':
|
3537 | state = 'importRule';
|
3538 | break;
|
3539 | }
|
3540 | break;
|
3541 |
|
3542 | // Comment
|
3543 | case "/":
|
3544 | if (token.charAt(i + 1) === "*") {
|
3545 | i += 2;
|
3546 | index = token.indexOf("*/", i);
|
3547 | if (index === -1) {
|
3548 | parseError("Missing */");
|
3549 | } else {
|
3550 | i = index + 1;
|
3551 | }
|
3552 | } else {
|
3553 | buffer += character;
|
3554 | }
|
3555 | if (state === "importRule-begin") {
|
3556 | buffer += " ";
|
3557 | state = "importRule";
|
3558 | }
|
3559 | break;
|
3560 |
|
3561 | // At-rule
|
3562 | case "@":
|
3563 | if (token.indexOf("@-moz-document", i) === i) {
|
3564 | state = "documentRule-begin";
|
3565 | documentRule = new CSSOM.CSSDocumentRule();
|
3566 | documentRule.__starts = i;
|
3567 | i += "-moz-document".length;
|
3568 | buffer = "";
|
3569 | break;
|
3570 | } else if (token.indexOf("@media", i) === i) {
|
3571 | state = "atBlock";
|
3572 | mediaRule = new CSSOM.CSSMediaRule();
|
3573 | mediaRule.__starts = i;
|
3574 | i += "media".length;
|
3575 | buffer = "";
|
3576 | break;
|
3577 | } else if (token.indexOf("@host", i) === i) {
|
3578 | state = "hostRule-begin";
|
3579 | i += "host".length;
|
3580 | hostRule = new CSSOM.CSSHostRule();
|
3581 | hostRule.__starts = i;
|
3582 | buffer = "";
|
3583 | break;
|
3584 | } else if (token.indexOf("@import", i) === i) {
|
3585 | state = "importRule-begin";
|
3586 | i += "import".length;
|
3587 | buffer += "@import";
|
3588 | break;
|
3589 | } else if (token.indexOf("@font-face", i) === i) {
|
3590 | state = "fontFaceRule-begin";
|
3591 | i += "font-face".length;
|
3592 | fontFaceRule = new CSSOM.CSSFontFaceRule();
|
3593 | fontFaceRule.__starts = i;
|
3594 | buffer = "";
|
3595 | break;
|
3596 | } else {
|
3597 | atKeyframesRegExp.lastIndex = i;
|
3598 | var matchKeyframes = atKeyframesRegExp.exec(token);
|
3599 | if (matchKeyframes && matchKeyframes.index === i) {
|
3600 | state = "keyframesRule-begin";
|
3601 | keyframesRule = new CSSOM.CSSKeyframesRule();
|
3602 | keyframesRule.__starts = i;
|
3603 | keyframesRule._vendorPrefix = matchKeyframes[1]; // Will come out as undefined if no prefix was found
|
3604 | i += matchKeyframes[0].length - 1;
|
3605 | buffer = "";
|
3606 | break;
|
3607 | } else if (state === "selector") {
|
3608 | state = "atRule";
|
3609 | }
|
3610 | }
|
3611 | buffer += character;
|
3612 | break;
|
3613 |
|
3614 | case "{":
|
3615 | if (state === "selector" || state === "atRule") {
|
3616 | styleRule.selectorText = buffer.trim();
|
3617 | styleRule.style.__starts = i;
|
3618 | buffer = "";
|
3619 | state = "before-name";
|
3620 | } else if (state === "atBlock") {
|
3621 | mediaRule.media.mediaText = buffer.trim();
|
3622 | currentScope = parentRule = mediaRule;
|
3623 | mediaRule.parentStyleSheet = styleSheet;
|
3624 | buffer = "";
|
3625 | state = "before-selector";
|
3626 | } else if (state === "hostRule-begin") {
|
3627 | currentScope = parentRule = hostRule;
|
3628 | hostRule.parentStyleSheet = styleSheet;
|
3629 | buffer = "";
|
3630 | state = "before-selector";
|
3631 | } else if (state === "fontFaceRule-begin") {
|
3632 | if (parentRule) {
|
3633 | fontFaceRule.parentRule = parentRule;
|
3634 | }
|
3635 | fontFaceRule.parentStyleSheet = styleSheet;
|
3636 | styleRule = fontFaceRule;
|
3637 | buffer = "";
|
3638 | state = "before-name";
|
3639 | } else if (state === "keyframesRule-begin") {
|
3640 | keyframesRule.name = buffer.trim();
|
3641 | if (parentRule) {
|
3642 | keyframesRule.parentRule = parentRule;
|
3643 | }
|
3644 | keyframesRule.parentStyleSheet = styleSheet;
|
3645 | currentScope = parentRule = keyframesRule;
|
3646 | buffer = "";
|
3647 | state = "keyframeRule-begin";
|
3648 | } else if (state === "keyframeRule-begin") {
|
3649 | styleRule = new CSSOM.CSSKeyframeRule();
|
3650 | styleRule.keyText = buffer.trim();
|
3651 | styleRule.__starts = i;
|
3652 | buffer = "";
|
3653 | state = "before-name";
|
3654 | } else if (state === "documentRule-begin") {
|
3655 | // FIXME: what if this '{' is in the url text of the match function?
|
3656 | documentRule.matcher.matcherText = buffer.trim();
|
3657 | if (parentRule) {
|
3658 | documentRule.parentRule = parentRule;
|
3659 | }
|
3660 | currentScope = parentRule = documentRule;
|
3661 | documentRule.parentStyleSheet = styleSheet;
|
3662 | buffer = "";
|
3663 | state = "before-selector";
|
3664 | }
|
3665 | break;
|
3666 |
|
3667 | case ":":
|
3668 | if (state === "name") {
|
3669 | name = buffer.trim();
|
3670 | buffer = "";
|
3671 | state = "before-value";
|
3672 | } else {
|
3673 | buffer += character;
|
3674 | }
|
3675 | break;
|
3676 |
|
3677 | case "(":
|
3678 | if (state === 'value') {
|
3679 | // ie css expression mode
|
3680 | if (buffer.trim() === 'expression') {
|
3681 | var info = (new CSSOM.CSSValueExpression(token, i)).parse();
|
3682 |
|
3683 | if (info.error) {
|
3684 | parseError(info.error);
|
3685 | } else {
|
3686 | buffer += info.expression;
|
3687 | i = info.idx;
|
3688 | }
|
3689 | } else {
|
3690 | state = 'value-parenthesis';
|
3691 | //always ensure this is reset to 1 on transition
|
3692 | //from value to value-parenthesis
|
3693 | valueParenthesisDepth = 1;
|
3694 | buffer += character;
|
3695 | }
|
3696 | } else if (state === 'value-parenthesis') {
|
3697 | valueParenthesisDepth++;
|
3698 | buffer += character;
|
3699 | } else {
|
3700 | buffer += character;
|
3701 | }
|
3702 | break;
|
3703 |
|
3704 | case ")":
|
3705 | if (state === 'value-parenthesis') {
|
3706 | valueParenthesisDepth--;
|
3707 | if (valueParenthesisDepth === 0) state = 'value';
|
3708 | }
|
3709 | buffer += character;
|
3710 | break;
|
3711 |
|
3712 | case "!":
|
3713 | if (state === "value" && token.indexOf("!important", i) === i) {
|
3714 | priority = "important";
|
3715 | i += "important".length;
|
3716 | } else {
|
3717 | buffer += character;
|
3718 | }
|
3719 | break;
|
3720 |
|
3721 | case ";":
|
3722 | switch (state) {
|
3723 | case "value":
|
3724 | styleRule.style.setProperty(name, buffer.trim(), priority);
|
3725 | priority = "";
|
3726 | buffer = "";
|
3727 | state = "before-name";
|
3728 | break;
|
3729 | case "atRule":
|
3730 | buffer = "";
|
3731 | state = "before-selector";
|
3732 | break;
|
3733 | case "importRule":
|
3734 | importRule = new CSSOM.CSSImportRule();
|
3735 | importRule.parentStyleSheet = importRule.styleSheet.parentStyleSheet = styleSheet;
|
3736 | importRule.cssText = buffer + character;
|
3737 | styleSheet.cssRules.push(importRule);
|
3738 | buffer = "";
|
3739 | state = "before-selector";
|
3740 | break;
|
3741 | default:
|
3742 | buffer += character;
|
3743 | break;
|
3744 | }
|
3745 | break;
|
3746 |
|
3747 | case "}":
|
3748 | switch (state) {
|
3749 | case "value":
|
3750 | styleRule.style.setProperty(name, buffer.trim(), priority);
|
3751 | priority = "";
|
3752 | /* falls through */
|
3753 | case "before-name":
|
3754 | case "name":
|
3755 | styleRule.__ends = i + 1;
|
3756 | if (parentRule) {
|
3757 | styleRule.parentRule = parentRule;
|
3758 | }
|
3759 | styleRule.parentStyleSheet = styleSheet;
|
3760 | currentScope.cssRules.push(styleRule);
|
3761 | buffer = "";
|
3762 | if (currentScope.constructor === CSSOM.CSSKeyframesRule) {
|
3763 | state = "keyframeRule-begin";
|
3764 | } else {
|
3765 | state = "before-selector";
|
3766 | }
|
3767 | break;
|
3768 | case "keyframeRule-begin":
|
3769 | case "before-selector":
|
3770 | case "selector":
|
3771 | // End of media/document rule.
|
3772 | if (!parentRule) {
|
3773 | parseError("Unexpected }");
|
3774 | }
|
3775 | currentScope.__ends = i + 1;
|
3776 | // Nesting rules aren't supported yet
|
3777 | styleSheet.cssRules.push(currentScope);
|
3778 | currentScope = styleSheet;
|
3779 | parentRule = null;
|
3780 | buffer = "";
|
3781 | state = "before-selector";
|
3782 | break;
|
3783 | }
|
3784 | break;
|
3785 |
|
3786 | default:
|
3787 | switch (state) {
|
3788 | case "before-selector":
|
3789 | state = "selector";
|
3790 | styleRule = new CSSOM.CSSStyleRule();
|
3791 | styleRule.__starts = i;
|
3792 | break;
|
3793 | case "before-name":
|
3794 | state = "name";
|
3795 | break;
|
3796 | case "before-value":
|
3797 | state = "value";
|
3798 | break;
|
3799 | case "importRule-begin":
|
3800 | state = "importRule";
|
3801 | break;
|
3802 | }
|
3803 | buffer += character;
|
3804 | break;
|
3805 | }
|
3806 | }
|
3807 |
|
3808 | return styleSheet;
|
3809 | };
|
3810 |
|
3811 |
|
3812 | //.CommonJS
|
3813 | exports.parse = CSSOM.parse;
|
3814 | // The following modules cannot be included sooner due to the mutual dependency with parse.js
|
3815 | CSSOM.CSSStyleSheet = require("./CSSStyleSheet").CSSStyleSheet;
|
3816 | CSSOM.CSSStyleRule = require("./CSSStyleRule").CSSStyleRule;
|
3817 | CSSOM.CSSImportRule = require("./CSSImportRule").CSSImportRule;
|
3818 | CSSOM.CSSMediaRule = require("./CSSMediaRule").CSSMediaRule;
|
3819 | CSSOM.CSSFontFaceRule = require("./CSSFontFaceRule").CSSFontFaceRule;
|
3820 | CSSOM.CSSHostRule = require("./CSSHostRule").CSSHostRule;
|
3821 | CSSOM.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration;
|
3822 | CSSOM.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule;
|
3823 | CSSOM.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule;
|
3824 | CSSOM.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
|
3825 | CSSOM.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
|
3826 | ///CommonJS
|
3827 |
|
3828 | },{"./CSSDocumentRule":9,"./CSSFontFaceRule":10,"./CSSHostRule":11,"./CSSImportRule":12,"./CSSKeyframeRule":13,"./CSSKeyframesRule":14,"./CSSMediaRule":15,"./CSSStyleDeclaration":17,"./CSSStyleRule":18,"./CSSStyleSheet":19,"./CSSValueExpression":21}],28:[function(require,module,exports){
|
3829 | // Simple, stupid "background"/"background-image" value parser that just aims at exposing the image URLs
|
3830 | "use strict";
|
3831 |
|
3832 | var cssSupport = require('./cssSupport');
|
3833 |
|
3834 |
|
3835 | var trimCSSWhitespace = function (url) {
|
3836 | var whitespaceRegex = /^[\t\r\f\n ]*(.+?)[\t\r\f\n ]*$/;
|
3837 |
|
3838 | return url.replace(whitespaceRegex, "$1");
|
3839 | };
|
3840 |
|
3841 | // TODO exporting this for the sake of unit testing. Should rather test the background value parser explicitly.
|
3842 | exports.extractCssUrl = function (cssUrl) {
|
3843 | var urlRegex = /^url\(([^\)]+)\)/,
|
3844 | quotedUrl;
|
3845 |
|
3846 | if (!urlRegex.test(cssUrl)) {
|
3847 | throw new Error("Invalid url");
|
3848 | }
|
3849 |
|
3850 | quotedUrl = urlRegex.exec(cssUrl)[1];
|
3851 | return cssSupport.unquoteString(trimCSSWhitespace(quotedUrl));
|
3852 | };
|
3853 |
|
3854 | var sliceBackgroundDeclaration = function (backgroundDeclarationText) {
|
3855 | var functionParamRegexS = "\\s*(?:\"[^\"]*\"|'[^']*'|[^\\(]+)\\s*",
|
3856 | valueRegexS = "(" + "url\\(" + functionParamRegexS + "\\)" + "|" + "[^,\\s]+" + ")",
|
3857 | simpleSingularBackgroundRegexS = "(?:\\s*" + valueRegexS + ")+",
|
3858 | simpleBackgroundRegexS = "^\\s*(" + simpleSingularBackgroundRegexS + ")" +
|
3859 | "(?:\\s*,\\s*(" + simpleSingularBackgroundRegexS + "))*" +
|
3860 | "\\s*$",
|
3861 | simpleSingularBackgroundRegex = new RegExp(simpleSingularBackgroundRegexS, "g"),
|
3862 | outerRepeatedMatch,
|
3863 | backgroundLayers = [],
|
3864 | getValues = function (singularBackgroundDeclaration) {
|
3865 | var valueRegex = new RegExp(valueRegexS, "g"),
|
3866 | backgroundValues = [],
|
3867 | repeatedMatch;
|
3868 |
|
3869 | repeatedMatch = valueRegex.exec(singularBackgroundDeclaration);
|
3870 | while (repeatedMatch) {
|
3871 | backgroundValues.push(repeatedMatch[1]);
|
3872 | repeatedMatch = valueRegex.exec(singularBackgroundDeclaration);
|
3873 | }
|
3874 | return backgroundValues;
|
3875 | };
|
3876 |
|
3877 | if (backgroundDeclarationText.match(new RegExp(simpleBackgroundRegexS))) {
|
3878 | outerRepeatedMatch = simpleSingularBackgroundRegex.exec(backgroundDeclarationText);
|
3879 | while (outerRepeatedMatch) {
|
3880 | backgroundLayers.push(getValues(outerRepeatedMatch[0]));
|
3881 | outerRepeatedMatch = simpleSingularBackgroundRegex.exec(backgroundDeclarationText);
|
3882 | }
|
3883 |
|
3884 | return backgroundLayers;
|
3885 | }
|
3886 | return [];
|
3887 | };
|
3888 |
|
3889 | var findBackgroundImageUrlInValues = function (values) {
|
3890 | var i, url;
|
3891 |
|
3892 | for(i = 0; i < values.length; i++) {
|
3893 | try {
|
3894 | url = exports.extractCssUrl(values[i]);
|
3895 | return {
|
3896 | url: url,
|
3897 | idx: i
|
3898 | };
|
3899 | } catch (e) {}
|
3900 | }
|
3901 | };
|
3902 |
|
3903 | exports.parse = function (backgroundValue) {
|
3904 | var backgroundLayers = sliceBackgroundDeclaration(backgroundValue);
|
3905 |
|
3906 | return backgroundLayers.map(function (backgroundLayerValues) {
|
3907 | var urlMatch = findBackgroundImageUrlInValues(backgroundLayerValues);
|
3908 |
|
3909 | if (urlMatch) {
|
3910 | return {
|
3911 | preUrl: backgroundLayerValues.slice(0, urlMatch.idx),
|
3912 | url: urlMatch.url,
|
3913 | postUrl: backgroundLayerValues.slice(urlMatch.idx+1),
|
3914 | };
|
3915 | } else {
|
3916 | return {
|
3917 | preUrl: backgroundLayerValues
|
3918 | };
|
3919 | }
|
3920 | });
|
3921 | };
|
3922 |
|
3923 | exports.serialize = function (parsedBackground) {
|
3924 | var backgroundLayers = parsedBackground.map(function (backgroundLayer) {
|
3925 | var values = [].concat(backgroundLayer.preUrl);
|
3926 |
|
3927 | if (backgroundLayer.url) {
|
3928 | values.push('url("' + backgroundLayer.url + '")');
|
3929 | }
|
3930 | if (backgroundLayer.postUrl) {
|
3931 | values = values.concat(backgroundLayer.postUrl);
|
3932 | }
|
3933 |
|
3934 | return values.join(' ');
|
3935 | });
|
3936 |
|
3937 | return backgroundLayers.join(', ');
|
3938 | };
|
3939 |
|
3940 | },{"./cssSupport":29}],29:[function(require,module,exports){
|
3941 | "use strict";
|
3942 |
|
3943 | var cssom;
|
3944 |
|
3945 | try {
|
3946 | cssom = require('cssom');
|
3947 | } catch (e) {
|
3948 | }
|
3949 |
|
3950 |
|
3951 | exports.unquoteString = function (quotedUrl) {
|
3952 | var doubleQuoteRegex = /^"(.*)"$/,
|
3953 | singleQuoteRegex = /^'(.*)'$/;
|
3954 |
|
3955 | if (doubleQuoteRegex.test(quotedUrl)) {
|
3956 | return quotedUrl.replace(doubleQuoteRegex, "$1");
|
3957 | } else {
|
3958 | if (singleQuoteRegex.test(quotedUrl)) {
|
3959 | return quotedUrl.replace(singleQuoteRegex, "$1");
|
3960 | } else {
|
3961 | return quotedUrl;
|
3962 | }
|
3963 | }
|
3964 | };
|
3965 |
|
3966 | var rulesForCssTextFromBrowser = function (styleContent) {
|
3967 | var doc = document.implementation.createHTMLDocument(""),
|
3968 | styleElement = document.createElement("style"),
|
3969 | rules;
|
3970 |
|
3971 | styleElement.textContent = styleContent;
|
3972 | // the style will only be parsed once it is added to a document
|
3973 | doc.body.appendChild(styleElement);
|
3974 | rules = styleElement.sheet.cssRules;
|
3975 |
|
3976 | return Array.prototype.slice.call(rules);
|
3977 | };
|
3978 |
|
3979 | var browserHasBackgroundImageUrlIssue = (function () {
|
3980 | // Checks for http://code.google.com/p/chromium/issues/detail?id=161644
|
3981 | var rules = rulesForCssTextFromBrowser('a{background:url(i)}');
|
3982 | return !rules.length || rules[0].cssText.indexOf('url()') >= 0;
|
3983 | }());
|
3984 |
|
3985 | var browserHasFontFaceUrlIssue = (function () {
|
3986 | // Checks for https://bugs.chromium.org/p/chromium/issues/detail?id=588129
|
3987 | var rules = rulesForCssTextFromBrowser('@font-face { font-family: "f"; src: url("f"); }');
|
3988 | return !rules.length || /url\(['"]*\)/.test(rules[0].cssText);
|
3989 | }());
|
3990 |
|
3991 | var browserHasBackgroundImageUrlSetIssue = (function () {
|
3992 | // Checks for https://bugs.chromium.org/p/chromium/issues/detail?id=660663
|
3993 | var rules = rulesForCssTextFromBrowser('a{background:url(old)}');
|
3994 | rules[0].style.setProperty('background', 'url(new)', '');
|
3995 | return rules[0].style.getPropertyValue('background').indexOf('old') >= 0;
|
3996 | }());
|
3997 |
|
3998 | exports.rulesForCssText = function (styleContent) {
|
3999 | if ((browserHasBackgroundImageUrlIssue || browserHasFontFaceUrlIssue || browserHasBackgroundImageUrlSetIssue) && cssom && cssom.parse) {
|
4000 | return cssom.parse(styleContent).cssRules;
|
4001 | } else {
|
4002 | return rulesForCssTextFromBrowser(styleContent);
|
4003 | }
|
4004 | };
|
4005 |
|
4006 | exports.cssRulesToText = function (cssRules) {
|
4007 | return cssRules.reduce(function (cssText, rule) {
|
4008 | return cssText + rule.cssText;
|
4009 | }, '');
|
4010 | };
|
4011 |
|
4012 | exports.exchangeRule = function (cssRules, rule, newRuleText) {
|
4013 | var ruleIdx = cssRules.indexOf(rule);
|
4014 |
|
4015 | // We create a new document and stylesheet to parse the rule,
|
4016 | // instead of relying on rule.parentStyleSheet, because
|
4017 | // rule.parentStyleSheet may be null
|
4018 | // (https://github.com/cburgmer/inlineresources/issues/3)
|
4019 | cssRules[ruleIdx] = exports.rulesForCssText(newRuleText)[0];
|
4020 | };
|
4021 |
|
4022 | // Workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=443978
|
4023 | exports.changeFontFaceRuleSrc = function (cssRules, rule, newSrc) {
|
4024 | var newRuleText = '@font-face { font-family: ' + rule.style.getPropertyValue("font-family") + '; ';
|
4025 |
|
4026 | if (rule.style.getPropertyValue("font-style")) {
|
4027 | newRuleText += 'font-style: ' + rule.style.getPropertyValue("font-style") + '; ';
|
4028 | }
|
4029 |
|
4030 | if (rule.style.getPropertyValue("font-weight")) {
|
4031 | newRuleText += 'font-weight: ' + rule.style.getPropertyValue("font-weight") + '; ';
|
4032 | }
|
4033 |
|
4034 | newRuleText += 'src: ' + newSrc + '}';
|
4035 | exports.exchangeRule(cssRules, rule, newRuleText);
|
4036 | };
|
4037 |
|
4038 | },{"cssom":26}],30:[function(require,module,exports){
|
4039 | "use strict";
|
4040 |
|
4041 | var util = require('./util'),
|
4042 | inlineImage = require('./inlineImage'),
|
4043 | inlineScript = require('./inlineScript'),
|
4044 | inlineCss = require('./inlineCss'),
|
4045 | cssSupport = require('./cssSupport');
|
4046 |
|
4047 |
|
4048 | var getUrlBasePath = function (url) {
|
4049 | return util.joinUrl(url, '.');
|
4050 | };
|
4051 |
|
4052 | var parameterHashFunction = function (params) {
|
4053 | // HACK JSON.stringify is poor man's hashing;
|
4054 | // same objects might not receive same result as key order is not guaranteed
|
4055 | var a = params.map(function (param, idx) {
|
4056 | // Only include options relevant for method
|
4057 | if (idx === (params.length - 1)) {
|
4058 | param = {
|
4059 | // Two different HTML pages on the same path level have the same base path, but a different URL
|
4060 | baseUrl: getUrlBasePath(param.baseUrl)
|
4061 | };
|
4062 | }
|
4063 | return JSON.stringify(param);
|
4064 | });
|
4065 | return a;
|
4066 | };
|
4067 |
|
4068 | var memoizeFunctionOnCaching = function (func, options) {
|
4069 | if ((options.cache !== false && options.cache !== 'none') && options.cacheBucket) {
|
4070 | return util.memoize(func, parameterHashFunction, options.cacheBucket);
|
4071 | } else {
|
4072 | return func;
|
4073 | }
|
4074 | };
|
4075 |
|
4076 | /* Style inlining */
|
4077 |
|
4078 | var requestExternalsForStylesheet = function (styleContent, alreadyLoadedCssUrls, options) {
|
4079 | var cssRules = cssSupport.rulesForCssText(styleContent);
|
4080 |
|
4081 | return inlineCss.loadCSSImportsForRules(cssRules, alreadyLoadedCssUrls, options).then(function (cssImportResult) {
|
4082 | return inlineCss.loadAndInlineCSSResourcesForRules(cssRules, options).then(function (cssResourcesResult) {
|
4083 | var errors = cssImportResult.errors.concat(cssResourcesResult.errors),
|
4084 | hasChanges = cssImportResult.hasChanges || cssResourcesResult.hasChanges;
|
4085 |
|
4086 | if (hasChanges) {
|
4087 | styleContent = cssSupport.cssRulesToText(cssRules);
|
4088 | }
|
4089 |
|
4090 | return {
|
4091 | hasChanges: hasChanges,
|
4092 | content: styleContent,
|
4093 | errors: errors
|
4094 | };
|
4095 | });
|
4096 | });
|
4097 | };
|
4098 |
|
4099 | var loadAndInlineCssForStyle = function (style, options, alreadyLoadedCssUrls) {
|
4100 | var styleContent = style.textContent,
|
4101 | processExternals = memoizeFunctionOnCaching(requestExternalsForStylesheet, options);
|
4102 |
|
4103 | return processExternals(styleContent, alreadyLoadedCssUrls, options).then(function (result) {
|
4104 | if (result.hasChanges) {
|
4105 | style.childNodes[0].nodeValue = result.content;
|
4106 | }
|
4107 |
|
4108 | return util.cloneArray(result.errors);
|
4109 | });
|
4110 | };
|
4111 |
|
4112 | var getCssStyleElements = function (doc) {
|
4113 | var styles = doc.getElementsByTagName("style");
|
4114 |
|
4115 | return Array.prototype.filter.call(styles, function (style) {
|
4116 | return !style.attributes.type || style.attributes.type.value === "text/css";
|
4117 | });
|
4118 | };
|
4119 |
|
4120 | exports.loadAndInlineStyles = function (doc, options) {
|
4121 | var styles = getCssStyleElements(doc),
|
4122 | allErrors = [],
|
4123 | alreadyLoadedCssUrls = [],
|
4124 | inlineOptions;
|
4125 |
|
4126 | inlineOptions = util.clone(options);
|
4127 | inlineOptions.baseUrl = inlineOptions.baseUrl || util.getDocumentBaseUrl(doc);
|
4128 |
|
4129 | return util.all(styles.map(function (style) {
|
4130 | return loadAndInlineCssForStyle(style, inlineOptions, alreadyLoadedCssUrls).then(function (errors) {
|
4131 | allErrors = allErrors.concat(errors);
|
4132 | });
|
4133 | })).then(function () {
|
4134 | return allErrors;
|
4135 | });
|
4136 | };
|
4137 |
|
4138 | /* CSS link inlining */
|
4139 |
|
4140 | var substituteLinkWithInlineStyle = function (oldLinkNode, styleContent) {
|
4141 | var parent = oldLinkNode.parentNode,
|
4142 | styleNode;
|
4143 |
|
4144 | styleContent = styleContent.trim();
|
4145 | if (styleContent) {
|
4146 | styleNode = oldLinkNode.ownerDocument.createElement("style");
|
4147 | styleNode.type = "text/css";
|
4148 | styleNode.appendChild(oldLinkNode.ownerDocument.createTextNode(styleContent));
|
4149 |
|
4150 | parent.insertBefore(styleNode, oldLinkNode);
|
4151 | }
|
4152 |
|
4153 | parent.removeChild(oldLinkNode);
|
4154 | };
|
4155 |
|
4156 | var requestStylesheetAndInlineResources = function (url, options) {
|
4157 | return util.ajax(url, options)
|
4158 | .then(function (content) {
|
4159 | var cssRules = cssSupport.rulesForCssText(content);
|
4160 |
|
4161 | return {
|
4162 | content: content,
|
4163 | cssRules: cssRules
|
4164 | };
|
4165 | })
|
4166 | .then(function (result) {
|
4167 | var hasChangesFromPathAdjustment = inlineCss.adjustPathsOfCssResources(url, result.cssRules);
|
4168 |
|
4169 | return {
|
4170 | content: result.content,
|
4171 | cssRules: result.cssRules,
|
4172 | hasChanges: hasChangesFromPathAdjustment
|
4173 | };
|
4174 | })
|
4175 | .then(function (result) {
|
4176 | return inlineCss.loadCSSImportsForRules(result.cssRules, [], options)
|
4177 | .then(function (cssImportResult) {
|
4178 | return {
|
4179 | content: result.content,
|
4180 | cssRules: result.cssRules,
|
4181 | hasChanges: result.hasChanges || cssImportResult.hasChanges,
|
4182 | errors: cssImportResult.errors
|
4183 | };
|
4184 | });
|
4185 | })
|
4186 | .then(function (result) {
|
4187 | return inlineCss.loadAndInlineCSSResourcesForRules(result.cssRules, options)
|
4188 | .then(function (cssResourcesResult) {
|
4189 | return {
|
4190 | content: result.content,
|
4191 | cssRules: result.cssRules,
|
4192 | hasChanges: result.hasChanges || cssResourcesResult.hasChanges,
|
4193 | errors: result.errors.concat(cssResourcesResult.errors)
|
4194 | };
|
4195 | });
|
4196 | })
|
4197 | .then(function (result) {
|
4198 | var content = result.content;
|
4199 | if (result.hasChanges) {
|
4200 | content = cssSupport.cssRulesToText(result.cssRules);
|
4201 | }
|
4202 | return {
|
4203 | content: content,
|
4204 | errors: result.errors
|
4205 | };
|
4206 | });
|
4207 | };
|
4208 |
|
4209 | var loadLinkedCSS = function (link, options) {
|
4210 | var cssHref = link.attributes.href.value,
|
4211 | documentBaseUrl = util.getDocumentBaseUrl(link.ownerDocument),
|
4212 | ajaxOptions = util.clone(options);
|
4213 |
|
4214 | if (!ajaxOptions.baseUrl && documentBaseUrl) {
|
4215 | ajaxOptions.baseUrl = documentBaseUrl;
|
4216 | }
|
4217 |
|
4218 | var processStylesheet = memoizeFunctionOnCaching(requestStylesheetAndInlineResources, options);
|
4219 |
|
4220 | return processStylesheet(cssHref, ajaxOptions).then(function (result) {
|
4221 | return {
|
4222 | content: result.content,
|
4223 | errors: util.cloneArray(result.errors)
|
4224 | };
|
4225 | });
|
4226 | };
|
4227 |
|
4228 | var getCssStylesheetLinks = function (doc) {
|
4229 | var links = doc.getElementsByTagName("link");
|
4230 |
|
4231 | return Array.prototype.filter.call(links, function (link) {
|
4232 | return link.attributes.rel && link.attributes.rel.value === "stylesheet" &&
|
4233 | (!link.attributes.type || link.attributes.type.value === "text/css");
|
4234 | });
|
4235 | };
|
4236 |
|
4237 | exports.loadAndInlineCssLinks = function (doc, options) {
|
4238 | var links = getCssStylesheetLinks(doc),
|
4239 | errors = [];
|
4240 |
|
4241 | return util.all(links.map(function (link) {
|
4242 | return loadLinkedCSS(link, options).then(function(result) {
|
4243 | substituteLinkWithInlineStyle(link, result.content + "\n");
|
4244 |
|
4245 | errors = errors.concat(result.errors);
|
4246 | }, function (e) {
|
4247 | errors.push({
|
4248 | resourceType: "stylesheet",
|
4249 | url: e.url,
|
4250 | msg: "Unable to load stylesheet " + e.url
|
4251 | });
|
4252 | });
|
4253 | })).then(function () {
|
4254 | return errors;
|
4255 | });
|
4256 | };
|
4257 |
|
4258 | /* Main */
|
4259 |
|
4260 | exports.loadAndInlineImages = inlineImage.inline;
|
4261 | exports.loadAndInlineScript = inlineScript.inline;
|
4262 |
|
4263 | exports.inlineReferences = function (doc, options) {
|
4264 | var allErrors = [],
|
4265 | inlineFuncs = [
|
4266 | exports.loadAndInlineImages,
|
4267 | exports.loadAndInlineStyles,
|
4268 | exports.loadAndInlineCssLinks];
|
4269 |
|
4270 | if (options.inlineScripts !== false) {
|
4271 | inlineFuncs.push(exports.loadAndInlineScript);
|
4272 | }
|
4273 |
|
4274 | return util.all(inlineFuncs.map(function (func) {
|
4275 | return func(doc, options)
|
4276 | .then(function (errors) {
|
4277 | allErrors = allErrors.concat(errors);
|
4278 | });
|
4279 | })).then(function () {
|
4280 | return allErrors;
|
4281 | });
|
4282 | };
|
4283 |
|
4284 | },{"./cssSupport":29,"./inlineCss":31,"./inlineImage":32,"./inlineScript":33,"./util":34}],31:[function(require,module,exports){
|
4285 | "use strict";
|
4286 |
|
4287 | var ayepromise = require('ayepromise'),
|
4288 | util = require('./util'),
|
4289 | cssSupport = require('./cssSupport'),
|
4290 | backgroundValueParser = require('./backgroundValueParser'),
|
4291 | fontFaceSrcValueParser = require('css-font-face-src');
|
4292 |
|
4293 |
|
4294 | var updateCssPropertyValue = function (rule, property, value) {
|
4295 | rule.style.setProperty(property, value, rule.style.getPropertyPriority(property));
|
4296 | };
|
4297 |
|
4298 | var findBackgroundImageRules = function (cssRules) {
|
4299 | return cssRules.filter(function (rule) {
|
4300 | return rule.type === window.CSSRule.STYLE_RULE && (rule.style.getPropertyValue('background-image') || rule.style.getPropertyValue('background'));
|
4301 | });
|
4302 | };
|
4303 |
|
4304 | var findBackgroundDeclarations = function (rules) {
|
4305 | var backgroundDeclarations = [];
|
4306 |
|
4307 | rules.forEach(function (rule) {
|
4308 | if (rule.style.getPropertyValue('background-image')) {
|
4309 | backgroundDeclarations.push({
|
4310 | property: 'background-image',
|
4311 | value: rule.style.getPropertyValue('background-image'),
|
4312 | rule: rule
|
4313 | });
|
4314 | } else if (rule.style.getPropertyValue('background')) {
|
4315 | backgroundDeclarations.push({
|
4316 | property: 'background',
|
4317 | value: rule.style.getPropertyValue('background'),
|
4318 | rule: rule
|
4319 | });
|
4320 | }
|
4321 | });
|
4322 |
|
4323 | return backgroundDeclarations;
|
4324 | };
|
4325 |
|
4326 | var findFontFaceRules = function (cssRules) {
|
4327 | return cssRules.filter(function (rule) {
|
4328 | return rule.type === window.CSSRule.FONT_FACE_RULE && rule.style.getPropertyValue("src");
|
4329 | });
|
4330 | };
|
4331 |
|
4332 | var findCSSImportRules = function (cssRules) {
|
4333 | return cssRules.filter(function (rule) {
|
4334 | return rule.type === window.CSSRule.IMPORT_RULE && rule.href;
|
4335 | });
|
4336 | };
|
4337 |
|
4338 | var findExternalBackgroundUrls = function (parsedBackground) {
|
4339 | var matchIndices = [];
|
4340 |
|
4341 | parsedBackground.forEach(function (backgroundLayer, i) {
|
4342 | if (backgroundLayer.url && !util.isDataUri(backgroundLayer.url)) {
|
4343 | matchIndices.push(i);
|
4344 | }
|
4345 | });
|
4346 |
|
4347 | return matchIndices;
|
4348 | };
|
4349 |
|
4350 | var findExternalFontFaceUrls = function (parsedFontFaceSources) {
|
4351 | var sourceIndices = [];
|
4352 | parsedFontFaceSources.forEach(function (sourceItem, i) {
|
4353 | if (sourceItem.url && !util.isDataUri(sourceItem.url)) {
|
4354 | sourceIndices.push(i);
|
4355 | }
|
4356 | });
|
4357 | return sourceIndices;
|
4358 | };
|
4359 |
|
4360 | exports.adjustPathsOfCssResources = function (baseUrl, cssRules) {
|
4361 | var backgroundRules = findBackgroundImageRules(cssRules),
|
4362 | backgroundDeclarations = findBackgroundDeclarations(backgroundRules),
|
4363 | change = false;
|
4364 |
|
4365 | backgroundDeclarations.forEach(function (declaration) {
|
4366 | var parsedBackground = backgroundValueParser.parse(declaration.value),
|
4367 | externalBackgroundIndices = findExternalBackgroundUrls(parsedBackground),
|
4368 | backgroundValue;
|
4369 |
|
4370 | if (externalBackgroundIndices.length > 0) {
|
4371 | externalBackgroundIndices.forEach(function (backgroundLayerIndex) {
|
4372 | var relativeUrl = parsedBackground[backgroundLayerIndex].url,
|
4373 | url = util.joinUrl(baseUrl, relativeUrl);
|
4374 | parsedBackground[backgroundLayerIndex].url = url;
|
4375 | });
|
4376 |
|
4377 | backgroundValue = backgroundValueParser.serialize(parsedBackground);
|
4378 |
|
4379 | updateCssPropertyValue(declaration.rule, declaration.property, backgroundValue);
|
4380 |
|
4381 | change = true;
|
4382 | }
|
4383 | });
|
4384 | findFontFaceRules(cssRules).forEach(function (rule) {
|
4385 | var fontFaceSrcDeclaration = rule.style.getPropertyValue("src"),
|
4386 | parsedFontFaceSources, externalFontFaceUrlIndices;
|
4387 |
|
4388 | try {
|
4389 | parsedFontFaceSources = fontFaceSrcValueParser.parse(fontFaceSrcDeclaration);
|
4390 | } catch (e) {
|
4391 | return;
|
4392 | }
|
4393 | externalFontFaceUrlIndices = findExternalFontFaceUrls(parsedFontFaceSources);
|
4394 |
|
4395 | if (externalFontFaceUrlIndices.length > 0) {
|
4396 | externalFontFaceUrlIndices.forEach(function (fontFaceUrlIndex) {
|
4397 | var relativeUrl = parsedFontFaceSources[fontFaceUrlIndex].url,
|
4398 | url = util.joinUrl(baseUrl, relativeUrl);
|
4399 |
|
4400 | parsedFontFaceSources[fontFaceUrlIndex].url = url;
|
4401 | });
|
4402 |
|
4403 | cssSupport.changeFontFaceRuleSrc(cssRules, rule, fontFaceSrcValueParser.serialize(parsedFontFaceSources));
|
4404 |
|
4405 | change = true;
|
4406 | }
|
4407 | });
|
4408 | findCSSImportRules(cssRules).forEach(function (rule) {
|
4409 | var cssUrl = rule.href,
|
4410 | url = util.joinUrl(baseUrl, cssUrl);
|
4411 |
|
4412 | cssSupport.exchangeRule(cssRules, rule, "@import url(" + url + ");");
|
4413 |
|
4414 | change = true;
|
4415 | });
|
4416 |
|
4417 | return change;
|
4418 | };
|
4419 |
|
4420 | /* CSS import inlining */
|
4421 |
|
4422 | var substituteRule = function (cssRules, rule, newCssRules) {
|
4423 | var position = cssRules.indexOf(rule);
|
4424 |
|
4425 | cssRules.splice(position, 1);
|
4426 |
|
4427 | newCssRules.forEach(function (newRule, i) {
|
4428 | cssRules.splice(position + i, 0, newRule);
|
4429 | });
|
4430 | };
|
4431 |
|
4432 | var fulfilledPromise = function (value) {
|
4433 | var defer = ayepromise.defer();
|
4434 | defer.resolve(value);
|
4435 | return defer.promise;
|
4436 | };
|
4437 |
|
4438 | var loadAndInlineCSSImport = function (cssRules, rule, alreadyLoadedCssUrls, options) {
|
4439 | var url = rule.href,
|
4440 | cssHrefRelativeToDoc;
|
4441 |
|
4442 | url = cssSupport.unquoteString(url);
|
4443 |
|
4444 | cssHrefRelativeToDoc = util.joinUrl(options.baseUrl, url);
|
4445 |
|
4446 | if (alreadyLoadedCssUrls.indexOf(cssHrefRelativeToDoc) >= 0) {
|
4447 | // Remove URL by adding empty string
|
4448 | substituteRule(cssRules, rule, []);
|
4449 | return fulfilledPromise([]);
|
4450 | } else {
|
4451 | alreadyLoadedCssUrls.push(cssHrefRelativeToDoc);
|
4452 | }
|
4453 |
|
4454 | return util.ajax(url, options)
|
4455 | .then(function (cssText) {
|
4456 | var externalCssRules = cssSupport.rulesForCssText(cssText);
|
4457 |
|
4458 | // Recursively follow @import statements
|
4459 | return exports.loadCSSImportsForRules(externalCssRules, alreadyLoadedCssUrls, options)
|
4460 | .then(function (result) {
|
4461 | exports.adjustPathsOfCssResources(url, externalCssRules);
|
4462 |
|
4463 | substituteRule(cssRules, rule, externalCssRules);
|
4464 |
|
4465 | return result.errors;
|
4466 | });
|
4467 | }, function (e) {
|
4468 | throw {
|
4469 | resourceType: "stylesheet",
|
4470 | url: e.url,
|
4471 | msg: "Unable to load stylesheet " + e.url
|
4472 | };
|
4473 | });
|
4474 | };
|
4475 |
|
4476 | exports.loadCSSImportsForRules = function (cssRules, alreadyLoadedCssUrls, options) {
|
4477 | var rulesToInline = findCSSImportRules(cssRules),
|
4478 | errors = [],
|
4479 | hasChanges = false;
|
4480 |
|
4481 | return util.all(rulesToInline.map(function (rule) {
|
4482 | return loadAndInlineCSSImport(cssRules, rule, alreadyLoadedCssUrls, options).then(function (moreErrors) {
|
4483 | errors = errors.concat(moreErrors);
|
4484 |
|
4485 | hasChanges = true;
|
4486 | }, function (e) {
|
4487 | errors.push(e);
|
4488 | });
|
4489 | })).then(function () {
|
4490 | return {
|
4491 | hasChanges: hasChanges,
|
4492 | errors: errors
|
4493 | };
|
4494 | });
|
4495 | };
|
4496 |
|
4497 | /* CSS linked resource inlining */
|
4498 |
|
4499 | var loadAndInlineBackgroundImages = function (backgroundValue, options) {
|
4500 | var parsedBackground = backgroundValueParser.parse(backgroundValue),
|
4501 | externalBackgroundLayerIndices = findExternalBackgroundUrls(parsedBackground),
|
4502 | hasChanges = false;
|
4503 |
|
4504 | return util.collectAndReportErrors(externalBackgroundLayerIndices.map(function (backgroundLayerIndex) {
|
4505 | var url = parsedBackground[backgroundLayerIndex].url;
|
4506 |
|
4507 | return util.getDataURIForImageURL(url, options)
|
4508 | .then(function (dataURI) {
|
4509 | parsedBackground[backgroundLayerIndex].url = dataURI;
|
4510 |
|
4511 | hasChanges = true;
|
4512 | }, function (e) {
|
4513 | throw {
|
4514 | resourceType: "backgroundImage",
|
4515 | url: e.url,
|
4516 | msg: "Unable to load background-image " + e.url
|
4517 | };
|
4518 | });
|
4519 | })).then(function (errors) {
|
4520 | return {
|
4521 | backgroundValue: backgroundValueParser.serialize(parsedBackground),
|
4522 | hasChanges: hasChanges,
|
4523 | errors: errors
|
4524 | };
|
4525 | });
|
4526 | };
|
4527 |
|
4528 | var iterateOverRulesAndInlineBackgroundImages = function (cssRules, options) {
|
4529 | var rulesToInline = findBackgroundImageRules(cssRules),
|
4530 | backgroundDeclarations = findBackgroundDeclarations(rulesToInline),
|
4531 | errors = [],
|
4532 | cssHasChanges = false;
|
4533 |
|
4534 | return util.all(backgroundDeclarations.map(function (declaration) {
|
4535 | return loadAndInlineBackgroundImages(declaration.value, options)
|
4536 | .then(function (result) {
|
4537 | if (result.hasChanges) {
|
4538 | updateCssPropertyValue(declaration.rule, declaration.property, result.backgroundValue);
|
4539 |
|
4540 | cssHasChanges = true;
|
4541 | }
|
4542 |
|
4543 | errors = errors.concat(result.errors);
|
4544 | });
|
4545 | })).then(function () {
|
4546 | return {
|
4547 | hasChanges: cssHasChanges,
|
4548 | errors: errors
|
4549 | };
|
4550 | });
|
4551 | };
|
4552 |
|
4553 | var loadAndInlineFontFace = function (srcDeclarationValue, options) {
|
4554 | var hasChanges = false,
|
4555 | parsedFontFaceSources, externalFontFaceUrlIndices;
|
4556 |
|
4557 | try {
|
4558 | parsedFontFaceSources = fontFaceSrcValueParser.parse(srcDeclarationValue);
|
4559 | } catch (e) {
|
4560 | parsedFontFaceSources = [];
|
4561 | }
|
4562 | externalFontFaceUrlIndices = findExternalFontFaceUrls(parsedFontFaceSources);
|
4563 |
|
4564 | return util.collectAndReportErrors(externalFontFaceUrlIndices.map(function (urlIndex) {
|
4565 | var fontSrc = parsedFontFaceSources[urlIndex],
|
4566 | format = fontSrc.format || "woff";
|
4567 |
|
4568 | return util.binaryAjax(fontSrc.url, options)
|
4569 | .then(function (content) {
|
4570 | var base64Content = btoa(content);
|
4571 | fontSrc.url = 'data:font/' + format + ';base64,' + base64Content;
|
4572 |
|
4573 | hasChanges = true;
|
4574 | }, function (e) {
|
4575 | throw {
|
4576 | resourceType: "fontFace",
|
4577 | url: e.url,
|
4578 | msg: "Unable to load font-face " + e.url
|
4579 | };
|
4580 | });
|
4581 | })).then(function (errors) {
|
4582 | return {
|
4583 | srcDeclarationValue: fontFaceSrcValueParser.serialize(parsedFontFaceSources),
|
4584 | hasChanges: hasChanges,
|
4585 | errors: errors
|
4586 | };
|
4587 | });
|
4588 | };
|
4589 |
|
4590 | var iterateOverRulesAndInlineFontFace = function (cssRules, options) {
|
4591 | var rulesToInline = findFontFaceRules(cssRules),
|
4592 | errors = [],
|
4593 | hasChanges = false;
|
4594 |
|
4595 | return util.all(rulesToInline.map(function (rule) {
|
4596 | var srcDeclarationValue = rule.style.getPropertyValue("src");
|
4597 |
|
4598 | return loadAndInlineFontFace(srcDeclarationValue, options).then(function (result) {
|
4599 | if (result.hasChanges) {
|
4600 | cssSupport.changeFontFaceRuleSrc(cssRules, rule, result.srcDeclarationValue);
|
4601 |
|
4602 | hasChanges = true;
|
4603 | }
|
4604 |
|
4605 | errors = errors.concat(result.errors);
|
4606 | });
|
4607 | })).then(function () {
|
4608 | return {
|
4609 | hasChanges: hasChanges,
|
4610 | errors: errors
|
4611 | };
|
4612 | });
|
4613 | };
|
4614 |
|
4615 | exports.loadAndInlineCSSResourcesForRules = function (cssRules, options) {
|
4616 | var hasChanges = false,
|
4617 | errors = [];
|
4618 |
|
4619 | return util.all([iterateOverRulesAndInlineBackgroundImages, iterateOverRulesAndInlineFontFace].map(function (func) {
|
4620 | return func(cssRules, options)
|
4621 | .then(function (result) {
|
4622 | hasChanges = hasChanges || result.hasChanges;
|
4623 | errors = errors.concat(result.errors);
|
4624 | });
|
4625 | })).then(function () {
|
4626 | return {
|
4627 | hasChanges: hasChanges,
|
4628 | errors: errors
|
4629 | };
|
4630 | });
|
4631 | };
|
4632 |
|
4633 | },{"./backgroundValueParser":28,"./cssSupport":29,"./util":34,"ayepromise":2,"css-font-face-src":6}],32:[function(require,module,exports){
|
4634 | "use strict";
|
4635 |
|
4636 | var util = require('./util');
|
4637 |
|
4638 |
|
4639 | var encodeImageAsDataURI = function (image, options) {
|
4640 | var url = null;
|
4641 | if(image.hasAttribute('src')){
|
4642 | url = image.getAttribute('src');
|
4643 | }
|
4644 | else if(image.hasAttributeNS('http://www.w3.org/1999/xlink','href')){
|
4645 | url = image.getAttributeNS('http://www.w3.org/1999/xlink','href');
|
4646 | }
|
4647 | else if(image.hasAttribute('href')){
|
4648 | url = image.getAttribute('href');
|
4649 | }
|
4650 | var documentBase = util.getDocumentBaseUrl(image.ownerDocument),
|
4651 | ajaxOptions = util.clone(options);
|
4652 |
|
4653 | if (!ajaxOptions.baseUrl && documentBase) {
|
4654 | ajaxOptions.baseUrl = documentBase;
|
4655 | }
|
4656 |
|
4657 | return util.getDataURIForImageURL(url, ajaxOptions)
|
4658 | .then(function (dataURI) {
|
4659 | return dataURI;
|
4660 | }, function (e) {
|
4661 | throw {
|
4662 | resourceType: "image",
|
4663 | url: e.url,
|
4664 | msg: "Unable to load image " + e.url
|
4665 | };
|
4666 | });
|
4667 | };
|
4668 |
|
4669 | var filterExternalImages = function (images) {
|
4670 | return images.filter(function (image) {
|
4671 | var url = null;
|
4672 | if(image.hasAttribute('src')){
|
4673 | url = image.getAttribute('src');
|
4674 | }
|
4675 | else if(image.hasAttributeNS('http://www.w3.org/1999/xlink','href')){
|
4676 | url = image.getAttributeNS('http://www.w3.org/1999/xlink','href');
|
4677 | }
|
4678 | else if(image.hasAttribute('href')){
|
4679 | url = image.getAttribute('href');
|
4680 | }
|
4681 |
|
4682 | return url !== null && !util.isDataUri(url);
|
4683 | });
|
4684 | };
|
4685 |
|
4686 | var filterInputsForImageType = function (inputs) {
|
4687 | return Array.prototype.filter.call(inputs, function (input) {
|
4688 | return input.type === "image";
|
4689 | });
|
4690 | };
|
4691 |
|
4692 | var toArray = function (arrayLike) {
|
4693 | return Array.prototype.slice.call(arrayLike);
|
4694 | };
|
4695 |
|
4696 | exports.inline = function (doc, options) {
|
4697 | var images = toArray(doc.getElementsByTagName("img")),
|
4698 | svgImages = toArray(doc.getElementsByTagName("image")),
|
4699 | imageInputs = filterInputsForImageType(doc.getElementsByTagName("input"));
|
4700 |
|
4701 | images = images.concat(svgImages);
|
4702 | images = images.concat(imageInputs);
|
4703 | var externalImages = filterExternalImages(images);
|
4704 |
|
4705 | return util.collectAndReportErrors(externalImages.map(function (image) {
|
4706 | return encodeImageAsDataURI(image, options).then(function (dataURI) {
|
4707 | if(!!image.attributes.src){
|
4708 | image.attributes.src.value = dataURI;
|
4709 | }
|
4710 | else if(!!image.attributes['xlink:href']){
|
4711 | image.attributes['xlink:href'].value = dataURI;
|
4712 | }
|
4713 | else if(!!image.attributes.href){
|
4714 | image.attributes.href.value = dataURI;
|
4715 | }
|
4716 | });
|
4717 | }));
|
4718 | };
|
4719 |
|
4720 | },{"./util":34}],33:[function(require,module,exports){
|
4721 | "use strict";
|
4722 |
|
4723 | var util = require('./util');
|
4724 |
|
4725 |
|
4726 | var loadLinkedScript = function (script, options) {
|
4727 | var src = script.attributes.src.value,
|
4728 | documentBase = util.getDocumentBaseUrl(script.ownerDocument),
|
4729 | ajaxOptions = util.clone(options);
|
4730 |
|
4731 | if (!ajaxOptions.baseUrl && documentBase) {
|
4732 | ajaxOptions.baseUrl = documentBase;
|
4733 | }
|
4734 |
|
4735 | return util.ajax(src, ajaxOptions)
|
4736 | .fail(function (e) {
|
4737 | throw {
|
4738 | resourceType: "script",
|
4739 | url: e.url,
|
4740 | msg: "Unable to load script " + e.url
|
4741 | };
|
4742 | });
|
4743 | };
|
4744 |
|
4745 | var escapeClosingTags = function (text) {
|
4746 | // http://stackoverflow.com/questions/9246382/escaping-script-tag-inside-javascript
|
4747 | return text.replace(/<\//g, '<\\/');
|
4748 | };
|
4749 |
|
4750 | var substituteExternalScriptWithInline = function (scriptNode, jsCode) {
|
4751 | scriptNode.attributes.removeNamedItem('src');
|
4752 | scriptNode.textContent = escapeClosingTags(jsCode);
|
4753 | };
|
4754 |
|
4755 | var getScripts = function (doc) {
|
4756 | var scripts = doc.getElementsByTagName("script");
|
4757 |
|
4758 | return Array.prototype.filter.call(scripts, function (script) {
|
4759 | return !!script.attributes.src;
|
4760 | });
|
4761 | };
|
4762 |
|
4763 | exports.inline = function (doc, options) {
|
4764 | var scripts = getScripts(doc);
|
4765 |
|
4766 | return util.collectAndReportErrors(scripts.map(function (script) {
|
4767 | return loadLinkedScript(script, options).then(function (jsCode) {
|
4768 | substituteExternalScriptWithInline(script, jsCode);
|
4769 | });
|
4770 | }));
|
4771 | };
|
4772 |
|
4773 | },{"./util":34}],34:[function(require,module,exports){
|
4774 | "use strict";
|
4775 |
|
4776 | var url = require('url'),
|
4777 | ayepromise = require('ayepromise');
|
4778 |
|
4779 |
|
4780 | exports.getDocumentBaseUrl = function (doc) {
|
4781 | if (doc.baseURI !== 'about:blank') {
|
4782 | return doc.baseURI;
|
4783 | }
|
4784 |
|
4785 | return null;
|
4786 | };
|
4787 |
|
4788 | exports.clone = function (object) {
|
4789 | var theClone = {},
|
4790 | i;
|
4791 | for (i in object) {
|
4792 | if (object.hasOwnProperty(i)) {
|
4793 | theClone[i] = object[i];
|
4794 | }
|
4795 | }
|
4796 | return theClone;
|
4797 | };
|
4798 |
|
4799 | exports.cloneArray = function (nodeList) {
|
4800 | return Array.prototype.slice.apply(nodeList, [0]);
|
4801 | };
|
4802 |
|
4803 | exports.joinUrl = function (baseUrl, relUrl) {
|
4804 | if (!baseUrl) {
|
4805 | return relUrl;
|
4806 | }
|
4807 | return url.resolve(baseUrl, relUrl);
|
4808 | };
|
4809 |
|
4810 | exports.isDataUri = function (url) {
|
4811 | return (/^data:/).test(url);
|
4812 | };
|
4813 |
|
4814 | exports.all = function (promises) {
|
4815 | var defer = ayepromise.defer(),
|
4816 | pendingPromiseCount = promises.length,
|
4817 | resolvedValues = [];
|
4818 |
|
4819 | if (promises.length === 0) {
|
4820 | defer.resolve([]);
|
4821 | return defer.promise;
|
4822 | }
|
4823 |
|
4824 | promises.forEach(function (promise, idx) {
|
4825 | promise.then(function (value) {
|
4826 | pendingPromiseCount -= 1;
|
4827 | resolvedValues[idx] = value;
|
4828 |
|
4829 | if (pendingPromiseCount === 0) {
|
4830 | defer.resolve(resolvedValues);
|
4831 | }
|
4832 | }, function (e) {
|
4833 | defer.reject(e);
|
4834 | });
|
4835 | });
|
4836 | return defer.promise;
|
4837 | };
|
4838 |
|
4839 | exports.collectAndReportErrors = function (promises) {
|
4840 | var errors = [];
|
4841 |
|
4842 | return exports.all(promises.map(function (promise) {
|
4843 | return promise.fail(function (e) {
|
4844 | errors.push(e);
|
4845 | });
|
4846 | })).then(function () {
|
4847 | return errors;
|
4848 | });
|
4849 | };
|
4850 |
|
4851 | var lastCacheDate = null;
|
4852 |
|
4853 | var getUncachableURL = function (url, cache) {
|
4854 | if (cache === false || cache === 'none' || cache === 'repeated') {
|
4855 | if (lastCacheDate === null || cache !== 'repeated') {
|
4856 | lastCacheDate = Date.now();
|
4857 | }
|
4858 | return url + "?_=" + lastCacheDate;
|
4859 | } else {
|
4860 | return url;
|
4861 | }
|
4862 | };
|
4863 |
|
4864 | exports.ajax = function (url, options) {
|
4865 | var ajaxRequest = new window.XMLHttpRequest(),
|
4866 | defer = ayepromise.defer(),
|
4867 | joinedUrl = exports.joinUrl(options.baseUrl, url),
|
4868 | augmentedUrl;
|
4869 |
|
4870 | var doReject = function () {
|
4871 | defer.reject({
|
4872 | msg: 'Unable to load url',
|
4873 | url: joinedUrl
|
4874 | });
|
4875 | };
|
4876 |
|
4877 | augmentedUrl = getUncachableURL(joinedUrl, options.cache);
|
4878 |
|
4879 | ajaxRequest.addEventListener("load", function () {
|
4880 | if (ajaxRequest.status === 200 || ajaxRequest.status === 0) {
|
4881 | defer.resolve(ajaxRequest.response);
|
4882 | } else {
|
4883 | doReject();
|
4884 | }
|
4885 | }, false);
|
4886 |
|
4887 | ajaxRequest.addEventListener("error", doReject, false);
|
4888 |
|
4889 | try {
|
4890 | ajaxRequest.open('GET', augmentedUrl, true);
|
4891 | ajaxRequest.overrideMimeType(options.mimeType);
|
4892 | ajaxRequest.send(null);
|
4893 | } catch (e) {
|
4894 | doReject();
|
4895 | }
|
4896 |
|
4897 | return defer.promise;
|
4898 | };
|
4899 |
|
4900 | exports.binaryAjax = function (url, options) {
|
4901 | var ajaxOptions = exports.clone(options);
|
4902 |
|
4903 | ajaxOptions.mimeType = 'text/plain; charset=x-user-defined';
|
4904 |
|
4905 | return exports.ajax(url, ajaxOptions)
|
4906 | .then(function (content) {
|
4907 | var binaryContent = "";
|
4908 |
|
4909 | for (var i = 0; i < content.length; i++) {
|
4910 | binaryContent += String.fromCharCode(content.charCodeAt(i) & 0xFF);
|
4911 | }
|
4912 |
|
4913 | return binaryContent;
|
4914 | });
|
4915 | };
|
4916 |
|
4917 | var detectMimeType = function (content) {
|
4918 | var startsWith = function (string, substring) {
|
4919 | return string.substring(0, substring.length) === substring;
|
4920 | };
|
4921 |
|
4922 | if (startsWith(content, '<?xml') || startsWith(content, '<svg')) {
|
4923 | return 'image/svg+xml';
|
4924 | }
|
4925 | return 'image/png';
|
4926 | };
|
4927 |
|
4928 | exports.getDataURIForImageURL = function (url, options) {
|
4929 | return exports.binaryAjax(url, options)
|
4930 | .then(function (content) {
|
4931 | var base64Content = btoa(content),
|
4932 | mimeType = detectMimeType(content);
|
4933 |
|
4934 | return 'data:' + mimeType + ';base64,' + base64Content;
|
4935 | });
|
4936 | };
|
4937 |
|
4938 | var uniqueIdList = [];
|
4939 |
|
4940 | var constantUniqueIdFor = function (element) {
|
4941 | // HACK, using a list results in O(n), but how do we hash a function?
|
4942 | if (uniqueIdList.indexOf(element) < 0) {
|
4943 | uniqueIdList.push(element);
|
4944 | }
|
4945 | return uniqueIdList.indexOf(element);
|
4946 | };
|
4947 |
|
4948 | exports.memoize = function (func, hasher, memo) {
|
4949 | if (typeof memo !== "object") {
|
4950 | throw new Error("cacheBucket is not an object");
|
4951 | }
|
4952 |
|
4953 | return function () {
|
4954 | var args = Array.prototype.slice.call(arguments);
|
4955 |
|
4956 | var argumentHash = hasher(args),
|
4957 | funcHash = constantUniqueIdFor(func),
|
4958 | retValue;
|
4959 |
|
4960 | if (memo[funcHash] && memo[funcHash][argumentHash]) {
|
4961 | return memo[funcHash][argumentHash];
|
4962 | } else {
|
4963 | retValue = func.apply(null, args);
|
4964 |
|
4965 | memo[funcHash] = memo[funcHash] || {};
|
4966 | memo[funcHash][argumentHash] = retValue;
|
4967 |
|
4968 | return retValue;
|
4969 | }
|
4970 | };
|
4971 | };
|
4972 |
|
4973 | },{"ayepromise":2,"url":3}],35:[function(require,module,exports){
|
4974 | (function (global){
|
4975 | /*! https://mths.be/punycode v1.3.2 by @mathias */
|
4976 | ;(function(root) {
|
4977 |
|
4978 | /** Detect free variables */
|
4979 | var freeExports = typeof exports == 'object' && exports &&
|
4980 | !exports.nodeType && exports;
|
4981 | var freeModule = typeof module == 'object' && module &&
|
4982 | !module.nodeType && module;
|
4983 | var freeGlobal = typeof global == 'object' && global;
|
4984 | if (
|
4985 | freeGlobal.global === freeGlobal ||
|
4986 | freeGlobal.window === freeGlobal ||
|
4987 | freeGlobal.self === freeGlobal
|
4988 | ) {
|
4989 | root = freeGlobal;
|
4990 | }
|
4991 |
|
4992 | /**
|
4993 | * The `punycode` object.
|
4994 | * @name punycode
|
4995 | * @type Object
|
4996 | */
|
4997 | var punycode,
|
4998 |
|
4999 | /** Highest positive signed 32-bit float value */
|
5000 | maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
|
5001 |
|
5002 | /** Bootstring parameters */
|
5003 | base = 36,
|
5004 | tMin = 1,
|
5005 | tMax = 26,
|
5006 | skew = 38,
|
5007 | damp = 700,
|
5008 | initialBias = 72,
|
5009 | initialN = 128, // 0x80
|
5010 | delimiter = '-', // '\x2D'
|
5011 |
|
5012 | /** Regular expressions */
|
5013 | regexPunycode = /^xn--/,
|
5014 | regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
|
5015 | regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
|
5016 |
|
5017 | /** Error messages */
|
5018 | errors = {
|
5019 | 'overflow': 'Overflow: input needs wider integers to process',
|
5020 | 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
|
5021 | 'invalid-input': 'Invalid input'
|
5022 | },
|
5023 |
|
5024 | /** Convenience shortcuts */
|
5025 | baseMinusTMin = base - tMin,
|
5026 | floor = Math.floor,
|
5027 | stringFromCharCode = String.fromCharCode,
|
5028 |
|
5029 | /** Temporary variable */
|
5030 | key;
|
5031 |
|
5032 | /*--------------------------------------------------------------------------*/
|
5033 |
|
5034 | /**
|
5035 | * A generic error utility function.
|
5036 | * @private
|
5037 | * @param {String} type The error type.
|
5038 | * @returns {Error} Throws a `RangeError` with the applicable error message.
|
5039 | */
|
5040 | function error(type) {
|
5041 | throw RangeError(errors[type]);
|
5042 | }
|
5043 |
|
5044 | /**
|
5045 | * A generic `Array#map` utility function.
|
5046 | * @private
|
5047 | * @param {Array} array The array to iterate over.
|
5048 | * @param {Function} callback The function that gets called for every array
|
5049 | * item.
|
5050 | * @returns {Array} A new array of values returned by the callback function.
|
5051 | */
|
5052 | function map(array, fn) {
|
5053 | var length = array.length;
|
5054 | var result = [];
|
5055 | while (length--) {
|
5056 | result[length] = fn(array[length]);
|
5057 | }
|
5058 | return result;
|
5059 | }
|
5060 |
|
5061 | /**
|
5062 | * A simple `Array#map`-like wrapper to work with domain name strings or email
|
5063 | * addresses.
|
5064 | * @private
|
5065 | * @param {String} domain The domain name or email address.
|
5066 | * @param {Function} callback The function that gets called for every
|
5067 | * character.
|
5068 | * @returns {Array} A new string of characters returned by the callback
|
5069 | * function.
|
5070 | */
|
5071 | function mapDomain(string, fn) {
|
5072 | var parts = string.split('@');
|
5073 | var result = '';
|
5074 | if (parts.length > 1) {
|
5075 | // In email addresses, only the domain name should be punycoded. Leave
|
5076 | // the local part (i.e. everything up to `@`) intact.
|
5077 | result = parts[0] + '@';
|
5078 | string = parts[1];
|
5079 | }
|
5080 | // Avoid `split(regex)` for IE8 compatibility. See #17.
|
5081 | string = string.replace(regexSeparators, '\x2E');
|
5082 | var labels = string.split('.');
|
5083 | var encoded = map(labels, fn).join('.');
|
5084 | return result + encoded;
|
5085 | }
|
5086 |
|
5087 | /**
|
5088 | * Creates an array containing the numeric code points of each Unicode
|
5089 | * character in the string. While JavaScript uses UCS-2 internally,
|
5090 | * this function will convert a pair of surrogate halves (each of which
|
5091 | * UCS-2 exposes as separate characters) into a single code point,
|
5092 | * matching UTF-16.
|
5093 | * @see `punycode.ucs2.encode`
|
5094 | * @see <https://mathiasbynens.be/notes/javascript-encoding>
|
5095 | * @memberOf punycode.ucs2
|
5096 | * @name decode
|
5097 | * @param {String} string The Unicode input string (UCS-2).
|
5098 | * @returns {Array} The new array of code points.
|
5099 | */
|
5100 | function ucs2decode(string) {
|
5101 | var output = [],
|
5102 | counter = 0,
|
5103 | length = string.length,
|
5104 | value,
|
5105 | extra;
|
5106 | while (counter < length) {
|
5107 | value = string.charCodeAt(counter++);
|
5108 | if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
|
5109 | // high surrogate, and there is a next character
|
5110 | extra = string.charCodeAt(counter++);
|
5111 | if ((extra & 0xFC00) == 0xDC00) { // low surrogate
|
5112 | output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
|
5113 | } else {
|
5114 | // unmatched surrogate; only append this code unit, in case the next
|
5115 | // code unit is the high surrogate of a surrogate pair
|
5116 | output.push(value);
|
5117 | counter--;
|
5118 | }
|
5119 | } else {
|
5120 | output.push(value);
|
5121 | }
|
5122 | }
|
5123 | return output;
|
5124 | }
|
5125 |
|
5126 | /**
|
5127 | * Creates a string based on an array of numeric code points.
|
5128 | * @see `punycode.ucs2.decode`
|
5129 | * @memberOf punycode.ucs2
|
5130 | * @name encode
|
5131 | * @param {Array} codePoints The array of numeric code points.
|
5132 | * @returns {String} The new Unicode string (UCS-2).
|
5133 | */
|
5134 | function ucs2encode(array) {
|
5135 | return map(array, function(value) {
|
5136 | var output = '';
|
5137 | if (value > 0xFFFF) {
|
5138 | value -= 0x10000;
|
5139 | output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
|
5140 | value = 0xDC00 | value & 0x3FF;
|
5141 | }
|
5142 | output += stringFromCharCode(value);
|
5143 | return output;
|
5144 | }).join('');
|
5145 | }
|
5146 |
|
5147 | /**
|
5148 | * Converts a basic code point into a digit/integer.
|
5149 | * @see `digitToBasic()`
|
5150 | * @private
|
5151 | * @param {Number} codePoint The basic numeric code point value.
|
5152 | * @returns {Number} The numeric value of a basic code point (for use in
|
5153 | * representing integers) in the range `0` to `base - 1`, or `base` if
|
5154 | * the code point does not represent a value.
|
5155 | */
|
5156 | function basicToDigit(codePoint) {
|
5157 | if (codePoint - 48 < 10) {
|
5158 | return codePoint - 22;
|
5159 | }
|
5160 | if (codePoint - 65 < 26) {
|
5161 | return codePoint - 65;
|
5162 | }
|
5163 | if (codePoint - 97 < 26) {
|
5164 | return codePoint - 97;
|
5165 | }
|
5166 | return base;
|
5167 | }
|
5168 |
|
5169 | /**
|
5170 | * Converts a digit/integer into a basic code point.
|
5171 | * @see `basicToDigit()`
|
5172 | * @private
|
5173 | * @param {Number} digit The numeric value of a basic code point.
|
5174 | * @returns {Number} The basic code point whose value (when used for
|
5175 | * representing integers) is `digit`, which needs to be in the range
|
5176 | * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
|
5177 | * used; else, the lowercase form is used. The behavior is undefined
|
5178 | * if `flag` is non-zero and `digit` has no uppercase form.
|
5179 | */
|
5180 | function digitToBasic(digit, flag) {
|
5181 | // 0..25 map to ASCII a..z or A..Z
|
5182 | // 26..35 map to ASCII 0..9
|
5183 | return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
|
5184 | }
|
5185 |
|
5186 | /**
|
5187 | * Bias adaptation function as per section 3.4 of RFC 3492.
|
5188 | * http://tools.ietf.org/html/rfc3492#section-3.4
|
5189 | * @private
|
5190 | */
|
5191 | function adapt(delta, numPoints, firstTime) {
|
5192 | var k = 0;
|
5193 | delta = firstTime ? floor(delta / damp) : delta >> 1;
|
5194 | delta += floor(delta / numPoints);
|
5195 | for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
|
5196 | delta = floor(delta / baseMinusTMin);
|
5197 | }
|
5198 | return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
|
5199 | }
|
5200 |
|
5201 | /**
|
5202 | * Converts a Punycode string of ASCII-only symbols to a string of Unicode
|
5203 | * symbols.
|
5204 | * @memberOf punycode
|
5205 | * @param {String} input The Punycode string of ASCII-only symbols.
|
5206 | * @returns {String} The resulting string of Unicode symbols.
|
5207 | */
|
5208 | function decode(input) {
|
5209 | // Don't use UCS-2
|
5210 | var output = [],
|
5211 | inputLength = input.length,
|
5212 | out,
|
5213 | i = 0,
|
5214 | n = initialN,
|
5215 | bias = initialBias,
|
5216 | basic,
|
5217 | j,
|
5218 | index,
|
5219 | oldi,
|
5220 | w,
|
5221 | k,
|
5222 | digit,
|
5223 | t,
|
5224 | /** Cached calculation results */
|
5225 | baseMinusT;
|
5226 |
|
5227 | // Handle the basic code points: let `basic` be the number of input code
|
5228 | // points before the last delimiter, or `0` if there is none, then copy
|
5229 | // the first basic code points to the output.
|
5230 |
|
5231 | basic = input.lastIndexOf(delimiter);
|
5232 | if (basic < 0) {
|
5233 | basic = 0;
|
5234 | }
|
5235 |
|
5236 | for (j = 0; j < basic; ++j) {
|
5237 | // if it's not a basic code point
|
5238 | if (input.charCodeAt(j) >= 0x80) {
|
5239 | error('not-basic');
|
5240 | }
|
5241 | output.push(input.charCodeAt(j));
|
5242 | }
|
5243 |
|
5244 | // Main decoding loop: start just after the last delimiter if any basic code
|
5245 | // points were copied; start at the beginning otherwise.
|
5246 |
|
5247 | for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
|
5248 |
|
5249 | // `index` is the index of the next character to be consumed.
|
5250 | // Decode a generalized variable-length integer into `delta`,
|
5251 | // which gets added to `i`. The overflow checking is easier
|
5252 | // if we increase `i` as we go, then subtract off its starting
|
5253 | // value at the end to obtain `delta`.
|
5254 | for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
|
5255 |
|
5256 | if (index >= inputLength) {
|
5257 | error('invalid-input');
|
5258 | }
|
5259 |
|
5260 | digit = basicToDigit(input.charCodeAt(index++));
|
5261 |
|
5262 | if (digit >= base || digit > floor((maxInt - i) / w)) {
|
5263 | error('overflow');
|
5264 | }
|
5265 |
|
5266 | i += digit * w;
|
5267 | t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
|
5268 |
|
5269 | if (digit < t) {
|
5270 | break;
|
5271 | }
|
5272 |
|
5273 | baseMinusT = base - t;
|
5274 | if (w > floor(maxInt / baseMinusT)) {
|
5275 | error('overflow');
|
5276 | }
|
5277 |
|
5278 | w *= baseMinusT;
|
5279 |
|
5280 | }
|
5281 |
|
5282 | out = output.length + 1;
|
5283 | bias = adapt(i - oldi, out, oldi == 0);
|
5284 |
|
5285 | // `i` was supposed to wrap around from `out` to `0`,
|
5286 | // incrementing `n` each time, so we'll fix that now:
|
5287 | if (floor(i / out) > maxInt - n) {
|
5288 | error('overflow');
|
5289 | }
|
5290 |
|
5291 | n += floor(i / out);
|
5292 | i %= out;
|
5293 |
|
5294 | // Insert `n` at position `i` of the output
|
5295 | output.splice(i++, 0, n);
|
5296 |
|
5297 | }
|
5298 |
|
5299 | return ucs2encode(output);
|
5300 | }
|
5301 |
|
5302 | /**
|
5303 | * Converts a string of Unicode symbols (e.g. a domain name label) to a
|
5304 | * Punycode string of ASCII-only symbols.
|
5305 | * @memberOf punycode
|
5306 | * @param {String} input The string of Unicode symbols.
|
5307 | * @returns {String} The resulting Punycode string of ASCII-only symbols.
|
5308 | */
|
5309 | function encode(input) {
|
5310 | var n,
|
5311 | delta,
|
5312 | handledCPCount,
|
5313 | basicLength,
|
5314 | bias,
|
5315 | j,
|
5316 | m,
|
5317 | q,
|
5318 | k,
|
5319 | t,
|
5320 | currentValue,
|
5321 | output = [],
|
5322 | /** `inputLength` will hold the number of code points in `input`. */
|
5323 | inputLength,
|
5324 | /** Cached calculation results */
|
5325 | handledCPCountPlusOne,
|
5326 | baseMinusT,
|
5327 | qMinusT;
|
5328 |
|
5329 | // Convert the input in UCS-2 to Unicode
|
5330 | input = ucs2decode(input);
|
5331 |
|
5332 | // Cache the length
|
5333 | inputLength = input.length;
|
5334 |
|
5335 | // Initialize the state
|
5336 | n = initialN;
|
5337 | delta = 0;
|
5338 | bias = initialBias;
|
5339 |
|
5340 | // Handle the basic code points
|
5341 | for (j = 0; j < inputLength; ++j) {
|
5342 | currentValue = input[j];
|
5343 | if (currentValue < 0x80) {
|
5344 | output.push(stringFromCharCode(currentValue));
|
5345 | }
|
5346 | }
|
5347 |
|
5348 | handledCPCount = basicLength = output.length;
|
5349 |
|
5350 | // `handledCPCount` is the number of code points that have been handled;
|
5351 | // `basicLength` is the number of basic code points.
|
5352 |
|
5353 | // Finish the basic string - if it is not empty - with a delimiter
|
5354 | if (basicLength) {
|
5355 | output.push(delimiter);
|
5356 | }
|
5357 |
|
5358 | // Main encoding loop:
|
5359 | while (handledCPCount < inputLength) {
|
5360 |
|
5361 | // All non-basic code points < n have been handled already. Find the next
|
5362 | // larger one:
|
5363 | for (m = maxInt, j = 0; j < inputLength; ++j) {
|
5364 | currentValue = input[j];
|
5365 | if (currentValue >= n && currentValue < m) {
|
5366 | m = currentValue;
|
5367 | }
|
5368 | }
|
5369 |
|
5370 | // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>,
|
5371 | // but guard against overflow
|
5372 | handledCPCountPlusOne = handledCPCount + 1;
|
5373 | if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
|
5374 | error('overflow');
|
5375 | }
|
5376 |
|
5377 | delta += (m - n) * handledCPCountPlusOne;
|
5378 | n = m;
|
5379 |
|
5380 | for (j = 0; j < inputLength; ++j) {
|
5381 | currentValue = input[j];
|
5382 |
|
5383 | if (currentValue < n && ++delta > maxInt) {
|
5384 | error('overflow');
|
5385 | }
|
5386 |
|
5387 | if (currentValue == n) {
|
5388 | // Represent delta as a generalized variable-length integer
|
5389 | for (q = delta, k = base; /* no condition */; k += base) {
|
5390 | t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
|
5391 | if (q < t) {
|
5392 | break;
|
5393 | }
|
5394 | qMinusT = q - t;
|
5395 | baseMinusT = base - t;
|
5396 | output.push(
|
5397 | stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
|
5398 | );
|
5399 | q = floor(qMinusT / baseMinusT);
|
5400 | }
|
5401 |
|
5402 | output.push(stringFromCharCode(digitToBasic(q, 0)));
|
5403 | bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
|
5404 | delta = 0;
|
5405 | ++handledCPCount;
|
5406 | }
|
5407 | }
|
5408 |
|
5409 | ++delta;
|
5410 | ++n;
|
5411 |
|
5412 | }
|
5413 | return output.join('');
|
5414 | }
|
5415 |
|
5416 | /**
|
5417 | * Converts a Punycode string representing a domain name or an email address
|
5418 | * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
|
5419 | * it doesn't matter if you call it on a string that has already been
|
5420 | * converted to Unicode.
|
5421 | * @memberOf punycode
|
5422 | * @param {String} input The Punycoded domain name or email address to
|
5423 | * convert to Unicode.
|
5424 | * @returns {String} The Unicode representation of the given Punycode
|
5425 | * string.
|
5426 | */
|
5427 | function toUnicode(input) {
|
5428 | return mapDomain(input, function(string) {
|
5429 | return regexPunycode.test(string)
|
5430 | ? decode(string.slice(4).toLowerCase())
|
5431 | : string;
|
5432 | });
|
5433 | }
|
5434 |
|
5435 | /**
|
5436 | * Converts a Unicode string representing a domain name or an email address to
|
5437 | * Punycode. Only the non-ASCII parts of the domain name will be converted,
|
5438 | * i.e. it doesn't matter if you call it with a domain that's already in
|
5439 | * ASCII.
|
5440 | * @memberOf punycode
|
5441 | * @param {String} input The domain name or email address to convert, as a
|
5442 | * Unicode string.
|
5443 | * @returns {String} The Punycode representation of the given domain name or
|
5444 | * email address.
|
5445 | */
|
5446 | function toASCII(input) {
|
5447 | return mapDomain(input, function(string) {
|
5448 | return regexNonASCII.test(string)
|
5449 | ? 'xn--' + encode(string)
|
5450 | : string;
|
5451 | });
|
5452 | }
|
5453 |
|
5454 | /*--------------------------------------------------------------------------*/
|
5455 |
|
5456 | /** Define the public API */
|
5457 | punycode = {
|
5458 | /**
|
5459 | * A string representing the current Punycode.js version number.
|
5460 | * @memberOf punycode
|
5461 | * @type String
|
5462 | */
|
5463 | 'version': '1.3.2',
|
5464 | /**
|
5465 | * An object of methods to convert from JavaScript's internal character
|
5466 | * representation (UCS-2) to Unicode code points, and back.
|
5467 | * @see <https://mathiasbynens.be/notes/javascript-encoding>
|
5468 | * @memberOf punycode
|
5469 | * @type Object
|
5470 | */
|
5471 | 'ucs2': {
|
5472 | 'decode': ucs2decode,
|
5473 | 'encode': ucs2encode
|
5474 | },
|
5475 | 'decode': decode,
|
5476 | 'encode': encode,
|
5477 | 'toASCII': toASCII,
|
5478 | 'toUnicode': toUnicode
|
5479 | };
|
5480 |
|
5481 | /** Expose `punycode` */
|
5482 | // Some AMD build optimizers, like r.js, check for specific condition patterns
|
5483 | // like the following:
|
5484 | if (
|
5485 | typeof define == 'function' &&
|
5486 | typeof define.amd == 'object' &&
|
5487 | define.amd
|
5488 | ) {
|
5489 | define('punycode', function() {
|
5490 | return punycode;
|
5491 | });
|
5492 | } else if (freeExports && freeModule) {
|
5493 | if (module.exports == freeExports) { // in Node.js or RingoJS v0.8.0+
|
5494 | freeModule.exports = punycode;
|
5495 | } else { // in Narwhal or RingoJS v0.7.0-
|
5496 | for (key in punycode) {
|
5497 | punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
|
5498 | }
|
5499 | }
|
5500 | } else { // in Rhino or a web browser
|
5501 | root.punycode = punycode;
|
5502 | }
|
5503 |
|
5504 | }(this));
|
5505 |
|
5506 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
5507 | },{}],36:[function(require,module,exports){
|
5508 | // Copyright Joyent, Inc. and other Node contributors.
|
5509 | //
|
5510 | // Permission is hereby granted, free of charge, to any person obtaining a
|
5511 | // copy of this software and associated documentation files (the
|
5512 | // "Software"), to deal in the Software without restriction, including
|
5513 | // without limitation the rights to use, copy, modify, merge, publish,
|
5514 | // distribute, sublicense, and/or sell copies of the Software, and to permit
|
5515 | // persons to whom the Software is furnished to do so, subject to the
|
5516 | // following conditions:
|
5517 | //
|
5518 | // The above copyright notice and this permission notice shall be included
|
5519 | // in all copies or substantial portions of the Software.
|
5520 | //
|
5521 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
5522 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
5523 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
5524 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
5525 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
5526 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
5527 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
|
5528 |
|
5529 | 'use strict';
|
5530 |
|
5531 | // If obj.hasOwnProperty has been overridden, then calling
|
5532 | // obj.hasOwnProperty(prop) will break.
|
5533 | // See: https://github.com/joyent/node/issues/1707
|
5534 | function hasOwnProperty(obj, prop) {
|
5535 | return Object.prototype.hasOwnProperty.call(obj, prop);
|
5536 | }
|
5537 |
|
5538 | module.exports = function(qs, sep, eq, options) {
|
5539 | sep = sep || '&';
|
5540 | eq = eq || '=';
|
5541 | var obj = {};
|
5542 |
|
5543 | if (typeof qs !== 'string' || qs.length === 0) {
|
5544 | return obj;
|
5545 | }
|
5546 |
|
5547 | var regexp = /\+/g;
|
5548 | qs = qs.split(sep);
|
5549 |
|
5550 | var maxKeys = 1000;
|
5551 | if (options && typeof options.maxKeys === 'number') {
|
5552 | maxKeys = options.maxKeys;
|
5553 | }
|
5554 |
|
5555 | var len = qs.length;
|
5556 | // maxKeys <= 0 means that we should not limit keys count
|
5557 | if (maxKeys > 0 && len > maxKeys) {
|
5558 | len = maxKeys;
|
5559 | }
|
5560 |
|
5561 | for (var i = 0; i < len; ++i) {
|
5562 | var x = qs[i].replace(regexp, '%20'),
|
5563 | idx = x.indexOf(eq),
|
5564 | kstr, vstr, k, v;
|
5565 |
|
5566 | if (idx >= 0) {
|
5567 | kstr = x.substr(0, idx);
|
5568 | vstr = x.substr(idx + 1);
|
5569 | } else {
|
5570 | kstr = x;
|
5571 | vstr = '';
|
5572 | }
|
5573 |
|
5574 | k = decodeURIComponent(kstr);
|
5575 | v = decodeURIComponent(vstr);
|
5576 |
|
5577 | if (!hasOwnProperty(obj, k)) {
|
5578 | obj[k] = v;
|
5579 | } else if (isArray(obj[k])) {
|
5580 | obj[k].push(v);
|
5581 | } else {
|
5582 | obj[k] = [obj[k], v];
|
5583 | }
|
5584 | }
|
5585 |
|
5586 | return obj;
|
5587 | };
|
5588 |
|
5589 | var isArray = Array.isArray || function (xs) {
|
5590 | return Object.prototype.toString.call(xs) === '[object Array]';
|
5591 | };
|
5592 |
|
5593 | },{}],37:[function(require,module,exports){
|
5594 | // Copyright Joyent, Inc. and other Node contributors.
|
5595 | //
|
5596 | // Permission is hereby granted, free of charge, to any person obtaining a
|
5597 | // copy of this software and associated documentation files (the
|
5598 | // "Software"), to deal in the Software without restriction, including
|
5599 | // without limitation the rights to use, copy, modify, merge, publish,
|
5600 | // distribute, sublicense, and/or sell copies of the Software, and to permit
|
5601 | // persons to whom the Software is furnished to do so, subject to the
|
5602 | // following conditions:
|
5603 | //
|
5604 | // The above copyright notice and this permission notice shall be included
|
5605 | // in all copies or substantial portions of the Software.
|
5606 | //
|
5607 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
5608 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
5609 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
|
5610 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
5611 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
5612 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
5613 | // USE OR OTHER DEALINGS IN THE SOFTWARE.
|
5614 |
|
5615 | 'use strict';
|
5616 |
|
5617 | var stringifyPrimitive = function(v) {
|
5618 | switch (typeof v) {
|
5619 | case 'string':
|
5620 | return v;
|
5621 |
|
5622 | case 'boolean':
|
5623 | return v ? 'true' : 'false';
|
5624 |
|
5625 | case 'number':
|
5626 | return isFinite(v) ? v : '';
|
5627 |
|
5628 | default:
|
5629 | return '';
|
5630 | }
|
5631 | };
|
5632 |
|
5633 | module.exports = function(obj, sep, eq, name) {
|
5634 | sep = sep || '&';
|
5635 | eq = eq || '=';
|
5636 | if (obj === null) {
|
5637 | obj = undefined;
|
5638 | }
|
5639 |
|
5640 | if (typeof obj === 'object') {
|
5641 | return map(objectKeys(obj), function(k) {
|
5642 | var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
|
5643 | if (isArray(obj[k])) {
|
5644 | return map(obj[k], function(v) {
|
5645 | return ks + encodeURIComponent(stringifyPrimitive(v));
|
5646 | }).join(sep);
|
5647 | } else {
|
5648 | return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
|
5649 | }
|
5650 | }).join(sep);
|
5651 |
|
5652 | }
|
5653 |
|
5654 | if (!name) return '';
|
5655 | return encodeURIComponent(stringifyPrimitive(name)) + eq +
|
5656 | encodeURIComponent(stringifyPrimitive(obj));
|
5657 | };
|
5658 |
|
5659 | var isArray = Array.isArray || function (xs) {
|
5660 | return Object.prototype.toString.call(xs) === '[object Array]';
|
5661 | };
|
5662 |
|
5663 | function map (xs, f) {
|
5664 | if (xs.map) return xs.map(f);
|
5665 | var res = [];
|
5666 | for (var i = 0; i < xs.length; i++) {
|
5667 | res.push(f(xs[i], i));
|
5668 | }
|
5669 | return res;
|
5670 | }
|
5671 |
|
5672 | var objectKeys = Object.keys || function (obj) {
|
5673 | var res = [];
|
5674 | for (var key in obj) {
|
5675 | if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
|
5676 | }
|
5677 | return res;
|
5678 | };
|
5679 |
|
5680 | },{}],38:[function(require,module,exports){
|
5681 | 'use strict';
|
5682 |
|
5683 | exports.decode = exports.parse = require('./decode');
|
5684 | exports.encode = exports.stringify = require('./encode');
|
5685 |
|
5686 | },{"./decode":36,"./encode":37}],39:[function(require,module,exports){
|
5687 | /*! rasterizeHTML.js - v1.2.4 - 2016-10-30
|
5688 | * http://www.github.com/cburgmer/rasterizeHTML.js
|
5689 | * Copyright (c) 2016 Christoph Burgmer; Licensed MIT */
|
5690 | (function (root, factory) {
|
5691 | if (typeof define === 'function' && define.amd) {
|
5692 | // AMD. Register as an anonymous module unless amdModuleId is set
|
5693 | define(["url","css-mediaquery","xmlserializer","sane-domparser-error","ayepromise","inlineresources"], function (a0,b1,c2,d3,e4,f5) {
|
5694 | return (root['rasterizeHTML'] = factory(a0,b1,c2,d3,e4,f5));
|
5695 | });
|
5696 | } else if (typeof exports === 'object') {
|
5697 | // Node. Does not work with strict CommonJS, but
|
5698 | // only CommonJS-like environments that support module.exports,
|
5699 | // like Node.
|
5700 | module.exports = factory(require("url"),require("css-mediaquery"),require("xmlserializer"),require("sane-domparser-error"),require("ayepromise"),require("inlineresources"));
|
5701 | } else {
|
5702 | root['rasterizeHTML'] = factory(root["url"],root["cssMediaQuery"],root["xmlserializer"],root["sanedomparsererror"],root["ayepromise"],root["inlineresources"]);
|
5703 | }
|
5704 | }(this, function (url, cssMediaQuery, xmlserializer, sanedomparsererror, ayepromise, inlineresources) {
|
5705 |
|
5706 | var util = (function (url) {
|
5707 | "use strict";
|
5708 |
|
5709 | var module = {};
|
5710 |
|
5711 | var uniqueIdList = [];
|
5712 |
|
5713 | module.joinUrl = function (baseUrl, relUrl) {
|
5714 | if (!baseUrl) {
|
5715 | return relUrl;
|
5716 | }
|
5717 | return url.resolve(baseUrl, relUrl);
|
5718 | };
|
5719 |
|
5720 | module.getConstantUniqueIdFor = function (element) {
|
5721 | // HACK, using a list results in O(n), but how do we hash e.g. a DOM node?
|
5722 | if (uniqueIdList.indexOf(element) < 0) {
|
5723 | uniqueIdList.push(element);
|
5724 | }
|
5725 | return uniqueIdList.indexOf(element);
|
5726 | };
|
5727 |
|
5728 | module.clone = function (object) {
|
5729 | var theClone = {},
|
5730 | i;
|
5731 | for (i in object) {
|
5732 | if (object.hasOwnProperty(i)) {
|
5733 | theClone[i] = object[i];
|
5734 | }
|
5735 | }
|
5736 | return theClone;
|
5737 | };
|
5738 |
|
5739 | var isObject = function (obj) {
|
5740 | return typeof obj === "object" && obj !== null;
|
5741 | };
|
5742 |
|
5743 | var isCanvas = function (obj) {
|
5744 | return isObject(obj) &&
|
5745 | Object.prototype.toString.apply(obj).match(/\[object (Canvas|HTMLCanvasElement)\]/i);
|
5746 | };
|
5747 |
|
5748 | // args: canvas, options
|
5749 | module.parseOptionalParameters = function (args) {
|
5750 | var parameters = {
|
5751 | canvas: null,
|
5752 | options: {}
|
5753 | };
|
5754 |
|
5755 | if (args[0] == null || isCanvas(args[0])) {
|
5756 | parameters.canvas = args[0] || null;
|
5757 |
|
5758 | parameters.options = module.clone(args[1]);
|
5759 | } else {
|
5760 | parameters.options = module.clone(args[0]);
|
5761 | }
|
5762 |
|
5763 | return parameters;
|
5764 | };
|
5765 |
|
5766 | return module;
|
5767 | }(url));
|
5768 |
|
5769 | // Proxy objects by monkey patching
|
5770 | var proxies = (function (util, ayepromise) {
|
5771 | "use strict";
|
5772 |
|
5773 | var module = {};
|
5774 |
|
5775 | var monkeyPatchInstanceMethod = function (object, methodName, proxyFunc) {
|
5776 | var originalFunc = object[methodName];
|
5777 |
|
5778 | object[methodName] = function () {
|
5779 | var args = Array.prototype.slice.call(arguments);
|
5780 |
|
5781 | return proxyFunc.apply(this, [args, originalFunc]);
|
5782 | };
|
5783 |
|
5784 | return originalFunc;
|
5785 | };
|
5786 |
|
5787 | // Bases all XHR calls on the given base URL
|
5788 | module.baseUrlRespectingXhr = function (XHRObject, baseUrl) {
|
5789 | var xhrConstructor = function () {
|
5790 | var xhr = new XHRObject();
|
5791 |
|
5792 | monkeyPatchInstanceMethod(xhr, 'open', function (args, originalOpen) {
|
5793 | var method = args.shift(),
|
5794 | url = args.shift(),
|
5795 | joinedUrl = util.joinUrl(baseUrl, url);
|
5796 |
|
5797 | return originalOpen.apply(this, [method, joinedUrl].concat(args));
|
5798 | });
|
5799 |
|
5800 | return xhr;
|
5801 | };
|
5802 |
|
5803 | return xhrConstructor;
|
5804 | };
|
5805 |
|
5806 | // Provides a convenient way of being notified when all pending XHR calls are finished
|
5807 | module.finishNotifyingXhr = function (XHRObject) {
|
5808 | var totalXhrCount = 0,
|
5809 | doneXhrCount = 0,
|
5810 | waitingForPendingToClose = false,
|
5811 | defer = ayepromise.defer();
|
5812 |
|
5813 | var checkAllRequestsFinished = function () {
|
5814 | var pendingXhrCount = totalXhrCount - doneXhrCount;
|
5815 |
|
5816 | if (pendingXhrCount <= 0 && waitingForPendingToClose) {
|
5817 | defer.resolve({totalCount: totalXhrCount});
|
5818 | }
|
5819 | };
|
5820 |
|
5821 | var xhrConstructor = function () {
|
5822 | var xhr = new XHRObject();
|
5823 |
|
5824 | monkeyPatchInstanceMethod(xhr, 'send', function (_, originalSend) {
|
5825 | totalXhrCount += 1;
|
5826 | return originalSend.apply(this, arguments);
|
5827 | });
|
5828 |
|
5829 | xhr.addEventListener('load', function () {
|
5830 | doneXhrCount += 1;
|
5831 |
|
5832 | checkAllRequestsFinished();
|
5833 | });
|
5834 |
|
5835 | return xhr;
|
5836 | };
|
5837 |
|
5838 | xhrConstructor.waitForRequestsToFinish = function () {
|
5839 | waitingForPendingToClose = true;
|
5840 | checkAllRequestsFinished();
|
5841 | return defer.promise;
|
5842 | };
|
5843 |
|
5844 | return xhrConstructor;
|
5845 | };
|
5846 |
|
5847 | return module;
|
5848 | }(util, ayepromise));
|
5849 |
|
5850 | var documentUtil = (function () {
|
5851 | "use strict";
|
5852 |
|
5853 | var module = {};
|
5854 |
|
5855 | var asArray = function (arrayLike) {
|
5856 | return Array.prototype.slice.call(arrayLike);
|
5857 | };
|
5858 |
|
5859 | module.addClassName = function (element, className) {
|
5860 | element.className += ' ' + className;
|
5861 | };
|
5862 |
|
5863 | module.addClassNameRecursively = function (element, className) {
|
5864 | module.addClassName(element, className);
|
5865 |
|
5866 | if (element.parentNode !== element.ownerDocument) {
|
5867 | module.addClassNameRecursively(element.parentNode, className);
|
5868 | }
|
5869 | };
|
5870 |
|
5871 | var changeCssRule = function (rule, newRuleText) {
|
5872 | var styleSheet = rule.parentStyleSheet,
|
5873 | ruleIdx = asArray(styleSheet.cssRules).indexOf(rule);
|
5874 |
|
5875 | // Exchange rule with the new text
|
5876 | styleSheet.insertRule(newRuleText, ruleIdx+1);
|
5877 | styleSheet.deleteRule(ruleIdx);
|
5878 | };
|
5879 |
|
5880 | var updateRuleSelector = function (rule, updatedSelector) {
|
5881 | var styleDefinitions = rule.cssText.replace(/^[^\{]+/, ''),
|
5882 | newRule = updatedSelector + ' ' + styleDefinitions;
|
5883 |
|
5884 | changeCssRule(rule, newRule);
|
5885 | };
|
5886 |
|
5887 | var cssRulesToText = function (cssRules) {
|
5888 | return asArray(cssRules).reduce(function (cssText, rule) {
|
5889 | return cssText + rule.cssText;
|
5890 | }, '');
|
5891 | };
|
5892 |
|
5893 | var rewriteStyleContent = function (styleElement) {
|
5894 | styleElement.textContent = cssRulesToText(styleElement.sheet.cssRules);
|
5895 | };
|
5896 |
|
5897 | var addSheetPropertyToSvgStyleElement = function (svgStyleElement) {
|
5898 | var doc = document.implementation.createHTMLDocument(''),
|
5899 | cssStyleElement = document.createElement('style');
|
5900 |
|
5901 | cssStyleElement.textContent = svgStyleElement.textContent;
|
5902 | // the style will only be parsed once it is added to a document
|
5903 | doc.body.appendChild(cssStyleElement);
|
5904 |
|
5905 | svgStyleElement.sheet = cssStyleElement.sheet;
|
5906 | };
|
5907 |
|
5908 | var matchingSimpleSelectorsRegex = function (simpleSelectorList) {
|
5909 | return '(' +
|
5910 | '(?:^|[^.#:\\w])' + // start of string or not a simple selector character,
|
5911 | '|' + // ... or ...
|
5912 | '(?=\\W)' + // the next character parsed is not an alphabetic character (and thus a natural boundary)
|
5913 | ')' +
|
5914 | '(' +
|
5915 | simpleSelectorList.join('|') + // one out of the given simple selectors
|
5916 | ')' +
|
5917 | '(?=\\W|$)'; // followed either by a non-alphabetic character or the end of the string
|
5918 | };
|
5919 |
|
5920 | var replaceSimpleSelectorsBy = function (element, simpleSelectorList, caseInsensitiveReplaceFunc) {
|
5921 | var selectorRegex = matchingSimpleSelectorsRegex(simpleSelectorList);
|
5922 |
|
5923 | asArray(element.querySelectorAll('style')).forEach(function (styleElement) {
|
5924 | // SVGStyleElement doesn't have a property sheet in Safari, we need some workaround here
|
5925 | // more details can be found here: https://github.com/cburgmer/rasterizeHTML.js/issues/158
|
5926 | if (typeof styleElement.sheet === 'undefined') {
|
5927 | addSheetPropertyToSvgStyleElement(styleElement);
|
5928 | }
|
5929 |
|
5930 | var matchingRules = asArray(styleElement.sheet.cssRules).filter(function (rule) {
|
5931 | return rule.selectorText && new RegExp(selectorRegex, 'i').test(rule.selectorText);
|
5932 | });
|
5933 |
|
5934 | if (matchingRules.length) {
|
5935 | matchingRules.forEach(function (rule) {
|
5936 | var newSelector = rule.selectorText.replace(new RegExp(selectorRegex, 'gi'),
|
5937 | function (_, prefixMatch, selectorMatch) {
|
5938 | return prefixMatch + caseInsensitiveReplaceFunc(selectorMatch);
|
5939 | });
|
5940 |
|
5941 | if (newSelector !== rule.selectorText) {
|
5942 | updateRuleSelector(rule, newSelector);
|
5943 | }
|
5944 | });
|
5945 |
|
5946 | rewriteStyleContent(styleElement);
|
5947 | }
|
5948 | });
|
5949 | };
|
5950 |
|
5951 | module.rewriteCssSelectorWith = function (element, oldSelector, newSelector) {
|
5952 | replaceSimpleSelectorsBy(element, [oldSelector], function () {
|
5953 | return newSelector;
|
5954 | });
|
5955 | };
|
5956 |
|
5957 | module.lowercaseCssTypeSelectors = function (element, matchingTagNames) {
|
5958 | replaceSimpleSelectorsBy(element, matchingTagNames, function (match) {
|
5959 | return match.toLowerCase();
|
5960 | });
|
5961 | };
|
5962 |
|
5963 | module.findHtmlOnlyNodeNames = function (element) {
|
5964 | var treeWalker = element.ownerDocument.createTreeWalker(element, NodeFilter.SHOW_ELEMENT),
|
5965 | htmlNodeNames = {},
|
5966 | nonHtmlNodeNames = {},
|
5967 | currentTagName;
|
5968 |
|
5969 | do {
|
5970 | currentTagName = treeWalker.currentNode.tagName.toLowerCase();
|
5971 | if (treeWalker.currentNode.namespaceURI === 'http://www.w3.org/1999/xhtml') {
|
5972 | htmlNodeNames[currentTagName] = true;
|
5973 | } else {
|
5974 | nonHtmlNodeNames[currentTagName] = true;
|
5975 | }
|
5976 | } while(treeWalker.nextNode());
|
5977 |
|
5978 | return Object.keys(htmlNodeNames).filter(function (tagName) {
|
5979 | return !nonHtmlNodeNames[tagName];
|
5980 | });
|
5981 | };
|
5982 |
|
5983 | return module;
|
5984 | }());
|
5985 |
|
5986 | var documentHelper = (function (documentUtil) {
|
5987 | "use strict";
|
5988 |
|
5989 | var module = {};
|
5990 |
|
5991 | var asArray = function (arrayLike) {
|
5992 | return Array.prototype.slice.call(arrayLike);
|
5993 | };
|
5994 |
|
5995 | var cascadingAction = {
|
5996 | active: true,
|
5997 | hover: true,
|
5998 | focus: false,
|
5999 | target: false
|
6000 | };
|
6001 |
|
6002 | module.fakeUserAction = function (element, selector, action) {
|
6003 | var elem = element.querySelector(selector),
|
6004 | pseudoClass = ':' + action,
|
6005 | fakeActionClass = 'rasterizehtml' + action;
|
6006 | if (! elem) {
|
6007 | return;
|
6008 | }
|
6009 |
|
6010 | if (cascadingAction[action]) {
|
6011 | documentUtil.addClassNameRecursively(elem, fakeActionClass);
|
6012 | } else {
|
6013 | documentUtil.addClassName(elem, fakeActionClass);
|
6014 | }
|
6015 | documentUtil.rewriteCssSelectorWith(element, pseudoClass, '.' + fakeActionClass);
|
6016 | };
|
6017 |
|
6018 | module.persistInputValues = function (doc) {
|
6019 | var inputs = doc.querySelectorAll('input'),
|
6020 | textareas = doc.querySelectorAll('textarea'),
|
6021 | isCheckable = function (input) {
|
6022 | return input.type === 'checkbox' || input.type === 'radio';
|
6023 | };
|
6024 |
|
6025 | asArray(inputs).filter(isCheckable)
|
6026 | .forEach(function (input) {
|
6027 | if (input.checked) {
|
6028 | input.setAttribute('checked', '');
|
6029 | } else {
|
6030 | input.removeAttribute('checked');
|
6031 | }
|
6032 | });
|
6033 |
|
6034 | asArray(inputs).filter(function (input) { return !isCheckable(input); })
|
6035 | .forEach(function (input) {
|
6036 | input.setAttribute('value', input.value);
|
6037 | });
|
6038 |
|
6039 | asArray(textareas)
|
6040 | .forEach(function (textarea) {
|
6041 | textarea.textContent = textarea.value;
|
6042 | });
|
6043 | };
|
6044 |
|
6045 | module.rewriteTagNameSelectorsToLowerCase = function (element) {
|
6046 | documentUtil.lowercaseCssTypeSelectors(element, documentUtil.findHtmlOnlyNodeNames(element));
|
6047 | };
|
6048 |
|
6049 | return module;
|
6050 | }(documentUtil));
|
6051 |
|
6052 | var mediaQueryHelper = (function (cssMediaQuery) {
|
6053 | "use strict";
|
6054 |
|
6055 | var module = {};
|
6056 |
|
6057 | var svgImgBlueByEmMediaQuery = function () {
|
6058 | var svg = '<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="10" height="10">' +
|
6059 | '<style>@media (max-width: 1em) { svg { background: #00f; } }</style>' +
|
6060 | '</svg>';
|
6061 |
|
6062 | var url = "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg),
|
6063 | img = document.createElement('img');
|
6064 |
|
6065 | img.src = url;
|
6066 |
|
6067 | return img;
|
6068 | };
|
6069 |
|
6070 | var firstPixelHasColor = function (img, r, g, b) {
|
6071 | var canvas = document.createElement("canvas");
|
6072 | canvas.width = img.width;
|
6073 | canvas.height = img.height;
|
6074 |
|
6075 | var context = canvas.getContext("2d"),
|
6076 | data;
|
6077 |
|
6078 | context.drawImage(img, 0, 0);
|
6079 | data = context.getImageData(0, 0, 1, 1).data;
|
6080 | return data[0] === r && data[1] === g && data[2] === b;
|
6081 | };
|
6082 |
|
6083 | var hasEmMediaQueryIssue = function () {
|
6084 | var img = svgImgBlueByEmMediaQuery(),
|
6085 | defer = ayepromise.defer();
|
6086 |
|
6087 | document.querySelector('body').appendChild(img);
|
6088 |
|
6089 | img.onload = function () {
|
6090 | document.querySelector('body').removeChild(img);
|
6091 | try {
|
6092 | defer.resolve(!firstPixelHasColor(img, 0, 0, 255));
|
6093 | } catch (e) {
|
6094 | // Fails in PhantomJS, let's assume the issue exists
|
6095 | defer.resolve(true);
|
6096 | }
|
6097 | };
|
6098 | img.onerror = function () {
|
6099 | defer.reject();
|
6100 | };
|
6101 |
|
6102 | return defer.promise;
|
6103 | };
|
6104 |
|
6105 | var hasEmIssue;
|
6106 |
|
6107 | module.needsEmWorkaround = function () {
|
6108 | if (hasEmIssue === undefined) {
|
6109 | hasEmIssue = hasEmMediaQueryIssue();
|
6110 | }
|
6111 | return hasEmIssue;
|
6112 | };
|
6113 |
|
6114 | var asArray = function (arrayLike) {
|
6115 | return Array.prototype.slice.call(arrayLike);
|
6116 | };
|
6117 |
|
6118 | var cssRulesToText = function (cssRules) {
|
6119 | return asArray(cssRules).map(function (rule) {
|
6120 | return rule.cssText;
|
6121 | }).join('\n');
|
6122 | };
|
6123 |
|
6124 | var mediaQueryRule = function (mediaQuery, cssRules) {
|
6125 | return '@media ' + mediaQuery + '{' +
|
6126 | cssRulesToText(cssRules) +
|
6127 | '}';
|
6128 | };
|
6129 |
|
6130 | var exchangeRuleWithNewContent = function (styleSheet, ruleIdx, newRuleText) {
|
6131 | try {
|
6132 | styleSheet.insertRule(newRuleText, ruleIdx+1);
|
6133 | } catch (e) {
|
6134 | // In case the browser does not like our new rule we just keep the existing one and quietly leave
|
6135 | return;
|
6136 | }
|
6137 | styleSheet.deleteRule(ruleIdx);
|
6138 | };
|
6139 |
|
6140 | var changeCssRule = function (rule, newRuleText) {
|
6141 | var styleSheet = rule.parentStyleSheet,
|
6142 | ruleIdx = asArray(styleSheet.cssRules).indexOf(rule);
|
6143 |
|
6144 | exchangeRuleWithNewContent(styleSheet, ruleIdx, newRuleText);
|
6145 | };
|
6146 |
|
6147 | var rewriteStyleContent = function (styleElement) {
|
6148 | styleElement.textContent = cssRulesToText(styleElement.sheet.cssRules);
|
6149 | };
|
6150 |
|
6151 | var serializeExpression = function (exp) {
|
6152 | var feature = exp.modifier ? exp.modifier + '-' + exp.feature : exp.feature;
|
6153 | if (exp.value) {
|
6154 | return '(' + feature + ': ' + exp.value + ')';
|
6155 | } else {
|
6156 | return '(' + feature + ')';
|
6157 | }
|
6158 | };
|
6159 |
|
6160 | var serializeQueryPart = function (q) {
|
6161 | var segments = [];
|
6162 |
|
6163 | if (q.inverse) {
|
6164 | segments.push("not");
|
6165 | }
|
6166 |
|
6167 | segments.push(q.type);
|
6168 |
|
6169 | if (q.expressions.length > 0) {
|
6170 | segments.push('and ' + q.expressions.map(serializeExpression).join(' and '));
|
6171 | }
|
6172 |
|
6173 | return segments.join(' ');
|
6174 | };
|
6175 |
|
6176 | // poor man's testability
|
6177 | module.serializeQuery = function (q) {
|
6178 | var queryParts = q.map(serializeQueryPart);
|
6179 | return queryParts.join(', ');
|
6180 | };
|
6181 |
|
6182 | var transformEmIntoPx = function (em) {
|
6183 | return em * 16;
|
6184 | };
|
6185 |
|
6186 | var replaceEmValueWithPx = function (value) {
|
6187 | // Match a number with em unit. Doesn't match all, but should be enough for now
|
6188 | var match = /^((?:\d+\.)?\d+)em/.exec(value);
|
6189 | if (match) {
|
6190 | return transformEmIntoPx(parseFloat(match[1])) + 'px';
|
6191 | }
|
6192 | return value;
|
6193 | };
|
6194 |
|
6195 | var substituteEmWithPx = function (mediaQuery) {
|
6196 | var parsedQuery = cssMediaQuery.parse(mediaQuery),
|
6197 | hasChanges = false;
|
6198 |
|
6199 | parsedQuery.forEach(function (q) {
|
6200 | q.expressions.forEach(function (exp) {
|
6201 | var rewrittenValue = replaceEmValueWithPx(exp.value);
|
6202 |
|
6203 | hasChanges |= rewrittenValue !== exp.value;
|
6204 | exp.value = rewrittenValue;
|
6205 | });
|
6206 | });
|
6207 |
|
6208 | if (hasChanges) {
|
6209 | return module.serializeQuery(parsedQuery);
|
6210 | }
|
6211 | };
|
6212 |
|
6213 | var replaceEmsWithPx = function (mediaQueryRules) {
|
6214 | var anyRuleHasChanges = false;
|
6215 |
|
6216 | mediaQueryRules.forEach(function (rule) {
|
6217 | var rewrittenMediaQuery = substituteEmWithPx(rule.media.mediaText);
|
6218 |
|
6219 | if (rewrittenMediaQuery) {
|
6220 | changeCssRule(rule, mediaQueryRule(rewrittenMediaQuery, rule.cssRules));
|
6221 | }
|
6222 |
|
6223 | anyRuleHasChanges |= !!rewrittenMediaQuery;
|
6224 | });
|
6225 |
|
6226 | return anyRuleHasChanges;
|
6227 | };
|
6228 |
|
6229 | module.workAroundWebKitEmSizeIssue = function (element) {
|
6230 | var styles = element.querySelectorAll('style');
|
6231 |
|
6232 | asArray(styles).forEach(function (style) {
|
6233 | var mediaQueryRules = asArray(style.sheet.cssRules).filter(function (rule) {
|
6234 | return rule.type === window.CSSRule.MEDIA_RULE;
|
6235 | });
|
6236 |
|
6237 | var hasChanges = replaceEmsWithPx(mediaQueryRules);
|
6238 | if (hasChanges) {
|
6239 | rewriteStyleContent(style);
|
6240 | }
|
6241 | });
|
6242 | };
|
6243 |
|
6244 | return module;
|
6245 | }(cssMediaQuery));
|
6246 |
|
6247 | var browser = (function (util, proxies, ayepromise, sanedomparsererror, theWindow) {
|
6248 | "use strict";
|
6249 |
|
6250 | var module = {};
|
6251 |
|
6252 | var createHiddenElement = function (doc, tagName, width, height) {
|
6253 | var element = doc.createElement(tagName);
|
6254 | // 'display: none' doesn't cut it, as browsers seem to be lazy loading CSS
|
6255 | element.style.visibility = "hidden";
|
6256 | element.style.width = width + "px";
|
6257 | element.style.height = height + "px";
|
6258 | element.style.position = "absolute";
|
6259 | element.style.top = (-10000 - height) + "px";
|
6260 | element.style.left = (-10000 - width) + "px";
|
6261 | // We need to add the element to the document so that its content gets loaded
|
6262 | doc.getElementsByTagName("body")[0].appendChild(element);
|
6263 | return element;
|
6264 | };
|
6265 |
|
6266 | module.executeJavascript = function (element, options) {
|
6267 | var iframe = createHiddenElement(theWindow.document, "iframe", options.width, options.height),
|
6268 | html = element.outerHTML,
|
6269 | iframeErrorsMessages = [],
|
6270 | defer = ayepromise.defer(),
|
6271 | timeout = options.executeJsTimeout || 0;
|
6272 |
|
6273 | var doResolve = function () {
|
6274 | var doc = iframe.contentDocument;
|
6275 | theWindow.document.getElementsByTagName("body")[0].removeChild(iframe);
|
6276 | defer.resolve({
|
6277 | document: doc,
|
6278 | errors: iframeErrorsMessages
|
6279 | });
|
6280 | };
|
6281 |
|
6282 | var waitForJavaScriptToRun = function () {
|
6283 | var d = ayepromise.defer();
|
6284 | if (timeout > 0) {
|
6285 | setTimeout(d.resolve, timeout);
|
6286 | } else {
|
6287 | d.resolve();
|
6288 | }
|
6289 | return d.promise;
|
6290 | };
|
6291 |
|
6292 | var xhr = iframe.contentWindow.XMLHttpRequest,
|
6293 | finishNotifyXhrProxy = proxies.finishNotifyingXhr(xhr),
|
6294 | baseUrlXhrProxy = proxies.baseUrlRespectingXhr(finishNotifyXhrProxy, options.baseUrl);
|
6295 |
|
6296 | iframe.onload = function () {
|
6297 | waitForJavaScriptToRun()
|
6298 | .then(finishNotifyXhrProxy.waitForRequestsToFinish)
|
6299 | .then(doResolve);
|
6300 | };
|
6301 |
|
6302 | iframe.contentDocument.open();
|
6303 | iframe.contentWindow.XMLHttpRequest = baseUrlXhrProxy;
|
6304 | iframe.contentWindow.onerror = function (msg) {
|
6305 | iframeErrorsMessages.push({
|
6306 | resourceType: "scriptExecution",
|
6307 | msg: msg
|
6308 | });
|
6309 | };
|
6310 |
|
6311 | iframe.contentDocument.write('<!DOCTYPE html>');
|
6312 | iframe.contentDocument.write(html);
|
6313 | iframe.contentDocument.close();
|
6314 |
|
6315 | return defer.promise;
|
6316 | };
|
6317 |
|
6318 | var createHiddenSandboxedIFrame = function (doc, width, height) {
|
6319 | var iframe = doc.createElement('iframe');
|
6320 | iframe.style.width = width + "px";
|
6321 | iframe.style.height = height + "px";
|
6322 | // 'display: none' doesn't cut it, as browsers seem to be lazy loading content
|
6323 | iframe.style.visibility = "hidden";
|
6324 | iframe.style.position = "absolute";
|
6325 | iframe.style.top = (-10000 - height) + "px";
|
6326 | iframe.style.left = (-10000 - width) + "px";
|
6327 | // Don't execute JS, all we need from sandboxing is access to the iframe's document
|
6328 | iframe.sandbox = 'allow-same-origin';
|
6329 | // Don't include a scrollbar on Linux
|
6330 | iframe.scrolling = 'no';
|
6331 | return iframe;
|
6332 | };
|
6333 |
|
6334 | var createIframeWithSizeAtZoomLevel1 = function (width, height, zoom) {
|
6335 | var scaledViewportWidth = Math.floor(width / zoom),
|
6336 | scaledViewportHeight = Math.floor(height / zoom);
|
6337 |
|
6338 | return createHiddenSandboxedIFrame(theWindow.document, scaledViewportWidth, scaledViewportHeight);
|
6339 | };
|
6340 |
|
6341 | var calculateZoomedContentSizeAndRoundUp = function (actualViewport, requestedWidth, requestedHeight, zoom) {
|
6342 | return {
|
6343 | width: Math.max(actualViewport.width * zoom, requestedWidth),
|
6344 | height: Math.max(actualViewport.height * zoom, requestedHeight)
|
6345 | };
|
6346 | };
|
6347 |
|
6348 | var selectElementOrDescendant = function (element, selector) {
|
6349 | var descendant = element.querySelector(selector);
|
6350 | if (descendant) {
|
6351 | return descendant;
|
6352 | } else if (element.ownerDocument.querySelector(selector) === element) {
|
6353 | return element;
|
6354 | }
|
6355 |
|
6356 | throw {
|
6357 | message: "Clipping selector not found"
|
6358 | };
|
6359 | };
|
6360 |
|
6361 | var calculateContentSize = function (rootElement, selector, requestedWidth, requestedHeight, zoom) {
|
6362 | // clientWidth/clientHeight needed for PhantomJS
|
6363 | var actualViewportWidth = Math.max(rootElement.scrollWidth, rootElement.clientWidth),
|
6364 | actualViewportHeight = Math.max(rootElement.scrollHeight, rootElement.clientHeight),
|
6365 | top, left, originalWidth, originalHeight, rootFontSize,
|
6366 | element, rect, contentSize;
|
6367 |
|
6368 | if (selector) {
|
6369 | element = selectElementOrDescendant(rootElement, selector);
|
6370 |
|
6371 | rect = element.getBoundingClientRect();
|
6372 |
|
6373 | top = rect.top;
|
6374 | left = rect.left;
|
6375 | originalWidth = rect.width;
|
6376 | originalHeight = rect.height;
|
6377 | } else {
|
6378 | top = 0;
|
6379 | left = 0;
|
6380 | originalWidth = actualViewportWidth;
|
6381 | originalHeight = actualViewportHeight;
|
6382 | }
|
6383 |
|
6384 | contentSize = calculateZoomedContentSizeAndRoundUp({
|
6385 | width: originalWidth,
|
6386 | height: originalHeight
|
6387 | },
|
6388 | requestedWidth,
|
6389 | requestedHeight,
|
6390 | zoom);
|
6391 |
|
6392 | rootFontSize = theWindow.getComputedStyle(rootElement.ownerDocument.documentElement).fontSize;
|
6393 |
|
6394 | return {
|
6395 | left: left,
|
6396 | top: top,
|
6397 | width: contentSize.width,
|
6398 | height: contentSize.height,
|
6399 | viewportWidth: actualViewportWidth,
|
6400 | viewportHeight: actualViewportHeight,
|
6401 |
|
6402 | rootFontSize: rootFontSize
|
6403 | };
|
6404 | };
|
6405 |
|
6406 | var findCorrelatingElement = function (element, documentClone) {
|
6407 | var tagName = element.tagName;
|
6408 | // Stupid but simple method: find first match. Should work for a single HTML element, and any other element given as root
|
6409 | return documentClone.querySelector(tagName);
|
6410 | };
|
6411 |
|
6412 | var elementToFullHtmlDocument = function (element) {
|
6413 | var tagName = element.tagName.toLowerCase();
|
6414 | if (tagName === 'html' || tagName === 'body') {
|
6415 | return element.outerHTML;
|
6416 | }
|
6417 |
|
6418 | // Simple hack: hide the body from sizing, otherwise browser would apply a 8px margin
|
6419 | return '<body style="margin: 0;">' + element.outerHTML + '</body>';
|
6420 | };
|
6421 |
|
6422 | module.calculateDocumentContentSize = function (element, options) {
|
6423 | var defer = ayepromise.defer(),
|
6424 | zoom = options.zoom || 1,
|
6425 | iframe;
|
6426 |
|
6427 |
|
6428 | iframe = createIframeWithSizeAtZoomLevel1(options.width, options.height, zoom);
|
6429 | // We need to add the element to the document so that its content gets loaded
|
6430 | theWindow.document.getElementsByTagName("body")[0].appendChild(iframe);
|
6431 |
|
6432 | iframe.onload = function () {
|
6433 | var doc = iframe.contentDocument,
|
6434 | size;
|
6435 |
|
6436 | try {
|
6437 | size = calculateContentSize(findCorrelatingElement(element, doc), options.clip, options.width, options.height, zoom);
|
6438 |
|
6439 | defer.resolve(size);
|
6440 | } catch (e) {
|
6441 | defer.reject(e);
|
6442 | } finally {
|
6443 | theWindow.document.getElementsByTagName("body")[0].removeChild(iframe);
|
6444 | }
|
6445 | };
|
6446 |
|
6447 | // srcdoc doesn't work in PhantomJS yet
|
6448 | iframe.contentDocument.open();
|
6449 | iframe.contentDocument.write('<!DOCTYPE html>');
|
6450 | iframe.contentDocument.write(elementToFullHtmlDocument(element));
|
6451 | iframe.contentDocument.close();
|
6452 |
|
6453 | return defer.promise;
|
6454 | };
|
6455 |
|
6456 | module.parseHtmlFragment = function (htmlFragment) {
|
6457 | var doc = theWindow.document.implementation.createHTMLDocument('');
|
6458 | doc.documentElement.innerHTML = htmlFragment;
|
6459 |
|
6460 | var element = doc.querySelector('body').firstChild;
|
6461 |
|
6462 | if (!element) {
|
6463 | throw "Invalid source";
|
6464 | }
|
6465 |
|
6466 | return element;
|
6467 | };
|
6468 |
|
6469 | var addHTMLTagAttributes = function (doc, html) {
|
6470 | var attributeMatch = /<html((?:\s+[^>]*)?)>/im.exec(html),
|
6471 | helperDoc = theWindow.document.implementation.createHTMLDocument(''),
|
6472 | htmlTagSubstitute,
|
6473 | i, elementSubstitute, attribute;
|
6474 |
|
6475 | if (!attributeMatch) {
|
6476 | return;
|
6477 | }
|
6478 |
|
6479 | htmlTagSubstitute = '<div' + attributeMatch[1] + '></div>';
|
6480 | helperDoc.documentElement.innerHTML = htmlTagSubstitute;
|
6481 | elementSubstitute = helperDoc.querySelector('div');
|
6482 |
|
6483 | for (i = 0; i < elementSubstitute.attributes.length; i++) {
|
6484 | attribute = elementSubstitute.attributes[i];
|
6485 | doc.documentElement.setAttribute(attribute.name, attribute.value);
|
6486 | }
|
6487 | };
|
6488 |
|
6489 | module.parseHTML = function (html) {
|
6490 | // We should be using the DOMParser, but it is not supported in older browsers
|
6491 | var doc = theWindow.document.implementation.createHTMLDocument('');
|
6492 | doc.documentElement.innerHTML = html;
|
6493 |
|
6494 | addHTMLTagAttributes(doc, html);
|
6495 | return doc;
|
6496 | };
|
6497 |
|
6498 | var failOnInvalidSource = function (doc) {
|
6499 | try {
|
6500 | return sanedomparsererror.failOnParseError(doc);
|
6501 | } catch (e) {
|
6502 | throw {
|
6503 | message: "Invalid source",
|
6504 | originalError: e
|
6505 | };
|
6506 | }
|
6507 | };
|
6508 |
|
6509 | module.validateXHTML = function (xhtml) {
|
6510 | var p = new DOMParser(),
|
6511 | doc = p.parseFromString(xhtml, "application/xml");
|
6512 |
|
6513 | failOnInvalidSource(doc);
|
6514 | };
|
6515 |
|
6516 | var lastCacheDate = null;
|
6517 |
|
6518 | var getUncachableURL = function (url, cache) {
|
6519 | if (cache === 'none' || cache === 'repeated') {
|
6520 | if (lastCacheDate === null || cache !== 'repeated') {
|
6521 | lastCacheDate = Date.now();
|
6522 | }
|
6523 | return url + "?_=" + lastCacheDate;
|
6524 | } else {
|
6525 | return url;
|
6526 | }
|
6527 | };
|
6528 |
|
6529 | var doDocumentLoad = function (url, options) {
|
6530 | var xhr = new window.XMLHttpRequest(),
|
6531 | joinedUrl = util.joinUrl(options.baseUrl, url),
|
6532 | augmentedUrl = getUncachableURL(joinedUrl, options.cache),
|
6533 | defer = ayepromise.defer(),
|
6534 | doReject = function (e) {
|
6535 | defer.reject({
|
6536 | message: "Unable to load page",
|
6537 | originalError: e
|
6538 | });
|
6539 | };
|
6540 |
|
6541 | xhr.addEventListener("load", function () {
|
6542 | if (xhr.status === 200 || xhr.status === 0) {
|
6543 | defer.resolve(xhr.responseXML);
|
6544 | } else {
|
6545 | doReject(xhr.statusText);
|
6546 | }
|
6547 | }, false);
|
6548 |
|
6549 | xhr.addEventListener("error", function (e) {
|
6550 | doReject(e);
|
6551 | }, false);
|
6552 |
|
6553 | try {
|
6554 | xhr.open('GET', augmentedUrl, true);
|
6555 | xhr.responseType = "document";
|
6556 | xhr.send(null);
|
6557 | } catch (e) {
|
6558 | doReject(e);
|
6559 | }
|
6560 |
|
6561 | return defer.promise;
|
6562 | };
|
6563 |
|
6564 | module.loadDocument = function (url, options) {
|
6565 | return doDocumentLoad(url, options)
|
6566 | .then(function (doc) {
|
6567 | return failOnInvalidSource(doc);
|
6568 | });
|
6569 | };
|
6570 |
|
6571 | return module;
|
6572 | }(util, proxies, ayepromise, sanedomparsererror, window));
|
6573 |
|
6574 | var svg2image = (function (ayepromise, window) {
|
6575 | "use strict";
|
6576 |
|
6577 | var module = {};
|
6578 |
|
6579 | var urlForSvg = function (svg, useBlobs) {
|
6580 | if (useBlobs) {
|
6581 | return URL.createObjectURL(new Blob([svg], {"type": "image/svg+xml"}));
|
6582 | } else {
|
6583 | return "data:image/svg+xml;charset=utf-8," + encodeURIComponent(svg);
|
6584 | }
|
6585 | };
|
6586 |
|
6587 | var cleanUpUrl = function (url) {
|
6588 | if (url instanceof Blob) {
|
6589 | URL.revokeObjectURL(url);
|
6590 | }
|
6591 | };
|
6592 |
|
6593 | var simpleForeignObjectSvg = '<svg xmlns="http://www.w3.org/2000/svg" width="1" height="1"><foreignObject></foreignObject></svg>';
|
6594 |
|
6595 | var supportsReadingObjectFromCanvas = function (url) {
|
6596 | var canvas = document.createElement("canvas"),
|
6597 | image = new Image(),
|
6598 | defer = ayepromise.defer();
|
6599 |
|
6600 | image.onload = function () {
|
6601 | var context = canvas.getContext("2d");
|
6602 | try {
|
6603 | context.drawImage(image, 0, 0);
|
6604 | // This will fail in Chrome & Safari
|
6605 | canvas.toDataURL("image/png");
|
6606 | defer.resolve(true);
|
6607 | } catch (e) {
|
6608 | defer.resolve(false);
|
6609 | }
|
6610 | };
|
6611 | image.onerror = defer.reject;
|
6612 | image.src = url;
|
6613 |
|
6614 | return defer.promise;
|
6615 | };
|
6616 |
|
6617 | var readingBackFromCanvasBenefitsFromOldSchoolDataUris = function () {
|
6618 | // Check for work around for https://code.google.com/p/chromium/issues/detail?id=294129
|
6619 | var blobUrl = urlForSvg(simpleForeignObjectSvg, true);
|
6620 | return supportsReadingObjectFromCanvas(blobUrl)
|
6621 | .then(function (supportsReadingFromBlobs) {
|
6622 | cleanUpUrl(blobUrl);
|
6623 | if (supportsReadingFromBlobs) {
|
6624 | return false;
|
6625 | }
|
6626 | return supportsReadingObjectFromCanvas(urlForSvg(simpleForeignObjectSvg, false))
|
6627 | .then(function (s) {
|
6628 | return s;
|
6629 | });
|
6630 | }, function () {
|
6631 | return false;
|
6632 | });
|
6633 | };
|
6634 |
|
6635 | var supportsBlobBuilding = function () {
|
6636 | if (window.Blob) {
|
6637 | // Available as constructor only in newer builds for all browsers
|
6638 | try {
|
6639 | new Blob(['<b></b>'], { "type" : "text/xml" });
|
6640 | return true;
|
6641 | } catch (err) {}
|
6642 | }
|
6643 | return false;
|
6644 | };
|
6645 |
|
6646 | var checkBlobSupport = function () {
|
6647 | var defer = ayepromise.defer();
|
6648 |
|
6649 | if (supportsBlobBuilding && window.URL) {
|
6650 | readingBackFromCanvasBenefitsFromOldSchoolDataUris()
|
6651 | .then(function (doesBenefit) {
|
6652 | defer.resolve(! doesBenefit);
|
6653 | }, function () {
|
6654 | defer.reject();
|
6655 | });
|
6656 | } else {
|
6657 | defer.resolve(false);
|
6658 | }
|
6659 |
|
6660 | return defer.promise;
|
6661 | };
|
6662 |
|
6663 | var checkForBlobsResult;
|
6664 |
|
6665 | var checkForBlobs = function () {
|
6666 | if (checkForBlobsResult === undefined) {
|
6667 | checkForBlobsResult = checkBlobSupport();
|
6668 | }
|
6669 |
|
6670 | return checkForBlobsResult;
|
6671 | };
|
6672 |
|
6673 | var buildImageUrl = function (svg) {
|
6674 | return checkForBlobs().then(function (useBlobs) {
|
6675 | return urlForSvg(svg, useBlobs);
|
6676 | });
|
6677 | };
|
6678 |
|
6679 | module.renderSvg = function (svg) {
|
6680 | var url, image,
|
6681 | defer = ayepromise.defer(),
|
6682 | resetEventHandlers = function () {
|
6683 | image.onload = null;
|
6684 | image.onerror = null;
|
6685 | },
|
6686 | cleanUp = function () {
|
6687 | if (url) {
|
6688 | cleanUpUrl(url);
|
6689 | }
|
6690 | };
|
6691 |
|
6692 | image = new Image();
|
6693 | image.onload = function() {
|
6694 | resetEventHandlers();
|
6695 | cleanUp();
|
6696 |
|
6697 | defer.resolve(image);
|
6698 | };
|
6699 | image.onerror = function () {
|
6700 | cleanUp();
|
6701 |
|
6702 | // Webkit calls the onerror handler if the SVG is faulty
|
6703 | defer.reject();
|
6704 | };
|
6705 |
|
6706 | buildImageUrl(svg).then(function (imageUrl) {
|
6707 | url = imageUrl;
|
6708 | image.src = url;
|
6709 | }, defer.reject);
|
6710 |
|
6711 | return defer.promise;
|
6712 | };
|
6713 |
|
6714 | return module;
|
6715 | }(ayepromise, window));
|
6716 |
|
6717 | var document2svg = (function (util, browser, documentHelper, mediaQueryHelper, xmlserializer) {
|
6718 | "use strict";
|
6719 |
|
6720 | var module = {};
|
6721 |
|
6722 | var svgAttributes = function (size, zoom) {
|
6723 | var zoomFactor = zoom || 1;
|
6724 |
|
6725 | var attributes = {
|
6726 | width: size.width,
|
6727 | height: size.height,
|
6728 | 'font-size': size.rootFontSize
|
6729 | };
|
6730 |
|
6731 | if (zoomFactor !== 1) {
|
6732 | attributes.style = 'transform:scale(' + zoomFactor + '); transform-origin: 0 0;';
|
6733 | }
|
6734 |
|
6735 | return attributes;
|
6736 | };
|
6737 |
|
6738 | var foreignObjectAttributes = function (size) {
|
6739 | var closestScaledWith, closestScaledHeight,
|
6740 | offsetX, offsetY;
|
6741 |
|
6742 | closestScaledWith = Math.round(size.viewportWidth);
|
6743 | closestScaledHeight = Math.round(size.viewportHeight);
|
6744 |
|
6745 | offsetX = -size.left;
|
6746 | offsetY = -size.top;
|
6747 |
|
6748 | var attributes = {
|
6749 | 'x': offsetX,
|
6750 | 'y': offsetY,
|
6751 | 'width': closestScaledWith,
|
6752 | 'height': closestScaledHeight
|
6753 | };
|
6754 |
|
6755 | return attributes;
|
6756 | };
|
6757 |
|
6758 | var workAroundCollapsingMarginsAcrossSVGElementInWebKitLike = function (attributes) {
|
6759 | var style = attributes.style || '';
|
6760 | attributes.style = style + 'float: left;';
|
6761 | };
|
6762 |
|
6763 | var workAroundSafariSometimesNotShowingExternalResources = function (attributes) {
|
6764 | /* Let's hope that works some magic. The spec says SVGLoad only fires
|
6765 | * now when all externals are available.
|
6766 | * http://www.w3.org/TR/SVG/struct.html#ExternalResourcesRequired */
|
6767 | attributes.externalResourcesRequired = true;
|
6768 | };
|
6769 |
|
6770 | var workAroundChromeShowingScrollbarsUnderLinuxIfHtmlIsOverflowScroll = function () {
|
6771 | return '<style scoped="">html::-webkit-scrollbar { display: none; }</style>';
|
6772 | };
|
6773 |
|
6774 | var serializeAttributes = function (attributes) {
|
6775 | var keys = Object.keys(attributes);
|
6776 | if (!keys.length) {
|
6777 | return '';
|
6778 | }
|
6779 |
|
6780 | return ' ' + keys.map(function (key) {
|
6781 | return key + '="' + attributes[key] + '"';
|
6782 | }).join(' ');
|
6783 | };
|
6784 |
|
6785 | var convertElementToSvg = function (element, size, zoomFactor) {
|
6786 | var xhtml = xmlserializer.serializeToString(element);
|
6787 |
|
6788 | browser.validateXHTML(xhtml);
|
6789 |
|
6790 | var foreignObjectAttrs = foreignObjectAttributes(size);
|
6791 | workAroundCollapsingMarginsAcrossSVGElementInWebKitLike(foreignObjectAttrs);
|
6792 | workAroundSafariSometimesNotShowingExternalResources(foreignObjectAttrs);
|
6793 |
|
6794 | return (
|
6795 | '<svg xmlns="http://www.w3.org/2000/svg"' +
|
6796 | serializeAttributes(svgAttributes(size, zoomFactor)) +
|
6797 | '>' +
|
6798 | workAroundChromeShowingScrollbarsUnderLinuxIfHtmlIsOverflowScroll() +
|
6799 | '<foreignObject' + serializeAttributes(foreignObjectAttrs) + '>' +
|
6800 | xhtml +
|
6801 | '</foreignObject>' +
|
6802 | '</svg>'
|
6803 | );
|
6804 | };
|
6805 |
|
6806 | module.getSvgForDocument = function (element, size, zoomFactor) {
|
6807 | documentHelper.rewriteTagNameSelectorsToLowerCase(element);
|
6808 |
|
6809 | return mediaQueryHelper.needsEmWorkaround().then(function (needsWorkaround) {
|
6810 | if (needsWorkaround) {
|
6811 | mediaQueryHelper.workAroundWebKitEmSizeIssue(element);
|
6812 | }
|
6813 |
|
6814 | return convertElementToSvg(element, size, zoomFactor);
|
6815 | });
|
6816 | };
|
6817 |
|
6818 | module.drawDocumentAsSvg = function (element, options) {
|
6819 | ['hover', 'active', 'focus', 'target'].forEach(function (action) {
|
6820 | if (options[action]) {
|
6821 | documentHelper.fakeUserAction(element, options[action], action);
|
6822 | }
|
6823 | });
|
6824 |
|
6825 | return browser.calculateDocumentContentSize(element, options)
|
6826 | .then(function (size) {
|
6827 | return module.getSvgForDocument(element, size, options.zoom);
|
6828 | });
|
6829 | };
|
6830 |
|
6831 | return module;
|
6832 | }(util, browser, documentHelper, mediaQueryHelper, xmlserializer));
|
6833 |
|
6834 | var rasterize = (function (util, browser, documentHelper, document2svg, svg2image, inlineresources) {
|
6835 | "use strict";
|
6836 |
|
6837 | var module = {};
|
6838 |
|
6839 | var generalDrawError = function (e) {
|
6840 | return {
|
6841 | message: "Error rendering page",
|
6842 | originalError: e
|
6843 | };
|
6844 | };
|
6845 |
|
6846 | var drawSvgAsImg = function (svg) {
|
6847 | return svg2image.renderSvg(svg)
|
6848 | .then(function (image) {
|
6849 | return {
|
6850 | image: image,
|
6851 | svg: svg
|
6852 | };
|
6853 | }, function (e) {
|
6854 | throw generalDrawError(e);
|
6855 | });
|
6856 | };
|
6857 |
|
6858 | var drawImageOnCanvas = function (image, canvas) {
|
6859 | try {
|
6860 | canvas.getContext("2d").drawImage(image, 0, 0);
|
6861 | } catch (e) {
|
6862 | // Firefox throws a 'NS_ERROR_NOT_AVAILABLE' if the SVG is faulty
|
6863 | throw generalDrawError(e);
|
6864 | }
|
6865 | };
|
6866 |
|
6867 | var doDraw = function (element, canvas, options) {
|
6868 | return document2svg.drawDocumentAsSvg(element, options)
|
6869 | .then(drawSvgAsImg)
|
6870 | .then(function (result) {
|
6871 | if (canvas) {
|
6872 | drawImageOnCanvas(result.image, canvas);
|
6873 | }
|
6874 |
|
6875 | return result;
|
6876 | });
|
6877 | };
|
6878 |
|
6879 | var operateJavaScriptOnDocument = function (element, options) {
|
6880 | return browser.executeJavascript(element, options)
|
6881 | .then(function (result) {
|
6882 | var document = result.document;
|
6883 | documentHelper.persistInputValues(document);
|
6884 |
|
6885 | return {
|
6886 | document: document,
|
6887 | errors: result.errors
|
6888 | };
|
6889 | });
|
6890 | };
|
6891 |
|
6892 | module.rasterize = function (element, canvas, options) {
|
6893 | var inlineOptions;
|
6894 |
|
6895 | inlineOptions = util.clone(options);
|
6896 | inlineOptions.inlineScripts = options.executeJs === true;
|
6897 |
|
6898 | return inlineresources.inlineReferences(element, inlineOptions)
|
6899 | .then(function (errors) {
|
6900 | if (options.executeJs) {
|
6901 | return operateJavaScriptOnDocument(element, options)
|
6902 | .then(function (result) {
|
6903 | return {
|
6904 | element: result.document.documentElement,
|
6905 | errors: errors.concat(result.errors)
|
6906 | };
|
6907 | });
|
6908 | } else {
|
6909 | return {
|
6910 | element: element,
|
6911 | errors: errors
|
6912 | };
|
6913 | }
|
6914 | }).then(function (result) {
|
6915 | return doDraw(result.element, canvas, options)
|
6916 | .then(function (drawResult) {
|
6917 | return {
|
6918 | image: drawResult.image,
|
6919 | svg: drawResult.svg,
|
6920 | errors: result.errors
|
6921 | };
|
6922 | });
|
6923 | });
|
6924 | };
|
6925 |
|
6926 | return module;
|
6927 | }(util, browser, documentHelper, document2svg, svg2image, inlineresources));
|
6928 |
|
6929 | var rasterizeHTML = (function (util, browser, rasterize) {
|
6930 | "use strict";
|
6931 |
|
6932 | var module = {};
|
6933 |
|
6934 | var getViewportSize = function (canvas, options) {
|
6935 | var defaultWidth = 300,
|
6936 | defaultHeight = 200,
|
6937 | fallbackWidth = canvas ? canvas.width : defaultWidth,
|
6938 | fallbackHeight = canvas ? canvas.height : defaultHeight,
|
6939 | width = options.width !== undefined ? options.width : fallbackWidth,
|
6940 | height = options.height !== undefined ? options.height : fallbackHeight;
|
6941 |
|
6942 | return {
|
6943 | width: width,
|
6944 | height: height
|
6945 | };
|
6946 | };
|
6947 |
|
6948 | var constructOptions = function (params) {
|
6949 | var viewport = getViewportSize(params.canvas, params.options),
|
6950 | options;
|
6951 |
|
6952 | options = util.clone(params.options);
|
6953 | options.width = viewport.width;
|
6954 | options.height = viewport.height;
|
6955 |
|
6956 | return options;
|
6957 | };
|
6958 |
|
6959 | /**
|
6960 | * Draws a Document to the canvas.
|
6961 | * rasterizeHTML.drawDocument( document [, canvas] [, options] ).then(function (result) { ... });
|
6962 | */
|
6963 | module.drawDocument = function () {
|
6964 | var doc = arguments[0],
|
6965 | optionalArguments = Array.prototype.slice.call(arguments, 1),
|
6966 | params = util.parseOptionalParameters(optionalArguments);
|
6967 |
|
6968 | var element = doc.documentElement ? doc.documentElement : doc;
|
6969 |
|
6970 | return rasterize.rasterize(element, params.canvas, constructOptions(params));
|
6971 | };
|
6972 |
|
6973 | var drawHTML = function (html, canvas, options) {
|
6974 | var doc = browser.parseHTML(html);
|
6975 |
|
6976 | return module.drawDocument(doc, canvas, options);
|
6977 | };
|
6978 |
|
6979 | /**
|
6980 | * Draws a HTML string to the canvas.
|
6981 | * rasterizeHTML.drawHTML( html [, canvas] [, options] ).then(function (result) { ... });
|
6982 | */
|
6983 | module.drawHTML = function () {
|
6984 | var html = arguments[0],
|
6985 | optionalArguments = Array.prototype.slice.call(arguments, 1),
|
6986 | params = util.parseOptionalParameters(optionalArguments);
|
6987 |
|
6988 | return drawHTML(html, params.canvas, params.options);
|
6989 | };
|
6990 |
|
6991 | // work around https://bugzilla.mozilla.org/show_bug.cgi?id=925493
|
6992 | var workAroundFirefoxNotLoadingStylesheetStyles = function (doc, url, options) {
|
6993 | var d = document.implementation.createHTMLDocument('');
|
6994 | d.replaceChild(doc.documentElement, d.documentElement);
|
6995 |
|
6996 | var extendedOptions = options ? util.clone(options) : {};
|
6997 |
|
6998 | if (!options.baseUrl) {
|
6999 | extendedOptions.baseUrl = url;
|
7000 | }
|
7001 |
|
7002 | return {
|
7003 | document: d,
|
7004 | options: extendedOptions
|
7005 | };
|
7006 | };
|
7007 |
|
7008 | var drawURL = function (url, canvas, options) {
|
7009 | return browser.loadDocument(url, options)
|
7010 | .then(function (doc) {
|
7011 | var workaround = workAroundFirefoxNotLoadingStylesheetStyles(doc, url, options);
|
7012 | return module.drawDocument(workaround.document, canvas, workaround.options);
|
7013 | });
|
7014 | };
|
7015 |
|
7016 | /**
|
7017 | * Draws a page to the canvas.
|
7018 | * rasterizeHTML.drawURL( url [, canvas] [, options] ).then(function (result) { ... });
|
7019 | */
|
7020 | module.drawURL = function () {
|
7021 | var url = arguments[0],
|
7022 | optionalArguments = Array.prototype.slice.call(arguments, 1),
|
7023 | params = util.parseOptionalParameters(optionalArguments);
|
7024 |
|
7025 | return drawURL(url, params.canvas, params.options);
|
7026 | };
|
7027 |
|
7028 | return module;
|
7029 | }(util, browser, rasterize));
|
7030 |
|
7031 | return rasterizeHTML;
|
7032 |
|
7033 | }));
|
7034 |
|
7035 | },{"ayepromise":2,"css-mediaquery":8,"inlineresources":30,"sane-domparser-error":40,"url":3,"xmlserializer":41}],40:[function(require,module,exports){
|
7036 | 'use strict';
|
7037 |
|
7038 | var innerXML = function (node) {
|
7039 | var s = new XMLSerializer();
|
7040 | return Array.prototype.map.call(node.childNodes, function (node) {
|
7041 | return s.serializeToString(node);
|
7042 | }).join('');
|
7043 | };
|
7044 |
|
7045 | var getParseError = function (doc) {
|
7046 | // Firefox
|
7047 | if (doc.documentElement.tagName === 'parsererror' &&
|
7048 | doc.documentElement.namespaceURI === 'http://www.mozilla.org/newlayout/xml/parsererror.xml') {
|
7049 | return doc.documentElement;
|
7050 | }
|
7051 |
|
7052 | // Chrome, Safari
|
7053 | if ((doc.documentElement.tagName === 'xml' || doc.documentElement.tagName === 'html') &&
|
7054 | doc.documentElement.childNodes &&
|
7055 | doc.documentElement.childNodes.length > 0 &&
|
7056 | doc.documentElement.childNodes[0].nodeName === 'parsererror') {
|
7057 | return doc.documentElement.childNodes[0];
|
7058 | }
|
7059 |
|
7060 | // PhantomJS
|
7061 | if (doc.documentElement.tagName === 'html' &&
|
7062 | doc.documentElement.childNodes &&
|
7063 | doc.documentElement.childNodes.length > 0 &&
|
7064 | doc.documentElement.childNodes[0].nodeName === 'body' &&
|
7065 | doc.documentElement.childNodes[0].childNodes &&
|
7066 | doc.documentElement.childNodes[0].childNodes.length &&
|
7067 | doc.documentElement.childNodes[0].childNodes[0].nodeName === 'parsererror') {
|
7068 | return doc.documentElement.childNodes[0].childNodes[0];
|
7069 | }
|
7070 |
|
7071 | return undefined;
|
7072 | };
|
7073 |
|
7074 | var errorMessagePatterns = [
|
7075 | // Chrome, Safari, PhantomJS
|
7076 | new RegExp('^<h3[^>]*>This page contains the following errors:<\/h3><div[^>]*>(.+?)\n?<\/div>'),
|
7077 | // Firefox
|
7078 | new RegExp('^(.+)\n')
|
7079 | ];
|
7080 |
|
7081 | var extractParseError = function (errorNode) {
|
7082 | var content = innerXML(errorNode);
|
7083 | var i, match;
|
7084 |
|
7085 | for(i = 0; i < errorMessagePatterns.length; i++) {
|
7086 | match = errorMessagePatterns[i].exec(content);
|
7087 |
|
7088 | if (match) {
|
7089 | return match[1];
|
7090 | }
|
7091 | }
|
7092 | return undefined;
|
7093 | };
|
7094 |
|
7095 | var failOnParseError = function (doc) {
|
7096 | var errorMessage;
|
7097 |
|
7098 | if (doc === null) {
|
7099 | throw new Error('Parse error');
|
7100 | }
|
7101 |
|
7102 | var parseError = getParseError(doc);
|
7103 | if (parseError !== undefined) {
|
7104 | errorMessage = extractParseError(parseError) || 'Parse error';
|
7105 | throw new Error(errorMessage);
|
7106 | }
|
7107 | };
|
7108 |
|
7109 | exports.failOnParseError = function (doc) {
|
7110 | failOnParseError(doc);
|
7111 |
|
7112 | return doc;
|
7113 | };
|
7114 |
|
7115 | },{}],41:[function(require,module,exports){
|
7116 | var removeInvalidCharacters = function (content) {
|
7117 | // See http://www.w3.org/TR/xml/#NT-Char for valid XML 1.0 characters
|
7118 | return content.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '');
|
7119 | };
|
7120 |
|
7121 | var serializeAttributeValue = function (value) {
|
7122 | return value
|
7123 | .replace(/&/g, '&')
|
7124 | .replace(/</g, '<')
|
7125 | .replace(/>/g, '>')
|
7126 | .replace(/"/g, '"')
|
7127 | .replace(/'/g, ''');
|
7128 | };
|
7129 |
|
7130 | var serializeTextContent = function (content) {
|
7131 | return content
|
7132 | .replace(/&/g, '&')
|
7133 | .replace(/</g, '<')
|
7134 | .replace(/>/g, '>');
|
7135 | };
|
7136 |
|
7137 | var serializeAttribute = function (attr) {
|
7138 | var value = attr.value;
|
7139 |
|
7140 | return ' ' + attr.name + '="' + serializeAttributeValue(value) + '"';
|
7141 | };
|
7142 |
|
7143 | var getTagName = function (node) {
|
7144 | var tagName = node.tagName;
|
7145 |
|
7146 | // Aid in serializing of original HTML documents
|
7147 | if (node.namespaceURI === 'http://www.w3.org/1999/xhtml') {
|
7148 | tagName = tagName.toLowerCase();
|
7149 | }
|
7150 | return tagName;
|
7151 | };
|
7152 |
|
7153 | var serializeNamespace = function (node, isRootNode) {
|
7154 | var nodeHasXmlnsAttr = Array.prototype.map.call(node.attributes || node.attrs, function (attr) {
|
7155 | return attr.name;
|
7156 | })
|
7157 | .indexOf('xmlns') >= 0;
|
7158 | // Serialize the namespace as an xmlns attribute whenever the element
|
7159 | // doesn't already have one and the inherited namespace does not match
|
7160 | // the element's namespace.
|
7161 | if (!nodeHasXmlnsAttr &&
|
7162 | (isRootNode ||
|
7163 | node.namespaceURI !== node.parentNode.namespaceURI)) {
|
7164 | return ' xmlns="' + node.namespaceURI + '"';
|
7165 | } else {
|
7166 | return '';
|
7167 | }
|
7168 | };
|
7169 |
|
7170 | var serializeChildren = function (node) {
|
7171 | return Array.prototype.map.call(node.childNodes, function (childNode) {
|
7172 | return nodeTreeToXHTML(childNode);
|
7173 | }).join('');
|
7174 | };
|
7175 |
|
7176 | var serializeTag = function (node, isRootNode) {
|
7177 | var output = '<' + getTagName(node);
|
7178 | output += serializeNamespace(node, isRootNode);
|
7179 |
|
7180 | Array.prototype.forEach.call(node.attributes || node.attrs, function (attr) {
|
7181 | output += serializeAttribute(attr);
|
7182 | });
|
7183 |
|
7184 | if (node.childNodes.length > 0) {
|
7185 | output += '>';
|
7186 | output += serializeChildren(node);
|
7187 | output += '</' + getTagName(node) + '>';
|
7188 | } else {
|
7189 | output += '/>';
|
7190 | }
|
7191 | return output;
|
7192 | };
|
7193 |
|
7194 | var serializeText = function (node) {
|
7195 | var text = node.nodeValue || node.value || '';
|
7196 | return serializeTextContent(text);
|
7197 | };
|
7198 |
|
7199 | var serializeComment = function (node) {
|
7200 | return '<!--' +
|
7201 | node.data
|
7202 | .replace(/-/g, '-') +
|
7203 | '-->';
|
7204 | };
|
7205 |
|
7206 | var serializeCDATA = function (node) {
|
7207 | return '<![CDATA[' + node.nodeValue + ']]>';
|
7208 | };
|
7209 |
|
7210 | var nodeTreeToXHTML = function (node, options) {
|
7211 | var isRootNode = options && options.rootNode;
|
7212 |
|
7213 | if (node.nodeName === '#document' ||
|
7214 | node.nodeName === '#document-fragment') {
|
7215 | return serializeChildren(node);
|
7216 | } else {
|
7217 | if (node.tagName) {
|
7218 | return serializeTag(node, isRootNode);
|
7219 | } else if (node.nodeName === '#text') {
|
7220 | return serializeText(node);
|
7221 | } else if (node.nodeName === '#comment') {
|
7222 | return serializeComment(node);
|
7223 | } else if (node.nodeName === '#cdata-section') {
|
7224 | return serializeCDATA(node);
|
7225 | }
|
7226 | }
|
7227 | };
|
7228 |
|
7229 | exports.serializeToString = function (node) {
|
7230 | return removeInvalidCharacters(nodeTreeToXHTML(node, {rootNode: true}));
|
7231 | };
|
7232 |
|
7233 | },{}]},{},[1]);
|