diff --git a/.eslintrc.yaml b/.eslintrc.yaml index d8442ff3a18c44..9b0bb9261eeac0 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -78,6 +78,9 @@ rules: no-delete-var: 2 no-undef: 2 no-unused-vars: [2, {args: none}] + no-use-before-define: [2, {classes: true, + functions: false, + variables: false}] # Node.js and CommonJS # http://eslint.org/docs/rules/#nodejs-and-commonjs diff --git a/lib/internal/url.js b/lib/internal/url.js index 7d7c79149a5c4f..ea973b3a57db11 100644 --- a/lib/internal/url.js +++ b/lib/internal/url.js @@ -90,6 +90,112 @@ class URLContext { } } +class URLSearchParams { + // URL Standard says the default value is '', but as undefined and '' have + // the same result, undefined is used to prevent unnecessary parsing. + // Default parameter is necessary to keep URLSearchParams.length === 0 in + // accordance with Web IDL spec. + constructor(init = undefined) { + if (init === null || init === undefined) { + this[searchParams] = []; + } else if ((typeof init === 'object' && init !== null) || + typeof init === 'function') { + const method = init[Symbol.iterator]; + if (method === this[Symbol.iterator]) { + // While the spec does not have this branch, we can use it as a + // shortcut to avoid having to go through the costly generic iterator. + const childParams = init[searchParams]; + this[searchParams] = childParams.slice(); + } else if (method !== null && method !== undefined) { + if (typeof method !== 'function') { + throw new errors.TypeError('ERR_ARG_NOT_ITERABLE', 'Query pairs'); + } + + // sequence> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if ((typeof pair !== 'object' && typeof pair !== 'function') || + pair === null || + typeof pair[Symbol.iterator] !== 'function') { + throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', + '[name, value]'); + } + const convertedPair = []; + for (const element of pair) + convertedPair.push(toUSVString(element)); + pairs.push(convertedPair); + } + + this[searchParams] = []; + for (const pair of pairs) { + if (pair.length !== 2) { + throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', + '[name, value]'); + } + this[searchParams].push(pair[0], pair[1]); + } + } else { + // record + // Need to use reflection APIs for full spec compliance. + this[searchParams] = []; + const keys = Reflect.ownKeys(init); + for (var i = 0; i < keys.length; i++) { + const key = keys[i]; + const desc = Reflect.getOwnPropertyDescriptor(init, key); + if (desc !== undefined && desc.enumerable) { + const typedKey = toUSVString(key); + const typedValue = toUSVString(init[key]); + this[searchParams].push(typedKey, typedValue); + } + } + } + } else { + // USVString + init = toUSVString(init); + if (init[0] === '?') init = init.slice(1); + initSearchParams(this, init); + } + + // "associated url object" + this[context] = null; + } + + [util.inspect.custom](recurseTimes, ctx) { + if (!this || !this[searchParams] || this[searchParams][searchParams]) { + throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams'); + } + + if (typeof recurseTimes === 'number' && recurseTimes < 0) + return ctx.stylize('[Object]', 'special'); + + var separator = ', '; + var innerOpts = Object.assign({}, ctx); + if (recurseTimes !== null) { + innerOpts.depth = recurseTimes - 1; + } + var innerInspect = (v) => util.inspect(v, innerOpts); + + var list = this[searchParams]; + var output = []; + for (var i = 0; i < list.length; i += 2) + output.push(`${innerInspect(list[i])} => ${innerInspect(list[i + 1])}`); + + var colorRe = /\u001b\[\d\d?m/g; + var length = output.reduce( + (prev, cur) => prev + cur.replace(colorRe, '').length + separator.length, + -separator.length + ); + if (length > ctx.breakLength) { + return `${this.constructor.name} {\n ${output.join(',\n ')} }`; + } else if (output.length) { + return `${this.constructor.name} { ${output.join(separator)} }`; + } else { + return `${this.constructor.name} {}`; + } + } +} + function onParseComplete(flags, protocol, username, password, host, port, path, query, fragment) { var ctx = this[context]; @@ -806,112 +912,6 @@ function defineIDLClass(proto, classStr, obj) { } } -class URLSearchParams { - // URL Standard says the default value is '', but as undefined and '' have - // the same result, undefined is used to prevent unnecessary parsing. - // Default parameter is necessary to keep URLSearchParams.length === 0 in - // accordance with Web IDL spec. - constructor(init = undefined) { - if (init === null || init === undefined) { - this[searchParams] = []; - } else if ((typeof init === 'object' && init !== null) || - typeof init === 'function') { - const method = init[Symbol.iterator]; - if (method === this[Symbol.iterator]) { - // While the spec does not have this branch, we can use it as a - // shortcut to avoid having to go through the costly generic iterator. - const childParams = init[searchParams]; - this[searchParams] = childParams.slice(); - } else if (method !== null && method !== undefined) { - if (typeof method !== 'function') { - throw new errors.TypeError('ERR_ARG_NOT_ITERABLE', 'Query pairs'); - } - - // sequence> - // Note: per spec we have to first exhaust the lists then process them - const pairs = []; - for (const pair of init) { - if ((typeof pair !== 'object' && typeof pair !== 'function') || - pair === null || - typeof pair[Symbol.iterator] !== 'function') { - throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', - '[name, value]'); - } - const convertedPair = []; - for (const element of pair) - convertedPair.push(toUSVString(element)); - pairs.push(convertedPair); - } - - this[searchParams] = []; - for (const pair of pairs) { - if (pair.length !== 2) { - throw new errors.TypeError('ERR_INVALID_TUPLE', 'Each query pair', - '[name, value]'); - } - this[searchParams].push(pair[0], pair[1]); - } - } else { - // record - // Need to use reflection APIs for full spec compliance. - this[searchParams] = []; - const keys = Reflect.ownKeys(init); - for (var i = 0; i < keys.length; i++) { - const key = keys[i]; - const desc = Reflect.getOwnPropertyDescriptor(init, key); - if (desc !== undefined && desc.enumerable) { - const typedKey = toUSVString(key); - const typedValue = toUSVString(init[key]); - this[searchParams].push(typedKey, typedValue); - } - } - } - } else { - // USVString - init = toUSVString(init); - if (init[0] === '?') init = init.slice(1); - initSearchParams(this, init); - } - - // "associated url object" - this[context] = null; - } - - [util.inspect.custom](recurseTimes, ctx) { - if (!this || !this[searchParams] || this[searchParams][searchParams]) { - throw new errors.TypeError('ERR_INVALID_THIS', 'URLSearchParams'); - } - - if (typeof recurseTimes === 'number' && recurseTimes < 0) - return ctx.stylize('[Object]', 'special'); - - var separator = ', '; - var innerOpts = Object.assign({}, ctx); - if (recurseTimes !== null) { - innerOpts.depth = recurseTimes - 1; - } - var innerInspect = (v) => util.inspect(v, innerOpts); - - var list = this[searchParams]; - var output = []; - for (var i = 0; i < list.length; i += 2) - output.push(`${innerInspect(list[i])} => ${innerInspect(list[i + 1])}`); - - var colorRe = /\u001b\[\d\d?m/g; - var length = output.reduce( - (prev, cur) => prev + cur.replace(colorRe, '').length + separator.length, - -separator.length - ); - if (length > ctx.breakLength) { - return `${this.constructor.name} {\n ${output.join(',\n ')} }`; - } else if (output.length) { - return `${this.constructor.name} { ${output.join(separator)} }`; - } else { - return `${this.constructor.name} {}`; - } - } -} - // for merge sort function merge(out, start, mid, end, lBuffer, rBuffer) { const sizeLeft = mid - start; diff --git a/lib/repl.js b/lib/repl.js index 42634157c7c722..31e51616016146 100644 --- a/lib/repl.js +++ b/lib/repl.js @@ -739,6 +739,7 @@ function complete(line, callback) { var completeOn, i, group, c; // REPL commands (e.g. ".break"). + var filter; var match = null; match = line.match(/^\s*\.(\w*)$/); if (match) { @@ -758,7 +759,7 @@ function complete(line, callback) { completeOn = match[1]; var subdir = match[2] || ''; - var filter = match[1]; + filter = match[1]; var dir, files, f, name, base, ext, abs, subfiles, s; group = []; var paths = module.paths.concat(require('module').globalPaths);