Stop exposing the URL
polyfill in the global scope
This moves/exposes the `URL` polyfill similarily to the existing `ReadableStream` polyfill, rather than exposing it globally, to avoid interfering with any "outside" code. Both the `URL` and `ReadableStream` polyfills are now exposed on the `pdfjsLib` object, such that they are accessible to the viewer components. Furthermore, the `no-restricted-globals` ESLint rule is also enabled to prevent accidental usage of the native `URL`/`ReadableStream` implementations directly in the `src/` and `web/` folders; see also https://eslint.org/docs/rules/no-restricted-globals Addresses the remaining TODO in https://github.com/mozilla/pdf.js/projects/6
This commit is contained in:
parent
42922c9ae5
commit
a9ce4e8417
@ -98,6 +98,7 @@
|
|||||||
"no-catch-shadow": "error",
|
"no-catch-shadow": "error",
|
||||||
"no-delete-var": "error",
|
"no-delete-var": "error",
|
||||||
"no-label-var": "error",
|
"no-label-var": "error",
|
||||||
|
"no-restricted-globals": "off",
|
||||||
"no-shadow-restricted-names": "error",
|
"no-shadow-restricted-names": "error",
|
||||||
"no-shadow": "off",
|
"no-shadow": "off",
|
||||||
"no-undef-init": "error",
|
"no-undef-init": "error",
|
||||||
|
627
external/url/url-lib.js
vendored
Normal file
627
external/url/url-lib.js
vendored
Normal file
@ -0,0 +1,627 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Polyfill obtained from: https://github.com/Polymer/URL
|
||||||
|
|
||||||
|
(function URLConstructorClosure() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var relative = Object.create(null);
|
||||||
|
relative['ftp'] = 21;
|
||||||
|
relative['file'] = 0;
|
||||||
|
relative['gopher'] = 70;
|
||||||
|
relative['http'] = 80;
|
||||||
|
relative['https'] = 443;
|
||||||
|
relative['ws'] = 80;
|
||||||
|
relative['wss'] = 443;
|
||||||
|
|
||||||
|
var relativePathDotMapping = Object.create(null);
|
||||||
|
relativePathDotMapping['%2e'] = '.';
|
||||||
|
relativePathDotMapping['.%2e'] = '..';
|
||||||
|
relativePathDotMapping['%2e.'] = '..';
|
||||||
|
relativePathDotMapping['%2e%2e'] = '..';
|
||||||
|
|
||||||
|
function isRelativeScheme(scheme) {
|
||||||
|
return relative[scheme] !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function invalid() {
|
||||||
|
clear.call(this);
|
||||||
|
this._isInvalid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function IDNAToASCII(h) {
|
||||||
|
if (h === '') {
|
||||||
|
invalid.call(this);
|
||||||
|
}
|
||||||
|
// XXX
|
||||||
|
return h.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
function percentEscape(c) {
|
||||||
|
var unicode = c.charCodeAt(0);
|
||||||
|
if (unicode > 0x20 &&
|
||||||
|
unicode < 0x7F &&
|
||||||
|
// " # < > ? `
|
||||||
|
[0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) === -1
|
||||||
|
) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return encodeURIComponent(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
function percentEscapeQuery(c) {
|
||||||
|
// XXX This actually needs to encode c using encoding and then
|
||||||
|
// convert the bytes one-by-one.
|
||||||
|
|
||||||
|
var unicode = c.charCodeAt(0);
|
||||||
|
if (unicode > 0x20 &&
|
||||||
|
unicode < 0x7F &&
|
||||||
|
// " # < > ` (do not escape '?')
|
||||||
|
[0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) === -1
|
||||||
|
) {
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return encodeURIComponent(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
var EOF, ALPHA = /[a-zA-Z]/,
|
||||||
|
ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
|
||||||
|
|
||||||
|
function parse(input, stateOverride, base) {
|
||||||
|
function err(message) {
|
||||||
|
errors.push(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
var state = stateOverride || 'scheme start',
|
||||||
|
cursor = 0,
|
||||||
|
buffer = '',
|
||||||
|
seenAt = false,
|
||||||
|
seenBracket = false,
|
||||||
|
errors = [];
|
||||||
|
|
||||||
|
loop: while ((input[cursor - 1] !== EOF || cursor === 0) &&
|
||||||
|
!this._isInvalid) {
|
||||||
|
var c = input[cursor];
|
||||||
|
switch (state) {
|
||||||
|
case 'scheme start':
|
||||||
|
if (c && ALPHA.test(c)) {
|
||||||
|
buffer += c.toLowerCase(); // ASCII-safe
|
||||||
|
state = 'scheme';
|
||||||
|
} else if (!stateOverride) {
|
||||||
|
buffer = '';
|
||||||
|
state = 'no scheme';
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
err('Invalid scheme.');
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'scheme':
|
||||||
|
if (c && ALPHANUMERIC.test(c)) {
|
||||||
|
buffer += c.toLowerCase(); // ASCII-safe
|
||||||
|
} else if (c === ':') {
|
||||||
|
this._scheme = buffer;
|
||||||
|
buffer = '';
|
||||||
|
if (stateOverride) {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
if (isRelativeScheme(this._scheme)) {
|
||||||
|
this._isRelative = true;
|
||||||
|
}
|
||||||
|
if (this._scheme === 'file') {
|
||||||
|
state = 'relative';
|
||||||
|
} else if (this._isRelative && base &&
|
||||||
|
base._scheme === this._scheme) {
|
||||||
|
state = 'relative or authority';
|
||||||
|
} else if (this._isRelative) {
|
||||||
|
state = 'authority first slash';
|
||||||
|
} else {
|
||||||
|
state = 'scheme data';
|
||||||
|
}
|
||||||
|
} else if (!stateOverride) {
|
||||||
|
buffer = '';
|
||||||
|
cursor = 0;
|
||||||
|
state = 'no scheme';
|
||||||
|
continue;
|
||||||
|
} else if (c === EOF) {
|
||||||
|
break loop;
|
||||||
|
} else {
|
||||||
|
err('Code point not allowed in scheme: ' + c);
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'scheme data':
|
||||||
|
if (c === '?') {
|
||||||
|
this._query = '?';
|
||||||
|
state = 'query';
|
||||||
|
} else if (c === '#') {
|
||||||
|
this._fragment = '#';
|
||||||
|
state = 'fragment';
|
||||||
|
} else {
|
||||||
|
// XXX error handling
|
||||||
|
if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
||||||
|
this._schemeData += percentEscape(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'no scheme':
|
||||||
|
if (!base || !(isRelativeScheme(base._scheme))) {
|
||||||
|
err('Missing scheme.');
|
||||||
|
invalid.call(this);
|
||||||
|
} else {
|
||||||
|
state = 'relative';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'relative or authority':
|
||||||
|
if (c === '/' && input[cursor + 1] === '/') {
|
||||||
|
state = 'authority ignore slashes';
|
||||||
|
} else {
|
||||||
|
err('Expected /, got: ' + c);
|
||||||
|
state = 'relative';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'relative':
|
||||||
|
this._isRelative = true;
|
||||||
|
if (this._scheme !== 'file') {
|
||||||
|
this._scheme = base._scheme;
|
||||||
|
}
|
||||||
|
if (c === EOF) {
|
||||||
|
this._host = base._host;
|
||||||
|
this._port = base._port;
|
||||||
|
this._path = base._path.slice();
|
||||||
|
this._query = base._query;
|
||||||
|
this._username = base._username;
|
||||||
|
this._password = base._password;
|
||||||
|
break loop;
|
||||||
|
} else if (c === '/' || c === '\\') {
|
||||||
|
if (c === '\\') {
|
||||||
|
err('\\ is an invalid code point.');
|
||||||
|
}
|
||||||
|
state = 'relative slash';
|
||||||
|
} else if (c === '?') {
|
||||||
|
this._host = base._host;
|
||||||
|
this._port = base._port;
|
||||||
|
this._path = base._path.slice();
|
||||||
|
this._query = '?';
|
||||||
|
this._username = base._username;
|
||||||
|
this._password = base._password;
|
||||||
|
state = 'query';
|
||||||
|
} else if (c === '#') {
|
||||||
|
this._host = base._host;
|
||||||
|
this._port = base._port;
|
||||||
|
this._path = base._path.slice();
|
||||||
|
this._query = base._query;
|
||||||
|
this._fragment = '#';
|
||||||
|
this._username = base._username;
|
||||||
|
this._password = base._password;
|
||||||
|
state = 'fragment';
|
||||||
|
} else {
|
||||||
|
var nextC = input[cursor + 1];
|
||||||
|
var nextNextC = input[cursor + 2];
|
||||||
|
if (this._scheme !== 'file' || !ALPHA.test(c) ||
|
||||||
|
(nextC !== ':' && nextC !== '|') ||
|
||||||
|
(nextNextC !== EOF && nextNextC !== '/' && nextNextC !== '\\' &&
|
||||||
|
nextNextC !== '?' && nextNextC !== '#')) {
|
||||||
|
this._host = base._host;
|
||||||
|
this._port = base._port;
|
||||||
|
this._username = base._username;
|
||||||
|
this._password = base._password;
|
||||||
|
this._path = base._path.slice();
|
||||||
|
this._path.pop();
|
||||||
|
}
|
||||||
|
state = 'relative path';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'relative slash':
|
||||||
|
if (c === '/' || c === '\\') {
|
||||||
|
if (c === '\\') {
|
||||||
|
err('\\ is an invalid code point.');
|
||||||
|
}
|
||||||
|
if (this._scheme === 'file') {
|
||||||
|
state = 'file host';
|
||||||
|
} else {
|
||||||
|
state = 'authority ignore slashes';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (this._scheme !== 'file') {
|
||||||
|
this._host = base._host;
|
||||||
|
this._port = base._port;
|
||||||
|
this._username = base._username;
|
||||||
|
this._password = base._password;
|
||||||
|
}
|
||||||
|
state = 'relative path';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'authority first slash':
|
||||||
|
if (c === '/') {
|
||||||
|
state = 'authority second slash';
|
||||||
|
} else {
|
||||||
|
err('Expected \'/\', got: ' + c);
|
||||||
|
state = 'authority ignore slashes';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'authority second slash':
|
||||||
|
state = 'authority ignore slashes';
|
||||||
|
if (c !== '/') {
|
||||||
|
err('Expected \'/\', got: ' + c);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'authority ignore slashes':
|
||||||
|
if (c !== '/' && c !== '\\') {
|
||||||
|
state = 'authority';
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
err('Expected authority, got: ' + c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'authority':
|
||||||
|
if (c === '@') {
|
||||||
|
if (seenAt) {
|
||||||
|
err('@ already seen.');
|
||||||
|
buffer += '%40';
|
||||||
|
}
|
||||||
|
seenAt = true;
|
||||||
|
for (var i = 0; i < buffer.length; i++) {
|
||||||
|
var cp = buffer[i];
|
||||||
|
if (cp === '\t' || cp === '\n' || cp === '\r') {
|
||||||
|
err('Invalid whitespace in authority.');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// XXX check URL code points
|
||||||
|
if (cp === ':' && this._password === null) {
|
||||||
|
this._password = '';
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
var tempC = percentEscape(cp);
|
||||||
|
if (this._password !== null) {
|
||||||
|
this._password += tempC;
|
||||||
|
} else {
|
||||||
|
this._username += tempC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer = '';
|
||||||
|
} else if (c === EOF || c === '/' || c === '\\' ||
|
||||||
|
c === '?' || c === '#') {
|
||||||
|
cursor -= buffer.length;
|
||||||
|
buffer = '';
|
||||||
|
state = 'host';
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
buffer += c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'file host':
|
||||||
|
if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
|
||||||
|
if (buffer.length === 2 && ALPHA.test(buffer[0]) &&
|
||||||
|
(buffer[1] === ':' || buffer[1] === '|')) {
|
||||||
|
state = 'relative path';
|
||||||
|
} else if (buffer.length === 0) {
|
||||||
|
state = 'relative path start';
|
||||||
|
} else {
|
||||||
|
this._host = IDNAToASCII.call(this, buffer);
|
||||||
|
buffer = '';
|
||||||
|
state = 'relative path start';
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (c === '\t' || c === '\n' || c === '\r') {
|
||||||
|
err('Invalid whitespace in file host.');
|
||||||
|
} else {
|
||||||
|
buffer += c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'host':
|
||||||
|
case 'hostname':
|
||||||
|
if (c === ':' && !seenBracket) {
|
||||||
|
// XXX host parsing
|
||||||
|
this._host = IDNAToASCII.call(this, buffer);
|
||||||
|
buffer = '';
|
||||||
|
state = 'port';
|
||||||
|
if (stateOverride === 'hostname') {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
} else if (c === EOF || c === '/' ||
|
||||||
|
c === '\\' || c === '?' || c === '#') {
|
||||||
|
this._host = IDNAToASCII.call(this, buffer);
|
||||||
|
buffer = '';
|
||||||
|
state = 'relative path start';
|
||||||
|
if (stateOverride) {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (c !== '\t' && c !== '\n' && c !== '\r') {
|
||||||
|
if (c === '[') {
|
||||||
|
seenBracket = true;
|
||||||
|
} else if (c === ']') {
|
||||||
|
seenBracket = false;
|
||||||
|
}
|
||||||
|
buffer += c;
|
||||||
|
} else {
|
||||||
|
err('Invalid code point in host/hostname: ' + c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'port':
|
||||||
|
if (/[0-9]/.test(c)) {
|
||||||
|
buffer += c;
|
||||||
|
} else if (c === EOF || c === '/' || c === '\\' ||
|
||||||
|
c === '?' || c === '#' || stateOverride) {
|
||||||
|
if (buffer !== '') {
|
||||||
|
var temp = parseInt(buffer, 10);
|
||||||
|
if (temp !== relative[this._scheme]) {
|
||||||
|
this._port = temp + '';
|
||||||
|
}
|
||||||
|
buffer = '';
|
||||||
|
}
|
||||||
|
if (stateOverride) {
|
||||||
|
break loop;
|
||||||
|
}
|
||||||
|
state = 'relative path start';
|
||||||
|
continue;
|
||||||
|
} else if (c === '\t' || c === '\n' || c === '\r') {
|
||||||
|
err('Invalid code point in port: ' + c);
|
||||||
|
} else {
|
||||||
|
invalid.call(this);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'relative path start':
|
||||||
|
if (c === '\\') {
|
||||||
|
err('\'\\\' not allowed in path.');
|
||||||
|
}
|
||||||
|
state = 'relative path';
|
||||||
|
if (c !== '/' && c !== '\\') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'relative path':
|
||||||
|
if (c === EOF || c === '/' || c === '\\' ||
|
||||||
|
(!stateOverride && (c === '?' || c === '#'))) {
|
||||||
|
if (c === '\\') {
|
||||||
|
err('\\ not allowed in relative path.');
|
||||||
|
}
|
||||||
|
var tmp;
|
||||||
|
if ((tmp = relativePathDotMapping[buffer.toLowerCase()])) {
|
||||||
|
buffer = tmp;
|
||||||
|
}
|
||||||
|
if (buffer === '..') {
|
||||||
|
this._path.pop();
|
||||||
|
if (c !== '/' && c !== '\\') {
|
||||||
|
this._path.push('');
|
||||||
|
}
|
||||||
|
} else if (buffer === '.' && c !== '/' && c !== '\\') {
|
||||||
|
this._path.push('');
|
||||||
|
} else if (buffer !== '.') {
|
||||||
|
if (this._scheme === 'file' && this._path.length === 0 &&
|
||||||
|
buffer.length === 2 && ALPHA.test(buffer[0]) &&
|
||||||
|
buffer[1] === '|') {
|
||||||
|
buffer = buffer[0] + ':';
|
||||||
|
}
|
||||||
|
this._path.push(buffer);
|
||||||
|
}
|
||||||
|
buffer = '';
|
||||||
|
if (c === '?') {
|
||||||
|
this._query = '?';
|
||||||
|
state = 'query';
|
||||||
|
} else if (c === '#') {
|
||||||
|
this._fragment = '#';
|
||||||
|
state = 'fragment';
|
||||||
|
}
|
||||||
|
} else if (c !== '\t' && c !== '\n' && c !== '\r') {
|
||||||
|
buffer += percentEscape(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'query':
|
||||||
|
if (!stateOverride && c === '#') {
|
||||||
|
this._fragment = '#';
|
||||||
|
state = 'fragment';
|
||||||
|
} else if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
||||||
|
this._query += percentEscapeQuery(c);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'fragment':
|
||||||
|
if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
||||||
|
this._fragment += c;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cursor++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
this._scheme = '';
|
||||||
|
this._schemeData = '';
|
||||||
|
this._username = '';
|
||||||
|
this._password = null;
|
||||||
|
this._host = '';
|
||||||
|
this._port = '';
|
||||||
|
this._path = [];
|
||||||
|
this._query = '';
|
||||||
|
this._fragment = '';
|
||||||
|
this._isInvalid = false;
|
||||||
|
this._isRelative = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does not process domain names or IP addresses.
|
||||||
|
// Does not handle encoding for the query parameter.
|
||||||
|
function JURL(url, base /* , encoding */) {
|
||||||
|
if (base !== undefined && !(base instanceof JURL)) {
|
||||||
|
base = new JURL(String(base));
|
||||||
|
}
|
||||||
|
|
||||||
|
this._url = url;
|
||||||
|
clear.call(this);
|
||||||
|
|
||||||
|
var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, '');
|
||||||
|
// encoding = encoding || 'utf-8'
|
||||||
|
|
||||||
|
parse.call(this, input, null, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
JURL.prototype = {
|
||||||
|
toString() {
|
||||||
|
return this.href;
|
||||||
|
},
|
||||||
|
get href() {
|
||||||
|
if (this._isInvalid) {
|
||||||
|
return this._url;
|
||||||
|
}
|
||||||
|
var authority = '';
|
||||||
|
if (this._username !== '' || this._password !== null) {
|
||||||
|
authority = this._username +
|
||||||
|
(this._password !== null ? ':' + this._password : '') + '@';
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.protocol +
|
||||||
|
(this._isRelative ? '//' + authority + this.host : '') +
|
||||||
|
this.pathname + this._query + this._fragment;
|
||||||
|
},
|
||||||
|
// The named parameter should be different from the setter's function name.
|
||||||
|
// Otherwise Safari 5 will throw an error (see issue 8541)
|
||||||
|
set href(value) {
|
||||||
|
clear.call(this);
|
||||||
|
parse.call(this, value);
|
||||||
|
},
|
||||||
|
|
||||||
|
get protocol() {
|
||||||
|
return this._scheme + ':';
|
||||||
|
},
|
||||||
|
set protocol(value) {
|
||||||
|
if (this._isInvalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse.call(this, value + ':', 'scheme start');
|
||||||
|
},
|
||||||
|
|
||||||
|
get host() {
|
||||||
|
return this._isInvalid ? '' : this._port ?
|
||||||
|
this._host + ':' + this._port : this._host;
|
||||||
|
},
|
||||||
|
set host(value) {
|
||||||
|
if (this._isInvalid || !this._isRelative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse.call(this, value, 'host');
|
||||||
|
},
|
||||||
|
|
||||||
|
get hostname() {
|
||||||
|
return this._host;
|
||||||
|
},
|
||||||
|
set hostname(value) {
|
||||||
|
if (this._isInvalid || !this._isRelative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse.call(this, value, 'hostname');
|
||||||
|
},
|
||||||
|
|
||||||
|
get port() {
|
||||||
|
return this._port;
|
||||||
|
},
|
||||||
|
set port(value) {
|
||||||
|
if (this._isInvalid || !this._isRelative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
parse.call(this, value, 'port');
|
||||||
|
},
|
||||||
|
|
||||||
|
get pathname() {
|
||||||
|
return this._isInvalid ? '' : this._isRelative ?
|
||||||
|
'/' + this._path.join('/') : this._schemeData;
|
||||||
|
},
|
||||||
|
set pathname(value) {
|
||||||
|
if (this._isInvalid || !this._isRelative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._path = [];
|
||||||
|
parse.call(this, value, 'relative path start');
|
||||||
|
},
|
||||||
|
|
||||||
|
get search() {
|
||||||
|
return this._isInvalid || !this._query || this._query === '?' ?
|
||||||
|
'' : this._query;
|
||||||
|
},
|
||||||
|
set search(value) {
|
||||||
|
if (this._isInvalid || !this._isRelative) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._query = '?';
|
||||||
|
if (value[0] === '?') {
|
||||||
|
value = value.slice(1);
|
||||||
|
}
|
||||||
|
parse.call(this, value, 'query');
|
||||||
|
},
|
||||||
|
|
||||||
|
get hash() {
|
||||||
|
return this._isInvalid || !this._fragment || this._fragment === '#' ?
|
||||||
|
'' : this._fragment;
|
||||||
|
},
|
||||||
|
set hash(value) {
|
||||||
|
if (this._isInvalid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._fragment = '#';
|
||||||
|
if (value[0] === '#') {
|
||||||
|
value = value.slice(1);
|
||||||
|
}
|
||||||
|
parse.call(this, value, 'fragment');
|
||||||
|
},
|
||||||
|
|
||||||
|
get origin() {
|
||||||
|
var host;
|
||||||
|
if (this._isInvalid || !this._scheme) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
// javascript: Gecko returns String(""), WebKit/Blink String("null")
|
||||||
|
// Gecko throws error for "data://"
|
||||||
|
// data: Gecko returns "", Blink returns "data://", WebKit returns "null"
|
||||||
|
// Gecko returns String("") for file: mailto:
|
||||||
|
// WebKit/Blink returns String("SCHEME://") for file: mailto:
|
||||||
|
switch (this._scheme) {
|
||||||
|
case 'data':
|
||||||
|
case 'file':
|
||||||
|
case 'javascript':
|
||||||
|
case 'mailto':
|
||||||
|
return 'null';
|
||||||
|
case 'blob':
|
||||||
|
// Special case of blob: -- returns valid origin of _schemeData.
|
||||||
|
try {
|
||||||
|
return new JURL(this._schemeData).origin || 'null';
|
||||||
|
} catch (_) {
|
||||||
|
// Invalid _schemeData origin -- ignoring errors.
|
||||||
|
}
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
host = this.host;
|
||||||
|
if (!host) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return this._scheme + '://' + host;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.URL = JURL;
|
||||||
|
})();
|
@ -941,6 +941,8 @@ gulp.task('lib', ['buildnumber'], function () {
|
|||||||
buildLib,
|
buildLib,
|
||||||
gulp.src('external/streams/streams-lib.js', { base: '.', })
|
gulp.src('external/streams/streams-lib.js', { base: '.', })
|
||||||
.pipe(gulp.dest('build/')),
|
.pipe(gulp.dest('build/')),
|
||||||
|
gulp.src('external/url/url-lib.js', { base: '.', })
|
||||||
|
.pipe(gulp.dest('build/')),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1243,6 +1245,8 @@ gulp.task('dist-pre',
|
|||||||
return merge([
|
return merge([
|
||||||
gulp.src('external/streams/streams-lib.js', { base: '.', })
|
gulp.src('external/streams/streams-lib.js', { base: '.', })
|
||||||
.pipe(gulp.dest('build/dist/')),
|
.pipe(gulp.dest('build/dist/')),
|
||||||
|
gulp.src('external/url/url-lib.js', { base: '.', })
|
||||||
|
.pipe(gulp.dest('build/dist/')),
|
||||||
packageJsonSrc.pipe(gulp.dest(DIST_DIR)),
|
packageJsonSrc.pipe(gulp.dest(DIST_DIR)),
|
||||||
bowerJsonSrc.pipe(gulp.dest(DIST_DIR)),
|
bowerJsonSrc.pipe(gulp.dest(DIST_DIR)),
|
||||||
vfs.src('external/dist/**/*',
|
vfs.src('external/dist/**/*',
|
||||||
|
14
src/.eslintrc
Normal file
14
src/.eslintrc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"extends": [
|
||||||
|
../.eslintrc
|
||||||
|
],
|
||||||
|
|
||||||
|
"rules": {
|
||||||
|
// Variables
|
||||||
|
"no-restricted-globals": ["error",
|
||||||
|
"ReadableStream",
|
||||||
|
"URL",
|
||||||
|
"WritableStream",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}
|
@ -18,7 +18,7 @@ import {
|
|||||||
assert, createPromiseCapability, getVerbosityLevel, info, InvalidPDFException,
|
assert, createPromiseCapability, getVerbosityLevel, info, InvalidPDFException,
|
||||||
isArrayBuffer, isSameOrigin, MissingPDFException, NativeImageDecoding,
|
isArrayBuffer, isSameOrigin, MissingPDFException, NativeImageDecoding,
|
||||||
PasswordException, setVerbosityLevel, shadow, stringToBytes,
|
PasswordException, setVerbosityLevel, shadow, stringToBytes,
|
||||||
UnexpectedResponseException, UnknownErrorException, unreachable, warn
|
UnexpectedResponseException, UnknownErrorException, unreachable, URL, warn
|
||||||
} from '../shared/util';
|
} from '../shared/util';
|
||||||
import {
|
import {
|
||||||
DOMCanvasFactory, DOMCMapReaderFactory, DummyStatTimer, loadScript,
|
DOMCanvasFactory, DOMCMapReaderFactory, DummyStatTimer, loadScript,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* eslint-disable no-unused-vars */
|
/* eslint-disable no-unused-vars, no-restricted-globals */
|
||||||
|
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -103,6 +103,8 @@ exports.removeNullCharacters = pdfjsSharedUtil.removeNullCharacters;
|
|||||||
exports.shadow = pdfjsSharedUtil.shadow;
|
exports.shadow = pdfjsSharedUtil.shadow;
|
||||||
exports.createBlob = pdfjsSharedUtil.createBlob;
|
exports.createBlob = pdfjsSharedUtil.createBlob;
|
||||||
exports.Util = pdfjsSharedUtil.Util;
|
exports.Util = pdfjsSharedUtil.Util;
|
||||||
|
exports.ReadableStream = pdfjsSharedUtil.ReadableStream;
|
||||||
|
exports.URL = pdfjsSharedUtil.URL;
|
||||||
exports.RenderingCancelledException =
|
exports.RenderingCancelledException =
|
||||||
pdfjsDisplayDOMUtils.RenderingCancelledException;
|
pdfjsDisplayDOMUtils.RenderingCancelledException;
|
||||||
exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
|
exports.getFilenameFromUrl = pdfjsDisplayDOMUtils.getFilenameFromUrl;
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
/* eslint-disable mozilla/use-includes-instead-of-indexOf */
|
|
||||||
|
|
||||||
const globalScope = require('./global_scope');
|
const globalScope = require('./global_scope');
|
||||||
|
|
||||||
@ -166,664 +165,6 @@ const hasDOM = typeof window === 'object' && typeof document === 'object';
|
|||||||
globalScope.WeakMap = require('core-js/fn/weak-map');
|
globalScope.WeakMap = require('core-js/fn/weak-map');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// Support: IE, Chrome<32
|
|
||||||
// Polyfill from https://github.com/Polymer/URL
|
|
||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
(function checkURLConstructor() {
|
|
||||||
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
|
|
||||||
// The current image decoders doesn't utilize the `URL` constructor, hence
|
|
||||||
// it shouldn't need to be polyfilled for the IMAGE_DECODERS build target.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// feature detect for URL constructor
|
|
||||||
var hasWorkingUrl = false;
|
|
||||||
try {
|
|
||||||
if (typeof URL === 'function' &&
|
|
||||||
typeof URL.prototype === 'object' &&
|
|
||||||
('origin' in URL.prototype)) {
|
|
||||||
var u = new URL('b', 'http://a');
|
|
||||||
u.pathname = 'c%20d';
|
|
||||||
hasWorkingUrl = u.href === 'http://a/c%20d';
|
|
||||||
}
|
|
||||||
} catch (e) { }
|
|
||||||
|
|
||||||
if (hasWorkingUrl) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var relative = Object.create(null);
|
|
||||||
relative['ftp'] = 21;
|
|
||||||
relative['file'] = 0;
|
|
||||||
relative['gopher'] = 70;
|
|
||||||
relative['http'] = 80;
|
|
||||||
relative['https'] = 443;
|
|
||||||
relative['ws'] = 80;
|
|
||||||
relative['wss'] = 443;
|
|
||||||
|
|
||||||
var relativePathDotMapping = Object.create(null);
|
|
||||||
relativePathDotMapping['%2e'] = '.';
|
|
||||||
relativePathDotMapping['.%2e'] = '..';
|
|
||||||
relativePathDotMapping['%2e.'] = '..';
|
|
||||||
relativePathDotMapping['%2e%2e'] = '..';
|
|
||||||
|
|
||||||
function isRelativeScheme(scheme) {
|
|
||||||
return relative[scheme] !== undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
function invalid() {
|
|
||||||
clear.call(this);
|
|
||||||
this._isInvalid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function IDNAToASCII(h) {
|
|
||||||
if (h === '') {
|
|
||||||
invalid.call(this);
|
|
||||||
}
|
|
||||||
// XXX
|
|
||||||
return h.toLowerCase();
|
|
||||||
}
|
|
||||||
|
|
||||||
function percentEscape(c) {
|
|
||||||
var unicode = c.charCodeAt(0);
|
|
||||||
if (unicode > 0x20 &&
|
|
||||||
unicode < 0x7F &&
|
|
||||||
// " # < > ? `
|
|
||||||
[0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) === -1
|
|
||||||
) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
return encodeURIComponent(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
function percentEscapeQuery(c) {
|
|
||||||
// XXX This actually needs to encode c using encoding and then
|
|
||||||
// convert the bytes one-by-one.
|
|
||||||
|
|
||||||
var unicode = c.charCodeAt(0);
|
|
||||||
if (unicode > 0x20 &&
|
|
||||||
unicode < 0x7F &&
|
|
||||||
// " # < > ` (do not escape '?')
|
|
||||||
[0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) === -1
|
|
||||||
) {
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
return encodeURIComponent(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
var EOF, ALPHA = /[a-zA-Z]/,
|
|
||||||
ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
|
|
||||||
|
|
||||||
function parse(input, stateOverride, base) {
|
|
||||||
function err(message) {
|
|
||||||
errors.push(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
var state = stateOverride || 'scheme start',
|
|
||||||
cursor = 0,
|
|
||||||
buffer = '',
|
|
||||||
seenAt = false,
|
|
||||||
seenBracket = false,
|
|
||||||
errors = [];
|
|
||||||
|
|
||||||
loop: while ((input[cursor - 1] !== EOF || cursor === 0) &&
|
|
||||||
!this._isInvalid) {
|
|
||||||
var c = input[cursor];
|
|
||||||
switch (state) {
|
|
||||||
case 'scheme start':
|
|
||||||
if (c && ALPHA.test(c)) {
|
|
||||||
buffer += c.toLowerCase(); // ASCII-safe
|
|
||||||
state = 'scheme';
|
|
||||||
} else if (!stateOverride) {
|
|
||||||
buffer = '';
|
|
||||||
state = 'no scheme';
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
err('Invalid scheme.');
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'scheme':
|
|
||||||
if (c && ALPHANUMERIC.test(c)) {
|
|
||||||
buffer += c.toLowerCase(); // ASCII-safe
|
|
||||||
} else if (c === ':') {
|
|
||||||
this._scheme = buffer;
|
|
||||||
buffer = '';
|
|
||||||
if (stateOverride) {
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
if (isRelativeScheme(this._scheme)) {
|
|
||||||
this._isRelative = true;
|
|
||||||
}
|
|
||||||
if (this._scheme === 'file') {
|
|
||||||
state = 'relative';
|
|
||||||
} else if (this._isRelative && base &&
|
|
||||||
base._scheme === this._scheme) {
|
|
||||||
state = 'relative or authority';
|
|
||||||
} else if (this._isRelative) {
|
|
||||||
state = 'authority first slash';
|
|
||||||
} else {
|
|
||||||
state = 'scheme data';
|
|
||||||
}
|
|
||||||
} else if (!stateOverride) {
|
|
||||||
buffer = '';
|
|
||||||
cursor = 0;
|
|
||||||
state = 'no scheme';
|
|
||||||
continue;
|
|
||||||
} else if (c === EOF) {
|
|
||||||
break loop;
|
|
||||||
} else {
|
|
||||||
err('Code point not allowed in scheme: ' + c);
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'scheme data':
|
|
||||||
if (c === '?') {
|
|
||||||
this._query = '?';
|
|
||||||
state = 'query';
|
|
||||||
} else if (c === '#') {
|
|
||||||
this._fragment = '#';
|
|
||||||
state = 'fragment';
|
|
||||||
} else {
|
|
||||||
// XXX error handling
|
|
||||||
if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
|
||||||
this._schemeData += percentEscape(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'no scheme':
|
|
||||||
if (!base || !(isRelativeScheme(base._scheme))) {
|
|
||||||
err('Missing scheme.');
|
|
||||||
invalid.call(this);
|
|
||||||
} else {
|
|
||||||
state = 'relative';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'relative or authority':
|
|
||||||
if (c === '/' && input[cursor + 1] === '/') {
|
|
||||||
state = 'authority ignore slashes';
|
|
||||||
} else {
|
|
||||||
err('Expected /, got: ' + c);
|
|
||||||
state = 'relative';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'relative':
|
|
||||||
this._isRelative = true;
|
|
||||||
if (this._scheme !== 'file') {
|
|
||||||
this._scheme = base._scheme;
|
|
||||||
}
|
|
||||||
if (c === EOF) {
|
|
||||||
this._host = base._host;
|
|
||||||
this._port = base._port;
|
|
||||||
this._path = base._path.slice();
|
|
||||||
this._query = base._query;
|
|
||||||
this._username = base._username;
|
|
||||||
this._password = base._password;
|
|
||||||
break loop;
|
|
||||||
} else if (c === '/' || c === '\\') {
|
|
||||||
if (c === '\\') {
|
|
||||||
err('\\ is an invalid code point.');
|
|
||||||
}
|
|
||||||
state = 'relative slash';
|
|
||||||
} else if (c === '?') {
|
|
||||||
this._host = base._host;
|
|
||||||
this._port = base._port;
|
|
||||||
this._path = base._path.slice();
|
|
||||||
this._query = '?';
|
|
||||||
this._username = base._username;
|
|
||||||
this._password = base._password;
|
|
||||||
state = 'query';
|
|
||||||
} else if (c === '#') {
|
|
||||||
this._host = base._host;
|
|
||||||
this._port = base._port;
|
|
||||||
this._path = base._path.slice();
|
|
||||||
this._query = base._query;
|
|
||||||
this._fragment = '#';
|
|
||||||
this._username = base._username;
|
|
||||||
this._password = base._password;
|
|
||||||
state = 'fragment';
|
|
||||||
} else {
|
|
||||||
var nextC = input[cursor + 1];
|
|
||||||
var nextNextC = input[cursor + 2];
|
|
||||||
if (this._scheme !== 'file' || !ALPHA.test(c) ||
|
|
||||||
(nextC !== ':' && nextC !== '|') ||
|
|
||||||
(nextNextC !== EOF && nextNextC !== '/' && nextNextC !== '\\' &&
|
|
||||||
nextNextC !== '?' && nextNextC !== '#')) {
|
|
||||||
this._host = base._host;
|
|
||||||
this._port = base._port;
|
|
||||||
this._username = base._username;
|
|
||||||
this._password = base._password;
|
|
||||||
this._path = base._path.slice();
|
|
||||||
this._path.pop();
|
|
||||||
}
|
|
||||||
state = 'relative path';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'relative slash':
|
|
||||||
if (c === '/' || c === '\\') {
|
|
||||||
if (c === '\\') {
|
|
||||||
err('\\ is an invalid code point.');
|
|
||||||
}
|
|
||||||
if (this._scheme === 'file') {
|
|
||||||
state = 'file host';
|
|
||||||
} else {
|
|
||||||
state = 'authority ignore slashes';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this._scheme !== 'file') {
|
|
||||||
this._host = base._host;
|
|
||||||
this._port = base._port;
|
|
||||||
this._username = base._username;
|
|
||||||
this._password = base._password;
|
|
||||||
}
|
|
||||||
state = 'relative path';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'authority first slash':
|
|
||||||
if (c === '/') {
|
|
||||||
state = 'authority second slash';
|
|
||||||
} else {
|
|
||||||
err('Expected \'/\', got: ' + c);
|
|
||||||
state = 'authority ignore slashes';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'authority second slash':
|
|
||||||
state = 'authority ignore slashes';
|
|
||||||
if (c !== '/') {
|
|
||||||
err('Expected \'/\', got: ' + c);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'authority ignore slashes':
|
|
||||||
if (c !== '/' && c !== '\\') {
|
|
||||||
state = 'authority';
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
err('Expected authority, got: ' + c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'authority':
|
|
||||||
if (c === '@') {
|
|
||||||
if (seenAt) {
|
|
||||||
err('@ already seen.');
|
|
||||||
buffer += '%40';
|
|
||||||
}
|
|
||||||
seenAt = true;
|
|
||||||
for (var i = 0; i < buffer.length; i++) {
|
|
||||||
var cp = buffer[i];
|
|
||||||
if (cp === '\t' || cp === '\n' || cp === '\r') {
|
|
||||||
err('Invalid whitespace in authority.');
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// XXX check URL code points
|
|
||||||
if (cp === ':' && this._password === null) {
|
|
||||||
this._password = '';
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
var tempC = percentEscape(cp);
|
|
||||||
if (this._password !== null) {
|
|
||||||
this._password += tempC;
|
|
||||||
} else {
|
|
||||||
this._username += tempC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffer = '';
|
|
||||||
} else if (c === EOF || c === '/' || c === '\\' ||
|
|
||||||
c === '?' || c === '#') {
|
|
||||||
cursor -= buffer.length;
|
|
||||||
buffer = '';
|
|
||||||
state = 'host';
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
buffer += c;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'file host':
|
|
||||||
if (c === EOF || c === '/' || c === '\\' || c === '?' || c === '#') {
|
|
||||||
if (buffer.length === 2 && ALPHA.test(buffer[0]) &&
|
|
||||||
(buffer[1] === ':' || buffer[1] === '|')) {
|
|
||||||
state = 'relative path';
|
|
||||||
} else if (buffer.length === 0) {
|
|
||||||
state = 'relative path start';
|
|
||||||
} else {
|
|
||||||
this._host = IDNAToASCII.call(this, buffer);
|
|
||||||
buffer = '';
|
|
||||||
state = 'relative path start';
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} else if (c === '\t' || c === '\n' || c === '\r') {
|
|
||||||
err('Invalid whitespace in file host.');
|
|
||||||
} else {
|
|
||||||
buffer += c;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'host':
|
|
||||||
case 'hostname':
|
|
||||||
if (c === ':' && !seenBracket) {
|
|
||||||
// XXX host parsing
|
|
||||||
this._host = IDNAToASCII.call(this, buffer);
|
|
||||||
buffer = '';
|
|
||||||
state = 'port';
|
|
||||||
if (stateOverride === 'hostname') {
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
} else if (c === EOF || c === '/' ||
|
|
||||||
c === '\\' || c === '?' || c === '#') {
|
|
||||||
this._host = IDNAToASCII.call(this, buffer);
|
|
||||||
buffer = '';
|
|
||||||
state = 'relative path start';
|
|
||||||
if (stateOverride) {
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
} else if (c !== '\t' && c !== '\n' && c !== '\r') {
|
|
||||||
if (c === '[') {
|
|
||||||
seenBracket = true;
|
|
||||||
} else if (c === ']') {
|
|
||||||
seenBracket = false;
|
|
||||||
}
|
|
||||||
buffer += c;
|
|
||||||
} else {
|
|
||||||
err('Invalid code point in host/hostname: ' + c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'port':
|
|
||||||
if (/[0-9]/.test(c)) {
|
|
||||||
buffer += c;
|
|
||||||
} else if (c === EOF || c === '/' || c === '\\' ||
|
|
||||||
c === '?' || c === '#' || stateOverride) {
|
|
||||||
if (buffer !== '') {
|
|
||||||
var temp = parseInt(buffer, 10);
|
|
||||||
if (temp !== relative[this._scheme]) {
|
|
||||||
this._port = temp + '';
|
|
||||||
}
|
|
||||||
buffer = '';
|
|
||||||
}
|
|
||||||
if (stateOverride) {
|
|
||||||
break loop;
|
|
||||||
}
|
|
||||||
state = 'relative path start';
|
|
||||||
continue;
|
|
||||||
} else if (c === '\t' || c === '\n' || c === '\r') {
|
|
||||||
err('Invalid code point in port: ' + c);
|
|
||||||
} else {
|
|
||||||
invalid.call(this);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'relative path start':
|
|
||||||
if (c === '\\') {
|
|
||||||
err('\'\\\' not allowed in path.');
|
|
||||||
}
|
|
||||||
state = 'relative path';
|
|
||||||
if (c !== '/' && c !== '\\') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'relative path':
|
|
||||||
if (c === EOF || c === '/' || c === '\\' ||
|
|
||||||
(!stateOverride && (c === '?' || c === '#'))) {
|
|
||||||
if (c === '\\') {
|
|
||||||
err('\\ not allowed in relative path.');
|
|
||||||
}
|
|
||||||
var tmp;
|
|
||||||
if ((tmp = relativePathDotMapping[buffer.toLowerCase()])) {
|
|
||||||
buffer = tmp;
|
|
||||||
}
|
|
||||||
if (buffer === '..') {
|
|
||||||
this._path.pop();
|
|
||||||
if (c !== '/' && c !== '\\') {
|
|
||||||
this._path.push('');
|
|
||||||
}
|
|
||||||
} else if (buffer === '.' && c !== '/' && c !== '\\') {
|
|
||||||
this._path.push('');
|
|
||||||
} else if (buffer !== '.') {
|
|
||||||
if (this._scheme === 'file' && this._path.length === 0 &&
|
|
||||||
buffer.length === 2 && ALPHA.test(buffer[0]) &&
|
|
||||||
buffer[1] === '|') {
|
|
||||||
buffer = buffer[0] + ':';
|
|
||||||
}
|
|
||||||
this._path.push(buffer);
|
|
||||||
}
|
|
||||||
buffer = '';
|
|
||||||
if (c === '?') {
|
|
||||||
this._query = '?';
|
|
||||||
state = 'query';
|
|
||||||
} else if (c === '#') {
|
|
||||||
this._fragment = '#';
|
|
||||||
state = 'fragment';
|
|
||||||
}
|
|
||||||
} else if (c !== '\t' && c !== '\n' && c !== '\r') {
|
|
||||||
buffer += percentEscape(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'query':
|
|
||||||
if (!stateOverride && c === '#') {
|
|
||||||
this._fragment = '#';
|
|
||||||
state = 'fragment';
|
|
||||||
} else if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
|
||||||
this._query += percentEscapeQuery(c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'fragment':
|
|
||||||
if (c !== EOF && c !== '\t' && c !== '\n' && c !== '\r') {
|
|
||||||
this._fragment += c;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clear() {
|
|
||||||
this._scheme = '';
|
|
||||||
this._schemeData = '';
|
|
||||||
this._username = '';
|
|
||||||
this._password = null;
|
|
||||||
this._host = '';
|
|
||||||
this._port = '';
|
|
||||||
this._path = [];
|
|
||||||
this._query = '';
|
|
||||||
this._fragment = '';
|
|
||||||
this._isInvalid = false;
|
|
||||||
this._isRelative = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does not process domain names or IP addresses.
|
|
||||||
// Does not handle encoding for the query parameter.
|
|
||||||
function JURL(url, base /* , encoding */) {
|
|
||||||
if (base !== undefined && !(base instanceof JURL)) {
|
|
||||||
base = new JURL(String(base));
|
|
||||||
}
|
|
||||||
|
|
||||||
this._url = url;
|
|
||||||
clear.call(this);
|
|
||||||
|
|
||||||
var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, '');
|
|
||||||
// encoding = encoding || 'utf-8'
|
|
||||||
|
|
||||||
parse.call(this, input, null, base);
|
|
||||||
}
|
|
||||||
|
|
||||||
JURL.prototype = {
|
|
||||||
toString() {
|
|
||||||
return this.href;
|
|
||||||
},
|
|
||||||
get href() {
|
|
||||||
if (this._isInvalid) {
|
|
||||||
return this._url;
|
|
||||||
}
|
|
||||||
var authority = '';
|
|
||||||
if (this._username !== '' || this._password !== null) {
|
|
||||||
authority = this._username +
|
|
||||||
(this._password !== null ? ':' + this._password : '') + '@';
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.protocol +
|
|
||||||
(this._isRelative ? '//' + authority + this.host : '') +
|
|
||||||
this.pathname + this._query + this._fragment;
|
|
||||||
},
|
|
||||||
// The named parameter should be different from the setter's function name.
|
|
||||||
// Otherwise Safari 5 will throw an error (see issue 8541)
|
|
||||||
set href(value) {
|
|
||||||
clear.call(this);
|
|
||||||
parse.call(this, value);
|
|
||||||
},
|
|
||||||
|
|
||||||
get protocol() {
|
|
||||||
return this._scheme + ':';
|
|
||||||
},
|
|
||||||
set protocol(value) {
|
|
||||||
if (this._isInvalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse.call(this, value + ':', 'scheme start');
|
|
||||||
},
|
|
||||||
|
|
||||||
get host() {
|
|
||||||
return this._isInvalid ? '' : this._port ?
|
|
||||||
this._host + ':' + this._port : this._host;
|
|
||||||
},
|
|
||||||
set host(value) {
|
|
||||||
if (this._isInvalid || !this._isRelative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse.call(this, value, 'host');
|
|
||||||
},
|
|
||||||
|
|
||||||
get hostname() {
|
|
||||||
return this._host;
|
|
||||||
},
|
|
||||||
set hostname(value) {
|
|
||||||
if (this._isInvalid || !this._isRelative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse.call(this, value, 'hostname');
|
|
||||||
},
|
|
||||||
|
|
||||||
get port() {
|
|
||||||
return this._port;
|
|
||||||
},
|
|
||||||
set port(value) {
|
|
||||||
if (this._isInvalid || !this._isRelative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
parse.call(this, value, 'port');
|
|
||||||
},
|
|
||||||
|
|
||||||
get pathname() {
|
|
||||||
return this._isInvalid ? '' : this._isRelative ?
|
|
||||||
'/' + this._path.join('/') : this._schemeData;
|
|
||||||
},
|
|
||||||
set pathname(value) {
|
|
||||||
if (this._isInvalid || !this._isRelative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._path = [];
|
|
||||||
parse.call(this, value, 'relative path start');
|
|
||||||
},
|
|
||||||
|
|
||||||
get search() {
|
|
||||||
return this._isInvalid || !this._query || this._query === '?' ?
|
|
||||||
'' : this._query;
|
|
||||||
},
|
|
||||||
set search(value) {
|
|
||||||
if (this._isInvalid || !this._isRelative) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._query = '?';
|
|
||||||
if (value[0] === '?') {
|
|
||||||
value = value.slice(1);
|
|
||||||
}
|
|
||||||
parse.call(this, value, 'query');
|
|
||||||
},
|
|
||||||
|
|
||||||
get hash() {
|
|
||||||
return this._isInvalid || !this._fragment || this._fragment === '#' ?
|
|
||||||
'' : this._fragment;
|
|
||||||
},
|
|
||||||
set hash(value) {
|
|
||||||
if (this._isInvalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this._fragment = '#';
|
|
||||||
if (value[0] === '#') {
|
|
||||||
value = value.slice(1);
|
|
||||||
}
|
|
||||||
parse.call(this, value, 'fragment');
|
|
||||||
},
|
|
||||||
|
|
||||||
get origin() {
|
|
||||||
var host;
|
|
||||||
if (this._isInvalid || !this._scheme) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
// javascript: Gecko returns String(""), WebKit/Blink String("null")
|
|
||||||
// Gecko throws error for "data://"
|
|
||||||
// data: Gecko returns "", Blink returns "data://", WebKit returns "null"
|
|
||||||
// Gecko returns String("") for file: mailto:
|
|
||||||
// WebKit/Blink returns String("SCHEME://") for file: mailto:
|
|
||||||
switch (this._scheme) {
|
|
||||||
case 'data':
|
|
||||||
case 'file':
|
|
||||||
case 'javascript':
|
|
||||||
case 'mailto':
|
|
||||||
return 'null';
|
|
||||||
case 'blob':
|
|
||||||
// Special case of blob: -- returns valid origin of _schemeData.
|
|
||||||
try {
|
|
||||||
return new JURL(this._schemeData).origin || 'null';
|
|
||||||
} catch (_) {
|
|
||||||
// Invalid _schemeData origin -- ignoring errors.
|
|
||||||
}
|
|
||||||
return 'null';
|
|
||||||
}
|
|
||||||
host = this.host;
|
|
||||||
if (!host) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return this._scheme + '://' + host;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Copy over the static methods
|
|
||||||
var OriginalURL = globalScope.URL;
|
|
||||||
if (OriginalURL) {
|
|
||||||
JURL.createObjectURL = function(blob) {
|
|
||||||
// IE extension allows a second optional options argument.
|
|
||||||
// http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx
|
|
||||||
return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
|
|
||||||
};
|
|
||||||
JURL.revokeObjectURL = function(url) {
|
|
||||||
OriginalURL.revokeObjectURL(url);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
globalScope.URL = JURL;
|
|
||||||
})();
|
|
||||||
|
|
||||||
} // End of !PDFJSDev.test('CHROME')
|
} // End of !PDFJSDev.test('CHROME')
|
||||||
|
|
||||||
// Provides support for Object.values in legacy browsers.
|
// Provides support for Object.values in legacy browsers.
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
/* eslint-disable no-restricted-globals */
|
||||||
|
|
||||||
let isReadableStreamSupported = false;
|
let isReadableStreamSupported = false;
|
||||||
if (typeof ReadableStream !== 'undefined') {
|
if (typeof ReadableStream !== 'undefined') {
|
||||||
|
63
src/shared/url_polyfill.js
Normal file
63
src/shared/url_polyfill.js
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/* Copyright 2018 Mozilla Foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/* eslint-disable no-restricted-globals */
|
||||||
|
|
||||||
|
if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('GENERIC')) {
|
||||||
|
// The `URL` constructor is assumed to be available in the extension builds.
|
||||||
|
exports.URL = URL;
|
||||||
|
} else {
|
||||||
|
let isURLSupported = false;
|
||||||
|
try {
|
||||||
|
if (typeof URL === 'function' && typeof URL.prototype === 'object' &&
|
||||||
|
('origin' in URL.prototype)) {
|
||||||
|
const u = new URL('b', 'http://a');
|
||||||
|
u.pathname = 'c%20d';
|
||||||
|
isURLSupported = (u.href === 'http://a/c%20d');
|
||||||
|
}
|
||||||
|
} catch (ex) {
|
||||||
|
// The `URL` constructor cannot be used.
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isURLSupported) {
|
||||||
|
exports.URL = URL;
|
||||||
|
} else {
|
||||||
|
if (typeof PDFJSDev !== 'undefined' && PDFJSDev.test('IMAGE_DECODERS')) {
|
||||||
|
class DummyURL {
|
||||||
|
constructor() {
|
||||||
|
throw new Error('The current image decoders doesn\'t utilize the ' +
|
||||||
|
'`URL` constructor, hence it shouldn\'t need to be ' +
|
||||||
|
'polyfilled for the IMAGE_DECODERS build target.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.URL = DummyURL;
|
||||||
|
} else {
|
||||||
|
const PolyfillURL = require('../../external/url/url-lib').URL;
|
||||||
|
|
||||||
|
// Attempt to copy over the static methods.
|
||||||
|
const OriginalURL = require('./global_scope').URL;
|
||||||
|
if (OriginalURL) {
|
||||||
|
PolyfillURL.createObjectURL = function(blob) {
|
||||||
|
// IE extension allows a second optional options argument, see
|
||||||
|
// http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx
|
||||||
|
return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
|
||||||
|
};
|
||||||
|
PolyfillURL.revokeObjectURL = function(url) {
|
||||||
|
OriginalURL.revokeObjectURL(url);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
exports.URL = PolyfillURL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import './compatibility';
|
import './compatibility';
|
||||||
import { ReadableStream } from './streams_polyfill';
|
import { ReadableStream } from './streams_polyfill';
|
||||||
|
import { URL } from './url_polyfill';
|
||||||
|
|
||||||
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
var FONT_IDENTITY_MATRIX = [0.001, 0, 0, 0.001, 0, 0];
|
||||||
|
|
||||||
@ -1075,6 +1076,7 @@ export {
|
|||||||
readUint32,
|
readUint32,
|
||||||
removeNullCharacters,
|
removeNullCharacters,
|
||||||
ReadableStream,
|
ReadableStream,
|
||||||
|
URL,
|
||||||
setVerbosityLevel,
|
setVerbosityLevel,
|
||||||
shadow,
|
shadow,
|
||||||
string32,
|
string32,
|
||||||
|
@ -4,6 +4,13 @@
|
|||||||
],
|
],
|
||||||
|
|
||||||
"rules": {
|
"rules": {
|
||||||
|
// Variables
|
||||||
|
"no-restricted-globals": ["error",
|
||||||
|
"ReadableStream",
|
||||||
|
"URL",
|
||||||
|
"WritableStream",
|
||||||
|
],
|
||||||
|
|
||||||
// ECMAScript 6
|
// ECMAScript 6
|
||||||
"no-var": "error",
|
"no-var": "error",
|
||||||
},
|
},
|
||||||
|
@ -21,9 +21,10 @@ import {
|
|||||||
TextLayerMode
|
TextLayerMode
|
||||||
} from './ui_utils';
|
} from './ui_utils';
|
||||||
import {
|
import {
|
||||||
build, createBlob, getDocument, getFilenameFromUrl, GlobalWorkerOptions,
|
build, createBlob, createObjectURL, getDocument, getFilenameFromUrl,
|
||||||
InvalidPDFException, LinkTarget, loadScript, MissingPDFException, OPS,
|
GlobalWorkerOptions, InvalidPDFException, LinkTarget, loadScript,
|
||||||
PDFWorker, shadow, UnexpectedResponseException, UNSUPPORTED_FEATURES, version
|
MissingPDFException, OPS, PDFWorker, shadow, UnexpectedResponseException,
|
||||||
|
UNSUPPORTED_FEATURES, URL, version
|
||||||
} from 'pdfjs-lib';
|
} from 'pdfjs-lib';
|
||||||
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
|
import { CursorTool, PDFCursorTools } from './pdf_cursor_tools';
|
||||||
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
|
import { PDFRenderingQueue, RenderingStates } from './pdf_rendering_queue';
|
||||||
@ -1583,6 +1584,7 @@ function loadAndEnablePDFBug(enabledTabs) {
|
|||||||
PDFBug.enable(enabledTabs);
|
PDFBug.enable(enabledTabs);
|
||||||
PDFBug.init({
|
PDFBug.init({
|
||||||
OPS,
|
OPS,
|
||||||
|
createObjectURL,
|
||||||
}, appConfig.mainContainer);
|
}, appConfig.mainContainer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import { AppOptions } from './app_options';
|
|||||||
import { BasePreferences } from './preferences';
|
import { BasePreferences } from './preferences';
|
||||||
import { DownloadManager } from './download_manager';
|
import { DownloadManager } from './download_manager';
|
||||||
import { GenericL10n } from './genericl10n';
|
import { GenericL10n } from './genericl10n';
|
||||||
|
import { URL } from 'pdfjs-lib';
|
||||||
|
|
||||||
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) {
|
if (typeof PDFJSDev === 'undefined' || !PDFJSDev.test('CHROME')) {
|
||||||
throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' +
|
throw new Error('Module "pdfjs-web/chromecom" shall not be used outside ' +
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var FontInspector = (function FontInspectorClosure() {
|
var FontInspector = (function FontInspectorClosure() {
|
||||||
var fonts;
|
var fonts, createObjectURL;
|
||||||
var active = false;
|
var active = false;
|
||||||
var fontAttribute = 'data-font-name';
|
var fontAttribute = 'data-font-name';
|
||||||
function removeSelection() {
|
function removeSelection() {
|
||||||
@ -75,6 +75,8 @@ var FontInspector = (function FontInspectorClosure() {
|
|||||||
|
|
||||||
fonts = document.createElement('div');
|
fonts = document.createElement('div');
|
||||||
panel.appendChild(fonts);
|
panel.appendChild(fonts);
|
||||||
|
|
||||||
|
createObjectURL = pdfjsLib.createObjectURL;
|
||||||
},
|
},
|
||||||
cleanup: function cleanup() {
|
cleanup: function cleanup() {
|
||||||
fonts.textContent = '';
|
fonts.textContent = '';
|
||||||
@ -119,10 +121,7 @@ var FontInspector = (function FontInspectorClosure() {
|
|||||||
url = /url\(['"]?([^\)"']+)/.exec(url);
|
url = /url\(['"]?([^\)"']+)/.exec(url);
|
||||||
download.href = url[1];
|
download.href = url[1];
|
||||||
} else if (fontObj.data) {
|
} else if (fontObj.data) {
|
||||||
url = URL.createObjectURL(new Blob([fontObj.data], {
|
download.href = createObjectURL(fontObj.data, fontObj.mimeType);
|
||||||
type: fontObj.mimeType,
|
|
||||||
}));
|
|
||||||
download.href = url;
|
|
||||||
}
|
}
|
||||||
download.textContent = 'Download';
|
download.textContent = 'Download';
|
||||||
var logIt = document.createElement('a');
|
var logIt = document.createElement('a');
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
apiCompatibilityParams, createObjectURL, createValidAbsoluteUrl
|
apiCompatibilityParams, createObjectURL, createValidAbsoluteUrl, URL
|
||||||
} from 'pdfjs-lib';
|
} from 'pdfjs-lib';
|
||||||
|
|
||||||
if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) {
|
if (typeof PDFJSDev !== 'undefined' && !PDFJSDev.test('CHROME || GENERIC')) {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import '../extensions/firefox/tools/l10n';
|
import '../extensions/firefox/tools/l10n';
|
||||||
import { createObjectURL, PDFDataRangeTransport, shadow } from 'pdfjs-lib';
|
import { createObjectURL, PDFDataRangeTransport, shadow, URL } from 'pdfjs-lib';
|
||||||
import { BasePreferences } from './preferences';
|
import { BasePreferences } from './preferences';
|
||||||
import { PDFViewerApplication } from './app';
|
import { PDFViewerApplication } from './app';
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import { CSS_UNITS, NullL10n } from './ui_utils';
|
import { CSS_UNITS, NullL10n } from './ui_utils';
|
||||||
import { PDFPrintServiceFactory, PDFViewerApplication } from './app';
|
import { PDFPrintServiceFactory, PDFViewerApplication } from './app';
|
||||||
|
import { URL } from 'pdfjs-lib';
|
||||||
|
|
||||||
let activeService = null;
|
let activeService = null;
|
||||||
let overlayManager = null;
|
let overlayManager = null;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user