From d203efaba8f30bc7d7e789f94c627c66753eaeb2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Felix=20B=C3=B6hm?=
Date: Sat, 17 Apr 2021 00:24:15 +0100
Subject: [PATCH 1/3] refactor: Automatically modernize with eslint
---
.eslintrc.json | 90 +++-
benchmark/benchmark.js | 149 +++---
benchmark/suite.js | 60 +--
index.js | 4 +-
lib/api/attributes.js | 181 ++++---
lib/api/css.js | 29 +-
lib/api/forms.js | 53 +-
lib/api/manipulation.js | 220 +++++----
lib/api/traversing.js | 179 ++++---
lib/cheerio.js | 20 +-
lib/load.js | 26 +-
lib/options.js | 2 +-
lib/parse.js | 24 +-
lib/parsers/parse5.js | 20 +-
lib/static.js | 64 +--
lib/utils.js | 24 +-
test/api/attributes.js | 512 +++++++++----------
test/api/css.js | 74 +--
test/api/deprecated.js | 136 +++---
test/api/forms.js | 64 ++-
test/api/manipulation.js | 952 +++++++++++++++++-------------------
test/api/traversing.js | 1004 +++++++++++++++++++-------------------
test/api/utils.js | 227 ++++-----
test/cheerio.js | 328 ++++++-------
test/parse.js | 230 ++++-----
test/xml.js | 42 +-
26 files changed, 2365 insertions(+), 2349 deletions(-)
diff --git a/.eslintrc.json b/.eslintrc.json
index e86d7b0dfe..ca53e0b6d8 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,7 +1,4 @@
{
- "env": {
- "node": true
- },
"plugins": ["jsdoc"],
"extends": [
"eslint:recommended",
@@ -10,7 +7,10 @@
"plugin:node/recommended",
"prettier"
],
- "globals": { "Set": true, "Symbol": true },
+ "env": {
+ "node": true,
+ "es6": true
+ },
"rules": {
"array-callback-return": [
2,
@@ -19,33 +19,39 @@
}
],
"block-scoped-var": 2,
- "eqeqeq": [
- 2,
- "always",
- {
- "null": "ignore"
- }
- ],
"no-lonely-if": 2,
"no-proto": 2,
- "curly": [2, "multi-line"],
+ "eqeqeq": [2, "smart"],
+ "no-caller": 2,
+ "dot-notation": 2,
+ "no-var": 2,
+ "prefer-const": 2,
+ "prefer-arrow-callback": [2, { "allowNamedFunctions": true }],
+ "arrow-body-style": [2, "as-needed"],
+ "object-shorthand": 2,
+ "prefer-template": 2,
"one-var": [2, "never"],
+ "prefer-destructuring": [2, { "object": true }],
+ "capitalized-comments": 2,
+ "multiline-comment-style": [2, "starred-block"],
+ "spaced-comment": 2,
+ "yoda": [2, "never"],
+ "curly": [2, "multi-line"],
+
"no-else-return": [
2,
{
"allowElseIf": false
}
],
- "no-shadow": 2,
"no-unused-expressions": 2,
"no-useless-call": 2,
"no-use-before-define": [2, "nofunc"],
"no-void": 2,
- "yoda": 2,
"strict": 2,
"jsdoc/require-jsdoc": 0,
- "jsdoc/check-param-names": 2,
+ "jsdoc/check-param-names": 0,
"jsdoc/check-tag-names": 2,
"jsdoc/check-types": 2,
"jsdoc/newline-after-description": 2,
@@ -53,24 +59,54 @@
"jsdoc/require-hyphen-before-param-description": 2,
"jsdoc/require-param-description": 2,
"jsdoc/require-param-name": 2,
- "jsdoc/require-param-type": 2,
- "jsdoc/require-param": 2,
+ "jsdoc/require-param-type": 0,
+ "jsdoc/require-returns-type": 0,
+ "jsdoc/require-param": 0,
"jsdoc/valid-types": 2,
- "node/no-unsupported-features/es-builtins": 0, // TODO
- "node/shebang": 0
+ "node/no-unsupported-features/es-syntax": 0,
+ "node/no-missing-import": [
+ 2,
+ { "tryExtensions": [".js", ".json", ".node", ".ts"] }
+ ]
},
"settings": {
"jsdoc": {
- "additionalTagNames": {
- "customTags": ["hideconstructor"]
+ "mode": "typescript"
+ }
+ },
+ "overrides": [
+ {
+ "files": "*.ts",
+ "extends": [
+ "plugin:@typescript-eslint/eslint-recommended",
+ "plugin:@typescript-eslint/recommended",
+ "prettier"
+ ],
+ "parserOptions": {
+ "sourceType": "module",
+ "project": "./tsconfig.eslint.json"
},
- "preferredTypes": {
- "node": "Node",
- "nodewithchildren": "NodeWithChildren",
- "element": "Element",
- "cheerio": "Cheerio"
+ "rules": {
+ "@typescript-eslint/prefer-for-of": 0,
+ "@typescript-eslint/member-ordering": 0,
+ "@typescript-eslint/explicit-function-return-type": 0,
+ "@typescript-eslint/no-unused-vars": 0,
+ "@typescript-eslint/no-use-before-define": [2, { "functions": false }],
+ "@typescript-eslint/consistent-type-definitions": [2, "interface"],
+ "@typescript-eslint/prefer-function-type": 2,
+ "@typescript-eslint/no-unnecessary-type-arguments": 2,
+ "@typescript-eslint/prefer-string-starts-ends-with": 2,
+ "@typescript-eslint/prefer-readonly": 2,
+ "@typescript-eslint/prefer-includes": 2,
+ "@typescript-eslint/no-unnecessary-condition": 0, // TODO
+ "@typescript-eslint/switch-exhaustiveness-check": 2,
+ "@typescript-eslint/prefer-nullish-coalescing": 2,
+
+ "@typescript-eslint/no-explicit-any": 1, // TODO
+ "@typescript-eslint/ban-ts-comment": 0, // TODO
+ "@typescript-eslint/no-non-null-assertion": 0 // TODO
}
}
- }
+ ]
}
diff --git a/benchmark/benchmark.js b/benchmark/benchmark.js
index 2d614b03bf..574ca06c0e 100755
--- a/benchmark/benchmark.js
+++ b/benchmark/benchmark.js
@@ -1,10 +1,9 @@
-#!/usr/bin/env node
'use strict';
-var Suites = require('./suite');
-var suites = new Suites();
+const Suites = require('./suite');
+const suites = new Suites();
-var regexIdx = process.argv.indexOf('--regex') + 1;
+const regexIdx = process.argv.indexOf('--regex') + 1;
if (regexIdx > 0) {
if (regexIdx === process.argv.length) {
throw new Error('Error: the "--regex" option requires a value');
@@ -16,12 +15,12 @@ if (process.argv.indexOf('--cheerio-only') >= 0) {
}
suites.add('Select all', 'jquery.html', {
- test: function ($) {
+ test($) {
return $('*').length;
},
});
suites.add('Select some', 'jquery.html', {
- test: function ($) {
+ test($) {
return $('li').length;
},
});
@@ -30,87 +29,87 @@ suites.add('Select some', 'jquery.html', {
* Manipulation Tests
*/
suites.add('manipulation - append', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $body) {
+ test($, $body) {
$body.append(new Array(50).join(''));
},
});
// These tests run out of memory in jsdom
suites.add('manipulation - prepend - highmem', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $body) {
+ test($, $body) {
$body.prepend(new Array(50).join('
'));
},
});
suites.add('manipulation - after - highmem', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $body) {
+ test($, $body) {
$body.after(new Array(50).join('
'));
},
});
suites.add('manipulation - before - highmem', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $body) {
+ test($, $body) {
$body.before(new Array(50).join('
'));
},
});
suites.add('manipulation - remove', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $lis) {
- var child = $('
');
+ test($, $lis) {
+ const child = $('
');
$lis.append(child);
child.remove();
},
});
suites.add('manipulation - replaceWith', 'jquery.html', {
- setup: function ($) {
+ setup($) {
$('body').append('
');
},
- test: function ($) {
+ test($) {
$('#foo').replaceWith('
');
},
});
suites.add('manipulation - empty', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.empty();
},
});
suites.add('manipulation - html', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.html();
$lis.html('foo');
},
});
suites.add('manipulation - html render', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.html();
},
});
suites.add('manipulation - html independent', 'jquery.html', {
- setup: function () {
+ setup() {
return (
'
' +
'
' +
@@ -120,15 +119,15 @@ suites.add('manipulation - html independent', 'jquery.html', {
'
'
);
},
- test: function ($, content) {
+ test($, content) {
$(content).html();
},
});
suites.add('manipulation - text', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.text();
$lis.text('foo');
},
@@ -138,130 +137,130 @@ suites.add('manipulation - text', 'jquery.html', {
* Traversing Tests
*/
suites.add('traversing - Find', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.find('li').length;
},
});
suites.add('traversing - Parent', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.parent('div').length;
},
});
suites.add('traversing - Parents', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.parents('div').length;
},
});
suites.add('traversing - Closest', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.closest('div').length;
},
});
suites.add('traversing - next', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.next().length;
},
});
suites.add('traversing - nextAll', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.nextAll('li').length;
},
});
suites.add('traversing - nextUntil', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.nextUntil('li').length;
},
});
suites.add('traversing - prev', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.prev().length;
},
});
suites.add('traversing - prevAll', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.prevAll('li').length;
},
});
suites.add('traversing - prevUntil', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.prevUntil('li').length;
},
});
suites.add('traversing - siblings', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.siblings('li').length;
},
});
suites.add('traversing - Children', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.children('a').length;
},
});
suites.add('traversing - Filter', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.filter('li').length;
},
});
suites.add('traversing - First', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.first().first().length;
},
});
suites.add('traversing - Last', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.last().last().length;
},
});
suites.add('traversing - Eq', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
return $lis.eq(0).eq(0).length;
},
});
@@ -270,39 +269,39 @@ suites.add('traversing - Eq', 'jquery.html', {
* Attributes Tests
*/
suites.add('attributes - Attributes', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.attr('foo', 'bar');
$lis.attr('foo');
$lis.removeAttr('foo');
},
});
suites.add('attributes - Single Attribute', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('body');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.attr('foo', 'bar');
$lis.attr('foo');
$lis.removeAttr('foo');
},
});
suites.add('attributes - Data', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.data('foo', 'bar');
$lis.data('foo');
},
});
suites.add('attributes - Val', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('select,input,textarea,option');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.each(function () {
$(this).val();
$(this).val('foo');
@@ -311,26 +310,26 @@ suites.add('attributes - Val', 'jquery.html', {
});
suites.add('attributes - Has class', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.hasClass('foo');
},
});
suites.add('attributes - Toggle class', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.toggleClass('foo');
},
});
suites.add('attributes - Add Remove class', 'jquery.html', {
- setup: function ($) {
+ setup($) {
return $('li');
},
- test: function ($, $lis) {
+ test($, $lis) {
$lis.addClass('foo');
$lis.removeClass('foo');
},
diff --git a/benchmark/suite.js b/benchmark/suite.js
index 6a1aa4004d..b1c7a4130d 100644
--- a/benchmark/suite.js
+++ b/benchmark/suite.js
@@ -1,21 +1,21 @@
'use strict';
-var fs = require('fs');
-var path = require('path');
+const fs = require('fs');
+const path = require('path');
-var Benchmark = require('benchmark');
-var JSDOM = require('jsdom').JSDOM;
-var Script = require('vm').Script;
-var cheerio = require('..');
+const Benchmark = require('benchmark');
+const { JSDOM } = require('jsdom');
+const { Script } = require('vm');
+const cheerio = require('..');
-var documentDir = path.join(__dirname, 'documents');
-var jQuerySrc = fs.readFileSync(
+const documentDir = path.join(__dirname, 'documents');
+const jQuerySrc = fs.readFileSync(
path.join(__dirname, '../node_modules/jquery/dist/jquery.slim.js')
);
-var jQueryScript = new Script(jQuerySrc);
-var filterRe = /./;
-var cheerioOnly = false;
+const jQueryScript = new Script(jQuerySrc);
+let filterRe = /./;
+let cheerioOnly = false;
-var Suites = (module.exports = function () {});
+const Suites = (module.exports = function () {});
Suites.prototype.filter = function (str) {
filterRe = new RegExp(str, 'i');
@@ -29,21 +29,21 @@ Suites.prototype.add = function (name, fileName, options) {
if (!filterRe.test(name)) {
return;
}
- var markup = fs.readFileSync(path.join(documentDir, fileName), 'utf8');
- var suite = new Benchmark.Suite(name);
+ const markup = fs.readFileSync(path.join(documentDir, fileName), 'utf8');
+ const suite = new Benchmark.Suite(name);
- suite.on('start', function () {
- console.log('Test: ' + name + ' (file: ' + fileName + ')');
+ suite.on('start', () => {
+ console.log(`Test: ${name} (file: ${fileName})`);
});
- suite.on('cycle', function (event) {
+ suite.on('cycle', (event) => {
if (event.target.error) {
return;
}
- console.log('\t' + String(event.target));
+ console.log(`\t${String(event.target)}`);
});
- suite.on('error', function (event) {
- console.log('*** Error in ' + event.target.name + ': ***');
- console.log('\t' + event.target.error);
+ suite.on('error', (event) => {
+ console.log(`*** Error in ${event.target.name}: ***`);
+ console.log(`\t${event.target.error}`);
console.log('*** Test invalidated. ***');
});
suite.on('complete', function (event) {
@@ -51,7 +51,7 @@ Suites.prototype.add = function (name, fileName, options) {
console.log();
return;
}
- console.log('\tFastest: ' + this.filter('fastest')[0].name + '\n');
+ console.log(`\tFastest: ${this.filter('fastest')[0].name}\n`);
});
this._benchCheerio(suite, markup, options);
@@ -63,26 +63,26 @@ Suites.prototype.add = function (name, fileName, options) {
};
Suites.prototype._benchJsDom = function (suite, markup, options) {
- var testFn = options.test;
+ const testFn = options.test;
- var dom = new JSDOM(markup, { runScripts: 'outside-only' });
+ const dom = new JSDOM(markup, { runScripts: 'outside-only' });
jQueryScript.runInContext(dom.getInternalVMContext());
- var setupData = options.setup && options.setup.call(null, dom.window.$);
+ const setupData = options.setup && options.setup.call(null, dom.window.$);
- suite.add('jsdom', function () {
+ suite.add('jsdom', () => {
testFn(dom.window.$, setupData);
});
suite.run();
};
Suites.prototype._benchCheerio = function (suite, markup, options) {
- var $ = cheerio.load(markup);
- var testFn = options.test;
- var setupData = options.setup && options.setup.call(null, $);
+ const $ = cheerio.load(markup);
+ const testFn = options.test;
+ const setupData = options.setup && options.setup.call(null, $);
- suite.add('cheerio', function () {
+ suite.add('cheerio', () => {
testFn($, setupData);
});
};
diff --git a/index.js b/index.js
index 33882be68a..67d4ef8279 100644
--- a/index.js
+++ b/index.js
@@ -8,8 +8,8 @@
*/
exports = module.exports = require('./lib/cheerio');
-var staticMethods = require('./lib/static');
-var loadMethod = require('./lib/load');
+const staticMethods = require('./lib/static');
+const loadMethod = require('./lib/load');
/**
* An identifier describing the version of Cheerio which has been executed.
diff --git a/lib/api/attributes.js b/lib/api/attributes.js
index 46c30741da..f80c086fa9 100644
--- a/lib/api/attributes.js
+++ b/lib/api/attributes.js
@@ -5,26 +5,28 @@
* @module cheerio/attributes
*/
-var text = require('../static').text;
-var utils = require('../utils');
-var isTag = utils.isTag;
-var domEach = utils.domEach;
-var hasOwn = Object.prototype.hasOwnProperty;
-var camelCase = utils.camelCase;
-var cssCase = utils.cssCase;
-var rspace = /\s+/;
-var dataAttrPrefix = 'data-';
-// Lookup table for coercing string data-* attributes to their corresponding
-// JavaScript primitives
-var primitives = {
+const { text } = require('../static');
+const utils = require('../utils');
+const { isTag } = utils;
+const { domEach } = utils;
+const hasOwn = Object.prototype.hasOwnProperty;
+const { camelCase } = utils;
+const { cssCase } = utils;
+const rspace = /\s+/;
+const dataAttrPrefix = 'data-';
+/*
+ * Lookup table for coercing string data-* attributes to their corresponding
+ * JavaScript primitives
+ */
+const primitives = {
null: null,
true: true,
false: false,
};
// Attributes that are booleans
-var rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
+const rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i;
// Matches strings that look like JSON objects or arrays
-var rbrace = /^(?:{[\w\W]*}|\[[\w\W]*])$/;
+const rbrace = /^(?:{[\w\W]*}|\[[\w\W]*])$/;
/**
* Gets a node's attribute. For boolean attributes, it will return the value's
@@ -81,7 +83,7 @@ function setAttr(el, name, value) {
if (value === null) {
removeAttribute(el, name);
} else {
- el.attribs[name] = value + '';
+ el.attribs[name] = `${value}`;
}
}
@@ -108,16 +110,16 @@ exports.attr = function (name, value) {
// Set the value (with attr map support)
if (typeof name === 'object' || value !== undefined) {
if (typeof value === 'function') {
- return domEach(this, function (i, el) {
+ return domEach(this, (i, el) => {
setAttr(el, name, value.call(el, i, el.attribs[name]));
});
}
- return domEach(this, function (i, el) {
+ return domEach(this, (i, el) => {
if (!isTag(el)) return;
if (typeof name === 'object') {
- Object.keys(name).forEach(function (objName) {
- var objValue = name[objName];
+ Object.keys(name).forEach((objName) => {
+ const objValue = name[objName];
setAttr(el, objName, objValue);
});
} else {
@@ -184,9 +186,9 @@ exports.prop = function (name, value) {
if (typeof name === 'string' && value === undefined) {
switch (name) {
case 'style': {
- var property = this.css();
- var keys = Object.keys(property);
- keys.forEach(function (p, i) {
+ const property = this.css();
+ const keys = Object.keys(property);
+ keys.forEach((p, i) => {
property[i] = p;
});
@@ -211,17 +213,17 @@ exports.prop = function (name, value) {
if (typeof name === 'object' || value !== undefined) {
if (typeof value === 'function') {
- return domEach(this, function (j, el) {
+ return domEach(this, (j, el) => {
setProp(el, name, value.call(el, j, getProp(el, name)));
});
}
- return domEach(this, function (__, el) {
+ return domEach(this, (__, el) => {
if (!isTag(el)) return;
if (typeof name === 'object') {
- Object.keys(name).forEach(function (key) {
- var val = name[key];
+ Object.keys(name).forEach((key) => {
+ const val = name[key];
setProp(el, key, val);
});
} else {
@@ -261,26 +263,26 @@ function setData(el, name, value) {
* @returns {any} The data attribute's value, or a map with all of the data attribute.
*/
function readData(el, name) {
- var readAll = arguments.length === 1;
- var domNames;
- var jsNames;
- var value;
+ const readAll = arguments.length === 1;
+ let domNames;
+ let jsNames;
+ let value;
if (readAll) {
- domNames = Object.keys(el.attribs).filter(function (attrName) {
- return attrName.slice(0, dataAttrPrefix.length) === dataAttrPrefix;
- });
- jsNames = domNames.map(function (_domName) {
- return camelCase(_domName.slice(dataAttrPrefix.length));
- });
+ domNames = Object.keys(el.attribs).filter(
+ (attrName) => attrName.slice(0, dataAttrPrefix.length) === dataAttrPrefix
+ );
+ jsNames = domNames.map((_domName) =>
+ camelCase(_domName.slice(dataAttrPrefix.length))
+ );
} else {
domNames = [dataAttrPrefix + cssCase(name)];
jsNames = [name];
}
- for (var idx = 0; idx < domNames.length; ++idx) {
- var domName = domNames[idx];
- var jsName = jsNames[idx];
+ for (let idx = 0; idx < domNames.length; ++idx) {
+ const domName = domNames[idx];
+ const jsName = jsNames[idx];
if (hasOwn.call(el.attribs, domName) && !hasOwn.call(el.data, jsName)) {
value = el.attribs[domName];
@@ -292,7 +294,7 @@ function readData(el, name) {
try {
value = JSON.parse(value);
} catch (e) {
- /* ignore */
+ /* Ignore */
}
}
@@ -325,7 +327,7 @@ function readData(el, name) {
* @see {@link https://api.jquery.com/data/}
*/
exports.data = function (name, value) {
- var elem = this[0];
+ const elem = this[0];
if (!elem || !isTag(elem)) return;
@@ -340,7 +342,7 @@ exports.data = function (name, value) {
// Set the value (with attr map support)
if (typeof name === 'object' || value !== undefined) {
- domEach(this, function (i, el) {
+ domEach(this, (i, el) => {
setData(el, name, value);
});
return this;
@@ -369,8 +371,8 @@ exports.data = function (name, value) {
* @see {@link https://api.jquery.com/val/}
*/
exports.val = function (value) {
- var querying = arguments.length === 0;
- var element = this[0];
+ const querying = arguments.length === 0;
+ const element = this[0];
if (!element) return;
@@ -378,7 +380,7 @@ exports.val = function (value) {
case 'textarea':
return this.text(value);
case 'select': {
- var option = this.find('option:selected');
+ const option = this.find('option:selected');
if (!option) return;
if (!querying) {
if (this.attr('multiple') == null && typeof value === 'object') {
@@ -388,16 +390,14 @@ exports.val = function (value) {
value = [value];
}
this.find('option').removeAttr('selected');
- for (var i = 0; i < value.length; i++) {
- this.find('option[value="' + value[i] + '"]').attr('selected', '');
+ for (let i = 0; i < value.length; i++) {
+ this.find(`option[value="${value[i]}"]`).attr('selected', '');
}
return this;
}
return this.attr('multiple')
- ? option.toArray().map(function (el) {
- return getAttr(el, 'value');
- })
+ ? option.toArray().map((el) => getAttr(el, 'value'))
: option.attr('value');
}
case 'input':
@@ -445,10 +445,10 @@ function splitNames(names) {
* @see {@link https://api.jquery.com/removeAttr/}
*/
exports.removeAttr = function (name) {
- var attrNames = splitNames(name);
+ const attrNames = splitNames(name);
for (var i = 0; i < attrNames.length; i++) {
- domEach(this, function (_, elem) {
+ domEach(this, (_, elem) => {
removeAttribute(elem, attrNames[i]);
});
}
@@ -474,13 +474,13 @@ exports.removeAttr = function (name) {
* @see {@link https://api.jquery.com/hasClass/}
*/
exports.hasClass = function (className) {
- return this.toArray().some(function (elem) {
- var clazz = elem.attribs && elem.attribs['class'];
- var idx = -1;
+ return this.toArray().some((elem) => {
+ const clazz = elem.attribs && elem.attribs.class;
+ let idx = -1;
if (clazz && className.length) {
while ((idx = clazz.indexOf(className, idx + 1)) > -1) {
- var end = idx + className.length;
+ const end = idx + className.length;
if (
(idx === 0 || rspace.test(clazz[idx - 1])) &&
@@ -512,8 +512,8 @@ exports.hasClass = function (className) {
exports.addClass = function (value) {
// Support functions
if (typeof value === 'function') {
- return domEach(this, function (i, el) {
- var className = el.attribs['class'] || '';
+ return domEach(this, (i, el) => {
+ const className = el.attribs.class || '';
exports.addClass.call([el], value.call(el, i, className));
});
}
@@ -521,25 +521,25 @@ exports.addClass = function (value) {
// Return if no value or not a string or function
if (!value || typeof value !== 'string') return this;
- var classNames = value.split(rspace);
- var numElements = this.length;
+ const classNames = value.split(rspace);
+ const numElements = this.length;
- for (var i = 0; i < numElements; i++) {
+ for (let i = 0; i < numElements; i++) {
// If selected element isn't a tag, move on
if (!isTag(this[i])) continue;
// If we don't already have classes
- var className = getAttr(this[i], 'class');
+ const className = getAttr(this[i], 'class');
if (!className) {
setAttr(this[i], 'class', classNames.join(' ').trim());
} else {
- var setClass = ' ' + className + ' ';
+ let setClass = ` ${className} `;
// Check if class already exists
- for (var j = 0; j < classNames.length; j++) {
- var appendClass = classNames[j] + ' ';
- if (setClass.indexOf(' ' + appendClass) < 0) setClass += appendClass;
+ for (let j = 0; j < classNames.length; j++) {
+ const appendClass = `${classNames[j]} `;
+ if (setClass.indexOf(` ${appendClass}`) < 0) setClass += appendClass;
}
setAttr(this[i], 'class', setClass.trim());
@@ -568,37 +568,36 @@ exports.addClass = function (value) {
exports.removeClass = function (value) {
// Handle if value is a function
if (typeof value === 'function') {
- return domEach(this, function (i, el) {
- exports.removeClass.call(
- [el],
- value.call(el, i, el.attribs['class'] || '')
- );
+ return domEach(this, (i, el) => {
+ exports.removeClass.call([el], value.call(el, i, el.attribs.class || ''));
});
}
- var classes = splitNames(value);
- var numClasses = classes.length;
- var removeAll = arguments.length === 0;
+ const classes = splitNames(value);
+ const numClasses = classes.length;
+ const removeAll = arguments.length === 0;
- return domEach(this, function (_, el) {
+ return domEach(this, (_, el) => {
if (!isTag(el)) return;
if (removeAll) {
// Short circuit the remove all case as this is the nice one
el.attribs.class = '';
} else {
- var elClasses = splitNames(el.attribs.class);
- var changed = false;
+ const elClasses = splitNames(el.attribs.class);
+ let changed = false;
- for (var j = 0; j < numClasses; j++) {
- var index = elClasses.indexOf(classes[j]);
+ for (let j = 0; j < numClasses; j++) {
+ const index = elClasses.indexOf(classes[j]);
if (index >= 0) {
elClasses.splice(index, 1);
changed = true;
- // We have to do another pass to ensure that there are not duplicate
- // classes listed
+ /*
+ * We have to do another pass to ensure that there are not duplicate
+ * classes listed
+ */
j--;
}
}
@@ -629,10 +628,10 @@ exports.removeClass = function (value) {
exports.toggleClass = function (value, stateVal) {
// Support functions
if (typeof value === 'function') {
- return domEach(this, function (i, el) {
+ return domEach(this, (i, el) => {
exports.toggleClass.call(
[el],
- value.call(el, i, el.attribs['class'] || '', stateVal),
+ value.call(el, i, el.attribs.class || '', stateVal),
stateVal
);
});
@@ -641,21 +640,21 @@ exports.toggleClass = function (value, stateVal) {
// Return if no value or not a string or function
if (!value || typeof value !== 'string') return this;
- var classNames = value.split(rspace);
- var numClasses = classNames.length;
- var state = typeof stateVal === 'boolean' ? (stateVal ? 1 : -1) : 0;
- var numElements = this.length;
+ const classNames = value.split(rspace);
+ const numClasses = classNames.length;
+ const state = typeof stateVal === 'boolean' ? (stateVal ? 1 : -1) : 0;
+ const numElements = this.length;
- for (var i = 0; i < numElements; i++) {
+ for (let i = 0; i < numElements; i++) {
// If selected element isn't a tag, move on
if (!isTag(this[i])) continue;
- var elementClasses = splitNames(this[i].attribs.class);
+ const elementClasses = splitNames(this[i].attribs.class);
// Check if class already exists
- for (var j = 0; j < numClasses; j++) {
+ for (let j = 0; j < numClasses; j++) {
// Check if the class name is currently defined
- var index = elementClasses.indexOf(classNames[j]);
+ const index = elementClasses.indexOf(classNames[j]);
// Add if stateValue === true or we are toggling and there is no value
if (state >= 0 && index < 0) {
diff --git a/lib/api/css.js b/lib/api/css.js
index 970b52f821..bb910ca3d0 100644
--- a/lib/api/css.js
+++ b/lib/api/css.js
@@ -1,9 +1,9 @@
'use strict';
/** @module cheerio/css */
-var domEach = require('../utils').domEach;
+const { domEach } = require('../utils');
-var toString = Object.prototype.toString;
+const { toString } = Object.prototype;
/**
* Get the value of a style property for the first element in the set of matched
@@ -20,7 +20,7 @@ exports.css = function (prop, val) {
// When `prop` is a "plain" object
toString.call(prop) === '[object Object]'
) {
- return domEach(this, function (idx, el) {
+ return domEach(this, (idx, el) => {
setCss(el, prop, val, idx);
});
}
@@ -38,7 +38,7 @@ exports.css = function (prop, val) {
*/
function setCss(el, prop, val, idx) {
if (typeof prop === 'string') {
- var styles = getCss(el);
+ const styles = getCss(el);
if (typeof val === 'function') {
val = val.call(el, idx, styles[prop]);
}
@@ -51,7 +51,7 @@ function setCss(el, prop, val, idx) {
el.attribs.style = stringify(styles);
} else if (typeof prop === 'object') {
- Object.keys(prop).forEach(function (k) {
+ Object.keys(prop).forEach((k) => {
setCss(el, k, prop[k]);
});
}
@@ -68,13 +68,13 @@ function setCss(el, prop, val, idx) {
function getCss(el, prop) {
if (!el || !el.attribs) return;
- var styles = parse(el.attribs.style);
+ const styles = parse(el.attribs.style);
if (typeof prop === 'string') {
return styles[prop];
}
if (Array.isArray(prop)) {
- var newStyles = {};
- prop.forEach(function (item) {
+ const newStyles = {};
+ prop.forEach((item) => {
if (styles[item] != null) {
newStyles[item] = styles[item];
}
@@ -92,9 +92,10 @@ function getCss(el, prop) {
* @returns {string} The serialized styles.
*/
function stringify(obj) {
- return Object.keys(obj || {}).reduce(function (str, prop) {
- return (str += '' + (str ? ' ' : '') + prop + ': ' + obj[prop] + ';');
- }, '');
+ return Object.keys(obj || {}).reduce(
+ (str, prop) => (str += `${str ? ' ' : ''}${prop}: ${obj[prop]};`),
+ ''
+ );
}
/**
@@ -109,9 +110,9 @@ function parse(styles) {
if (!styles) return {};
- return styles.split(';').reduce(function (obj, str) {
- var n = str.indexOf(':');
- // skip if there is no :, or if it is the first/last character
+ return styles.split(';').reduce((obj, str) => {
+ const n = str.indexOf(':');
+ // Skip if there is no :, or if it is the first/last character
if (n < 1 || n === str.length - 1) return obj;
obj[str.slice(0, n).trim()] = str.slice(n + 1).trim();
return obj;
diff --git a/lib/api/forms.js b/lib/api/forms.js
index f0bedc068e..5202a9bcba 100644
--- a/lib/api/forms.js
+++ b/lib/api/forms.js
@@ -1,11 +1,13 @@
'use strict';
/** @module cheerio/forms */
-// https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
-// https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
-var submittableSelector = 'input,select,textarea,keygen';
-var r20 = /%20/g;
-var rCRLF = /\r?\n/g;
+/*
+ * https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js
+ * https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js
+ */
+const submittableSelector = 'input,select,textarea,keygen';
+const r20 = /%20/g;
+const rCRLF = /\r?\n/g;
/**
* Encode a set of form elements as a string for submission.
@@ -15,12 +17,13 @@ var rCRLF = /\r?\n/g;
*/
exports.serialize = function () {
// Convert form elements into name/value objects
- var arr = this.serializeArray();
+ const arr = this.serializeArray();
// Serialize each element into a key/value string
- var retArr = arr.map(function (data) {
- return encodeURIComponent(data.name) + '=' + encodeURIComponent(data.value);
- });
+ const retArr = arr.map(
+ (data) =>
+ `${encodeURIComponent(data.name)}=${encodeURIComponent(data.value)}`
+ );
// Return the resulting serialization
return retArr.join('&').replace(r20, '+');
@@ -39,9 +42,9 @@ exports.serialize = function () {
*/
exports.serializeArray = function () {
// Resolve all form elements from either forms or collections of form elements
- var Cheerio = this.constructor;
- return this.map(function (_, elem) {
- var $elem = Cheerio(elem);
+ const Cheerio = this.constructor;
+ return this.map((_, elem) => {
+ const $elem = Cheerio(elem);
if (elem.name === 'form') {
return $elem.find(submittableSelector).toArray();
}
@@ -50,16 +53,16 @@ exports.serializeArray = function () {
.filter(
// Verify elements have a name (`attr.name`) and are not disabled (`:enabled`)
'[name!=""]:enabled' +
- // and cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
+ // And cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`)
':not(:submit, :button, :image, :reset, :file)' +
- // and are either checked/don't have a checkable state
+ // And are either checked/don't have a checkable state
':matches([checked], :not(:checkbox, :radio))'
// Convert each of the elements to its value(s)
)
- .map(function (_, elem) {
- var $elem = Cheerio(elem);
- var name = $elem.attr('name');
- var value = $elem.val();
+ .map((_, elem) => {
+ const $elem = Cheerio(elem);
+ const name = $elem.attr('name');
+ let value = $elem.val();
// If there is no value set (e.g. `undefined`, `null`), then default value to empty
if (value == null) {
@@ -68,14 +71,16 @@ exports.serializeArray = function () {
// If we have an array of values (e.g. `
foo', {
+ it('(html) : should handle xml tag option', () => {
+ const $ = cheerio.load('
', {
xml: true,
});
expect($('script')[0].children[0].type).toBe('tag');
});
- it('(buffer) : should accept a buffer', function () {
- var html = '