MinsoftK

10

Showing 1000 changed files with 0 additions and 4791 deletions

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

1 -// Standard YAML's Core schema.
2 -// http://www.yaml.org/spec/1.2/spec.html#id2804923
3 -//
4 -// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
5 -// So, Core schema has no distinctions from JSON schema is JS-YAML.
6 -
7 -
8 -'use strict';
9 -
10 -
11 -var Schema = require('../schema');
12 -
13 -
14 -module.exports = new Schema({
15 - include: [
16 - require('./json')
17 - ]
18 -});
1 -// JS-YAML's default schema for `load` function.
2 -// It is not described in the YAML specification.
3 -//
4 -// This schema is based on JS-YAML's default safe schema and includes
5 -// JavaScript-specific types: !!js/undefined, !!js/regexp and !!js/function.
6 -//
7 -// Also this schema is used as default base schema at `Schema.create` function.
8 -
9 -
10 -'use strict';
11 -
12 -
13 -var Schema = require('../schema');
14 -
15 -
16 -module.exports = Schema.DEFAULT = new Schema({
17 - include: [
18 - require('./default_safe')
19 - ],
20 - explicit: [
21 - require('../type/js/undefined'),
22 - require('../type/js/regexp'),
23 - require('../type/js/function')
24 - ]
25 -});
1 -// JS-YAML's default schema for `safeLoad` function.
2 -// It is not described in the YAML specification.
3 -//
4 -// This schema is based on standard YAML's Core schema and includes most of
5 -// extra types described at YAML tag repository. (http://yaml.org/type/)
6 -
7 -
8 -'use strict';
9 -
10 -
11 -var Schema = require('../schema');
12 -
13 -
14 -module.exports = new Schema({
15 - include: [
16 - require('./core')
17 - ],
18 - implicit: [
19 - require('../type/timestamp'),
20 - require('../type/merge')
21 - ],
22 - explicit: [
23 - require('../type/binary'),
24 - require('../type/omap'),
25 - require('../type/pairs'),
26 - require('../type/set')
27 - ]
28 -});
1 -// Standard YAML's Failsafe schema.
2 -// http://www.yaml.org/spec/1.2/spec.html#id2802346
3 -
4 -
5 -'use strict';
6 -
7 -
8 -var Schema = require('../schema');
9 -
10 -
11 -module.exports = new Schema({
12 - explicit: [
13 - require('../type/str'),
14 - require('../type/seq'),
15 - require('../type/map')
16 - ]
17 -});
1 -// Standard YAML's JSON schema.
2 -// http://www.yaml.org/spec/1.2/spec.html#id2803231
3 -//
4 -// NOTE: JS-YAML does not support schema-specific tag resolution restrictions.
5 -// So, this schema is not such strict as defined in the YAML specification.
6 -// It allows numbers in binary notaion, use `Null` and `NULL` as `null`, etc.
7 -
8 -
9 -'use strict';
10 -
11 -
12 -var Schema = require('../schema');
13 -
14 -
15 -module.exports = new Schema({
16 - include: [
17 - require('./failsafe')
18 - ],
19 - implicit: [
20 - require('../type/null'),
21 - require('../type/bool'),
22 - require('../type/int'),
23 - require('../type/float')
24 - ]
25 -});
1 -'use strict';
2 -
3 -var YAMLException = require('./exception');
4 -
5 -var TYPE_CONSTRUCTOR_OPTIONS = [
6 - 'kind',
7 - 'resolve',
8 - 'construct',
9 - 'instanceOf',
10 - 'predicate',
11 - 'represent',
12 - 'defaultStyle',
13 - 'styleAliases'
14 -];
15 -
16 -var YAML_NODE_KINDS = [
17 - 'scalar',
18 - 'sequence',
19 - 'mapping'
20 -];
21 -
22 -function compileStyleAliases(map) {
23 - var result = {};
24 -
25 - if (map !== null) {
26 - Object.keys(map).forEach(function (style) {
27 - map[style].forEach(function (alias) {
28 - result[String(alias)] = style;
29 - });
30 - });
31 - }
32 -
33 - return result;
34 -}
35 -
36 -function Type(tag, options) {
37 - options = options || {};
38 -
39 - Object.keys(options).forEach(function (name) {
40 - if (TYPE_CONSTRUCTOR_OPTIONS.indexOf(name) === -1) {
41 - throw new YAMLException('Unknown option "' + name + '" is met in definition of "' + tag + '" YAML type.');
42 - }
43 - });
44 -
45 - // TODO: Add tag format check.
46 - this.tag = tag;
47 - this.kind = options['kind'] || null;
48 - this.resolve = options['resolve'] || function () { return true; };
49 - this.construct = options['construct'] || function (data) { return data; };
50 - this.instanceOf = options['instanceOf'] || null;
51 - this.predicate = options['predicate'] || null;
52 - this.represent = options['represent'] || null;
53 - this.defaultStyle = options['defaultStyle'] || null;
54 - this.styleAliases = compileStyleAliases(options['styleAliases'] || null);
55 -
56 - if (YAML_NODE_KINDS.indexOf(this.kind) === -1) {
57 - throw new YAMLException('Unknown kind "' + this.kind + '" is specified for "' + tag + '" YAML type.');
58 - }
59 -}
60 -
61 -module.exports = Type;
1 -'use strict';
2 -
3 -/*eslint-disable no-bitwise*/
4 -
5 -var NodeBuffer;
6 -
7 -try {
8 - // A trick for browserified version, to not include `Buffer` shim
9 - var _require = require;
10 - NodeBuffer = _require('buffer').Buffer;
11 -} catch (__) {}
12 -
13 -var Type = require('../type');
14 -
15 -
16 -// [ 64, 65, 66 ] -> [ padding, CR, LF ]
17 -var BASE64_MAP = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=\n\r';
18 -
19 -
20 -function resolveYamlBinary(data) {
21 - if (data === null) return false;
22 -
23 - var code, idx, bitlen = 0, max = data.length, map = BASE64_MAP;
24 -
25 - // Convert one by one.
26 - for (idx = 0; idx < max; idx++) {
27 - code = map.indexOf(data.charAt(idx));
28 -
29 - // Skip CR/LF
30 - if (code > 64) continue;
31 -
32 - // Fail on illegal characters
33 - if (code < 0) return false;
34 -
35 - bitlen += 6;
36 - }
37 -
38 - // If there are any bits left, source was corrupted
39 - return (bitlen % 8) === 0;
40 -}
41 -
42 -function constructYamlBinary(data) {
43 - var idx, tailbits,
44 - input = data.replace(/[\r\n=]/g, ''), // remove CR/LF & padding to simplify scan
45 - max = input.length,
46 - map = BASE64_MAP,
47 - bits = 0,
48 - result = [];
49 -
50 - // Collect by 6*4 bits (3 bytes)
51 -
52 - for (idx = 0; idx < max; idx++) {
53 - if ((idx % 4 === 0) && idx) {
54 - result.push((bits >> 16) & 0xFF);
55 - result.push((bits >> 8) & 0xFF);
56 - result.push(bits & 0xFF);
57 - }
58 -
59 - bits = (bits << 6) | map.indexOf(input.charAt(idx));
60 - }
61 -
62 - // Dump tail
63 -
64 - tailbits = (max % 4) * 6;
65 -
66 - if (tailbits === 0) {
67 - result.push((bits >> 16) & 0xFF);
68 - result.push((bits >> 8) & 0xFF);
69 - result.push(bits & 0xFF);
70 - } else if (tailbits === 18) {
71 - result.push((bits >> 10) & 0xFF);
72 - result.push((bits >> 2) & 0xFF);
73 - } else if (tailbits === 12) {
74 - result.push((bits >> 4) & 0xFF);
75 - }
76 -
77 - // Wrap into Buffer for NodeJS and leave Array for browser
78 - if (NodeBuffer) {
79 - // Support node 6.+ Buffer API when available
80 - return NodeBuffer.from ? NodeBuffer.from(result) : new NodeBuffer(result);
81 - }
82 -
83 - return result;
84 -}
85 -
86 -function representYamlBinary(object /*, style*/) {
87 - var result = '', bits = 0, idx, tail,
88 - max = object.length,
89 - map = BASE64_MAP;
90 -
91 - // Convert every three bytes to 4 ASCII characters.
92 -
93 - for (idx = 0; idx < max; idx++) {
94 - if ((idx % 3 === 0) && idx) {
95 - result += map[(bits >> 18) & 0x3F];
96 - result += map[(bits >> 12) & 0x3F];
97 - result += map[(bits >> 6) & 0x3F];
98 - result += map[bits & 0x3F];
99 - }
100 -
101 - bits = (bits << 8) + object[idx];
102 - }
103 -
104 - // Dump tail
105 -
106 - tail = max % 3;
107 -
108 - if (tail === 0) {
109 - result += map[(bits >> 18) & 0x3F];
110 - result += map[(bits >> 12) & 0x3F];
111 - result += map[(bits >> 6) & 0x3F];
112 - result += map[bits & 0x3F];
113 - } else if (tail === 2) {
114 - result += map[(bits >> 10) & 0x3F];
115 - result += map[(bits >> 4) & 0x3F];
116 - result += map[(bits << 2) & 0x3F];
117 - result += map[64];
118 - } else if (tail === 1) {
119 - result += map[(bits >> 2) & 0x3F];
120 - result += map[(bits << 4) & 0x3F];
121 - result += map[64];
122 - result += map[64];
123 - }
124 -
125 - return result;
126 -}
127 -
128 -function isBinary(object) {
129 - return NodeBuffer && NodeBuffer.isBuffer(object);
130 -}
131 -
132 -module.exports = new Type('tag:yaml.org,2002:binary', {
133 - kind: 'scalar',
134 - resolve: resolveYamlBinary,
135 - construct: constructYamlBinary,
136 - predicate: isBinary,
137 - represent: representYamlBinary
138 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -function resolveYamlBoolean(data) {
6 - if (data === null) return false;
7 -
8 - var max = data.length;
9 -
10 - return (max === 4 && (data === 'true' || data === 'True' || data === 'TRUE')) ||
11 - (max === 5 && (data === 'false' || data === 'False' || data === 'FALSE'));
12 -}
13 -
14 -function constructYamlBoolean(data) {
15 - return data === 'true' ||
16 - data === 'True' ||
17 - data === 'TRUE';
18 -}
19 -
20 -function isBoolean(object) {
21 - return Object.prototype.toString.call(object) === '[object Boolean]';
22 -}
23 -
24 -module.exports = new Type('tag:yaml.org,2002:bool', {
25 - kind: 'scalar',
26 - resolve: resolveYamlBoolean,
27 - construct: constructYamlBoolean,
28 - predicate: isBoolean,
29 - represent: {
30 - lowercase: function (object) { return object ? 'true' : 'false'; },
31 - uppercase: function (object) { return object ? 'TRUE' : 'FALSE'; },
32 - camelcase: function (object) { return object ? 'True' : 'False'; }
33 - },
34 - defaultStyle: 'lowercase'
35 -});
1 -'use strict';
2 -
3 -var common = require('../common');
4 -var Type = require('../type');
5 -
6 -var YAML_FLOAT_PATTERN = new RegExp(
7 - // 2.5e4, 2.5 and integers
8 - '^(?:[-+]?(?:0|[1-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?' +
9 - // .2e4, .2
10 - // special case, seems not from spec
11 - '|\\.[0-9_]+(?:[eE][-+]?[0-9]+)?' +
12 - // 20:59
13 - '|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*' +
14 - // .inf
15 - '|[-+]?\\.(?:inf|Inf|INF)' +
16 - // .nan
17 - '|\\.(?:nan|NaN|NAN))$');
18 -
19 -function resolveYamlFloat(data) {
20 - if (data === null) return false;
21 -
22 - if (!YAML_FLOAT_PATTERN.test(data) ||
23 - // Quick hack to not allow integers end with `_`
24 - // Probably should update regexp & check speed
25 - data[data.length - 1] === '_') {
26 - return false;
27 - }
28 -
29 - return true;
30 -}
31 -
32 -function constructYamlFloat(data) {
33 - var value, sign, base, digits;
34 -
35 - value = data.replace(/_/g, '').toLowerCase();
36 - sign = value[0] === '-' ? -1 : 1;
37 - digits = [];
38 -
39 - if ('+-'.indexOf(value[0]) >= 0) {
40 - value = value.slice(1);
41 - }
42 -
43 - if (value === '.inf') {
44 - return (sign === 1) ? Number.POSITIVE_INFINITY : Number.NEGATIVE_INFINITY;
45 -
46 - } else if (value === '.nan') {
47 - return NaN;
48 -
49 - } else if (value.indexOf(':') >= 0) {
50 - value.split(':').forEach(function (v) {
51 - digits.unshift(parseFloat(v, 10));
52 - });
53 -
54 - value = 0.0;
55 - base = 1;
56 -
57 - digits.forEach(function (d) {
58 - value += d * base;
59 - base *= 60;
60 - });
61 -
62 - return sign * value;
63 -
64 - }
65 - return sign * parseFloat(value, 10);
66 -}
67 -
68 -
69 -var SCIENTIFIC_WITHOUT_DOT = /^[-+]?[0-9]+e/;
70 -
71 -function representYamlFloat(object, style) {
72 - var res;
73 -
74 - if (isNaN(object)) {
75 - switch (style) {
76 - case 'lowercase': return '.nan';
77 - case 'uppercase': return '.NAN';
78 - case 'camelcase': return '.NaN';
79 - }
80 - } else if (Number.POSITIVE_INFINITY === object) {
81 - switch (style) {
82 - case 'lowercase': return '.inf';
83 - case 'uppercase': return '.INF';
84 - case 'camelcase': return '.Inf';
85 - }
86 - } else if (Number.NEGATIVE_INFINITY === object) {
87 - switch (style) {
88 - case 'lowercase': return '-.inf';
89 - case 'uppercase': return '-.INF';
90 - case 'camelcase': return '-.Inf';
91 - }
92 - } else if (common.isNegativeZero(object)) {
93 - return '-0.0';
94 - }
95 -
96 - res = object.toString(10);
97 -
98 - // JS stringifier can build scientific format without dots: 5e-100,
99 - // while YAML requres dot: 5.e-100. Fix it with simple hack
100 -
101 - return SCIENTIFIC_WITHOUT_DOT.test(res) ? res.replace('e', '.e') : res;
102 -}
103 -
104 -function isFloat(object) {
105 - return (Object.prototype.toString.call(object) === '[object Number]') &&
106 - (object % 1 !== 0 || common.isNegativeZero(object));
107 -}
108 -
109 -module.exports = new Type('tag:yaml.org,2002:float', {
110 - kind: 'scalar',
111 - resolve: resolveYamlFloat,
112 - construct: constructYamlFloat,
113 - predicate: isFloat,
114 - represent: representYamlFloat,
115 - defaultStyle: 'lowercase'
116 -});
1 -'use strict';
2 -
3 -var common = require('../common');
4 -var Type = require('../type');
5 -
6 -function isHexCode(c) {
7 - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */)) ||
8 - ((0x41/* A */ <= c) && (c <= 0x46/* F */)) ||
9 - ((0x61/* a */ <= c) && (c <= 0x66/* f */));
10 -}
11 -
12 -function isOctCode(c) {
13 - return ((0x30/* 0 */ <= c) && (c <= 0x37/* 7 */));
14 -}
15 -
16 -function isDecCode(c) {
17 - return ((0x30/* 0 */ <= c) && (c <= 0x39/* 9 */));
18 -}
19 -
20 -function resolveYamlInteger(data) {
21 - if (data === null) return false;
22 -
23 - var max = data.length,
24 - index = 0,
25 - hasDigits = false,
26 - ch;
27 -
28 - if (!max) return false;
29 -
30 - ch = data[index];
31 -
32 - // sign
33 - if (ch === '-' || ch === '+') {
34 - ch = data[++index];
35 - }
36 -
37 - if (ch === '0') {
38 - // 0
39 - if (index + 1 === max) return true;
40 - ch = data[++index];
41 -
42 - // base 2, base 8, base 16
43 -
44 - if (ch === 'b') {
45 - // base 2
46 - index++;
47 -
48 - for (; index < max; index++) {
49 - ch = data[index];
50 - if (ch === '_') continue;
51 - if (ch !== '0' && ch !== '1') return false;
52 - hasDigits = true;
53 - }
54 - return hasDigits && ch !== '_';
55 - }
56 -
57 -
58 - if (ch === 'x') {
59 - // base 16
60 - index++;
61 -
62 - for (; index < max; index++) {
63 - ch = data[index];
64 - if (ch === '_') continue;
65 - if (!isHexCode(data.charCodeAt(index))) return false;
66 - hasDigits = true;
67 - }
68 - return hasDigits && ch !== '_';
69 - }
70 -
71 - // base 8
72 - for (; index < max; index++) {
73 - ch = data[index];
74 - if (ch === '_') continue;
75 - if (!isOctCode(data.charCodeAt(index))) return false;
76 - hasDigits = true;
77 - }
78 - return hasDigits && ch !== '_';
79 - }
80 -
81 - // base 10 (except 0) or base 60
82 -
83 - // value should not start with `_`;
84 - if (ch === '_') return false;
85 -
86 - for (; index < max; index++) {
87 - ch = data[index];
88 - if (ch === '_') continue;
89 - if (ch === ':') break;
90 - if (!isDecCode(data.charCodeAt(index))) {
91 - return false;
92 - }
93 - hasDigits = true;
94 - }
95 -
96 - // Should have digits and should not end with `_`
97 - if (!hasDigits || ch === '_') return false;
98 -
99 - // if !base60 - done;
100 - if (ch !== ':') return true;
101 -
102 - // base60 almost not used, no needs to optimize
103 - return /^(:[0-5]?[0-9])+$/.test(data.slice(index));
104 -}
105 -
106 -function constructYamlInteger(data) {
107 - var value = data, sign = 1, ch, base, digits = [];
108 -
109 - if (value.indexOf('_') !== -1) {
110 - value = value.replace(/_/g, '');
111 - }
112 -
113 - ch = value[0];
114 -
115 - if (ch === '-' || ch === '+') {
116 - if (ch === '-') sign = -1;
117 - value = value.slice(1);
118 - ch = value[0];
119 - }
120 -
121 - if (value === '0') return 0;
122 -
123 - if (ch === '0') {
124 - if (value[1] === 'b') return sign * parseInt(value.slice(2), 2);
125 - if (value[1] === 'x') return sign * parseInt(value, 16);
126 - return sign * parseInt(value, 8);
127 - }
128 -
129 - if (value.indexOf(':') !== -1) {
130 - value.split(':').forEach(function (v) {
131 - digits.unshift(parseInt(v, 10));
132 - });
133 -
134 - value = 0;
135 - base = 1;
136 -
137 - digits.forEach(function (d) {
138 - value += (d * base);
139 - base *= 60;
140 - });
141 -
142 - return sign * value;
143 -
144 - }
145 -
146 - return sign * parseInt(value, 10);
147 -}
148 -
149 -function isInteger(object) {
150 - return (Object.prototype.toString.call(object)) === '[object Number]' &&
151 - (object % 1 === 0 && !common.isNegativeZero(object));
152 -}
153 -
154 -module.exports = new Type('tag:yaml.org,2002:int', {
155 - kind: 'scalar',
156 - resolve: resolveYamlInteger,
157 - construct: constructYamlInteger,
158 - predicate: isInteger,
159 - represent: {
160 - binary: function (obj) { return obj >= 0 ? '0b' + obj.toString(2) : '-0b' + obj.toString(2).slice(1); },
161 - octal: function (obj) { return obj >= 0 ? '0' + obj.toString(8) : '-0' + obj.toString(8).slice(1); },
162 - decimal: function (obj) { return obj.toString(10); },
163 - /* eslint-disable max-len */
164 - hexadecimal: function (obj) { return obj >= 0 ? '0x' + obj.toString(16).toUpperCase() : '-0x' + obj.toString(16).toUpperCase().slice(1); }
165 - },
166 - defaultStyle: 'decimal',
167 - styleAliases: {
168 - binary: [ 2, 'bin' ],
169 - octal: [ 8, 'oct' ],
170 - decimal: [ 10, 'dec' ],
171 - hexadecimal: [ 16, 'hex' ]
172 - }
173 -});
1 -'use strict';
2 -
3 -var esprima;
4 -
5 -// Browserified version does not have esprima
6 -//
7 -// 1. For node.js just require module as deps
8 -// 2. For browser try to require mudule via external AMD system.
9 -// If not found - try to fallback to window.esprima. If not
10 -// found too - then fail to parse.
11 -//
12 -try {
13 - // workaround to exclude package from browserify list.
14 - var _require = require;
15 - esprima = _require('esprima');
16 -} catch (_) {
17 - /* eslint-disable no-redeclare */
18 - /* global window */
19 - if (typeof window !== 'undefined') esprima = window.esprima;
20 -}
21 -
22 -var Type = require('../../type');
23 -
24 -function resolveJavascriptFunction(data) {
25 - if (data === null) return false;
26 -
27 - try {
28 - var source = '(' + data + ')',
29 - ast = esprima.parse(source, { range: true });
30 -
31 - if (ast.type !== 'Program' ||
32 - ast.body.length !== 1 ||
33 - ast.body[0].type !== 'ExpressionStatement' ||
34 - (ast.body[0].expression.type !== 'ArrowFunctionExpression' &&
35 - ast.body[0].expression.type !== 'FunctionExpression')) {
36 - return false;
37 - }
38 -
39 - return true;
40 - } catch (err) {
41 - return false;
42 - }
43 -}
44 -
45 -function constructJavascriptFunction(data) {
46 - /*jslint evil:true*/
47 -
48 - var source = '(' + data + ')',
49 - ast = esprima.parse(source, { range: true }),
50 - params = [],
51 - body;
52 -
53 - if (ast.type !== 'Program' ||
54 - ast.body.length !== 1 ||
55 - ast.body[0].type !== 'ExpressionStatement' ||
56 - (ast.body[0].expression.type !== 'ArrowFunctionExpression' &&
57 - ast.body[0].expression.type !== 'FunctionExpression')) {
58 - throw new Error('Failed to resolve function');
59 - }
60 -
61 - ast.body[0].expression.params.forEach(function (param) {
62 - params.push(param.name);
63 - });
64 -
65 - body = ast.body[0].expression.body.range;
66 -
67 - // Esprima's ranges include the first '{' and the last '}' characters on
68 - // function expressions. So cut them out.
69 - if (ast.body[0].expression.body.type === 'BlockStatement') {
70 - /*eslint-disable no-new-func*/
71 - return new Function(params, source.slice(body[0] + 1, body[1] - 1));
72 - }
73 - // ES6 arrow functions can omit the BlockStatement. In that case, just return
74 - // the body.
75 - /*eslint-disable no-new-func*/
76 - return new Function(params, 'return ' + source.slice(body[0], body[1]));
77 -}
78 -
79 -function representJavascriptFunction(object /*, style*/) {
80 - return object.toString();
81 -}
82 -
83 -function isFunction(object) {
84 - return Object.prototype.toString.call(object) === '[object Function]';
85 -}
86 -
87 -module.exports = new Type('tag:yaml.org,2002:js/function', {
88 - kind: 'scalar',
89 - resolve: resolveJavascriptFunction,
90 - construct: constructJavascriptFunction,
91 - predicate: isFunction,
92 - represent: representJavascriptFunction
93 -});
1 -'use strict';
2 -
3 -var Type = require('../../type');
4 -
5 -function resolveJavascriptRegExp(data) {
6 - if (data === null) return false;
7 - if (data.length === 0) return false;
8 -
9 - var regexp = data,
10 - tail = /\/([gim]*)$/.exec(data),
11 - modifiers = '';
12 -
13 - // if regexp starts with '/' it can have modifiers and must be properly closed
14 - // `/foo/gim` - modifiers tail can be maximum 3 chars
15 - if (regexp[0] === '/') {
16 - if (tail) modifiers = tail[1];
17 -
18 - if (modifiers.length > 3) return false;
19 - // if expression starts with /, is should be properly terminated
20 - if (regexp[regexp.length - modifiers.length - 1] !== '/') return false;
21 - }
22 -
23 - return true;
24 -}
25 -
26 -function constructJavascriptRegExp(data) {
27 - var regexp = data,
28 - tail = /\/([gim]*)$/.exec(data),
29 - modifiers = '';
30 -
31 - // `/foo/gim` - tail can be maximum 4 chars
32 - if (regexp[0] === '/') {
33 - if (tail) modifiers = tail[1];
34 - regexp = regexp.slice(1, regexp.length - modifiers.length - 1);
35 - }
36 -
37 - return new RegExp(regexp, modifiers);
38 -}
39 -
40 -function representJavascriptRegExp(object /*, style*/) {
41 - var result = '/' + object.source + '/';
42 -
43 - if (object.global) result += 'g';
44 - if (object.multiline) result += 'm';
45 - if (object.ignoreCase) result += 'i';
46 -
47 - return result;
48 -}
49 -
50 -function isRegExp(object) {
51 - return Object.prototype.toString.call(object) === '[object RegExp]';
52 -}
53 -
54 -module.exports = new Type('tag:yaml.org,2002:js/regexp', {
55 - kind: 'scalar',
56 - resolve: resolveJavascriptRegExp,
57 - construct: constructJavascriptRegExp,
58 - predicate: isRegExp,
59 - represent: representJavascriptRegExp
60 -});
1 -'use strict';
2 -
3 -var Type = require('../../type');
4 -
5 -function resolveJavascriptUndefined() {
6 - return true;
7 -}
8 -
9 -function constructJavascriptUndefined() {
10 - /*eslint-disable no-undefined*/
11 - return undefined;
12 -}
13 -
14 -function representJavascriptUndefined() {
15 - return '';
16 -}
17 -
18 -function isUndefined(object) {
19 - return typeof object === 'undefined';
20 -}
21 -
22 -module.exports = new Type('tag:yaml.org,2002:js/undefined', {
23 - kind: 'scalar',
24 - resolve: resolveJavascriptUndefined,
25 - construct: constructJavascriptUndefined,
26 - predicate: isUndefined,
27 - represent: representJavascriptUndefined
28 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -module.exports = new Type('tag:yaml.org,2002:map', {
6 - kind: 'mapping',
7 - construct: function (data) { return data !== null ? data : {}; }
8 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -function resolveYamlMerge(data) {
6 - return data === '<<' || data === null;
7 -}
8 -
9 -module.exports = new Type('tag:yaml.org,2002:merge', {
10 - kind: 'scalar',
11 - resolve: resolveYamlMerge
12 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -function resolveYamlNull(data) {
6 - if (data === null) return true;
7 -
8 - var max = data.length;
9 -
10 - return (max === 1 && data === '~') ||
11 - (max === 4 && (data === 'null' || data === 'Null' || data === 'NULL'));
12 -}
13 -
14 -function constructYamlNull() {
15 - return null;
16 -}
17 -
18 -function isNull(object) {
19 - return object === null;
20 -}
21 -
22 -module.exports = new Type('tag:yaml.org,2002:null', {
23 - kind: 'scalar',
24 - resolve: resolveYamlNull,
25 - construct: constructYamlNull,
26 - predicate: isNull,
27 - represent: {
28 - canonical: function () { return '~'; },
29 - lowercase: function () { return 'null'; },
30 - uppercase: function () { return 'NULL'; },
31 - camelcase: function () { return 'Null'; }
32 - },
33 - defaultStyle: 'lowercase'
34 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -var _hasOwnProperty = Object.prototype.hasOwnProperty;
6 -var _toString = Object.prototype.toString;
7 -
8 -function resolveYamlOmap(data) {
9 - if (data === null) return true;
10 -
11 - var objectKeys = [], index, length, pair, pairKey, pairHasKey,
12 - object = data;
13 -
14 - for (index = 0, length = object.length; index < length; index += 1) {
15 - pair = object[index];
16 - pairHasKey = false;
17 -
18 - if (_toString.call(pair) !== '[object Object]') return false;
19 -
20 - for (pairKey in pair) {
21 - if (_hasOwnProperty.call(pair, pairKey)) {
22 - if (!pairHasKey) pairHasKey = true;
23 - else return false;
24 - }
25 - }
26 -
27 - if (!pairHasKey) return false;
28 -
29 - if (objectKeys.indexOf(pairKey) === -1) objectKeys.push(pairKey);
30 - else return false;
31 - }
32 -
33 - return true;
34 -}
35 -
36 -function constructYamlOmap(data) {
37 - return data !== null ? data : [];
38 -}
39 -
40 -module.exports = new Type('tag:yaml.org,2002:omap', {
41 - kind: 'sequence',
42 - resolve: resolveYamlOmap,
43 - construct: constructYamlOmap
44 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -var _toString = Object.prototype.toString;
6 -
7 -function resolveYamlPairs(data) {
8 - if (data === null) return true;
9 -
10 - var index, length, pair, keys, result,
11 - object = data;
12 -
13 - result = new Array(object.length);
14 -
15 - for (index = 0, length = object.length; index < length; index += 1) {
16 - pair = object[index];
17 -
18 - if (_toString.call(pair) !== '[object Object]') return false;
19 -
20 - keys = Object.keys(pair);
21 -
22 - if (keys.length !== 1) return false;
23 -
24 - result[index] = [ keys[0], pair[keys[0]] ];
25 - }
26 -
27 - return true;
28 -}
29 -
30 -function constructYamlPairs(data) {
31 - if (data === null) return [];
32 -
33 - var index, length, pair, keys, result,
34 - object = data;
35 -
36 - result = new Array(object.length);
37 -
38 - for (index = 0, length = object.length; index < length; index += 1) {
39 - pair = object[index];
40 -
41 - keys = Object.keys(pair);
42 -
43 - result[index] = [ keys[0], pair[keys[0]] ];
44 - }
45 -
46 - return result;
47 -}
48 -
49 -module.exports = new Type('tag:yaml.org,2002:pairs', {
50 - kind: 'sequence',
51 - resolve: resolveYamlPairs,
52 - construct: constructYamlPairs
53 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -module.exports = new Type('tag:yaml.org,2002:seq', {
6 - kind: 'sequence',
7 - construct: function (data) { return data !== null ? data : []; }
8 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -var _hasOwnProperty = Object.prototype.hasOwnProperty;
6 -
7 -function resolveYamlSet(data) {
8 - if (data === null) return true;
9 -
10 - var key, object = data;
11 -
12 - for (key in object) {
13 - if (_hasOwnProperty.call(object, key)) {
14 - if (object[key] !== null) return false;
15 - }
16 - }
17 -
18 - return true;
19 -}
20 -
21 -function constructYamlSet(data) {
22 - return data !== null ? data : {};
23 -}
24 -
25 -module.exports = new Type('tag:yaml.org,2002:set', {
26 - kind: 'mapping',
27 - resolve: resolveYamlSet,
28 - construct: constructYamlSet
29 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -module.exports = new Type('tag:yaml.org,2002:str', {
6 - kind: 'scalar',
7 - construct: function (data) { return data !== null ? data : ''; }
8 -});
1 -'use strict';
2 -
3 -var Type = require('../type');
4 -
5 -var YAML_DATE_REGEXP = new RegExp(
6 - '^([0-9][0-9][0-9][0-9])' + // [1] year
7 - '-([0-9][0-9])' + // [2] month
8 - '-([0-9][0-9])$'); // [3] day
9 -
10 -var YAML_TIMESTAMP_REGEXP = new RegExp(
11 - '^([0-9][0-9][0-9][0-9])' + // [1] year
12 - '-([0-9][0-9]?)' + // [2] month
13 - '-([0-9][0-9]?)' + // [3] day
14 - '(?:[Tt]|[ \\t]+)' + // ...
15 - '([0-9][0-9]?)' + // [4] hour
16 - ':([0-9][0-9])' + // [5] minute
17 - ':([0-9][0-9])' + // [6] second
18 - '(?:\\.([0-9]*))?' + // [7] fraction
19 - '(?:[ \\t]*(Z|([-+])([0-9][0-9]?)' + // [8] tz [9] tz_sign [10] tz_hour
20 - '(?::([0-9][0-9]))?))?$'); // [11] tz_minute
21 -
22 -function resolveYamlTimestamp(data) {
23 - if (data === null) return false;
24 - if (YAML_DATE_REGEXP.exec(data) !== null) return true;
25 - if (YAML_TIMESTAMP_REGEXP.exec(data) !== null) return true;
26 - return false;
27 -}
28 -
29 -function constructYamlTimestamp(data) {
30 - var match, year, month, day, hour, minute, second, fraction = 0,
31 - delta = null, tz_hour, tz_minute, date;
32 -
33 - match = YAML_DATE_REGEXP.exec(data);
34 - if (match === null) match = YAML_TIMESTAMP_REGEXP.exec(data);
35 -
36 - if (match === null) throw new Error('Date resolve error');
37 -
38 - // match: [1] year [2] month [3] day
39 -
40 - year = +(match[1]);
41 - month = +(match[2]) - 1; // JS month starts with 0
42 - day = +(match[3]);
43 -
44 - if (!match[4]) { // no hour
45 - return new Date(Date.UTC(year, month, day));
46 - }
47 -
48 - // match: [4] hour [5] minute [6] second [7] fraction
49 -
50 - hour = +(match[4]);
51 - minute = +(match[5]);
52 - second = +(match[6]);
53 -
54 - if (match[7]) {
55 - fraction = match[7].slice(0, 3);
56 - while (fraction.length < 3) { // milli-seconds
57 - fraction += '0';
58 - }
59 - fraction = +fraction;
60 - }
61 -
62 - // match: [8] tz [9] tz_sign [10] tz_hour [11] tz_minute
63 -
64 - if (match[9]) {
65 - tz_hour = +(match[10]);
66 - tz_minute = +(match[11] || 0);
67 - delta = (tz_hour * 60 + tz_minute) * 60000; // delta in mili-seconds
68 - if (match[9] === '-') delta = -delta;
69 - }
70 -
71 - date = new Date(Date.UTC(year, month, day, hour, minute, second, fraction));
72 -
73 - if (delta) date.setTime(date.getTime() - delta);
74 -
75 - return date;
76 -}
77 -
78 -function representYamlTimestamp(object /*, style*/) {
79 - return object.toISOString();
80 -}
81 -
82 -module.exports = new Type('tag:yaml.org,2002:timestamp', {
83 - kind: 'scalar',
84 - resolve: resolveYamlTimestamp,
85 - construct: constructYamlTimestamp,
86 - instanceOf: Date,
87 - represent: representYamlTimestamp
88 -});
1 -{
2 - "_from": "js-yaml@^3.13.1",
3 - "_id": "js-yaml@3.14.1",
4 - "_inBundle": false,
5 - "_integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
6 - "_location": "/js-yaml",
7 - "_phantomChildren": {},
8 - "_requested": {
9 - "type": "range",
10 - "registry": true,
11 - "raw": "js-yaml@^3.13.1",
12 - "name": "js-yaml",
13 - "escapedName": "js-yaml",
14 - "rawSpec": "^3.13.1",
15 - "saveSpec": null,
16 - "fetchSpec": "^3.13.1"
17 - },
18 - "_requiredBy": [
19 - "/@eslint/eslintrc",
20 - "/@istanbuljs/load-nyc-config",
21 - "/cssnano/cosmiconfig",
22 - "/eslint",
23 - "/postcss-load-config/cosmiconfig",
24 - "/svgo"
25 - ],
26 - "_resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
27 - "_shasum": "dae812fdb3825fa306609a8717383c50c36a0537",
28 - "_spec": "js-yaml@^3.13.1",
29 - "_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\svgo",
30 - "author": {
31 - "name": "Vladimir Zapparov",
32 - "email": "dervus.grim@gmail.com"
33 - },
34 - "bin": {
35 - "js-yaml": "bin/js-yaml.js"
36 - },
37 - "bugs": {
38 - "url": "https://github.com/nodeca/js-yaml/issues"
39 - },
40 - "bundleDependencies": false,
41 - "contributors": [
42 - {
43 - "name": "Aleksey V Zapparov",
44 - "email": "ixti@member.fsf.org",
45 - "url": "http://www.ixti.net/"
46 - },
47 - {
48 - "name": "Vitaly Puzrin",
49 - "email": "vitaly@rcdesign.ru",
50 - "url": "https://github.com/puzrin"
51 - },
52 - {
53 - "name": "Martin Grenfell",
54 - "email": "martin.grenfell@gmail.com",
55 - "url": "http://got-ravings.blogspot.com"
56 - }
57 - ],
58 - "dependencies": {
59 - "argparse": "^1.0.7",
60 - "esprima": "^4.0.0"
61 - },
62 - "deprecated": false,
63 - "description": "YAML 1.2 parser and serializer",
64 - "devDependencies": {
65 - "ansi": "^0.3.1",
66 - "benchmark": "^2.1.4",
67 - "browserify": "^16.2.2",
68 - "codemirror": "^5.13.4",
69 - "eslint": "^7.0.0",
70 - "fast-check": "^1.24.2",
71 - "istanbul": "^0.4.5",
72 - "mocha": "^7.1.2",
73 - "uglify-js": "^3.0.1"
74 - },
75 - "files": [
76 - "index.js",
77 - "lib/",
78 - "bin/",
79 - "dist/"
80 - ],
81 - "homepage": "https://github.com/nodeca/js-yaml",
82 - "jsdelivr": "dist/js-yaml.min.js",
83 - "keywords": [
84 - "yaml",
85 - "parser",
86 - "serializer",
87 - "pyyaml"
88 - ],
89 - "license": "MIT",
90 - "name": "js-yaml",
91 - "repository": {
92 - "type": "git",
93 - "url": "git+https://github.com/nodeca/js-yaml.git"
94 - },
95 - "scripts": {
96 - "test": "make test"
97 - },
98 - "unpkg": "dist/js-yaml.min.js",
99 - "version": "3.14.1"
100 -}
1 -node_modules
2 -.DS_Store
...\ No newline at end of file ...\ No newline at end of file
1 -Licensing
2 ----------
3 -
4 -This software is covered under the following copyright:
5 -
6 -/*
7 - * Copyright (c) 2003-2005 Tom Wu
8 - * All Rights Reserved.
9 - *
10 - * Permission is hereby granted, free of charge, to any person obtaining
11 - * a copy of this software and associated documentation files (the
12 - * "Software"), to deal in the Software without restriction, including
13 - * without limitation the rights to use, copy, modify, merge, publish,
14 - * distribute, sublicense, and/or sell copies of the Software, and to
15 - * permit persons to whom the Software is furnished to do so, subject to
16 - * the following conditions:
17 - *
18 - * The above copyright notice and this permission notice shall be
19 - * included in all copies or substantial portions of the Software.
20 - *
21 - * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
22 - * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
23 - * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
24 - *
25 - * IN NO EVENT SHALL TOM WU BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
26 - * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
27 - * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF
28 - * THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT
29 - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
30 - *
31 - * In addition, the following condition applies:
32 - *
33 - * All redistributions must retain an intact copy of this copyright notice
34 - * and disclaimer.
35 - */
36 -
37 -Address all questions regarding this license to:
38 -
39 - Tom Wu
40 - tjw@cs.Stanford.EDU
...\ No newline at end of file ...\ No newline at end of file
1 -# jsbn: javascript big number
2 -
3 -[Tom Wu's Original Website](http://www-cs-students.stanford.edu/~tjw/jsbn/)
4 -
5 -I felt compelled to put this on github and publish to npm. I haven't tested every other big integer library out there, but the few that I have tested in comparison to this one have not even come close in performance. I am aware of the `bi` module on npm, however it has been modified and I wanted to publish the original without modifications. This is jsbn and jsbn2 from Tom Wu's original website above, with the modular pattern applied to prevent global leaks and to allow for use with node.js on the server side.
6 -
7 -## usage
8 -
9 - var BigInteger = require('jsbn');
10 -
11 - var a = new BigInteger('91823918239182398123');
12 - alert(a.bitLength()); // 67
13 -
14 -
15 -## API
16 -
17 -### bi.toString()
18 -
19 -returns the base-10 number as a string
20 -
21 -### bi.negate()
22 -
23 -returns a new BigInteger equal to the negation of `bi`
24 -
25 -### bi.abs
26 -
27 -returns new BI of absolute value
28 -
29 -### bi.compareTo
30 -
31 -
32 -
33 -### bi.bitLength
34 -
35 -
36 -
37 -### bi.mod
38 -
39 -
40 -
41 -### bi.modPowInt
42 -
43 -
44 -
45 -### bi.clone
46 -
47 -
48 -
49 -### bi.intValue
50 -
51 -
52 -
53 -### bi.byteValue
54 -
55 -
56 -
57 -### bi.shortValue
58 -
59 -
60 -
61 -### bi.signum
62 -
63 -
64 -
65 -### bi.toByteArray
66 -
67 -
68 -
69 -### bi.equals
70 -
71 -
72 -
73 -### bi.min
74 -
75 -
76 -
77 -### bi.max
78 -
79 -
80 -
81 -### bi.and
82 -
83 -
84 -
85 -### bi.or
86 -
87 -
88 -
89 -### bi.xor
90 -
91 -
92 -
93 -### bi.andNot
94 -
95 -
96 -
97 -### bi.not
98 -
99 -
100 -
101 -### bi.shiftLeft
102 -
103 -
104 -
105 -### bi.shiftRight
106 -
107 -
108 -
109 -### bi.getLowestSetBit
110 -
111 -
112 -
113 -### bi.bitCount
114 -
115 -
116 -
117 -### bi.testBit
118 -
119 -
120 -
121 -### bi.setBit
122 -
123 -
124 -
125 -### bi.clearBit
126 -
127 -
128 -
129 -### bi.flipBit
130 -
131 -
132 -
133 -### bi.add
134 -
135 -
136 -
137 -### bi.subtract
138 -
139 -
140 -
141 -### bi.multiply
142 -
143 -
144 -
145 -### bi.divide
146 -
147 -
148 -
149 -### bi.remainder
150 -
151 -
152 -
153 -### bi.divideAndRemainder
154 -
155 -
156 -
157 -### bi.modPow
158 -
159 -
160 -
161 -### bi.modInverse
162 -
163 -
164 -
165 -### bi.pow
166 -
167 -
168 -
169 -### bi.gcd
170 -
171 -
172 -
173 -### bi.isProbablePrime
174 -
175 -
1 -<!DOCTYPE html>
2 -<html lang="en">
3 - <head>
4 - <meta charset="utf-8">
5 - <title></title>
6 - </head>
7 - <body>
8 -
9 -
10 - <script src="index.js"></script>
11 - </body>
12 -</html>
...\ No newline at end of file ...\ No newline at end of file
1 -var BigInteger = require('./');
2 -var a = new BigInteger('91823918239182398123');
3 -console.log(a.bitLength());
...\ No newline at end of file ...\ No newline at end of file
This diff is collapsed. Click to expand it.
1 -{
2 - "_from": "jsbn@~0.1.0",
3 - "_id": "jsbn@0.1.1",
4 - "_inBundle": false,
5 - "_integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
6 - "_location": "/jsbn",
7 - "_phantomChildren": {},
8 - "_requested": {
9 - "type": "range",
10 - "registry": true,
11 - "raw": "jsbn@~0.1.0",
12 - "name": "jsbn",
13 - "escapedName": "jsbn",
14 - "rawSpec": "~0.1.0",
15 - "saveSpec": null,
16 - "fetchSpec": "~0.1.0"
17 - },
18 - "_requiredBy": [
19 - "/ecc-jsbn",
20 - "/sshpk"
21 - ],
22 - "_resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
23 - "_shasum": "a5e654c2e5a2deb5f201d96cefbca80c0ef2f513",
24 - "_spec": "jsbn@~0.1.0",
25 - "_where": "C:\\Users\\kkwan_000\\Desktop\\git\\2017110269\\minsung\\node_modules\\sshpk",
26 - "author": {
27 - "name": "Tom Wu"
28 - },
29 - "bugs": {
30 - "url": "https://github.com/andyperlitch/jsbn/issues"
31 - },
32 - "bundleDependencies": false,
33 - "deprecated": false,
34 - "description": "The jsbn library is a fast, portable implementation of large-number math in pure JavaScript, enabling public-key crypto and other applications on desktop and mobile browsers.",
35 - "homepage": "https://github.com/andyperlitch/jsbn#readme",
36 - "keywords": [
37 - "biginteger",
38 - "bignumber",
39 - "big",
40 - "integer"
41 - ],
42 - "license": "MIT",
43 - "main": "index.js",
44 - "name": "jsbn",
45 - "repository": {
46 - "type": "git",
47 - "url": "git+https://github.com/andyperlitch/jsbn.git"
48 - },
49 - "scripts": {
50 - "test": "mocha test.js"
51 - },
52 - "version": "0.1.1"
53 -}
This diff could not be displayed because it is too large.
1 -Copyright (c) 2010 Elijah Insua
2 -
3 -Permission is hereby granted, free of charge, to any person
4 -obtaining a copy of this software and associated documentation
5 -files (the "Software"), to deal in the Software without
6 -restriction, including without limitation the rights to use,
7 -copy, modify, merge, publish, distribute, sublicense, and/or sell
8 -copies of the Software, and to permit persons to whom the
9 -Software is furnished to do so, subject to the following
10 -conditions:
11 -
12 -The above copyright notice and this permission notice shall be
13 -included in all copies or substantial portions of the Software.
14 -
15 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 -OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 -{
2 - "Object": {
3 - "writable": true,
4 - "enumerable": false,
5 - "configurable": true
6 - },
7 - "Function": {
8 - "writable": true,
9 - "enumerable": false,
10 - "configurable": true
11 - },
12 - "Array": {
13 - "writable": true,
14 - "enumerable": false,
15 - "configurable": true
16 - },
17 - "Number": {
18 - "writable": true,
19 - "enumerable": false,
20 - "configurable": true
21 - },
22 - "parseFloat": {
23 - "writable": true,
24 - "enumerable": false,
25 - "configurable": true
26 - },
27 - "parseInt": {
28 - "writable": true,
29 - "enumerable": false,
30 - "configurable": true
31 - },
32 - "Infinity": {
33 - "writable": false,
34 - "enumerable": false,
35 - "configurable": false
36 - },
37 - "NaN": {
38 - "writable": false,
39 - "enumerable": false,
40 - "configurable": false
41 - },
42 - "undefined": {
43 - "writable": false,
44 - "enumerable": false,
45 - "configurable": false
46 - },
47 - "Boolean": {
48 - "writable": true,
49 - "enumerable": false,
50 - "configurable": true
51 - },
52 - "String": {
53 - "writable": true,
54 - "enumerable": false,
55 - "configurable": true
56 - },
57 - "Symbol": {
58 - "writable": true,
59 - "enumerable": false,
60 - "configurable": true
61 - },
62 - "Date": {
63 - "writable": true,
64 - "enumerable": false,
65 - "configurable": true
66 - },
67 - "Promise": {
68 - "writable": true,
69 - "enumerable": false,
70 - "configurable": true
71 - },
72 - "RegExp": {
73 - "writable": true,
74 - "enumerable": false,
75 - "configurable": true
76 - },
77 - "Error": {
78 - "writable": true,
79 - "enumerable": false,
80 - "configurable": true
81 - },
82 - "EvalError": {
83 - "writable": true,
84 - "enumerable": false,
85 - "configurable": true
86 - },
87 - "RangeError": {
88 - "writable": true,
89 - "enumerable": false,
90 - "configurable": true
91 - },
92 - "ReferenceError": {
93 - "writable": true,
94 - "enumerable": false,
95 - "configurable": true
96 - },
97 - "SyntaxError": {
98 - "writable": true,
99 - "enumerable": false,
100 - "configurable": true
101 - },
102 - "TypeError": {
103 - "writable": true,
104 - "enumerable": false,
105 - "configurable": true
106 - },
107 - "URIError": {
108 - "writable": true,
109 - "enumerable": false,
110 - "configurable": true
111 - },
112 - "globalThis": {
113 - "writable": true,
114 - "enumerable": false,
115 - "configurable": true
116 - },
117 - "JSON": {
118 - "writable": true,
119 - "enumerable": false,
120 - "configurable": true
121 - },
122 - "Math": {
123 - "writable": true,
124 - "enumerable": false,
125 - "configurable": true
126 - },
127 - "Intl": {
128 - "writable": true,
129 - "enumerable": false,
130 - "configurable": true
131 - },
132 - "ArrayBuffer": {
133 - "writable": true,
134 - "enumerable": false,
135 - "configurable": true
136 - },
137 - "Uint8Array": {
138 - "writable": true,
139 - "enumerable": false,
140 - "configurable": true
141 - },
142 - "Int8Array": {
143 - "writable": true,
144 - "enumerable": false,
145 - "configurable": true
146 - },
147 - "Uint16Array": {
148 - "writable": true,
149 - "enumerable": false,
150 - "configurable": true
151 - },
152 - "Int16Array": {
153 - "writable": true,
154 - "enumerable": false,
155 - "configurable": true
156 - },
157 - "Uint32Array": {
158 - "writable": true,
159 - "enumerable": false,
160 - "configurable": true
161 - },
162 - "Int32Array": {
163 - "writable": true,
164 - "enumerable": false,
165 - "configurable": true
166 - },
167 - "Float32Array": {
168 - "writable": true,
169 - "enumerable": false,
170 - "configurable": true
171 - },
172 - "Float64Array": {
173 - "writable": true,
174 - "enumerable": false,
175 - "configurable": true
176 - },
177 - "Uint8ClampedArray": {
178 - "writable": true,
179 - "enumerable": false,
180 - "configurable": true
181 - },
182 - "BigUint64Array": {
183 - "writable": true,
184 - "enumerable": false,
185 - "configurable": true
186 - },
187 - "BigInt64Array": {
188 - "writable": true,
189 - "enumerable": false,
190 - "configurable": true
191 - },
192 - "DataView": {
193 - "writable": true,
194 - "enumerable": false,
195 - "configurable": true
196 - },
197 - "Map": {
198 - "writable": true,
199 - "enumerable": false,
200 - "configurable": true
201 - },
202 - "BigInt": {
203 - "writable": true,
204 - "enumerable": false,
205 - "configurable": true
206 - },
207 - "Set": {
208 - "writable": true,
209 - "enumerable": false,
210 - "configurable": true
211 - },
212 - "WeakMap": {
213 - "writable": true,
214 - "enumerable": false,
215 - "configurable": true
216 - },
217 - "WeakSet": {
218 - "writable": true,
219 - "enumerable": false,
220 - "configurable": true
221 - },
222 - "Proxy": {
223 - "writable": true,
224 - "enumerable": false,
225 - "configurable": true
226 - },
227 - "Reflect": {
228 - "writable": true,
229 - "enumerable": false,
230 - "configurable": true
231 - },
232 - "decodeURI": {
233 - "writable": true,
234 - "enumerable": false,
235 - "configurable": true
236 - },
237 - "decodeURIComponent": {
238 - "writable": true,
239 - "enumerable": false,
240 - "configurable": true
241 - },
242 - "encodeURI": {
243 - "writable": true,
244 - "enumerable": false,
245 - "configurable": true
246 - },
247 - "encodeURIComponent": {
248 - "writable": true,
249 - "enumerable": false,
250 - "configurable": true
251 - },
252 - "escape": {
253 - "writable": true,
254 - "enumerable": false,
255 - "configurable": true
256 - },
257 - "unescape": {
258 - "writable": true,
259 - "enumerable": false,
260 - "configurable": true
261 - },
262 - "eval": {
263 - "writable": true,
264 - "enumerable": false,
265 - "configurable": true
266 - },
267 - "isFinite": {
268 - "writable": true,
269 - "enumerable": false,
270 - "configurable": true
271 - },
272 - "isNaN": {
273 - "writable": true,
274 - "enumerable": false,
275 - "configurable": true
276 - },
277 - "SharedArrayBuffer": {
278 - "writable": true,
279 - "enumerable": false,
280 - "configurable": true
281 - },
282 - "Atomics": {
283 - "writable": true,
284 - "enumerable": false,
285 - "configurable": true
286 - },
287 - "WebAssembly": {
288 - "writable": true,
289 - "enumerable": false,
290 - "configurable": true
291 - }
292 -}
1 -"use strict";
2 -
3 -module.exports = function (nameForErrorMessage, window) {
4 - if (!window) {
5 - // Do nothing for window-less documents.
6 - return;
7 - }
8 -
9 - const error = new Error(`Not implemented: ${nameForErrorMessage}`);
10 - error.type = "not implemented";
11 -
12 - window._virtualConsole.emit("jsdomError", error);
13 -};
1 -"use strict";
2 -
3 -const parse5 = require("parse5");
4 -
5 -const { createElement } = require("../../living/helpers/create-element");
6 -
7 -const DocumentType = require("../../living/generated/DocumentType");
8 -const DocumentFragment = require("../../living/generated/DocumentFragment");
9 -const Text = require("../../living/generated/Text");
10 -const Comment = require("../../living/generated/Comment");
11 -
12 -const attributes = require("../../living/attributes");
13 -const nodeTypes = require("../../living/node-type");
14 -
15 -const serializationAdapter = require("../../living/domparsing/parse5-adapter-serialization");
16 -const {
17 - customElementReactionsStack, invokeCEReactions, lookupCEDefinition
18 -} = require("../../living/helpers/custom-elements");
19 -
20 -// Horrible monkey-patch to implement https://github.com/inikulin/parse5/issues/237 and
21 -// https://github.com/inikulin/parse5/issues/285.
22 -const OpenElementStack = require("parse5/lib/parser/open-element-stack");
23 -
24 -const openElementStackOriginalPush = OpenElementStack.prototype.push;
25 -OpenElementStack.prototype.push = function (...args) {
26 - openElementStackOriginalPush.apply(this, args);
27 - this.treeAdapter._currentElement = this.current;
28 -
29 - const after = this.items[this.stackTop];
30 - if (after._pushedOnStackOfOpenElements) {
31 - after._pushedOnStackOfOpenElements();
32 - }
33 -};
34 -
35 -const openElementStackOriginalPop = OpenElementStack.prototype.pop;
36 -OpenElementStack.prototype.pop = function (...args) {
37 - const before = this.items[this.stackTop];
38 -
39 - openElementStackOriginalPop.apply(this, args);
40 - this.treeAdapter._currentElement = this.current;
41 -
42 - if (before._poppedOffStackOfOpenElements) {
43 - before._poppedOffStackOfOpenElements();
44 - }
45 -};
46 -
47 -class JSDOMParse5Adapter {
48 - constructor(documentImpl, options = {}) {
49 - this._documentImpl = documentImpl;
50 - this._globalObject = documentImpl._globalObject;
51 - this._fragment = options.fragment || false;
52 -
53 - // Since the createElement hook doesn't provide the parent element, we keep track of this using _currentElement:
54 - // https://github.com/inikulin/parse5/issues/285. See above horrible monkey-patch for how this is maintained.
55 - this._currentElement = undefined;
56 - }
57 -
58 - _ownerDocument() {
59 - const { _currentElement } = this;
60 -
61 - // The _currentElement is undefined when parsing elements at the root of the document.
62 - if (_currentElement) {
63 - return _currentElement.localName === "template" ?
64 - _currentElement.content._ownerDocument :
65 - _currentElement._ownerDocument;
66 - }
67 -
68 - return this._documentImpl;
69 - }
70 -
71 - createDocument() {
72 - // parse5's model assumes that parse(html) will call into here to create the new Document, then return it. However,
73 - // jsdom's model assumes we can create a Window (and through that create an empty Document), do some other setup
74 - // stuff, and then parse, stuffing nodes into that Document as we go. So to adapt between these two models, we just
75 - // return the already-created Document when asked by parse5 to "create" a Document.
76 - return this._documentImpl;
77 - }
78 -
79 - createDocumentFragment() {
80 - const ownerDocument = this._ownerDocument();
81 - return DocumentFragment.createImpl(this._globalObject, [], { ownerDocument });
82 - }
83 -
84 - // https://html.spec.whatwg.org/#create-an-element-for-the-token
85 - createElement(localName, namespace, attrs) {
86 - const ownerDocument = this._ownerDocument();
87 -
88 - const isAttribute = attrs.find(attr => attr.name === "is");
89 - const isValue = isAttribute ? isAttribute.value : null;
90 -
91 - const definition = lookupCEDefinition(ownerDocument, namespace, localName);
92 -
93 - let willExecuteScript = false;
94 - if (definition !== null && !this._fragment) {
95 - willExecuteScript = true;
96 - }
97 -
98 - if (willExecuteScript) {
99 - ownerDocument._throwOnDynamicMarkupInsertionCounter++;
100 - customElementReactionsStack.push([]);
101 - }
102 -
103 - const element = createElement(ownerDocument, localName, namespace, null, isValue, willExecuteScript);
104 - this.adoptAttributes(element, attrs);
105 -
106 - if (willExecuteScript) {
107 - const queue = customElementReactionsStack.pop();
108 - invokeCEReactions(queue);
109 - ownerDocument._throwOnDynamicMarkupInsertionCounter--;
110 - }
111 -
112 - if ("_parserInserted" in element) {
113 - element._parserInserted = true;
114 - }
115 -
116 - return element;
117 - }
118 -
119 - createCommentNode(data) {
120 - const ownerDocument = this._ownerDocument();
121 - return Comment.createImpl(this._globalObject, [], { data, ownerDocument });
122 - }
123 -
124 - appendChild(parentNode, newNode) {
125 - parentNode._append(newNode);
126 - }
127 -
128 - insertBefore(parentNode, newNode, referenceNode) {
129 - parentNode._insert(newNode, referenceNode);
130 - }
131 -
132 - setTemplateContent(templateElement, contentFragment) {
133 - // This code makes the glue between jsdom and parse5 HTMLTemplateElement parsing:
134 - //
135 - // * jsdom during the construction of the HTMLTemplateElement (for example when create via
136 - // `document.createElement("template")`), creates a DocumentFragment and set it into _templateContents.
137 - // * parse5 when parsing a <template> tag creates an HTMLTemplateElement (`createElement` adapter hook) and also
138 - // create a DocumentFragment (`createDocumentFragment` adapter hook).
139 - //
140 - // At this point we now have to replace the one created in jsdom with one created by parse5.
141 - const { _ownerDocument, _host } = templateElement._templateContents;
142 - contentFragment._ownerDocument = _ownerDocument;
143 - contentFragment._host = _host;
144 -
145 - templateElement._templateContents = contentFragment;
146 - }
147 -
148 - setDocumentType(document, name, publicId, systemId) {
149 - const ownerDocument = this._ownerDocument();
150 - const documentType = DocumentType.createImpl(this._globalObject, [], { name, publicId, systemId, ownerDocument });
151 -
152 - document._append(documentType);
153 - }
154 -
155 - setDocumentMode(document, mode) {
156 - // TODO: the rest of jsdom ignores this
157 - document._mode = mode;
158 - }
159 -
160 - detachNode(node) {
161 - node.remove();
162 - }
163 -
164 - insertText(parentNode, text) {
165 - const { lastChild } = parentNode;
166 - if (lastChild && lastChild.nodeType === nodeTypes.TEXT_NODE) {
167 - lastChild.data += text;
168 - } else {
169 - const ownerDocument = this._ownerDocument();
170 - const textNode = Text.createImpl(this._globalObject, [], { data: text, ownerDocument });
171 - parentNode._append(textNode);
172 - }
173 - }
174 -
175 - insertTextBefore(parentNode, text, referenceNode) {
176 - const { previousSibling } = referenceNode;
177 - if (previousSibling && previousSibling.nodeType === nodeTypes.TEXT_NODE) {
178 - previousSibling.data += text;
179 - } else {
180 - const ownerDocument = this._ownerDocument();
181 - const textNode = Text.createImpl(this._globalObject, [], { data: text, ownerDocument });
182 - parentNode._append(textNode, referenceNode);
183 - }
184 - }
185 -
186 - adoptAttributes(element, attrs) {
187 - for (const attr of attrs) {
188 - const prefix = attr.prefix === "" ? null : attr.prefix;
189 - attributes.setAttributeValue(element, attr.name, attr.value, prefix, attr.namespace);
190 - }
191 - }
192 -}
193 -
194 -// Assign shared adapters with serializer.
195 -Object.assign(JSDOMParse5Adapter.prototype, serializationAdapter);
196 -
197 -function parseFragment(markup, contextElement) {
198 - const ownerDocument = contextElement.localName === "template" ?
199 - contextElement.content._ownerDocument :
200 - contextElement._ownerDocument;
201 -
202 - const config = Object.assign({}, ownerDocument._parseOptions, {
203 - treeAdapter: new JSDOMParse5Adapter(ownerDocument, {
204 - fragment: true
205 - })
206 - });
207 -
208 - return parse5.parseFragment(contextElement, markup, config);
209 -}
210 -
211 -function parseIntoDocument(markup, ownerDocument) {
212 - const config = Object.assign({}, ownerDocument._parseOptions, {
213 - treeAdapter: new JSDOMParse5Adapter(ownerDocument)
214 - });
215 -
216 - return parse5.parse(markup, config);
217 -}
218 -
219 -module.exports = {
220 - parseFragment,
221 - parseIntoDocument
222 -};
1 -"use strict";
2 -
3 -const xmlParser = require("./xml");
4 -const htmlParser = require("./html");
5 -
6 -// https://w3c.github.io/DOM-Parsing/#dfn-fragment-parsing-algorithm
7 -function parseFragment(markup, contextElement) {
8 - const { _parsingMode } = contextElement._ownerDocument;
9 -
10 - let parseAlgorithm;
11 - if (_parsingMode === "html") {
12 - parseAlgorithm = htmlParser.parseFragment;
13 - } else if (_parsingMode === "xml") {
14 - parseAlgorithm = xmlParser.parseFragment;
15 - }
16 -
17 - // Note: HTML and XML fragment parsing algorithm already return a document fragments; no need to do steps 3 and 4
18 - return parseAlgorithm(markup, contextElement);
19 -}
20 -
21 -function parseIntoDocument(markup, ownerDocument) {
22 - const { _parsingMode } = ownerDocument;
23 -
24 - let parseAlgorithm;
25 - if (_parsingMode === "html") {
26 - parseAlgorithm = htmlParser.parseIntoDocument;
27 - } else if (_parsingMode === "xml") {
28 - parseAlgorithm = xmlParser.parseIntoDocument;
29 - }
30 -
31 - return parseAlgorithm(markup, ownerDocument);
32 -}
33 -
34 -module.exports = {
35 - parseFragment,
36 - parseIntoDocument
37 -};
1 -"use strict";
2 -
3 -const { SaxesParser } = require("saxes");
4 -const DOMException = require("domexception/webidl2js-wrapper");
5 -
6 -const { createElement } = require("../../living/helpers/create-element");
7 -
8 -const DocumentFragment = require("../../living/generated/DocumentFragment");
9 -const DocumentType = require("../../living/generated/DocumentType");
10 -const CDATASection = require("../../living/generated/CDATASection");
11 -const Comment = require("../../living/generated/Comment");
12 -const ProcessingInstruction = require("../../living/generated/ProcessingInstruction");
13 -const Text = require("../../living/generated/Text");
14 -
15 -const attributes = require("../../living/attributes");
16 -const { HTML_NS } = require("../../living/helpers/namespaces");
17 -
18 -const HTML5_DOCTYPE = /<!doctype html>/i;
19 -const PUBLIC_DOCTYPE = /<!doctype\s+([^\s]+)\s+public\s+"([^"]+)"\s+"([^"]+)"/i;
20 -const SYSTEM_DOCTYPE = /<!doctype\s+([^\s]+)\s+system\s+"([^"]+)"/i;
21 -const CUSTOM_NAME_DOCTYPE = /<!doctype\s+([^\s>]+)/i;
22 -
23 -function parseDocType(globalObject, ownerDocument, html) {
24 - if (HTML5_DOCTYPE.test(html)) {
25 - return createDocumentType(globalObject, ownerDocument, "html", "", "");
26 - }
27 -
28 - const publicPieces = PUBLIC_DOCTYPE.exec(html);
29 - if (publicPieces) {
30 - return createDocumentType(globalObject, ownerDocument, publicPieces[1], publicPieces[2], publicPieces[3]);
31 - }
32 -
33 - const systemPieces = SYSTEM_DOCTYPE.exec(html);
34 - if (systemPieces) {
35 - return createDocumentType(globalObject, ownerDocument, systemPieces[1], "", systemPieces[2]);
36 - }
37 -
38 - const namePiece = CUSTOM_NAME_DOCTYPE.exec(html)[1] || "html";
39 - return createDocumentType(globalObject, ownerDocument, namePiece, "", "");
40 -}
41 -
42 -function createDocumentType(globalObject, ownerDocument, name, publicId, systemId) {
43 - return DocumentType.createImpl(globalObject, [], { ownerDocument, name, publicId, systemId });
44 -}
45 -
46 -function isHTMLTemplateElement(element) {
47 - return element.tagName === "template" && element.namespaceURI === HTML_NS;
48 -}
49 -
50 -
51 -function createParser(rootNode, globalObject, saxesOptions) {
52 - const parser = new SaxesParser({
53 - ...saxesOptions,
54 - // Browsers always have namespace support.
55 - xmlns: true,
56 - // We force the parser to treat all documents (even documents declaring themselves to be XML 1.1 documents) as XML
57 - // 1.0 documents. See https://github.com/jsdom/jsdom/issues/2677 for a discussion of the stakes.
58 - defaultXMLVersion: "1.0",
59 - forceXMLVersion: true
60 - });
61 - const openStack = [rootNode];
62 -
63 - function getOwnerDocument() {
64 - const currentElement = openStack[openStack.length - 1];
65 -
66 - return isHTMLTemplateElement(currentElement) ?
67 - currentElement._templateContents._ownerDocument :
68 - currentElement._ownerDocument;
69 - }
70 -
71 - function appendChild(child) {
72 - const parentElement = openStack[openStack.length - 1];
73 -
74 - if (isHTMLTemplateElement(parentElement)) {
75 - parentElement._templateContents._insert(child, null);
76 - } else {
77 - parentElement._insert(child, null);
78 - }
79 - }
80 -
81 - parser.on("text", saxesOptions.fragment ?
82 - // In a fragment, all text events produced by saxes must result in a text
83 - // node.
84 - data => {
85 - const ownerDocument = getOwnerDocument();
86 - appendChild(Text.createImpl(globalObject, [], { data, ownerDocument }));
87 - } :
88 - // When parsing a whole document, we must ignore those text nodes that are
89 - // produced outside the root element. Saxes produces events for them,
90 - // but DOM trees do not record text outside the root element.
91 - data => {
92 - if (openStack.length > 1) {
93 - const ownerDocument = getOwnerDocument();
94 - appendChild(Text.createImpl(globalObject, [], { data, ownerDocument }));
95 - }
96 - });
97 -
98 - parser.on("cdata", data => {
99 - const ownerDocument = getOwnerDocument();
100 - appendChild(CDATASection.createImpl(globalObject, [], { data, ownerDocument }));
101 - });
102 -
103 - parser.on("opentag", tag => {
104 - const { local: tagLocal, attributes: tagAttributes } = tag;
105 -
106 - const ownerDocument = getOwnerDocument();
107 - const tagNamespace = tag.uri === "" ? null : tag.uri;
108 - const tagPrefix = tag.prefix === "" ? null : tag.prefix;
109 - const isValue = tagAttributes.is === undefined ? null : tagAttributes.is.value;
110 -
111 - const elem = createElement(ownerDocument, tagLocal, tagNamespace, tagPrefix, isValue, true);
112 -
113 - // We mark a script element as "parser-inserted", which prevents it from
114 - // being immediately executed.
115 - if (tagLocal === "script" && tagNamespace === HTML_NS) {
116 - elem._parserInserted = true;
117 - }
118 -
119 - for (const key of Object.keys(tagAttributes)) {
120 - const { prefix, local, uri, value } = tagAttributes[key];
121 - attributes.setAttributeValue(
122 - elem, local, value, prefix === "" ? null : prefix,
123 - uri === "" ? null : uri
124 - );
125 - }
126 -
127 - appendChild(elem);
128 - openStack.push(elem);
129 - });
130 -
131 - parser.on("closetag", () => {
132 - const elem = openStack.pop();
133 - // Once a script is populated, we can execute it.
134 - if (elem.localName === "script" && elem.namespaceURI === HTML_NS) {
135 - elem._eval();
136 - }
137 - });
138 -
139 - parser.on("comment", data => {
140 - const ownerDocument = getOwnerDocument();
141 - appendChild(Comment.createImpl(globalObject, [], { data, ownerDocument }));
142 - });
143 -
144 - parser.on("processinginstruction", ({ target, body }) => {
145 - const ownerDocument = getOwnerDocument();
146 - appendChild(ProcessingInstruction.createImpl(globalObject, [], { target, data: body, ownerDocument }));
147 - });
148 -
149 - parser.on("doctype", dt => {
150 - const ownerDocument = getOwnerDocument();
151 - appendChild(parseDocType(globalObject, ownerDocument, `<!doctype ${dt}>`));
152 -
153 - const entityMatcher = /<!ENTITY ([^ ]+) "([^"]+)">/g;
154 - let result;
155 - while ((result = entityMatcher.exec(dt))) {
156 - const [, name, value] = result;
157 - if (!(name in parser.ENTITIES)) {
158 - parser.ENTITIES[name] = value;
159 - }
160 - }
161 - });
162 -
163 - parser.on("error", err => {
164 - throw DOMException.create(globalObject, [err.message, "SyntaxError"]);
165 - });
166 -
167 - return parser;
168 -}
169 -
170 -function parseFragment(markup, contextElement) {
171 - const { _globalObject, _ownerDocument } = contextElement;
172 -
173 - const fragment = DocumentFragment.createImpl(_globalObject, [], { ownerDocument: _ownerDocument });
174 -
175 - // Only parseFragment needs resolvePrefix per the saxes documentation:
176 - // https://github.com/lddubeau/saxes#parsing-xml-fragments
177 - const parser = createParser(fragment, _globalObject, {
178 - fragment: true,
179 - resolvePrefix(prefix) {
180 - // saxes wants undefined as the return value if the prefix is not defined, not null.
181 - return contextElement.lookupNamespaceURI(prefix) || undefined;
182 - }
183 - });
184 -
185 - parser.write(markup).close();
186 -
187 - return fragment;
188 -}
189 -
190 -function parseIntoDocument(markup, ownerDocument) {
191 - const { _globalObject } = ownerDocument;
192 -
193 - const parser = createParser(ownerDocument, _globalObject, {
194 - fileName: ownerDocument.location && ownerDocument.location.href
195 - });
196 -
197 - parser.write(markup).close();
198 -
199 - return ownerDocument;
200 -}
201 -
202 -module.exports = {
203 - parseFragment,
204 - parseIntoDocument
205 -};
1 -"use strict";
2 -
3 -class QueueItem {
4 - constructor(onLoad, onError, dependentItem) {
5 - this.onLoad = onLoad;
6 - this.onError = onError;
7 - this.data = null;
8 - this.error = null;
9 - this.dependentItem = dependentItem;
10 - }
11 -}
12 -
13 -/**
14 - * AsyncResourceQueue is the queue in charge of run the async scripts
15 - * and notify when they finish.
16 - */
17 -module.exports = class AsyncResourceQueue {
18 - constructor() {
19 - this.items = new Set();
20 - this.dependentItems = new Set();
21 - }
22 -
23 - count() {
24 - return this.items.size + this.dependentItems.size;
25 - }
26 -
27 - _notify() {
28 - if (this._listener) {
29 - this._listener();
30 - }
31 - }
32 -
33 - _check(item) {
34 - let promise;
35 -
36 - if (item.onError && item.error) {
37 - promise = item.onError(item.error);
38 - } else if (item.onLoad && item.data) {
39 - promise = item.onLoad(item.data);
40 - }
41 -
42 - promise
43 - .then(() => {
44 - this.items.delete(item);
45 - this.dependentItems.delete(item);
46 -
47 - if (this.count() === 0) {
48 - this._notify();
49 - }
50 - });
51 - }
52 -
53 - setListener(listener) {
54 - this._listener = listener;
55 - }
56 -
57 - push(request, onLoad, onError, dependentItem) {
58 - const q = this;
59 -
60 - const item = new QueueItem(onLoad, onError, dependentItem);
61 -
62 - q.items.add(item);
63 -
64 - return request
65 - .then(data => {
66 - item.data = data;
67 -
68 - if (dependentItem && !dependentItem.finished) {
69 - q.dependentItems.add(item);
70 - return q.items.delete(item);
71 - }
72 -
73 - if (onLoad) {
74 - return q._check(item);
75 - }
76 -
77 - q.items.delete(item);
78 -
79 - if (q.count() === 0) {
80 - q._notify();
81 - }
82 -
83 - return null;
84 - })
85 - .catch(err => {
86 - item.error = err;
87 -
88 - if (dependentItem && !dependentItem.finished) {
89 - q.dependentItems.add(item);
90 - return q.items.delete(item);
91 - }
92 -
93 - if (onError) {
94 - return q._check(item);
95 - }
96 -
97 - q.items.delete(item);
98 -
99 - if (q.count() === 0) {
100 - q._notify();
101 - }
102 -
103 - return null;
104 - });
105 - }
106 -
107 - notifyItem(syncItem) {
108 - for (const item of this.dependentItems) {
109 - if (item.dependentItem === syncItem) {
110 - this._check(item);
111 - }
112 - }
113 - }
114 -};
1 -"use strict";
2 -const ResourceLoader = require("./resource-loader.js");
3 -
4 -module.exports = class NoOpResourceLoader extends ResourceLoader {
5 - fetch() {
6 - return null;
7 - }
8 -};
1 -"use strict";
2 -const idlUtils = require("../../living/generated/utils");
3 -const { fireAnEvent } = require("../../living/helpers/events");
4 -
5 -module.exports = class PerDocumentResourceLoader {
6 - constructor(document) {
7 - this._document = document;
8 - this._defaultEncoding = document._encoding;
9 - this._resourceLoader = document._defaultView ? document._defaultView._resourceLoader : null;
10 - this._requestManager = document._requestManager;
11 - this._queue = document._queue;
12 - this._deferQueue = document._deferQueue;
13 - this._asyncQueue = document._asyncQueue;
14 - }
15 -
16 - fetch(url, { element, onLoad, onError }) {
17 - const request = this._resourceLoader.fetch(url, {
18 - cookieJar: this._document._cookieJar,
19 - element: idlUtils.wrapperForImpl(element),
20 - referrer: this._document.URL
21 - });
22 -
23 - if (request === null) {
24 - return null;
25 - }
26 -
27 - this._requestManager.add(request);
28 -
29 - const onErrorWrapped = error => {
30 - this._requestManager.remove(request);
31 -
32 - if (onError) {
33 - onError(error);
34 - }
35 -
36 - fireAnEvent("error", element);
37 -
38 - const err = new Error(`Could not load ${element.localName}: "${url}"`);
39 - err.type = "resource loading";
40 - err.detail = error;
41 -
42 - this._document._defaultView._virtualConsole.emit("jsdomError", err);
43 -
44 - return Promise.resolve();
45 - };
46 -
47 - const onLoadWrapped = data => {
48 - this._requestManager.remove(request);
49 -
50 - this._addCookies(url, request.response ? request.response.headers : {});
51 -
52 - try {
53 - const result = onLoad ? onLoad(data) : undefined;
54 -
55 - return Promise.resolve(result)
56 - .then(() => {
57 - fireAnEvent("load", element);
58 -
59 - return Promise.resolve();
60 - })
61 - .catch(err => {
62 - return onErrorWrapped(err);
63 - });
64 - } catch (err) {
65 - return onErrorWrapped(err);
66 - }
67 - };
68 -
69 - if (element.localName === "script" && element.hasAttributeNS(null, "async")) {
70 - this._asyncQueue.push(request, onLoadWrapped, onErrorWrapped, this._queue.getLastScript());
71 - } else if (element.localName === "script" && element.hasAttributeNS(null, "defer")) {
72 - this._deferQueue.push(request, onLoadWrapped, onErrorWrapped, false, element);
73 - } else {
74 - this._queue.push(request, onLoadWrapped, onErrorWrapped, false, element);
75 - }
76 -
77 - return request;
78 - }
79 -
80 - _addCookies(url, headers) {
81 - let cookies = headers["set-cookie"];
82 -
83 - if (!cookies) {
84 - return;
85 - }
86 -
87 - if (!Array.isArray(cookies)) {
88 - cookies = [cookies];
89 - }
90 -
91 - cookies.forEach(cookie => {
92 - this._document._cookieJar.setCookieSync(cookie, url, { http: true, ignoreError: true });
93 - });
94 - }
95 -};
1 -"use strict";
2 -
3 -/**
4 - * Manage all the request and it is able to abort
5 - * all pending request.
6 - */
7 -module.exports = class RequestManager {
8 - constructor() {
9 - this.openedRequests = [];
10 - }
11 -
12 - add(req) {
13 - this.openedRequests.push(req);
14 - }
15 -
16 - remove(req) {
17 - const idx = this.openedRequests.indexOf(req);
18 - if (idx !== -1) {
19 - this.openedRequests.splice(idx, 1);
20 - }
21 - }
22 -
23 - close() {
24 - for (const openedRequest of this.openedRequests) {
25 - openedRequest.abort();
26 - }
27 - this.openedRequests = [];
28 - }
29 -
30 - size() {
31 - return this.openedRequests.length;
32 - }
33 -};
1 -"use strict";
2 -const fs = require("fs");
3 -const { parseURL } = require("whatwg-url");
4 -const dataURLFromRecord = require("data-urls").fromURLRecord;
5 -const request = require("request-promise-native");
6 -const wrapCookieJarForRequest = require("../../living/helpers/wrap-cookie-jar-for-request");
7 -const packageVersion = require("../../../../package.json").version;
8 -const IS_BROWSER = Object.prototype.toString.call(process) !== "[object process]";
9 -
10 -module.exports = class ResourceLoader {
11 - constructor({
12 - strictSSL = true,
13 - proxy = undefined,
14 - userAgent = `Mozilla/5.0 (${process.platform || "unknown OS"}) AppleWebKit/537.36 ` +
15 - `(KHTML, like Gecko) jsdom/${packageVersion}`
16 - } = {}) {
17 - this._strictSSL = strictSSL;
18 - this._proxy = proxy;
19 - this._userAgent = userAgent;
20 - }
21 -
22 - _readDataURL(urlRecord) {
23 - const dataURL = dataURLFromRecord(urlRecord);
24 - let timeoutId;
25 - const promise = new Promise(resolve => {
26 - timeoutId = setTimeout(resolve, 0, dataURL.body);
27 - });
28 - promise.abort = () => {
29 - if (timeoutId !== undefined) {
30 - clearTimeout(timeoutId);
31 - }
32 - };
33 - return promise;
34 - }
35 -
36 - _readFile(filePath) {
37 - let readableStream;
38 - let abort; // Native Promises doesn't have an "abort" method.
39 -
40 - /*
41 - * Creating a promise for two reason:
42 - * 1. fetch always return a promise.
43 - * 2. We need to add an abort handler.
44 - */
45 - const promise = new Promise((resolve, reject) => {
46 - readableStream = fs.createReadStream(filePath);
47 - let data = Buffer.alloc(0);
48 -
49 - abort = reject;
50 -
51 - readableStream.on("error", reject);
52 -
53 - readableStream.on("data", chunk => {
54 - data = Buffer.concat([data, chunk]);
55 - });
56 -
57 - readableStream.on("end", () => {
58 - resolve(data);
59 - });
60 - });
61 -
62 - promise.abort = () => {
63 - readableStream.destroy();
64 - const error = new Error("request canceled by user");
65 - error.isAbortError = true;
66 - abort(error);
67 - };
68 -
69 - return promise;
70 - }
71 -
72 - _getRequestOptions({ cookieJar, referrer, accept = "*/*" }) {
73 - const requestOptions = {
74 - encoding: null,
75 - gzip: true,
76 - jar: wrapCookieJarForRequest(cookieJar),
77 - strictSSL: this._strictSSL,
78 - proxy: this._proxy,
79 - forever: true,
80 - headers: {
81 - "User-Agent": this._userAgent,
82 - "Accept-Language": "en",
83 - Accept: accept
84 - }
85 - };
86 -
87 - if (referrer && !IS_BROWSER) {
88 - requestOptions.headers.referer = referrer;
89 - }
90 -
91 - return requestOptions;
92 - }
93 -
94 - fetch(urlString, options = {}) {
95 - const url = parseURL(urlString);
96 -
97 - if (!url) {
98 - return Promise.reject(new Error(`Tried to fetch invalid URL ${urlString}`));
99 - }
100 -
101 - switch (url.scheme) {
102 - case "data": {
103 - return this._readDataURL(url);
104 - }
105 -
106 - case "http":
107 - case "https": {
108 - const requestOptions = this._getRequestOptions(options);
109 - return request(urlString, requestOptions);
110 - }
111 -
112 - case "file": {
113 - // TODO: Improve the URL => file algorithm. See https://github.com/jsdom/jsdom/pull/2279#discussion_r199977987
114 - const filePath = urlString
115 - .replace(/^file:\/\//, "")
116 - .replace(/^\/([a-z]):\//i, "$1:/")
117 - .replace(/%20/g, " ");
118 -
119 - return this._readFile(filePath);
120 - }
121 -
122 - default: {
123 - return Promise.reject(new Error(`Tried to fetch URL ${urlString} with invalid scheme ${url.scheme}`));
124 - }
125 - }
126 - }
127 -};
1 -"use strict";
2 -
3 -/**
4 - * Queue for all the resources to be download except async scripts.
5 - * Async scripts have their own queue AsyncResourceQueue.
6 - */
7 -module.exports = class ResourceQueue {
8 - constructor({ paused, asyncQueue } = {}) {
9 - this.paused = Boolean(paused);
10 - this._asyncQueue = asyncQueue;
11 - }
12 -
13 - getLastScript() {
14 - let head = this.tail;
15 -
16 - while (head) {
17 - if (head.isScript) {
18 - return head;
19 - }
20 - head = head.prev;
21 - }
22 -
23 - return null;
24 - }
25 -
26 - _moreScripts() {
27 - let found = false;
28 -
29 - let head = this.tail;
30 - while (head && !found) {
31 - found = head.isScript;
32 - head = head.prev;
33 - }
34 -
35 - return found;
36 - }
37 -
38 - _notify() {
39 - if (this._listener) {
40 - this._listener();
41 - }
42 - }
43 -
44 - setListener(listener) {
45 - this._listener = listener;
46 - }
47 -
48 - push(request, onLoad, onError, keepLast, element) {
49 - const isScript = element ? element.localName === "script" : false;
50 -
51 - if (!request) {
52 - if (isScript && !this._moreScripts()) {
53 - return onLoad();
54 - }
55 -
56 - request = new Promise(resolve => resolve());
57 - }
58 - const q = this;
59 - const item = {
60 - isScript,
61 - err: null,
62 - element,
63 - fired: false,
64 - data: null,
65 - keepLast,
66 - prev: q.tail,
67 - check() {
68 - if (!q.paused && !this.prev && this.fired) {
69 - let promise;
70 -
71 - if (this.err && onError) {
72 - promise = onError(this.err);
73 - }
74 -
75 - if (!this.err && onLoad) {
76 - promise = onLoad(this.data);
77 - }
78 -
79 - Promise.resolve(promise)
80 - .then(() => {
81 - if (this.next) {
82 - this.next.prev = null;
83 - this.next.check();
84 - } else { // q.tail===this
85 - q.tail = null;
86 - q._notify();
87 - }
88 -
89 - this.finished = true;
90 -
91 - if (q._asyncQueue) {
92 - q._asyncQueue.notifyItem(this);
93 - }
94 - });
95 - }
96 - }
97 - };
98 - if (q.tail) {
99 - if (q.tail.keepLast) {
100 - // if the tail is the load event in document and we receive a new element to load
101 - // we should add this new request before the load event.
102 - if (q.tail.prev) {
103 - q.tail.prev.next = item;
104 - }
105 - item.prev = q.tail.prev;
106 - q.tail.prev = item;
107 - item.next = q.tail;
108 - } else {
109 - q.tail.next = item;
110 - q.tail = item;
111 - }
112 - } else {
113 - q.tail = item;
114 - }
115 - return request
116 - .then(data => {
117 - item.fired = 1;
118 - item.data = data;
119 - item.check();
120 - })
121 - .catch(err => {
122 - item.fired = true;
123 - item.err = err;
124 - item.check();
125 - });
126 - }
127 -
128 - resume() {
129 - if (!this.paused) {
130 - return;
131 - }
132 - this.paused = false;
133 -
134 - let head = this.tail;
135 - while (head && head.prev) {
136 - head = head.prev;
137 - }
138 - if (head) {
139 - head.check();
140 - }
141 - }
142 -};
1 -"use strict";
2 -const cssom = require("cssom");
3 -const cssstyle = require("cssstyle");
4 -
5 -exports.addToCore = core => {
6 - // What works now:
7 - // - Accessing the rules defined in individual stylesheets
8 - // - Modifications to style content attribute are reflected in style property
9 - // - Modifications to style property are reflected in style content attribute
10 - // TODO
11 - // - Modifications to style element's textContent are reflected in sheet property.
12 - // - Modifications to style element's sheet property are reflected in textContent.
13 - // - Modifications to link.href property are reflected in sheet property.
14 - // - Less-used features of link: disabled
15 - // - Less-used features of style: disabled, scoped, title
16 - // - CSSOM-View
17 - // - getComputedStyle(): requires default stylesheet, cascading, inheritance,
18 - // filtering by @media (screen? print?), layout for widths/heights
19 - // - Load events are not in the specs, but apparently some browsers
20 - // implement something. Should onload only fire after all @imports have been
21 - // loaded, or only the primary sheet?
22 -
23 - core.StyleSheet = cssom.StyleSheet;
24 - core.MediaList = cssom.MediaList;
25 - core.CSSStyleSheet = cssom.CSSStyleSheet;
26 - core.CSSRule = cssom.CSSRule;
27 - core.CSSStyleRule = cssom.CSSStyleRule;
28 - core.CSSMediaRule = cssom.CSSMediaRule;
29 - core.CSSImportRule = cssom.CSSImportRule;
30 - core.CSSStyleDeclaration = cssstyle.CSSStyleDeclaration;
31 -
32 - // Relavant specs
33 - // http://www.w3.org/TR/DOM-Level-2-Style (2000)
34 - // http://www.w3.org/TR/cssom-view/ (2008)
35 - // http://dev.w3.org/csswg/cssom/ (2010) Meant to replace DOM Level 2 Style
36 - // http://www.whatwg.org/specs/web-apps/current-work/multipage/ HTML5, of course
37 - // http://dev.w3.org/csswg/css-style-attr/ not sure what's new here
38 -
39 - // Objects that aren't in cssom library but should be:
40 - // CSSRuleList (cssom just uses array)
41 - // CSSFontFaceRule
42 - // CSSPageRule
43 -
44 - // These rules don't really make sense to implement, so CSSOM draft makes them
45 - // obsolete.
46 - // CSSCharsetRule
47 - // CSSUnknownRule
48 -
49 - // These objects are considered obsolete by CSSOM draft, although modern
50 - // browsers implement them.
51 - // CSSValue
52 - // CSSPrimitiveValue
53 - // CSSValueList
54 - // RGBColor
55 - // Rect
56 - // Counter
57 -};
This diff is collapsed. Click to expand it.
1 -"use strict";
2 -
3 -const AbortSignal = require("../generated/AbortSignal");
4 -
5 -class AbortControllerImpl {
6 - constructor(globalObject) {
7 - this.signal = AbortSignal.createImpl(globalObject, []);
8 - }
9 -
10 - abort() {
11 - this.signal._signalAbort();
12 - }
13 -}
14 -
15 -module.exports = {
16 - implementation: AbortControllerImpl
17 -};
1 -"use strict";
2 -
3 -const { setupForSimpleEventAccessors } = require("../helpers/create-event-accessor");
4 -const { fireAnEvent } = require("../helpers/events");
5 -const EventTargetImpl = require("../events/EventTarget-impl").implementation;
6 -
7 -class AbortSignalImpl extends EventTargetImpl {
8 - constructor(globalObject, args, privateData) {
9 - super(globalObject, args, privateData);
10 -
11 - // make event firing possible
12 - this._ownerDocument = globalObject.document;
13 -
14 - this.aborted = false;
15 - this.abortAlgorithms = new Set();
16 - }
17 -
18 - _signalAbort() {
19 - if (this.aborted) {
20 - return;
21 - }
22 - this.aborted = true;
23 -
24 - for (const algorithm of this.abortAlgorithms) {
25 - algorithm();
26 - }
27 - this.abortAlgorithms.clear();
28 -
29 - fireAnEvent("abort", this);
30 - }
31 -
32 - _addAlgorithm(algorithm) {
33 - if (this.aborted) {
34 - return;
35 - }
36 - this.abortAlgorithms.add(algorithm);
37 - }
38 -
39 - _removeAlgorithm(algorithm) {
40 - this.abortAlgorithms.delete(algorithm);
41 - }
42 -}
43 -
44 -setupForSimpleEventAccessors(AbortSignalImpl.prototype, ["abort"]);
45 -
46 -module.exports = {
47 - implementation: AbortSignalImpl
48 -};
1 -"use strict";
2 -const DOMException = require("domexception/webidl2js-wrapper");
3 -
4 -const { HTML_NS } = require("./helpers/namespaces");
5 -const { asciiLowercase } = require("./helpers/strings");
6 -const { queueAttributeMutationRecord } = require("./helpers/mutation-observers");
7 -const { enqueueCECallbackReaction } = require("./helpers/custom-elements");
8 -
9 -// The following three are for https://dom.spec.whatwg.org/#concept-element-attribute-has. We don't just have a
10 -// predicate tester since removing that kind of flexibility gives us the potential for better future optimizations.
11 -
12 -/* eslint-disable no-restricted-properties */
13 -
14 -exports.hasAttribute = function (element, A) {
15 - return element._attributeList.includes(A);
16 -};
17 -
18 -exports.hasAttributeByName = function (element, name) {
19 - return element._attributesByNameMap.has(name);
20 -};
21 -
22 -exports.hasAttributeByNameNS = function (element, namespace, localName) {
23 - return element._attributeList.some(attribute => {
24 - return attribute._localName === localName && attribute._namespace === namespace;
25 - });
26 -};
27 -
28 -// https://dom.spec.whatwg.org/#concept-element-attributes-change
29 -exports.changeAttribute = (element, attribute, value) => {
30 - const { _localName, _namespace, _value } = attribute;
31 -
32 - queueAttributeMutationRecord(element, _localName, _namespace, _value);
33 -
34 - if (element._ceState === "custom") {
35 - enqueueCECallbackReaction(element, "attributeChangedCallback", [
36 - _localName,
37 - _value,
38 - value,
39 - _namespace
40 - ]);
41 - }
42 -
43 - attribute._value = value;
44 -
45 - // Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is changed."
46 - element._attrModified(attribute._qualifiedName, value, _value);
47 -};
48 -
49 -// https://dom.spec.whatwg.org/#concept-element-attributes-append
50 -exports.appendAttribute = function (element, attribute) {
51 - const { _localName, _namespace, _value } = attribute;
52 - queueAttributeMutationRecord(element, _localName, _namespace, null);
53 -
54 - if (element._ceState === "custom") {
55 - enqueueCECallbackReaction(element, "attributeChangedCallback", [
56 - _localName,
57 - null,
58 - _value,
59 - _namespace
60 - ]);
61 - }
62 -
63 - const attributeList = element._attributeList;
64 -
65 - attributeList.push(attribute);
66 - attribute._element = element;
67 -
68 - // Sync name cache
69 - const name = attribute._qualifiedName;
70 - const cache = element._attributesByNameMap;
71 - let entry = cache.get(name);
72 - if (!entry) {
73 - entry = [];
74 - cache.set(name, entry);
75 - }
76 - entry.push(attribute);
77 -
78 - // Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is added."
79 - element._attrModified(name, _value, null);
80 -};
81 -
82 -exports.removeAttribute = function (element, attribute) {
83 - // https://dom.spec.whatwg.org/#concept-element-attributes-remove
84 -
85 - const { _localName, _namespace, _value } = attribute;
86 -
87 - queueAttributeMutationRecord(element, _localName, _namespace, _value);
88 -
89 - if (element._ceState === "custom") {
90 - enqueueCECallbackReaction(element, "attributeChangedCallback", [
91 - _localName,
92 - _value,
93 - null,
94 - _namespace
95 - ]);
96 - }
97 -
98 - const attributeList = element._attributeList;
99 -
100 - for (let i = 0; i < attributeList.length; ++i) {
101 - if (attributeList[i] === attribute) {
102 - attributeList.splice(i, 1);
103 - attribute._element = null;
104 -
105 - // Sync name cache
106 - const name = attribute._qualifiedName;
107 - const cache = element._attributesByNameMap;
108 - const entry = cache.get(name);
109 - entry.splice(entry.indexOf(attribute), 1);
110 - if (entry.length === 0) {
111 - cache.delete(name);
112 - }
113 -
114 - // Run jsdom hooks; roughly correspond to spec's "An attribute is removed."
115 - element._attrModified(name, null, attribute._value);
116 -
117 - return;
118 - }
119 - }
120 -};
121 -
122 -exports.replaceAttribute = function (element, oldAttr, newAttr) {
123 - // https://dom.spec.whatwg.org/#concept-element-attributes-replace
124 -
125 - const { _localName, _namespace, _value } = oldAttr;
126 -
127 - queueAttributeMutationRecord(element, _localName, _namespace, _value);
128 -
129 - if (element._ceState === "custom") {
130 - enqueueCECallbackReaction(element, "attributeChangedCallback", [
131 - _localName,
132 - _value,
133 - newAttr._value,
134 - _namespace
135 - ]);
136 - }
137 -
138 - const attributeList = element._attributeList;
139 -
140 - for (let i = 0; i < attributeList.length; ++i) {
141 - if (attributeList[i] === oldAttr) {
142 - attributeList.splice(i, 1, newAttr);
143 - oldAttr._element = null;
144 - newAttr._element = element;
145 -
146 - // Sync name cache
147 - const name = newAttr._qualifiedName;
148 - const cache = element._attributesByNameMap;
149 - let entry = cache.get(name);
150 - if (!entry) {
151 - entry = [];
152 - cache.set(name, entry);
153 - }
154 - entry.splice(entry.indexOf(oldAttr), 1, newAttr);
155 -
156 - // Run jsdom hooks; roughly correspond to spec's "An attribute is set and an attribute is changed."
157 - element._attrModified(name, newAttr._value, oldAttr._value);
158 -
159 - return;
160 - }
161 - }
162 -};
163 -
164 -exports.getAttributeByName = function (element, name) {
165 - // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-name
166 -
167 - if (element._namespaceURI === HTML_NS &&
168 - element._ownerDocument._parsingMode === "html") {
169 - name = asciiLowercase(name);
170 - }
171 -
172 - const cache = element._attributesByNameMap;
173 - const entry = cache.get(name);
174 - if (!entry) {
175 - return null;
176 - }
177 -
178 - return entry[0];
179 -};
180 -
181 -exports.getAttributeByNameNS = function (element, namespace, localName) {
182 - // https://dom.spec.whatwg.org/#concept-element-attributes-get-by-namespace
183 -
184 - if (namespace === "") {
185 - namespace = null;
186 - }
187 -
188 - const attributeList = element._attributeList;
189 - for (let i = 0; i < attributeList.length; ++i) {
190 - const attr = attributeList[i];
191 - if (attr._namespace === namespace && attr._localName === localName) {
192 - return attr;
193 - }
194 - }
195 -
196 - return null;
197 -};
198 -
199 -// Both of the following functions implement https://dom.spec.whatwg.org/#concept-element-attributes-get-value.
200 -// Separated them into two to keep symmetry with other functions.
201 -exports.getAttributeValue = function (element, localName) {
202 - const attr = exports.getAttributeByNameNS(element, null, localName);
203 -
204 - if (!attr) {
205 - return "";
206 - }
207 -
208 - return attr._value;
209 -};
210 -
211 -exports.getAttributeValueNS = function (element, namespace, localName) {
212 - const attr = exports.getAttributeByNameNS(element, namespace, localName);
213 -
214 - if (!attr) {
215 - return "";
216 - }
217 -
218 - return attr._value;
219 -};
220 -
221 -exports.setAttribute = function (element, attr) {
222 - // https://dom.spec.whatwg.org/#concept-element-attributes-set
223 -
224 - if (attr._element !== null && attr._element !== element) {
225 - throw DOMException.create(element._globalObject, ["The attribute is in use.", "InUseAttributeError"]);
226 - }
227 -
228 - const oldAttr = exports.getAttributeByNameNS(element, attr._namespace, attr._localName);
229 - if (oldAttr === attr) {
230 - return attr;
231 - }
232 -
233 - if (oldAttr !== null) {
234 - exports.replaceAttribute(element, oldAttr, attr);
235 - } else {
236 - exports.appendAttribute(element, attr);
237 - }
238 -
239 - return oldAttr;
240 -};
241 -
242 -exports.setAttributeValue = function (element, localName, value, prefix, namespace) {
243 - // https://dom.spec.whatwg.org/#concept-element-attributes-set-value
244 -
245 - if (prefix === undefined) {
246 - prefix = null;
247 - }
248 - if (namespace === undefined) {
249 - namespace = null;
250 - }
251 -
252 - const attribute = exports.getAttributeByNameNS(element, namespace, localName);
253 - if (attribute === null) {
254 - const newAttribute = element._ownerDocument._createAttribute({
255 - namespace,
256 - namespacePrefix: prefix,
257 - localName,
258 - value
259 - });
260 - exports.appendAttribute(element, newAttribute);
261 -
262 - return;
263 - }
264 -
265 - exports.changeAttribute(element, attribute, value);
266 -};
267 -
268 -// https://dom.spec.whatwg.org/#set-an-existing-attribute-value
269 -exports.setAnExistingAttributeValue = (attribute, value) => {
270 - const element = attribute._element;
271 - if (element === null) {
272 - attribute._value = value;
273 - } else {
274 - exports.changeAttribute(element, attribute, value);
275 - }
276 -};
277 -
278 -exports.removeAttributeByName = function (element, name) {
279 - // https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-name
280 -
281 - const attr = exports.getAttributeByName(element, name);
282 -
283 - if (attr !== null) {
284 - exports.removeAttribute(element, attr);
285 - }
286 -
287 - return attr;
288 -};
289 -
290 -exports.removeAttributeByNameNS = function (element, namespace, localName) {
291 - // https://dom.spec.whatwg.org/#concept-element-attributes-remove-by-namespace
292 -
293 - const attr = exports.getAttributeByNameNS(element, namespace, localName);
294 -
295 - if (attr !== null) {
296 - exports.removeAttribute(element, attr);
297 - }
298 -
299 - return attr;
300 -};
301 -
302 -exports.attributeNames = function (element) {
303 - // Needed by https://dom.spec.whatwg.org/#dom-element-getattributenames
304 -
305 - return element._attributeList.map(a => a._qualifiedName);
306 -};
307 -
308 -exports.hasAttributes = function (element) {
309 - // Needed by https://dom.spec.whatwg.org/#dom-element-hasattributes
310 -
311 - return element._attributeList.length > 0;
312 -};
1 -"use strict";
2 -
3 -const { setAnExistingAttributeValue } = require("../attributes.js");
4 -const NodeImpl = require("../nodes/Node-impl.js").implementation;
5 -const { ATTRIBUTE_NODE } = require("../node-type.js");
6 -
7 -exports.implementation = class AttrImpl extends NodeImpl {
8 - constructor(globalObject, args, privateData) {
9 - super(globalObject, args, privateData);
10 -
11 - this._namespace = privateData.namespace !== undefined ? privateData.namespace : null;
12 - this._namespacePrefix = privateData.namespacePrefix !== undefined ? privateData.namespacePrefix : null;
13 - this._localName = privateData.localName;
14 - this._value = privateData.value !== undefined ? privateData.value : "";
15 - this._element = privateData.element !== undefined ? privateData.element : null;
16 -
17 - this.nodeType = ATTRIBUTE_NODE;
18 - this.specified = true;
19 - }
20 -
21 - get namespaceURI() {
22 - return this._namespace;
23 - }
24 -
25 - get prefix() {
26 - return this._namespacePrefix;
27 - }
28 -
29 - get localName() {
30 - return this._localName;
31 - }
32 -
33 - get name() {
34 - return this._qualifiedName;
35 - }
36 -
37 - get nodeName() {
38 - return this._qualifiedName;
39 - }
40 -
41 - get value() {
42 - return this._value;
43 - }
44 - set value(value) {
45 - setAnExistingAttributeValue(this, value);
46 - }
47 -
48 - get ownerElement() {
49 - return this._element;
50 - }
51 -
52 - get _qualifiedName() {
53 - // https://dom.spec.whatwg.org/#concept-attribute-qualified-name
54 - if (this._namespacePrefix === null) {
55 - return this._localName;
56 - }
57 -
58 - return this._namespacePrefix + ":" + this._localName;
59 - }
60 -};
1 -"use strict";
2 -
3 -const DOMException = require("domexception/webidl2js-wrapper");
4 -const idlUtils = require("../generated/utils.js");
5 -const attributes = require("../attributes.js");
6 -const { HTML_NS } = require("../helpers/namespaces");
7 -
8 -exports.implementation = class NamedNodeMapImpl {
9 - constructor(globalObject, args, privateData) {
10 - this._element = privateData.element;
11 -
12 - this._globalObject = globalObject;
13 - }
14 - get _attributeList() {
15 - return this._element._attributeList;
16 - }
17 -
18 - get [idlUtils.supportedPropertyIndices]() {
19 - return this._attributeList.keys();
20 - }
21 - get length() {
22 - return this._attributeList.length;
23 - }
24 - item(index) {
25 - if (index >= this._attributeList.length) {
26 - return null;
27 - }
28 - return this._attributeList[index];
29 - }
30 -
31 - get [idlUtils.supportedPropertyNames]() {
32 - const names = new Set(this._attributeList.map(a => a._qualifiedName));
33 - const el = this._element;
34 - if (el._namespaceURI === HTML_NS && el._ownerDocument._parsingMode === "html") {
35 - for (const name of names) {
36 - const lowercaseName = name.toLowerCase();
37 - if (lowercaseName !== name) {
38 - names.delete(name);
39 - }
40 - }
41 - }
42 - return names;
43 - }
44 - getNamedItem(qualifiedName) {
45 - return attributes.getAttributeByName(this._element, qualifiedName);
46 - }
47 - getNamedItemNS(namespace, localName) {
48 - return attributes.getAttributeByNameNS(this._element, namespace, localName);
49 - }
50 - setNamedItem(attr) {
51 - // eslint-disable-next-line no-restricted-properties
52 - return attributes.setAttribute(this._element, attr);
53 - }
54 - setNamedItemNS(attr) {
55 - // eslint-disable-next-line no-restricted-properties
56 - return attributes.setAttribute(this._element, attr);
57 - }
58 - removeNamedItem(qualifiedName) {
59 - const attr = attributes.removeAttributeByName(this._element, qualifiedName);
60 - if (attr === null) {
61 - throw DOMException.create(this._globalObject, [
62 - "Tried to remove an attribute that was not present",
63 - "NotFoundError"
64 - ]);
65 - }
66 - return attr;
67 - }
68 - removeNamedItemNS(namespace, localName) {
69 - const attr = attributes.removeAttributeByNameNS(this._element, namespace, localName);
70 - if (attr === null) {
71 - throw DOMException.create(this._globalObject, [
72 - "Tried to remove an attribute that was not present",
73 - "NotFoundError"
74 - ]);
75 - }
76 - return attr;
77 - }
78 -};
1 -"use strict";
2 -
3 -const ValidityState = require("../generated/ValidityState");
4 -const { isDisabled } = require("../helpers/form-controls");
5 -const { closest } = require("../helpers/traversal");
6 -const { fireAnEvent } = require("../helpers/events");
7 -
8 -exports.implementation = class DefaultConstraintValidationImpl {
9 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-willvalidate
10 - get willValidate() {
11 - return this._isCandidateForConstraintValidation();
12 - }
13 -
14 - get validity() {
15 - if (!this._validity) {
16 - this._validity = ValidityState.createImpl(this._globalObject, [], {
17 - element: this
18 - });
19 - }
20 - return this._validity;
21 - }
22 -
23 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-checkvalidity
24 - checkValidity() {
25 - if (!this._isCandidateForConstraintValidation()) {
26 - return true;
27 - }
28 - if (this._satisfiesConstraints()) {
29 - return true;
30 - }
31 - fireAnEvent("invalid", this, undefined, { cancelable: true });
32 - return false;
33 - }
34 -
35 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-setcustomvalidity
36 - setCustomValidity(message) {
37 - this._customValidityErrorMessage = message;
38 - }
39 -
40 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
41 - // Since jsdom has no user interaction, it's the same as #checkValidity
42 - reportValidity() {
43 - return this.checkValidity();
44 - }
45 -
46 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-validationmessage
47 - get validationMessage() {
48 - const { validity } = this;
49 - if (!this._isCandidateForConstraintValidation() || this._satisfiesConstraints()) {
50 - return "";
51 - }
52 - const isSufferingFromCustomError = validity.customError;
53 - if (isSufferingFromCustomError) {
54 - return this._customValidityErrorMessage;
55 - }
56 - return "Constraints not satisfied";
57 - }
58 -
59 - _isCandidateForConstraintValidation() {
60 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-disabled
61 - return !isDisabled(this) &&
62 - // If an element has a datalist element ancestor,
63 - // it is barred from constraint validation.
64 - closest(this, "datalist") === null &&
65 - !this._barredFromConstraintValidationSpecialization();
66 - }
67 -
68 - _isBarredFromConstraintValidation() {
69 - return !this._isCandidateForConstraintValidation();
70 - }
71 -
72 - _satisfiesConstraints() {
73 - return this.validity.valid;
74 - }
75 -};
1 -"use strict";
2 -
3 -exports.implementation = class ValidityStateImpl {
4 - constructor(globalObject, args, privateData) {
5 - const { element, state = {} } = privateData;
6 -
7 - this._element = element;
8 - this._state = state;
9 - }
10 -
11 - get badInput() {
12 - return this._failsConstraint("badInput");
13 - }
14 -
15 - // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#suffering-from-a-custom-error
16 - get customError() {
17 - return this._element._customValidityErrorMessage !== "";
18 - }
19 -
20 - get patternMismatch() {
21 - return this._failsConstraint("patternMismatch");
22 - }
23 -
24 - get rangeOverflow() {
25 - return this._failsConstraint("rangeOverflow");
26 - }
27 -
28 - get rangeUnderflow() {
29 - return this._failsConstraint("rangeUnderflow");
30 - }
31 -
32 - get stepMismatch() {
33 - return this._failsConstraint("stepMismatch");
34 - }
35 -
36 - get tooLong() {
37 - return this._failsConstraint("tooLong");
38 - }
39 -
40 - get tooShort() {
41 - return this._failsConstraint("tooShort");
42 - }
43 -
44 - get typeMismatch() {
45 - return this._failsConstraint("typeMismatch");
46 - }
47 -
48 - get valueMissing() {
49 - return this._failsConstraint("valueMissing");
50 - }
51 -
52 - _failsConstraint(method) {
53 - const validationMethod = this._state[method];
54 - if (validationMethod) {
55 - return validationMethod();
56 - }
57 -
58 - return false;
59 - }
60 -
61 - get valid() {
62 - return !(this.badInput || this.valueMissing || this.customError ||
63 - this.patternMismatch || this.rangeOverflow || this.rangeUnderflow ||
64 - this.stepMismatch || this.tooLong || this.tooShort || this.typeMismatch);
65 - }
66 -};
1 -"use strict";
2 -
3 -const idlUtils = require("../generated/utils.js");
4 -
5 -exports.implementation = class StyleSheetList {
6 - constructor() {
7 - this._list = [];
8 - }
9 -
10 - get length() {
11 - return this._list.length;
12 - }
13 -
14 - item(index) {
15 - const result = this._list[index];
16 - return result !== undefined ? result : null;
17 - }
18 -
19 - get [idlUtils.supportedPropertyIndices]() {
20 - return this._list.keys();
21 - }
22 -
23 - _add(sheet) {
24 - const { _list } = this;
25 - if (!_list.includes(sheet)) {
26 - _list.push(sheet);
27 - }
28 - }
29 -
30 - _remove(sheet) {
31 - const { _list } = this;
32 -
33 - const index = _list.indexOf(sheet);
34 - if (index >= 0) {
35 - _list.splice(index, 1);
36 - }
37 - }
38 -};
1 -"use strict";
2 -
3 -const webIDLConversions = require("webidl-conversions");
4 -const DOMException = require("domexception/webidl2js-wrapper");
5 -
6 -const NODE_TYPE = require("../node-type");
7 -
8 -const { HTML_NS } = require("../helpers/namespaces");
9 -const { getHTMLElementInterface } = require("../helpers/create-element");
10 -const { shadowIncludingInclusiveDescendantsIterator } = require("../helpers/shadow-dom");
11 -const { isValidCustomElementName, tryUpgradeElement, enqueueCEUpgradeReaction } = require("../helpers/custom-elements");
12 -
13 -const idlUtils = require("../generated/utils");
14 -const HTMLUnknownElement = require("../generated/HTMLUnknownElement");
15 -
16 -const LIFECYCLE_CALLBACKS = [
17 - "connectedCallback",
18 - "disconnectedCallback",
19 - "adoptedCallback",
20 - "attributeChangedCallback"
21 -];
22 -
23 -function convertToSequenceDOMString(obj) {
24 - if (!obj || !obj[Symbol.iterator]) {
25 - throw new TypeError("Invalid Sequence");
26 - }
27 -
28 - return Array.from(obj).map(webIDLConversions.DOMString);
29 -}
30 -
31 -// Returns true is the passed value is a valid constructor.
32 -// Borrowed from: https://stackoverflow.com/a/39336206/3832710
33 -function isConstructor(value) {
34 - if (typeof value !== "function") {
35 - return false;
36 - }
37 -
38 - try {
39 - const P = new Proxy(value, {
40 - construct() {
41 - return {};
42 - }
43 - });
44 -
45 - // eslint-disable-next-line no-new
46 - new P();
47 -
48 - return true;
49 - } catch {
50 - return false;
51 - }
52 -}
53 -
54 -// https://html.spec.whatwg.org/#customelementregistry
55 -class CustomElementRegistryImpl {
56 - constructor(globalObject) {
57 - this._customElementDefinitions = [];
58 - this._elementDefinitionIsRunning = false;
59 - this._whenDefinedPromiseMap = Object.create(null);
60 -
61 - this._globalObject = globalObject;
62 - }
63 -
64 - // https://html.spec.whatwg.org/#dom-customelementregistry-define
65 - define(name, ctor, options) {
66 - const { _globalObject } = this;
67 -
68 - if (!isConstructor(ctor)) {
69 - throw new TypeError("Constructor argument is not a constructor.");
70 - }
71 -
72 - if (!isValidCustomElementName(name)) {
73 - throw DOMException.create(_globalObject, ["Name argument is not a valid custom element name.", "SyntaxError"]);
74 - }
75 -
76 - const nameAlreadyRegistered = this._customElementDefinitions.some(entry => entry.name === name);
77 - if (nameAlreadyRegistered) {
78 - throw DOMException.create(_globalObject, [
79 - "This name has already been registered in the registry.",
80 - "NotSupportedError"
81 - ]);
82 - }
83 -
84 - const ctorAlreadyRegistered = this._customElementDefinitions.some(entry => entry.ctor === ctor);
85 - if (ctorAlreadyRegistered) {
86 - throw DOMException.create(_globalObject, [
87 - "This constructor has already been registered in the registry.",
88 - "NotSupportedError"
89 - ]);
90 - }
91 -
92 - let localName = name;
93 -
94 - let extendsOption = null;
95 - if (options !== undefined && options.extends) {
96 - extendsOption = options.extends;
97 - }
98 -
99 - if (extendsOption !== null) {
100 - if (isValidCustomElementName(extendsOption)) {
101 - throw DOMException.create(_globalObject, [
102 - "Option extends value can't be a valid custom element name.",
103 - "NotSupportedError"
104 - ]);
105 - }
106 -
107 - const extendsInterface = getHTMLElementInterface(extendsOption);
108 - if (extendsInterface === HTMLUnknownElement) {
109 - throw DOMException.create(_globalObject, [
110 - `${extendsOption} is an HTMLUnknownElement.`,
111 - "NotSupportedError"
112 - ]);
113 - }
114 -
115 - localName = extendsOption;
116 - }
117 -
118 - if (this._elementDefinitionIsRunning) {
119 - throw DOMException.create(_globalObject, [
120 - "Invalid nested custom element definition.",
121 - "NotSupportedError"
122 - ]);
123 - }
124 -
125 - this._elementDefinitionIsRunning = true;
126 -
127 - let disableShadow = false;
128 - let observedAttributes = [];
129 - const lifecycleCallbacks = {
130 - connectedCallback: null,
131 - disconnectedCallback: null,
132 - adoptedCallback: null,
133 - attributeChangedCallback: null
134 - };
135 -
136 - let caughtError;
137 - try {
138 - const { prototype } = ctor;
139 -
140 - if (typeof prototype !== "object") {
141 - throw new TypeError("Invalid constructor prototype.");
142 - }
143 -
144 - for (const callbackName of LIFECYCLE_CALLBACKS) {
145 - const callbackValue = prototype[callbackName];
146 -
147 - if (callbackValue !== undefined) {
148 - lifecycleCallbacks[callbackName] = webIDLConversions.Function(callbackValue);
149 - }
150 - }
151 -
152 - if (lifecycleCallbacks.attributeChangedCallback !== null) {
153 - const observedAttributesIterable = ctor.observedAttributes;
154 -
155 - if (observedAttributesIterable !== undefined) {
156 - observedAttributes = convertToSequenceDOMString(observedAttributesIterable);
157 - }
158 - }
159 -
160 - let disabledFeatures = [];
161 - const disabledFeaturesIterable = ctor.disabledFeatures;
162 - if (disabledFeaturesIterable) {
163 - disabledFeatures = convertToSequenceDOMString(disabledFeaturesIterable);
164 - }
165 -
166 - disableShadow = disabledFeatures.includes("shadow");
167 - } catch (err) {
168 - caughtError = err;
169 - } finally {
170 - this._elementDefinitionIsRunning = false;
171 - }
172 -
173 - if (caughtError !== undefined) {
174 - throw caughtError;
175 - }
176 -
177 - const definition = {
178 - name,
179 - localName,
180 - ctor,
181 - observedAttributes,
182 - lifecycleCallbacks,
183 - disableShadow,
184 - constructionStack: []
185 - };
186 -
187 - this._customElementDefinitions.push(definition);
188 -
189 - const document = idlUtils.implForWrapper(this._globalObject._document);
190 -
191 - const upgradeCandidates = [];
192 - for (const candidate of shadowIncludingInclusiveDescendantsIterator(document)) {
193 - if (
194 - (candidate._namespaceURI === HTML_NS && candidate._localName === localName) &&
195 - (extendsOption === null || candidate._isValue === name)
196 - ) {
197 - upgradeCandidates.push(candidate);
198 - }
199 - }
200 -
201 - for (const upgradeCandidate of upgradeCandidates) {
202 - enqueueCEUpgradeReaction(upgradeCandidate, definition);
203 - }
204 -
205 - if (this._whenDefinedPromiseMap[name] !== undefined) {
206 - this._whenDefinedPromiseMap[name].resolve(undefined);
207 - delete this._whenDefinedPromiseMap[name];
208 - }
209 - }
210 -
211 - // https://html.spec.whatwg.org/#dom-customelementregistry-get
212 - get(name) {
213 - const definition = this._customElementDefinitions.find(entry => entry.name === name);
214 - return definition && definition.ctor;
215 - }
216 -
217 - // https://html.spec.whatwg.org/#dom-customelementregistry-whendefined
218 - whenDefined(name) {
219 - if (!isValidCustomElementName(name)) {
220 - return Promise.reject(DOMException.create(
221 - this._globalObject,
222 - ["Name argument is not a valid custom element name.", "SyntaxError"]
223 - ));
224 - }
225 -
226 - const alreadyRegistered = this._customElementDefinitions.some(entry => entry.name === name);
227 - if (alreadyRegistered) {
228 - return Promise.resolve();
229 - }
230 -
231 - if (this._whenDefinedPromiseMap[name] === undefined) {
232 - let resolve;
233 - const promise = new Promise(r => {
234 - resolve = r;
235 - });
236 -
237 - // Store the pending Promise along with the extracted resolve callback to actually resolve the returned Promise,
238 - // once the custom element is registered.
239 - this._whenDefinedPromiseMap[name] = {
240 - promise,
241 - resolve
242 - };
243 - }
244 -
245 - return this._whenDefinedPromiseMap[name].promise;
246 - }
247 -
248 - // https://html.spec.whatwg.org/#dom-customelementregistry-upgrade
249 - upgrade(root) {
250 - for (const candidate of shadowIncludingInclusiveDescendantsIterator(root)) {
251 - if (candidate.nodeType === NODE_TYPE.ELEMENT_NODE) {
252 - tryUpgradeElement(candidate);
253 - }
254 - }
255 - }
256 -}
257 -
258 -module.exports = {
259 - implementation: CustomElementRegistryImpl
260 -};
1 -"use strict";
2 -const XMLDocument = require("../living/generated/XMLDocument.js");
3 -const Document = require("../living/generated/Document.js");
4 -const { wrapperForImpl } = require("./generated/utils.js");
5 -
6 -exports.createImpl = (globalObject, options, { alwaysUseDocumentClass = false } = {}) => {
7 - if (options.parsingMode === "xml" && !alwaysUseDocumentClass) {
8 - return XMLDocument.createImpl(globalObject, [], { options });
9 - }
10 - return Document.createImpl(globalObject, [], { options });
11 -};
12 -
13 -exports.createWrapper = (...args) => {
14 - return wrapperForImpl(exports.createImpl(...args));
15 -};
1 -"use strict";
2 -
3 -const { parseIntoDocument } = require("../../browser/parser");
4 -
5 -const Document = require("../generated/Document");
6 -
7 -exports.implementation = class DOMParserImpl {
8 - constructor(globalObject) {
9 - this._globalObject = globalObject;
10 - }
11 -
12 - parseFromString(string, contentType) {
13 - switch (String(contentType)) {
14 - case "text/html": {
15 - return this.createScriptingDisabledDocument("html", contentType, string);
16 - }
17 -
18 - case "text/xml":
19 - case "application/xml":
20 - case "application/xhtml+xml":
21 - case "image/svg+xml": {
22 - try {
23 - return this.createScriptingDisabledDocument("xml", contentType, string);
24 - } catch (error) {
25 - const document = this.createScriptingDisabledDocument("xml", contentType);
26 - const element = document.createElementNS("http://www.mozilla.org/newlayout/xml/parsererror.xml", "parsererror");
27 -
28 - element.textContent = error.message;
29 -
30 - document.appendChild(element);
31 - return document;
32 - }
33 - }
34 -
35 - default:
36 - throw new TypeError("Invalid contentType");
37 - }
38 - }
39 -
40 - createScriptingDisabledDocument(parsingMode, contentType, string) {
41 - const document = Document.createImpl(this._globalObject, [], {
42 - options: {
43 - parsingMode,
44 - encoding: "UTF-8",
45 - contentType,
46 - readyState: "complete",
47 - scriptingDisabled: true
48 - // TODO: somehow set URL to active document's URL
49 - }
50 - });
51 -
52 - if (string !== undefined) {
53 - parseIntoDocument(string, document);
54 - }
55 -
56 - return document;
57 - }
58 -};
1 -"use strict";
2 -const serialize = require("w3c-xmlserializer");
3 -const DOMException = require("domexception/webidl2js-wrapper");
4 -const utils = require("../generated/utils");
5 -
6 -exports.implementation = class XMLSerializerImpl {
7 - constructor(globalObject) {
8 - this._globalObject = globalObject;
9 - }
10 -
11 - serializeToString(root) {
12 - try {
13 - return serialize(utils.wrapperForImpl(root), { requireWellFormed: false });
14 - } catch (e) {
15 - throw DOMException.create(this._globalObject, [e.message, "InvalidStateError"]);
16 - }
17 - }
18 -};
1 -"use strict";
2 -const nodeTypes = require("../node-type");
3 -const { domSymbolTree } = require("../helpers/internal-constants");
4 -// Serialization only requires a subset of the tree adapter interface.
5 -
6 -// Tree traversing
7 -exports.getFirstChild = node => node.firstChild;
8 -
9 -exports.getChildNodes = node => node.childNodesForSerializing || domSymbolTree.childrenToArray(node);
10 -
11 -exports.getParentNode = node => node.parentNode;
12 -
13 -exports.getAttrList = element => {
14 - const attributeList = [...element._attributeList];
15 -
16 - if (element._isValue && attributeList.every(attr => attr.name !== "is")) {
17 - attributeList.unshift({
18 - name: "is",
19 - namespace: null,
20 - prefix: null,
21 - value: element._isValue
22 - });
23 - }
24 -
25 - return attributeList;
26 -};
27 -
28 -// Node data
29 -exports.getTagName = element => element._qualifiedName; // https://github.com/inikulin/parse5/issues/231
30 -
31 -exports.getNamespaceURI = element => element.namespaceURI;
32 -
33 -exports.getTextNodeContent = exports.getCommentNodeContent = node => node.data;
34 -
35 -exports.getDocumentTypeNodeName = node => node.name;
36 -
37 -exports.getDocumentTypeNodePublicId = node => node.publicId;
38 -
39 -exports.getDocumentTypeNodeSystemId = node => node.systemId;
40 -
41 -exports.getTemplateContent = templateElement => templateElement._templateContents;
42 -
43 -exports.getDocumentMode = document => document._mode;
44 -
45 -// Node types
46 -exports.isTextNode = node => node.nodeType === nodeTypes.TEXT_NODE;
47 -
48 -exports.isCommentNode = node => node.nodeType === nodeTypes.COMMENT_NODE;
49 -
50 -exports.isDocumentTypeNode = node => node.nodeType === nodeTypes.DOCUMENT_TYPE_NODE;
51 -
52 -exports.isElementNode = node => node.nodeType === nodeTypes.ELEMENT_NODE;
53 -
54 -// Source code location
55 -exports.setNodeSourceCodeLocation = (node, location) => {
56 - node.sourceCodeLocation = location;
57 -};
58 -
59 -exports.getNodeSourceCodeLocation = node => node.sourceCodeLocation;
1 -"use strict";
2 -
3 -const produceXMLSerialization = require("w3c-xmlserializer");
4 -const parse5 = require("parse5");
5 -const DOMException = require("domexception/webidl2js-wrapper");
6 -
7 -const utils = require("../generated/utils");
8 -const treeAdapter = require("./parse5-adapter-serialization");
9 -const NODE_TYPE = require("../node-type");
10 -const NAMESPACES = require("../helpers/namespaces");
11 -
12 -function htmlSerialization(node) {
13 - if (
14 - node.nodeType === NODE_TYPE.ELEMENT_NODE &&
15 - node.namespaceURI === NAMESPACES.HTML_NS &&
16 - node.tagName === "TEMPLATE"
17 - ) {
18 - node = node.content;
19 - }
20 -
21 - return parse5.serialize(node, { treeAdapter });
22 -}
23 -
24 -module.exports.fragmentSerialization = (node, { requireWellFormed, globalObject }) => {
25 - const contextDocument =
26 - node.nodeType === NODE_TYPE.DOCUMENT_NODE ? node : node._ownerDocument;
27 - if (contextDocument._parsingMode === "html") {
28 - return htmlSerialization(node);
29 - }
30 -
31 - const childNodes = node.childNodesForSerializing || node.childNodes;
32 -
33 - try {
34 - let serialized = "";
35 - for (let i = 0; i < childNodes.length; ++i) {
36 - serialized += produceXMLSerialization(
37 - utils.wrapperForImpl(childNodes[i] || childNodes.item(i)),
38 - { requireWellFormed }
39 - );
40 - }
41 - return serialized;
42 - } catch (e) {
43 - throw DOMException.create(globalObject, [e.message, "InvalidStateError"]);
44 - }
45 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const CloseEventInit = require("../generated/CloseEventInit");
6 -
7 -class CloseEventImpl extends EventImpl {}
8 -CloseEventImpl.defaultInit = CloseEventInit.convert(undefined);
9 -
10 -exports.implementation = CloseEventImpl;
1 -"use strict";
2 -
3 -const UIEventImpl = require("./UIEvent-impl").implementation;
4 -const CompositionEventInit = require("../generated/CompositionEventInit");
5 -
6 -class CompositionEventImpl extends UIEventImpl {
7 - initCompositionEvent(type, bubbles, cancelable, view, data) {
8 - if (this._dispatchFlag) {
9 - return;
10 - }
11 -
12 - this.initUIEvent(type, bubbles, cancelable, view, 0);
13 - this.data = data;
14 - }
15 -}
16 -CompositionEventImpl.defaultInit = CompositionEventInit.convert(undefined);
17 -
18 -module.exports = {
19 - implementation: CompositionEventImpl
20 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const CustomEventInit = require("../generated/CustomEventInit");
6 -
7 -class CustomEventImpl extends EventImpl {
8 - initCustomEvent(type, bubbles, cancelable, detail) {
9 - if (this._dispatchFlag) {
10 - return;
11 - }
12 -
13 - this.initEvent(type, bubbles, cancelable);
14 - this.detail = detail;
15 - }
16 -}
17 -CustomEventImpl.defaultInit = CustomEventInit.convert(undefined);
18 -
19 -module.exports = {
20 - implementation: CustomEventImpl
21 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const ErrorEventInit = require("../generated/ErrorEventInit");
6 -
7 -class ErrorEventImpl extends EventImpl {
8 -
9 -}
10 -ErrorEventImpl.defaultInit = ErrorEventInit.convert(undefined);
11 -
12 -module.exports = {
13 - implementation: ErrorEventImpl
14 -};
1 -"use strict";
2 -
3 -const idlUtils = require("../generated/utils");
4 -const EventInit = require("../generated/EventInit");
5 -
6 -class EventImpl {
7 - constructor(globalObject, args, privateData) {
8 - const [type, eventInitDict = this.constructor.defaultInit] = args;
9 -
10 - this.type = type;
11 -
12 - this.bubbles = false;
13 - this.cancelable = false;
14 - for (const key in eventInitDict) {
15 - if (key in this.constructor.defaultInit) {
16 - this[key] = eventInitDict[key];
17 - }
18 - }
19 - for (const key in this.constructor.defaultInit) {
20 - if (!(key in this)) {
21 - this[key] = this.constructor.defaultInit[key];
22 - }
23 - }
24 -
25 - this.target = null;
26 - this.currentTarget = null;
27 - this.eventPhase = 0;
28 -
29 - this._globalObject = globalObject;
30 - this._initializedFlag = true;
31 - this._stopPropagationFlag = false;
32 - this._stopImmediatePropagationFlag = false;
33 - this._canceledFlag = false;
34 - this._inPassiveListenerFlag = false;
35 - this._dispatchFlag = false;
36 - this._path = [];
37 -
38 - this.isTrusted = privateData.isTrusted || false;
39 - this.timeStamp = Date.now();
40 - }
41 -
42 - // https://dom.spec.whatwg.org/#set-the-canceled-flag
43 - _setTheCanceledFlag() {
44 - if (this.cancelable && !this._inPassiveListenerFlag) {
45 - this._canceledFlag = true;
46 - }
47 - }
48 -
49 - get srcElement() {
50 - return this.target;
51 - }
52 -
53 - get returnValue() {
54 - return !this._canceledFlag;
55 - }
56 -
57 - set returnValue(v) {
58 - if (v === false) {
59 - this._setTheCanceledFlag();
60 - }
61 - }
62 -
63 - get defaultPrevented() {
64 - return this._canceledFlag;
65 - }
66 -
67 - stopPropagation() {
68 - this._stopPropagationFlag = true;
69 - }
70 -
71 - get cancelBubble() {
72 - return this._stopPropagationFlag;
73 - }
74 -
75 - set cancelBubble(v) {
76 - if (v) {
77 - this._stopPropagationFlag = true;
78 - }
79 - }
80 -
81 - stopImmediatePropagation() {
82 - this._stopPropagationFlag = true;
83 - this._stopImmediatePropagationFlag = true;
84 - }
85 -
86 - preventDefault() {
87 - this._setTheCanceledFlag();
88 - }
89 -
90 - // https://dom.spec.whatwg.org/#dom-event-composedpath
91 - // Current implementation is based of https://whatpr.org/dom/699.html#dom-event-composedpath
92 - // due to a bug in composed path implementation https://github.com/whatwg/dom/issues/684
93 - composedPath() {
94 - const composedPath = [];
95 -
96 - const { currentTarget, _path: path } = this;
97 -
98 - if (path.length === 0) {
99 - return composedPath;
100 - }
101 -
102 - composedPath.push(currentTarget);
103 -
104 - let currentTargetIndex = 0;
105 - let currentTargetHiddenSubtreeLevel = 0;
106 -
107 - for (let index = path.length - 1; index >= 0; index--) {
108 - const { item, rootOfClosedTree, slotInClosedTree } = path[index];
109 -
110 - if (rootOfClosedTree) {
111 - currentTargetHiddenSubtreeLevel++;
112 - }
113 -
114 - if (item === idlUtils.implForWrapper(currentTarget)) {
115 - currentTargetIndex = index;
116 - break;
117 - }
118 -
119 - if (slotInClosedTree) {
120 - currentTargetHiddenSubtreeLevel--;
121 - }
122 - }
123 -
124 - let currentHiddenLevel = currentTargetHiddenSubtreeLevel;
125 - let maxHiddenLevel = currentTargetHiddenSubtreeLevel;
126 -
127 - for (let i = currentTargetIndex - 1; i >= 0; i--) {
128 - const { item, rootOfClosedTree, slotInClosedTree } = path[i];
129 -
130 - if (rootOfClosedTree) {
131 - currentHiddenLevel++;
132 - }
133 -
134 - if (currentHiddenLevel <= maxHiddenLevel) {
135 - composedPath.unshift(idlUtils.wrapperForImpl(item));
136 - }
137 -
138 - if (slotInClosedTree) {
139 - currentHiddenLevel--;
140 - if (currentHiddenLevel < maxHiddenLevel) {
141 - maxHiddenLevel = currentHiddenLevel;
142 - }
143 - }
144 - }
145 -
146 - currentHiddenLevel = currentTargetHiddenSubtreeLevel;
147 - maxHiddenLevel = currentTargetHiddenSubtreeLevel;
148 -
149 - for (let index = currentTargetIndex + 1; index < path.length; index++) {
150 - const { item, rootOfClosedTree, slotInClosedTree } = path[index];
151 -
152 - if (slotInClosedTree) {
153 - currentHiddenLevel++;
154 - }
155 -
156 - if (currentHiddenLevel <= maxHiddenLevel) {
157 - composedPath.push(idlUtils.wrapperForImpl(item));
158 - }
159 -
160 - if (rootOfClosedTree) {
161 - currentHiddenLevel--;
162 - if (currentHiddenLevel < maxHiddenLevel) {
163 - maxHiddenLevel = currentHiddenLevel;
164 - }
165 - }
166 - }
167 -
168 - return composedPath;
169 - }
170 -
171 - _initialize(type, bubbles, cancelable) {
172 - this.type = type;
173 - this._initializedFlag = true;
174 -
175 - this._stopPropagationFlag = false;
176 - this._stopImmediatePropagationFlag = false;
177 - this._canceledFlag = false;
178 -
179 - this.isTrusted = false;
180 - this.target = null;
181 - this.bubbles = bubbles;
182 - this.cancelable = cancelable;
183 - }
184 -
185 - initEvent(type, bubbles, cancelable) {
186 - if (this._dispatchFlag) {
187 - return;
188 - }
189 -
190 - this._initialize(type, bubbles, cancelable);
191 - }
192 -}
193 -EventImpl.defaultInit = EventInit.convert(undefined);
194 -
195 -module.exports = {
196 - implementation: EventImpl
197 -};
1 -"use strict";
2 -
3 -// This mixin doesn't have an IDL equivalent, but since MouseEvent and KeyboardEvent implement getModifierState() the
4 -// same way, its implementation is shared here.
5 -
6 -class EventModifierMixinImpl {
7 - // Event's constructor assumes all options correspond to IDL attributes with the same names, and sets them on `this`.
8 - // That is not the case for these modifier boolean options, but since the options are set on `this` anyway we'll
9 - // access them that way. The spec doesn't say much about the case where keyArg is not one of the valid ones
10 - // (https://w3c.github.io/uievents-key/#keys-modifier), but at least Chrome returns false for invalid modifiers. Since
11 - // these invalid modifiers will be undefined on `this` (thus `false` after casting it to boolean), we don't need to do
12 - // extra checking for validity.
13 - getModifierState(keyArg) {
14 - return Boolean(this[`modifier${keyArg}`]);
15 - }
16 -}
17 -
18 -exports.implementation = EventModifierMixinImpl;
1 -"use strict";
2 -const UIEventImpl = require("./UIEvent-impl").implementation;
3 -
4 -const FocusEventInit = require("../generated/FocusEventInit");
5 -
6 -class FocusEventImpl extends UIEventImpl {}
7 -FocusEventImpl.defaultInit = FocusEventInit.convert(undefined);
8 -
9 -exports.implementation = FocusEventImpl;
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const HashChangeEventInit = require("../generated/HashChangeEventInit");
6 -
7 -class HashChangeEventImpl extends EventImpl {
8 -
9 -}
10 -HashChangeEventImpl.defaultInit = HashChangeEventInit.convert(undefined);
11 -
12 -module.exports = {
13 - implementation: HashChangeEventImpl
14 -};
1 -"use strict";
2 -
3 -const UIEventImpl = require("./UIEvent-impl").implementation;
4 -
5 -const InputEventInit = require("../generated/InputEventInit");
6 -
7 -// https://w3c.github.io/uievents/#interface-inputevent
8 -class InputEventImpl extends UIEventImpl {
9 - initInputEvent(type, bubbles, cancelable, data, isComposing) {
10 - if (this._dispatchFlag) {
11 - return;
12 - }
13 -
14 - this.initUIEvent(type, bubbles, cancelable);
15 - this.data = data;
16 - this.isComposing = isComposing;
17 - }
18 -}
19 -InputEventImpl.defaultInit = InputEventInit.convert(undefined);
20 -
21 -module.exports = {
22 - implementation: InputEventImpl
23 -};
1 -"use strict";
2 -
3 -const { mixin } = require("../../utils");
4 -const EventModifierMixinImpl = require("./EventModifierMixin-impl").implementation;
5 -const UIEventImpl = require("./UIEvent-impl").implementation;
6 -
7 -const KeyboardEventInit = require("../generated/KeyboardEventInit");
8 -
9 -class KeyboardEventImpl extends UIEventImpl {
10 - initKeyboardEvent(type, bubbles, cancelable, view, key, location, ctrlKey, altKey, shiftKey, metaKey) {
11 - if (this._dispatchFlag) {
12 - return;
13 - }
14 -
15 - this.initUIEvent(type, bubbles, cancelable, view, 0);
16 - this.key = key;
17 - this.location = location;
18 - this.ctrlKey = ctrlKey;
19 - this.altKey = altKey;
20 - this.shiftKey = shiftKey;
21 - this.metaKey = metaKey;
22 - }
23 -}
24 -mixin(KeyboardEventImpl.prototype, EventModifierMixinImpl.prototype);
25 -KeyboardEventImpl.defaultInit = KeyboardEventInit.convert(undefined);
26 -
27 -module.exports = {
28 - implementation: KeyboardEventImpl
29 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const MessageEventInit = require("../generated/MessageEventInit");
6 -
7 -class MessageEventImpl extends EventImpl {
8 - initMessageEvent(type, bubbles, cancelable, data, origin, lastEventId, source, ports) {
9 - if (this._dispatchFlag) {
10 - return;
11 - }
12 -
13 - this.initEvent(type, bubbles, cancelable);
14 - this.data = data;
15 - this.origin = origin;
16 - this.lastEventId = lastEventId;
17 - this.source = source;
18 - this.ports = ports;
19 - }
20 -}
21 -MessageEventImpl.defaultInit = MessageEventInit.convert(undefined);
22 -
23 -module.exports = {
24 - implementation: MessageEventImpl
25 -};
1 -"use strict";
2 -
3 -const { mixin } = require("../../utils");
4 -const EventModifierMixinImpl = require("./EventModifierMixin-impl").implementation;
5 -const UIEventImpl = require("./UIEvent-impl").implementation;
6 -
7 -const MouseEventInit = require("../generated/MouseEventInit");
8 -
9 -class MouseEventImpl extends UIEventImpl {
10 - initMouseEvent(
11 - type, bubbles, cancelable, view, detail, screenX, screenY, clientX, clientY,
12 - ctrlKey, altKey, shiftKey, metaKey, button, relatedTarget
13 - ) {
14 - if (this._dispatchFlag) {
15 - return;
16 - }
17 -
18 - this.initUIEvent(type, bubbles, cancelable, view, detail);
19 - this.screenX = screenX;
20 - this.screenY = screenY;
21 - this.clientX = clientX;
22 - this.clientY = clientY;
23 - this.ctrlKey = ctrlKey;
24 - this.altKey = altKey;
25 - this.shiftKey = shiftKey;
26 - this.metaKey = metaKey;
27 - this.button = button;
28 - this.relatedTarget = relatedTarget;
29 - }
30 -}
31 -mixin(MouseEventImpl.prototype, EventModifierMixinImpl.prototype);
32 -MouseEventImpl.defaultInit = MouseEventInit.convert(undefined);
33 -
34 -module.exports = {
35 - implementation: MouseEventImpl
36 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const PageTransitionEventInit = require("../generated/PageTransitionEventInit");
6 -
7 -// https://html.spec.whatwg.org/multipage/browsing-the-web.html#pagetransitionevent
8 -class PageTransitionEventImpl extends EventImpl {
9 - initPageTransitionEvent(type, bubbles, cancelable, persisted) {
10 - if (this._dispatchFlag) {
11 - return;
12 - }
13 -
14 - this.initEvent(type, bubbles, cancelable);
15 - this.persisted = persisted;
16 - }
17 -}
18 -PageTransitionEventImpl.defaultInit = PageTransitionEventInit.convert(undefined);
19 -
20 -exports.implementation = PageTransitionEventImpl;
1 -"use strict";
2 -const EventImpl = require("./Event-impl.js").implementation;
3 -
4 -const PopStateEventInit = require("../generated/PopStateEventInit");
5 -
6 -class PopStateEventImpl extends EventImpl {}
7 -PopStateEventImpl.defaultInit = PopStateEventInit.convert(undefined);
8 -
9 -exports.implementation = PopStateEventImpl;
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const ProgressEventInit = require("../generated/ProgressEventInit");
6 -
7 -class ProgressEventImpl extends EventImpl {
8 -
9 -}
10 -ProgressEventImpl.defaultInit = ProgressEventInit.convert(undefined);
11 -
12 -module.exports = {
13 - implementation: ProgressEventImpl
14 -};
1 -"use strict";
2 -
3 -const EventImpl = require("./Event-impl").implementation;
4 -
5 -const StorageEventInit = require("../generated/StorageEventInit");
6 -
7 -// https://html.spec.whatwg.org/multipage/webstorage.html#the-storageevent-interface
8 -class StorageEventImpl extends EventImpl {
9 - initStorageEvent(type, bubbles, cancelable, key, oldValue, newValue, url, storageArea) {
10 - if (this._dispatchFlag) {
11 - return;
12 - }
13 -
14 - this.initEvent(type, bubbles, cancelable);
15 - this.key = key;
16 - this.oldValue = oldValue;
17 - this.newValue = newValue;
18 - this.url = url;
19 - this.storageArea = storageArea;
20 - }
21 -}
22 -StorageEventImpl.defaultInit = StorageEventInit.convert(undefined);
23 -
24 -module.exports = {
25 - implementation: StorageEventImpl
26 -};
1 -"use strict";
2 -
3 -const UIEventImpl = require("./UIEvent-impl").implementation;
4 -
5 -const TouchEventInit = require("../generated/TouchEventInit");
6 -
7 -class TouchEventImpl extends UIEventImpl {
8 -
9 -}
10 -TouchEventImpl.defaultInit = TouchEventInit.convert(undefined);
11 -
12 -module.exports = {
13 - implementation: TouchEventImpl
14 -};
1 -"use strict";
2 -
3 -const idlUtils = require("../generated/utils");
4 -const UIEventInit = require("../generated/UIEventInit");
5 -const EventImpl = require("./Event-impl").implementation;
6 -
7 -// Until webidl2js gains support for checking for Window, this would have to do.
8 -function isWindow(val) {
9 - if (typeof val !== "object") {
10 - return false;
11 - }
12 - const wrapper = idlUtils.wrapperForImpl(val);
13 - if (typeof wrapper === "object") {
14 - return wrapper === wrapper._globalProxy;
15 - }
16 -
17 - // `val` may be either impl or wrapper currently, because webidl2js currently unwraps Window objects (and their global
18 - // proxies) to their underlying EventTargetImpl during conversion, which is not what we want. But at the same time,
19 - // some internal usage call this constructor with the actual global proxy.
20 - return isWindow(idlUtils.implForWrapper(val));
21 -}
22 -
23 -class UIEventImpl extends EventImpl {
24 - constructor(globalObject, args, privateData) {
25 - const eventInitDict = args[1];
26 -
27 - // undefined check included so that we can omit the property in internal usage.
28 - if (eventInitDict && eventInitDict.view !== null && eventInitDict.view !== undefined) {
29 - if (!isWindow(eventInitDict.view)) {
30 - throw new TypeError(`Failed to construct '${new.target.name.replace(/Impl$/, "")}': member view is not of ` +
31 - "type Window.");
32 - }
33 - }
34 -
35 - super(globalObject, args, privateData);
36 - }
37 -
38 - initUIEvent(type, bubbles, cancelable, view, detail) {
39 - if (view !== null) {
40 - if (!isWindow(view)) {
41 - throw new TypeError(`Failed to execute 'initUIEvent' on '${this.constructor.name.replace(/Impl$/, "")}': ` +
42 - "parameter 4 is not of type 'Window'.");
43 - }
44 - }
45 -
46 - if (this._dispatchFlag) {
47 - return;
48 - }
49 -
50 - this.initEvent(type, bubbles, cancelable);
51 - this.view = view;
52 - this.detail = detail;
53 - }
54 -}
55 -UIEventImpl.defaultInit = UIEventInit.convert(undefined);
56 -
57 -module.exports = {
58 - implementation: UIEventImpl
59 -};
1 -"use strict";
2 -
3 -const MouseEventImpl = require("./MouseEvent-impl").implementation;
4 -
5 -const WheelEventInit = require("../generated/WheelEventInit");
6 -
7 -class WheelEventImpl extends MouseEventImpl {}
8 -WheelEventImpl.defaultInit = WheelEventInit.convert(undefined);
9 -
10 -module.exports = {
11 - implementation: WheelEventImpl
12 -};
1 -"use strict";
2 -
3 -const {
4 - isForbidden,
5 - isForbiddenResponse,
6 - isPrivilegedNoCORSRequest,
7 - isNoCORSSafelistedRequest,
8 - isCORSWhitelisted
9 -} = require("./header-types");
10 -const HeaderList = require("./header-list");
11 -
12 -function assertName(name) {
13 - if (!name.match(/^[!#$%&'*+\-.^`|~\w]+$/)) {
14 - throw new TypeError("name is invalid");
15 - }
16 -}
17 -
18 -function assertValue(value) {
19 - if (value.match(/[\0\r\n]/)) {
20 - throw new TypeError("value is invalid");
21 - }
22 -}
23 -
24 -class HeadersImpl {
25 - constructor(globalObject, args) {
26 - this.guard = "none";
27 - this.headersList = new HeaderList();
28 -
29 - if (args[0]) {
30 - this._fill(args[0]);
31 - }
32 - }
33 -
34 - _fill(init) {
35 - if (Array.isArray(init)) {
36 - for (const header of init) {
37 - if (header.length !== 2) {
38 - throw new TypeError("init is invalid");
39 - }
40 - this.append(header[0], header[1]);
41 - }
42 - } else {
43 - for (const key of Object.keys(init)) {
44 - this.append(key, init[key]);
45 - }
46 - }
47 - }
48 -
49 - has(name) {
50 - assertName(name);
51 - return this.headersList.contains(name);
52 - }
53 -
54 - get(name) {
55 - assertName(name);
56 - return this.headersList.get(name);
57 - }
58 -
59 - _removePrivilegedNoCORSHeaders() {
60 - this.headersList.delete("range");
61 - }
62 -
63 - append(name, value) {
64 - value = value.trim();
65 - assertName(name);
66 - assertValue(value);
67 -
68 - switch (this.guard) {
69 - case "immutable":
70 - throw new TypeError("Headers is immutable");
71 - case "request":
72 - if (isForbidden(name)) {
73 - return;
74 - }
75 - break;
76 - case "request-no-cors": {
77 - let temporaryValue = this.get(name);
78 - if (temporaryValue === null) {
79 - temporaryValue = value;
80 - } else {
81 - temporaryValue += `, ${value}`;
82 - }
83 - if (!isCORSWhitelisted(name, value)) {
84 - return;
85 - }
86 - break;
87 - }
88 - case "response":
89 - if (isForbiddenResponse(name)) {
90 - return;
91 - }
92 - break;
93 - }
94 -
95 - this.headersList.append(name, value);
96 - this._removePrivilegedNoCORSHeaders();
97 - }
98 -
99 - set(name, value) {
100 - value = value.trim();
101 - assertName(name);
102 - assertValue(value);
103 -
104 - switch (this.guard) {
105 - case "immutable":
106 - throw new TypeError("Headers is immutable");
107 - case "request":
108 - if (isForbidden(name)) {
109 - return;
110 - }
111 - break;
112 - case "request-no-cors": {
113 - if (!isCORSWhitelisted(name, value)) {
114 - return;
115 - }
116 - break;
117 - }
118 - case "response":
119 - if (isForbiddenResponse(name)) {
120 - return;
121 - }
122 - break;
123 - }
124 - this.headersList.set(name, value);
125 - this._removePrivilegedNoCORSHeaders();
126 - }
127 -
128 - delete(name) {
129 - assertName(name);
130 -
131 - switch (this.guard) {
132 - case "immutable":
133 - throw new TypeError("Headers is immutable");
134 - case "request":
135 - if (isForbidden(name)) {
136 - return;
137 - }
138 - break;
139 - case "request-no-cors": {
140 - if (
141 - !isNoCORSSafelistedRequest(name) &&
142 - !isPrivilegedNoCORSRequest(name)
143 - ) {
144 - return;
145 - }
146 - break;
147 - }
148 - case "response":
149 - if (isForbiddenResponse(name)) {
150 - return;
151 - }
152 - break;
153 - }
154 - this.headersList.delete(name);
155 - this._removePrivilegedNoCORSHeaders();
156 - }
157 -
158 - * [Symbol.iterator]() {
159 - for (const header of this.headersList.sortAndCombine()) {
160 - yield header;
161 - }
162 - }
163 -}
164 -
165 -exports.implementation = HeadersImpl;
1 -"use strict";
2 -
3 -/**
4 - * Provides some utility functions for somewhat efficiently modifying a
5 - * collection of headers.
6 - *
7 - * Note that this class only operates on ByteStrings (which is also why we use
8 - * toLowerCase internally).
9 - */
10 -class HeaderList {
11 - constructor() {
12 - this.headers = new Map();
13 - }
14 -
15 - append(name, value) {
16 - const existing = this.headers.get(name.toLowerCase());
17 - if (existing) {
18 - name = existing[0].name;
19 - existing.push({ name, value });
20 - } else {
21 - this.headers.set(name.toLowerCase(), [{ name, value }]);
22 - }
23 - }
24 -
25 - contains(name) {
26 - return this.headers.has(name.toLowerCase());
27 - }
28 -
29 - get(name) {
30 - name = name.toLowerCase();
31 - const values = this.headers.get(name);
32 - if (!values) {
33 - return null;
34 - }
35 - return values.map(h => h.value).join(", ");
36 - }
37 -
38 - delete(name) {
39 - this.headers.delete(name.toLowerCase());
40 - }
41 -
42 - set(name, value) {
43 - const lowerName = name.toLowerCase();
44 - this.headers.delete(lowerName);
45 - this.headers.set(lowerName, [{ name, value }]);
46 - }
47 -
48 - sortAndCombine() {
49 - const names = [...this.headers.keys()].sort();
50 - return names.map(n => [n, this.get(n)]);
51 - }
52 -}
53 -
54 -module.exports = HeaderList;
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff could not be displayed because it is too large.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.