diff --git a/packages/less/.eslintrc.js b/packages/less/.eslintrc.js new file mode 100644 index 000000000..95fd11c9b --- /dev/null +++ b/packages/less/.eslintrc.js @@ -0,0 +1,50 @@ +module.exports = { + 'parser': '@typescript-eslint/parser', + 'extends': 'eslint:recommended', + 'parserOptions': { + 'ecmaVersion': 2018, + 'sourceType': 'module' + }, + 'plugins': ['@typescript-eslint'], + 'env': { + 'browser': true, + 'node': true, + 'mocha': true + }, + 'globals': {}, + 'rules': { + indent: ['error', 4, { + SwitchCase: 1 + }], + 'no-empty': ['error', { 'allowEmptyCatch': true }], + quotes: ['error', 'single', { + avoidEscape: true + }], + /** + * The codebase uses some while(true) statements. + * Refactor to remove this rule. + */ + 'no-constant-condition': 0, + /** + * Less combines assignments with conditionals sometimes + */ + 'no-cond-assign': 0, + /** + * @todo - remove when some kind of code style (XO?) is added + */ + 'no-multiple-empty-lines': 'error' + }, + 'overrides': [ + { + files: ['*.ts'], + extends: ['plugin:@typescript-eslint/recommended'], + rules: { + /** + * Suppress until Less has better-defined types + * @see https://github.com/less/less.js/discussions/3786 + */ + '@typescript-eslint/no-explicit-any': 0 + } + } + ] +} diff --git a/packages/less/.eslintrc.json b/packages/less/.eslintrc.json deleted file mode 100644 index 9713bafa8..000000000 --- a/packages/less/.eslintrc.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 2018, - "sourceType": "module" - }, - "plugins": ["@typescript-eslint"], - "env": { - "browser": true, - "node": true - }, - "globals": {}, - "rules": { - "no-eval": 2, - "no-use-before-define": [ - 2, - { - "functions": false - } - ], - "no-undef": 0, - "no-unused-vars": 1, - "no-caller": 2, - "no-eq-null": 1, - "guard-for-in": 2, - "no-implicit-coercion": [ - 2, - { - "boolean": false, - "string": true, - "number": true - } - ], - "no-with": 2, - "no-mixed-spaces-and-tabs": 2, - "no-multiple-empty-lines": 2, - "dot-location": [2, "property"], - "operator-linebreak": [0, "after"], - "keyword-spacing": [2, {}], - "space-unary-ops": [ - 2, - { - "words": false, - "nonwords": false - } - ], - "no-spaced-func": 2, - "space-before-function-paren": [ - 1, - { - "anonymous": "ignore", - "named": "never" - } - ], - "comma-dangle": [2, "never"], - "no-trailing-spaces": 0, - "max-len": [2, 160], - "comma-style": [2, "last"], - "curly": [2, "all"], - "space-infix-ops": 2, - "spaced-comment": 1, - "space-before-blocks": [2, "always"], - "indent": [ - 2, - 4, - { - "SwitchCase": 1 - } - ] - } -} diff --git a/packages/less/Gruntfile.js b/packages/less/Gruntfile.js index 6aea41584..3a0745180 100644 --- a/packages/less/Gruntfile.js +++ b/packages/less/Gruntfile.js @@ -283,7 +283,7 @@ module.exports = function(grunt) { "!test/less/errors/plugin/plugin-error.js" ], options: { - configFile: ".eslintrc.json", + configFile: ".eslintrc.js", fix: true } }, diff --git a/packages/less/package.json b/packages/less/package.json index f98c14a4d..765e35ff1 100644 --- a/packages/less/package.json +++ b/packages/less/package.json @@ -37,6 +37,7 @@ "scripts": { "test": "grunt test", "grunt": "grunt", + "lint": "eslint '**/*.{ts,js}'", "build": "npm-run-all clean compile", "clean": "shx rm -rf ./lib tsconfig.tsbuildinfo", "compile": "tsc -p tsconfig.json", diff --git a/packages/less/src/less-browser/bootstrap.js b/packages/less/src/less-browser/bootstrap.js index aa01c64b3..2a73fe3c3 100644 --- a/packages/less/src/less-browser/bootstrap.js +++ b/packages/less/src/less-browser/bootstrap.js @@ -3,8 +3,6 @@ * used in the browser distributed version of less * to kick-start less using the browser api */ -/* global window, document */ - import defaultOptions from '../less/default-options'; import addDefaultOptions from './add-default-options'; import root from './index'; @@ -13,7 +11,7 @@ const options = defaultOptions(); if (window.less) { for (const key in window.less) { - if (window.less.hasOwnProperty(key)) { + if (Object.prototype.hasOwnProperty.call(window.less, key)) { options[key] = window.less[key]; } } diff --git a/packages/less/src/less-browser/cache.js b/packages/less/src/less-browser/cache.js index 5322c17b8..a106a6335 100644 --- a/packages/less/src/less-browser/cache.js +++ b/packages/less/src/less-browser/cache.js @@ -29,7 +29,7 @@ export default (window, options, logger) => { let vars = cache && cache.getItem(`${path}:vars`); modifyVars = modifyVars || {}; - vars = vars || "{}"; // if not set, treat as the JSON representation of an empty object + vars = vars || '{}'; // if not set, treat as the JSON representation of an empty object if (timestamp && webInfo.lastModified && (new Date(webInfo.lastModified).valueOf() === diff --git a/packages/less/src/less-browser/error-reporting.js b/packages/less/src/less-browser/error-reporting.js index c5606b643..e1ef840ac 100644 --- a/packages/less/src/less-browser/error-reporting.js +++ b/packages/less/src/less-browser/error-reporting.js @@ -11,7 +11,7 @@ export default (window, less, options) => { let content; const errors = []; const filename = e.filename || rootHref; - const filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; + const filenameNoPath = filename.match(/([^/]+(\?.*)?)$/)[1]; elem.id = id; elem.className = 'less-error-message'; @@ -113,7 +113,7 @@ export default (window, less, options) => { } } - function removeErrorConsole(path) { + function removeErrorConsole() { // no action } diff --git a/packages/less/src/less-browser/file-manager.js b/packages/less/src/less-browser/file-manager.js index fa8a8ea92..090886b73 100644 --- a/packages/less/src/less-browser/file-manager.js +++ b/packages/less/src/less-browser/file-manager.js @@ -1,5 +1,3 @@ -/* global window, XMLHttpRequest */ - import AbstractFileManager from '../less/environment/abstract-file-manager.js'; let options; @@ -66,7 +64,7 @@ FileManager.prototype = Object.assign(new AbstractFileManager(), { fileCache = {}; }, - loadFile(filename, currentDirectory, options, environment) { + loadFile(filename, currentDirectory, options) { // TODO: Add prefix support like less-node? // What about multiple paths? diff --git a/packages/less/src/less-browser/index.js b/packages/less/src/less-browser/index.js index 6ec83bb50..d2ab24a77 100644 --- a/packages/less/src/less-browser/index.js +++ b/packages/less/src/less-browser/index.js @@ -39,7 +39,7 @@ export default (window, options) => { function clone(obj) { const cloned = {}; for (const prop in obj) { - if (obj.hasOwnProperty(prop)) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { cloned[prop] = obj[prop]; } } @@ -159,6 +159,10 @@ export default (window, options) => { less.watchTimer = setInterval(() => { if (less.watchMode) { fileManager.clearFileCache(); + /** + * @todo remove when this is typed with JSDoc + */ + // eslint-disable-next-line no-unused-vars loadStyleSheets((e, css, _, sheet, webInfo) => { if (e) { errors.add(e, e.href || sheet.href); @@ -174,7 +178,7 @@ export default (window, options) => { // // Watch mode // - less.watch = function () { + less.watch = function () { if (!less.watchMode ) { less.env = 'development'; initRunningMode(); @@ -205,7 +209,7 @@ export default (window, options) => { // Asynchronously get all tags with the 'rel' attribute set to // "stylesheet/less", returning a Promise. // - less.registerStylesheets = () => new Promise((resolve, reject) => { + less.registerStylesheets = () => new Promise((resolve) => { less.registerStylesheetsImmediately(); resolve(); }); diff --git a/packages/less/src/less-browser/plugin-loader.js b/packages/less/src/less-browser/plugin-loader.js index be9a03dc2..2a7e21924 100644 --- a/packages/less/src/less-browser/plugin-loader.js +++ b/packages/less/src/less-browser/plugin-loader.js @@ -1,6 +1,6 @@ -// TODO: Add tests for browser @plugin -/* global window */ - +/** + * @todo Add tests for browser `@plugin` + */ import AbstractPluginLoader from '../less/environment/abstract-plugin-loader.js'; /** diff --git a/packages/less/src/less-browser/utils.js b/packages/less/src/less-browser/utils.js index 039f1d595..972160b6d 100644 --- a/packages/less/src/less-browser/utils.js +++ b/packages/less/src/less-browser/utils.js @@ -1,17 +1,17 @@ export function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain - .replace(/[\?\&]livereload=\w+/, '') // Remove LiveReload cachebuster + return href.replace(/^[a-z-]+:\/+?[^/]+/, '') // Remove protocol & domain + .replace(/[?&]livereload=\w+/, '') // Remove LiveReload cachebuster .replace(/^\//, '') // Remove root / .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters + .replace(/[^.\w-]+/g, '-') // Replace illegal characters .replace(/\./g, ':'); // Replace dots with colons(for valid id) } export function addDataAttr(options, tag) { if (!tag) {return;} // in case of tag is null or undefined for (const opt in tag.dataset) { - if (tag.dataset.hasOwnProperty(opt)) { + if (Object.prototype.hasOwnProperty.call(tag.dataset, opt)) { if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') { options[opt] = tag.dataset[opt]; } else { diff --git a/packages/less/src/less-node/file-manager.js b/packages/less/src/less-node/file-manager.js index 874f886b0..5482c420f 100644 --- a/packages/less/src/less-node/file-manager.js +++ b/packages/less/src/less-node/file-manager.js @@ -61,6 +61,23 @@ FileManager.prototype = Object.assign(new AbstractFileManager(), { function getFileData(fulfill, reject) { (function tryPathIndex(i) { + function tryWithExtension() { + const extFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename; + + if (extFilename !== fullFilename && !explicit && paths[i] === '.') { + try { + fullFilename = require.resolve(extFilename); + isNodeModule = true; + } + catch (e) { + filenamesTried.push(npmPrefix + extFilename); + fullFilename = extFilename; + } + } + else { + fullFilename = extFilename; + } + } if (i < paths.length) { (function tryPrefix(j) { if (j < prefixes.length) { @@ -83,25 +100,7 @@ FileManager.prototype = Object.assign(new AbstractFileManager(), { } else { tryWithExtension(); - } - - function tryWithExtension() { - const extFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename; - - if (extFilename !== fullFilename && !explicit && paths[i] === '.') { - try { - fullFilename = require.resolve(extFilename); - isNodeModule = true; - } - catch (e) { - filenamesTried.push(npmPrefix + extFilename); - fullFilename = extFilename; - } - } - else { - fullFilename = extFilename; - } - } + } const readFileArgs = [fullFilename]; if (!options.rawBuffer) { diff --git a/packages/less/src/less-node/lessc-helper.js b/packages/less/src/less-node/lessc-helper.js index e2c1c7c64..b37ee2ebc 100644 --- a/packages/less/src/less-node/lessc-helper.js +++ b/packages/less/src/less-node/lessc-helper.js @@ -88,4 +88,5 @@ const lessc_helper = { }; // Exports helper functions +// eslint-disable-next-line no-prototype-builtins for (const h in lessc_helper) { if (lessc_helper.hasOwnProperty(h)) { exports[h] = lessc_helper[h]; }} diff --git a/packages/less/src/less-node/url-file-manager.js b/packages/less/src/less-node/url-file-manager.js index 51e1b5014..7a9092e22 100644 --- a/packages/less/src/less-node/url-file-manager.js +++ b/packages/less/src/less-node/url-file-manager.js @@ -1,3 +1,8 @@ +/* eslint-disable no-unused-vars */ +/** + * @todo - remove top eslint rule when FileManagers have JSDoc type + * and are TS-type-checked + */ const isUrlRe = /^(?:https?:)?\/\//i; import url from 'url'; let request; diff --git a/packages/less/src/less/contexts.js b/packages/less/src/less/contexts.js index e76658833..8629073d1 100644 --- a/packages/less/src/less/contexts.js +++ b/packages/less/src/less/contexts.js @@ -6,7 +6,7 @@ const copyFromOriginal = function copyFromOriginal(original, destination, proper if (!original) { return; } for (let i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { + if (Object.prototype.hasOwnProperty.call(original, propertiesToCopy[i])) { destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; } } @@ -113,7 +113,7 @@ contexts.Eval.prototype.pathRequiresRewrite = function (path) { contexts.Eval.prototype.rewritePath = function (path, rootpath) { let newPath; - rootpath = rootpath || ''; + rootpath = rootpath || ''; newPath = this.normalizePath(rootpath + path); // If a path was explicit relative and the rootpath was not an absolute path diff --git a/packages/less/src/less/environment/abstract-file-manager.js b/packages/less/src/less/environment/abstract-file-manager.js index 03ca08613..3598313f3 100644 --- a/packages/less/src/less/environment/abstract-file-manager.js +++ b/packages/less/src/less/environment/abstract-file-manager.js @@ -15,7 +15,7 @@ class AbstractFileManager { } tryAppendExtension(path, ext) { - return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext; + return /(\.[a-z]*$)|([?;].*)$/.test(path) ? path : path + ext; } tryAppendLessExtension(path) { @@ -71,7 +71,13 @@ class AbstractFileManager { return diff; } - // helper function, not part of API + /** + * Helper function, not part of API. + * This should be replaceable by newer Node / Browser APIs + * + * @param {string} url + * @param {string} baseUrl + */ extractUrlParts(url, baseUrl) { // urlParts[1] = protocol://hostname/ OR / // urlParts[2] = / if path relative to host base @@ -79,7 +85,7 @@ class AbstractFileManager { // urlParts[4] = filename // urlParts[5] = parameters - const urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; + const urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^/?#]*\/)|([/\\]))?((?:[^/\\?#]*[/\\])*)([^/\\?#]*)([#?].*)?$/i; const urlParts = url.match(urlPartsRegex); const returner = {}; diff --git a/packages/less/src/less/environment/environment-api.js b/packages/less/src/less/environment/environment-api.js deleted file mode 100644 index 88d2927ea..000000000 --- a/packages/less/src/less/environment/environment-api.js +++ /dev/null @@ -1,25 +0,0 @@ -export default { - /** - * Converts a string to a base 64 string - * @param str - */ - encodeBase64: function(str) { - }, - /** - * Lookup the mime-type of a filename - * @param filename - */ - mimeLookup: function (filename) { - }, - /** - * Look up the charset of a mime type - * @param mime - */ - charsetLookup: function (mime) { - }, - /** - * Gets a source map generator - */ - getSourceMapGenerator: function getSourceMapGenerator() { - } -}; diff --git a/packages/less/src/less/environment/environment-api.ts b/packages/less/src/less/environment/environment-api.ts new file mode 100644 index 000000000..f3725a4ea --- /dev/null +++ b/packages/less/src/less/environment/environment-api.ts @@ -0,0 +1,21 @@ +export interface Environment { + /** + * Converts a string to a base 64 string + */ + encodeBase64(str: string): string + /** + * Lookup the mime-type of a filename + */ + mimeLookup(filename: string): string + /** + * Look up the charset of a mime type + * @param mime + */ + charsetLookup(mime: string): string + /** + * Gets a source map generator + * + * @todo - Figure out precise type + */ + getSourceMapGenerator(): any +} diff --git a/packages/less/src/less/environment/file-manager-api.js b/packages/less/src/less/environment/file-manager-api.js deleted file mode 100644 index 15cebeda0..000000000 --- a/packages/less/src/less/environment/file-manager-api.js +++ /dev/null @@ -1,103 +0,0 @@ -export default { - /** - * Given the full path to a file, return the path component - * Provided by AbstractFileManager - * @param {string} filename - * @returns {string} - */ - getPath: function(filename) { - }, - /** - * Append a .less extension if appropriate. Only called if less thinks one could be added. - * Provided by AbstractFileManager - * @param filename - * @returns {string} - */ - tryAppendLessExtension: function(filename) { - }, - /** - * Whether the rootpath should be converted to be absolute. - * The browser ovverides this to return true because urls must be absolute. - * Provided by AbstractFileManager (returns false) - * @returns {bool} - */ - alwaysMakePathsAbsolute: function() { - }, - /** - * Returns whether a path is absolute - * Provided by AbstractFileManager - * @param {string} path - * @returns {bool} - */ - isPathAbsolute: function(path) { - }, - /** - * joins together 2 paths - * Provided by AbstractFileManager - * @param {string} basePath - * @param {string} laterPath - */ - join: function(basePath, laterPath) { - }, - /** - * Returns the difference between 2 paths - * E.g. url = a/ baseUrl = a/b/ returns ../ - * url = a/b/ baseUrl = a/ returns b/ - * Provided by AbstractFileManager - * @param {string} url - * @param {string} baseUrl - * @returns {string} - */ - pathDiff: function(url, baseUrl) { - }, - /** - * Returns whether this file manager supports this file for syncronous file retrieval - * If true is returned, loadFileSync will then be called with the file. - * Provided by AbstractFileManager (returns false) - * @param {string} filename - * @param {string} currentDirectory - * @param {object} options - * @param {less.environment.environment} environment - * @returns {bool} - */ - supportsSync: function(filename, currentDirectory, options, environment) { - }, - /** - * - * @param {string} filename - * @param {string} currentDirectory - * @param {object} options - * @param {less.environment.environment} environment - * @returns {bool} - */ - supports: function(filename, currentDirectory, options, environment) { - }, - /** - * Loads a file asynchronously. Expects a promise that either rejects with an error or fulfills with an - * object containing - * { filename: - full resolved path to file - * contents: - the contents of the file, as a string } - * - * @param {string} filename - * @param {string} currentDirectory - * @param {object} options - * @param {less.environment.environment} environment - * @returns {Promise} - */ - loadFile: function(filename, currentDirectory, options, environment) { - }, - /** - * Loads a file synchronously. Expects an immediate return with an object containing - * { error: - error object if an error occurs - * filename: - full resolved path to file - * contents: - the contents of the file, as a string } - * - * @param {string} filename - * @param {string} currentDirectory - * @param {object} options - * @param {less.environment.environment} environment - * @returns {object} should be an object containing error or contents and filename - */ - loadFileSync: function(filename, currentDirectory, options, environment) { - } -}; diff --git a/packages/less/src/less/environment/file-manager-api.ts b/packages/less/src/less/environment/file-manager-api.ts new file mode 100644 index 000000000..47db48a25 --- /dev/null +++ b/packages/less/src/less/environment/file-manager-api.ts @@ -0,0 +1,77 @@ +import type { Environment } from './environment-api' + +export interface FileManager { + /** + * Given the full path to a file, return the path component + * Provided by AbstractFileManager + */ + getPath(filename: string): string + /** + * Append a .less extension if appropriate. Only called if less thinks one could be added. + * Provided by AbstractFileManager + */ + tryAppendLessExtension(filename: string): string + /** + * Whether the rootpath should be converted to be absolute. + * The browser ovverides this to return true because urls must be absolute. + * Provided by AbstractFileManager (returns false) + */ + alwaysMakePathsAbsolute(): boolean + /** + * Returns whether a path is absolute + * Provided by AbstractFileManager + */ + isPathAbsolute(path: string): boolean + /** + * joins together 2 paths + * Provided by AbstractFileManager + */ + join(basePath: string, laterPath: string): string + /** + * Returns the difference between 2 paths + * E.g. url = a/ baseUrl = a/b/ returns ../ + * url = a/b/ baseUrl = a/ returns b/ + * Provided by AbstractFileManager + */ + pathDiff(url: string, baseUrl: string): string + /** + * Returns whether this file manager supports this file for syncronous file retrieval + * If true is returned, loadFileSync will then be called with the file. + * Provided by AbstractFileManager (returns false) + * + * @todo - Narrow Options type + */ + supportsSync( + filename: string, + currentDirectory: string, + options: Record, + environment: Environment + ): boolean + /** + * If file manager supports async file retrieval for this file type + */ + supports( + filename: string, + currentDirectory: string, + options: Record, + environment: Environment + ): boolean + /** + * Loads a file asynchronously. + */ + loadFile( + filename: string, + currentDirectory: string, + options: Record, + environment: Environment + ): Promise<{ filename: string, contents: string }> + /** + * Loads a file synchronously. Expects an immediate return with an object + */ + loadFileSync( + filename: string, + currentDirectory: string, + options: Record, + environment: Environment + ): { error?: unknown, filename: string, contents: string } +} diff --git a/packages/less/src/less/functions/color-blending.js b/packages/less/src/less/functions/color-blending.js index 9f01626d2..c38a5e426 100644 --- a/packages/less/src/less/functions/color-blending.js +++ b/packages/less/src/less/functions/color-blending.js @@ -76,6 +76,7 @@ const colorBlendModeFunctions = { }; for (const f in colorBlendModeFunctions) { + // eslint-disable-next-line no-prototype-builtins if (colorBlendModeFunctions.hasOwnProperty(f)) { colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); } diff --git a/packages/less/src/less/functions/color.js b/packages/less/src/less/functions/color.js index f070e1690..c49d233ce 100644 --- a/packages/less/src/less/functions/color.js +++ b/packages/less/src/less/functions/color.js @@ -121,6 +121,25 @@ colorFunctions = { } }, hsla: function (h, s, l, a) { + let m1; + let m2; + + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { + return m1 + (m2 - m1) * h * 6; + } + else if (h * 2 < 1) { + return m2; + } + else if (h * 3 < 2) { + return m1 + (m2 - m1) * (2 / 3 - h) * 6; + } + else { + return m1; + } + } + try { if (h instanceof Color) { if (s) { @@ -131,25 +150,6 @@ colorFunctions = { return new Color(h.rgb, a, 'hsla'); } - let m1; - let m2; - - function hue(h) { - h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); - if (h * 6 < 1) { - return m1 + (m2 - m1) * h * 6; - } - else if (h * 2 < 1) { - return m2; - } - else if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - } - else { - return m1; - } - } - h = (number(h) % 360) / 360; s = clamp(number(s));l = clamp(number(l));a = clamp(number(a)); diff --git a/packages/less/src/less/functions/function-registry.js b/packages/less/src/less/functions/function-registry.js index 912a5acb7..82ee6f183 100644 --- a/packages/less/src/less/functions/function-registry.js +++ b/packages/less/src/less/functions/function-registry.js @@ -6,6 +6,7 @@ function makeRegistry( base ) { // the registry by function-caller uses lower case as well. name = name.toLowerCase(); + // eslint-disable-next-line no-prototype-builtins if (this._data.hasOwnProperty(name)) { // TODO warn } diff --git a/packages/less/src/less/functions/list.js b/packages/less/src/less/functions/list.js index 98a4c72c9..6ba33a305 100644 --- a/packages/less/src/less/functions/list.js +++ b/packages/less/src/less/functions/list.js @@ -142,14 +142,14 @@ export default { false, false, this.index, this.currentFileInfo)); } - rules.push(new Ruleset([ new(Selector)([ new Element("", '&') ]) ], + rules.push(new Ruleset([ new(Selector)([ new Element('', '&') ]) ], newRules, rs.strictImports, rs.visibilityInfo() )); } - return new Ruleset([ new(Selector)([ new Element("", '&') ]) ], + return new Ruleset([ new(Selector)([ new Element('', '&') ]) ], rules, rs.strictImports, rs.visibilityInfo() diff --git a/packages/less/src/less/functions/math.js b/packages/less/src/less/functions/math.js index f025dc2e2..0432eff60 100644 --- a/packages/less/src/less/functions/math.js +++ b/packages/less/src/less/functions/math.js @@ -15,6 +15,7 @@ const mathFunctions = { }; for (const f in mathFunctions) { + // eslint-disable-next-line no-prototype-builtins if (mathFunctions.hasOwnProperty(f)) { mathFunctions[f] = mathHelper.bind(null, Math[f], mathFunctions[f]); } diff --git a/packages/less/src/less/functions/svg.js b/packages/less/src/less/functions/svg.js index 3df96d66f..a1d06314c 100644 --- a/packages/less/src/less/functions/svg.js +++ b/packages/less/src/less/functions/svg.js @@ -4,7 +4,7 @@ import Expression from '../tree/expression'; import Quoted from '../tree/quoted'; import URL from '../tree/url'; -export default environment => { +export default () => { return { 'svg-gradient': function(direction) { let stops; let gradientDirectionSvg; diff --git a/packages/less/src/less/import-manager.js b/packages/less/src/less/import-manager.js index 227d120c4..350f242db 100644 --- a/packages/less/src/less/import-manager.js +++ b/packages/less/src/less/import-manager.js @@ -180,4 +180,4 @@ export default function(environment) { } return ImportManager; -}; +} diff --git a/packages/less/src/less/index.js b/packages/less/src/less/index.js index 4873f0b31..e10d0a12c 100644 --- a/packages/less/src/less/index.js +++ b/packages/less/src/less/index.js @@ -95,4 +95,4 @@ export default function(environment, fileManagers) { initial.render = initial.render.bind(api); return api; -}; +} diff --git a/packages/less/src/less/less-error.js b/packages/less/src/less/less-error.js index 9bd1aeb5a..a1399114c 100644 --- a/packages/less/src/less/less-error.js +++ b/packages/less/src/less/less-error.js @@ -62,8 +62,7 @@ const LessError = function(e, fileContentMap, currentFilename) { func(); } catch (e) { const match = e.stack.match(anonymousFunc); - var line = parseInt(match[2]); - lineAdjust = 1 - line; + lineAdjust = 1 - parseInt(match[2]); } if (found) { diff --git a/packages/less/src/less/parse-tree.js b/packages/less/src/less/parse-tree.js index 44f7deece..626ebb7b8 100644 --- a/packages/less/src/less/parse-tree.js +++ b/packages/less/src/less/parse-tree.js @@ -54,7 +54,7 @@ export default function(SourceMapBuilder) { result.imports = []; for (const file in this.imports.files) { - if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) { + if (Object.prototype.hasOwnProperty.call(this.imports.files, file) && file !== this.imports.rootFilename) { result.imports.push(file); } } @@ -63,4 +63,4 @@ export default function(SourceMapBuilder) { } return ParseTree; -}; +} diff --git a/packages/less/src/less/parse.js b/packages/less/src/less/parse.js index 931c9a91c..9a27e6155 100644 --- a/packages/less/src/less/parse.js +++ b/packages/less/src/less/parse.js @@ -39,7 +39,7 @@ export default function(environment, ParseTree, ImportManager) { rootFileInfo = options.rootFileInfo; } else { const filename = options.filename || 'input'; - const entryPath = filename.replace(/[^\/\\]*$/, ''); + const entryPath = filename.replace(/[^/\\]*$/, ''); rootFileInfo = { filename, rewriteUrls: context.rewriteUrls, @@ -84,4 +84,4 @@ export default function(environment, ParseTree, ImportManager) { } }; return parse; -}; +} diff --git a/packages/less/src/less/parser/chunker.js b/packages/less/src/less/parser/chunker.js index 8dae722f6..4274bac16 100644 --- a/packages/less/src/less/parser/chunker.js +++ b/packages/less/src/less/parser/chunker.js @@ -119,4 +119,4 @@ export default function (input, fail) { emitChunk(true); return chunks; -}; +} diff --git a/packages/less/src/less/parser/parser-input.js b/packages/less/src/less/parser/parser-input.js index 8e93a38a7..0823399d8 100644 --- a/packages/less/src/less/parser/parser-input.js +++ b/packages/less/src/less/parser/parser-input.js @@ -182,13 +182,14 @@ export default () => { case '\r': case '\n': break; - case startChar: + case startChar: { const str = input.substr(currentPosition, i + 1); if (!loc && loc !== 0) { skipWhitespace(i + 1); return str } return [startChar, str]; + } default: } } @@ -220,7 +221,6 @@ export default () => { } do { - let prevChar; let nextChar = input.charAt(i); if (blockDepth === 0 && testChar(nextChar)) { returnVal = input.substr(lastPos, i - lastPos); @@ -286,7 +286,7 @@ export default () => { break; case '}': case ')': - case ']': + case ']': { const expected = blockStack.pop(); if (nextChar === expected) { blockDepth--; @@ -296,13 +296,13 @@ export default () => { returnVal = expected; loop = false; } + } } i++; if (i > length) { loop = false; } } - prevChar = nextChar; } while (loop); return returnVal ? returnVal : null; diff --git a/packages/less/src/less/parser/parser.js b/packages/less/src/less/parser/parser.js index 1c05b145b..21e8f5cd0 100644 --- a/packages/less/src/less/parser/parser.js +++ b/packages/less/src/less/parser/parser.js @@ -163,7 +163,7 @@ const Parser = function Parser(context, imports, fileInfo) { error('@plugin statements are not allowed when disablePluginRule is set to true'); } } - }; + } globalVars = (additionalData && additionalData.globalVars) ? `${Parser.serializeVars(additionalData.globalVars)}\n` : ''; modifyVars = (additionalData && additionalData.modifyVars) ? `\n${Parser.serializeVars(additionalData.modifyVars)}` : ''; @@ -431,7 +431,7 @@ const Parser = function Parser(context, imports, fileInfo) { parserInput.save(); - name = parserInput.$re(/^([\w-]+|%|~|progid:[\w\.]+)\(/); + name = parserInput.$re(/^([\w-]+|%|~|progid:[\w.]+)\(/); if (!name) { parserInput.forget(); return; @@ -585,7 +585,7 @@ const Parser = function Parser(context, imports, fileInfo) { } value = this.quoted() || this.variable() || this.property() || - parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; + parserInput.$re(/^(?:(?:\\[()'"])|[^()'"])+/) || ''; parserInput.autoCommentAbsorb = true; @@ -670,7 +670,7 @@ const Parser = function Parser(context, imports, fileInfo) { let rgb; parserInput.save(); - if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { + if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#[])?/))) { if (!rgb[2]) { parserInput.forget(); return new(tree.Color)(rgb[1], undefined, rgb[0]); @@ -721,7 +721,7 @@ const Parser = function Parser(context, imports, fileInfo) { unicodeDescriptor: function () { let ud; - ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(-[0-9a-fA-F?]+)?/); if (ud) { return new(tree.UnicodeDescriptor)(ud[0]); } @@ -1170,7 +1170,6 @@ const Parser = function Parser(context, imports, fileInfo) { ruleLookups: function() { let rule; - let args; const lookups = []; if (parserInput.currentChar() !== '[') { @@ -1179,7 +1178,6 @@ const Parser = function Parser(context, imports, fileInfo) { while (true) { parserInput.save(); - args = null; rule = this.lookupValue(); if (!rule && rule !== '') { parserInput.restore(); @@ -1277,9 +1275,10 @@ const Parser = function Parser(context, imports, fileInfo) { c = this.combinator(); e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || + // eslint-disable-next-line no-control-regex parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || parserInput.$char('*') || parserInput.$char('&') || this.attribute() || - parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || + parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[.#:](?=@)/) || this.entities.variableCurly(); if (!e) { @@ -1398,11 +1397,11 @@ const Parser = function Parser(context, imports, fileInfo) { } parserInput.commentStore.length = 0; if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); + error('Guards are only currently allowed on a single selector.'); } if (!parserInput.$char(',')) { break; } if (s.condition) { - error("Guards are only currently allowed on a single selector."); + error('Guards are only currently allowed on a single selector.'); } parserInput.commentStore.length = 0; } @@ -1422,7 +1421,7 @@ const Parser = function Parser(context, imports, fileInfo) { let cif; if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + key = expect(/^(?:[_A-Za-z0-9-*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); } op = parserInput.$re(/^[|~*$^]?=/); @@ -1589,7 +1588,7 @@ const Parser = function Parser(context, imports, fileInfo) { }, anonymousValue: function () { const index = parserInput.i; - const match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); + const match = parserInput.$re(/^([^.#@$+/'"*`(;{}-]*);/); if (match) { return new(tree.Anonymous)(match[1], index); } @@ -1899,7 +1898,7 @@ const Parser = function Parser(context, imports, fileInfo) { parserInput.restore(); return null; } - const args = parserInput.$re(/^\s*([^\);]+)\)\s*/); + const args = parserInput.$re(/^\s*([^);]+)\)\s*/); if (args[1]) { parserInput.forget(); return args[1].trim(); @@ -2066,7 +2065,7 @@ const Parser = function Parser(context, imports, fileInfo) { if (m) { isSpaced = parserInput.isWhitespace(-1); while (true) { - if (parserInput.peek(/^\/[*\/]/)) { + if (parserInput.peek(/^\/[*/]/)) { break; } @@ -2241,7 +2240,7 @@ const Parser = function Parser(context, imports, fileInfo) { parserInput.forget(); return body; }, - atomicCondition: function (needsParens) { + atomicCondition: function () { const entities = this.entities; const index = parserInput.i; let a; @@ -2249,10 +2248,9 @@ const Parser = function Parser(context, imports, fileInfo) { let c; let op; - function cond() { + const cond = (function() { return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); - } - cond = cond.bind(this); + }).bind(this) a = cond(); if (a) { @@ -2301,7 +2299,7 @@ const Parser = function Parser(context, imports, fileInfo) { const entities = this.entities; let negate; - if (parserInput.peek(/^-[@\$\(]/)) { + if (parserInput.peek(/^-[@$(]/)) { negate = parserInput.$char('-'); } @@ -2347,7 +2345,7 @@ const Parser = function Parser(context, imports, fileInfo) { if (e) { entities.push(e); // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - if (!parserInput.peek(/^\/[\/*]/)) { + if (!parserInput.peek(/^\/[/*]/)) { delim = parserInput.$char('/'); if (delim) { entities.push(new(tree.Anonymous)(delim, index)); @@ -2391,7 +2389,7 @@ const Parser = function Parser(context, imports, fileInfo) { match(/^(\*?)/); while (true) { - if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { + if (!match(/^((?:[\w-]+)|(?:[@$]\{[\w-]+\}))/)) { break; } } diff --git a/packages/less/src/less/render.js b/packages/less/src/less/render.js index 9920d2fd1..8d25b1701 100644 --- a/packages/less/src/less/render.js +++ b/packages/less/src/less/render.js @@ -1,6 +1,6 @@ import * as utils from './utils'; -export default function(environment, ParseTree, ImportManager) { +export default function(environment, ParseTree) { const render = function (input, options, callback) { if (typeof options === 'function') { callback = options; @@ -38,4 +38,4 @@ export default function(environment, ParseTree, ImportManager) { }; return render; -}; +} diff --git a/packages/less/src/less/source-map-builder.js b/packages/less/src/less/source-map-builder.js index 53a6860a5..dcf40dfcd 100644 --- a/packages/less/src/less/source-map-builder.js +++ b/packages/less/src/less/source-map-builder.js @@ -79,4 +79,4 @@ export default function (SourceMapOutput, environment) { } return SourceMapBuilder; -}; +} diff --git a/packages/less/src/less/source-map-output.js b/packages/less/src/less/source-map-output.js index 1878d6f76..93d43d376 100644 --- a/packages/less/src/less/source-map-output.js +++ b/packages/less/src/less/source-map-output.js @@ -116,6 +116,7 @@ export default function (environment) { if (this._outputSourceFiles) { for (const filename in this._contentsMap) { + // eslint-disable-next-line no-prototype-builtins if (this._contentsMap.hasOwnProperty(filename)) { let source = this._contentsMap[filename]; if (this._contentsIgnoredCharsMap[filename]) { @@ -147,4 +148,4 @@ export default function (environment) { } return SourceMapOutput; -}; +} diff --git a/packages/less/src/less/transform-tree.js b/packages/less/src/less/transform-tree.js index 92479b73c..8426f3201 100644 --- a/packages/less/src/less/transform-tree.js +++ b/packages/less/src/less/transform-tree.js @@ -54,7 +54,7 @@ export default function(root, options) { */ if (options.pluginManager) { visitorIterator = options.pluginManager.visitor(); - for (var i = 0; i < 2; i++) { + for (let i = 0; i < 2; i++) { visitorIterator.first(); while ((v = visitorIterator.get())) { if (v.isPreEvalVisitor) { @@ -79,7 +79,7 @@ export default function(root, options) { evaldRoot = root.eval(evalEnv); - for (var i = 0; i < visitors.length; i++) { + for (let i = 0; i < visitors.length; i++) { visitors[i].run(evaldRoot); } @@ -94,4 +94,4 @@ export default function(root, options) { } return evaldRoot; -}; +} diff --git a/packages/less/src/less/tree/attribute.js b/packages/less/src/less/tree/attribute.js index 0fa07eaba..e716d13d8 100644 --- a/packages/less/src/less/tree/attribute.js +++ b/packages/less/src/less/tree/attribute.js @@ -32,7 +32,7 @@ Attribute.prototype = Object.assign(new Node(), { } if (this.cif) { - value = value + " " + this.cif; + value = value + ' ' + this.cif; } return `[${value}]`; diff --git a/packages/less/src/less/tree/call.js b/packages/less/src/less/tree/call.js index 61ed0173c..15e98eb80 100644 --- a/packages/less/src/less/tree/call.js +++ b/packages/less/src/less/tree/call.js @@ -58,6 +58,7 @@ Call.prototype = Object.assign(new Node(), { result = funcCaller.call(this.args); exitCalc(); } catch (e) { + // eslint-disable-next-line no-prototype-builtins if (e.hasOwnProperty('line') && e.hasOwnProperty('column')) { throw e; } diff --git a/packages/less/src/less/tree/color.js b/packages/less/src/less/tree/color.js index df068a59f..906e69167 100644 --- a/packages/less/src/less/tree/color.js +++ b/packages/less/src/less/tree/color.js @@ -96,6 +96,7 @@ Color.prototype = Object.assign(new Node(), { break; case 'hsla': args.push(clamp(alpha, 1)); + // eslint-disable-next-line no-fallthrough case 'hsl': color = this.toHSL(); args = [ @@ -212,6 +213,7 @@ Color.prototype = Object.assign(new Node(), { Color.fromKeyword = function(keyword) { let c; const key = keyword.toLowerCase(); + // eslint-disable-next-line no-prototype-builtins if (colors.hasOwnProperty(key)) { c = new Color(colors[key].slice(1)); } diff --git a/packages/less/src/less/tree/debug-info.js b/packages/less/src/less/tree/debug-info.js index 804e71723..3500e2bbf 100644 --- a/packages/less/src/less/tree/debug-info.js +++ b/packages/less/src/less/tree/debug-info.js @@ -7,9 +7,9 @@ function asMediaQuery(ctx) { if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { filenameWithProtocol = `file://${filenameWithProtocol}`; } - return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { + return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:/\\])/g, function (a) { if (a == '\\') { - a = '\/'; + a = '/'; } return `\\${a}`; })}}line{font-family:\\00003${ctx.debugInfo.lineNumber}}}\n`; diff --git a/packages/less/src/less/tree/dimension.js b/packages/less/src/less/tree/dimension.js index 8cbb3249d..838bd10e9 100644 --- a/packages/less/src/less/tree/dimension.js +++ b/packages/less/src/less/tree/dimension.js @@ -1,3 +1,4 @@ +/* eslint-disable no-prototype-builtins */ import Node from './node'; import unitConversions from '../data/unit-conversions'; import Unit from './unit'; @@ -23,6 +24,8 @@ Dimension.prototype = Object.assign(new Node(), { this.unit = visitor.visit(this.unit); }, + // remove when Nodes have JSDoc types + // eslint-disable-next-line no-unused-vars eval(context) { return this; }, @@ -81,7 +84,7 @@ Dimension.prototype = Object.assign(new Node(), { other = other.convertTo(this.unit.usedUnits()); if (context.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error(`Incompatible units. Change the units or use the unit function. ` + throw new Error('Incompatible units. Change the units or use the unit function. ' + `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`); } @@ -144,7 +147,6 @@ Dimension.prototype = Object.assign(new Node(), { conversions = derivedConversions; } applyUnit = function (atomicUnit, denominator) { - /* jshint loopfunc:true */ if (group.hasOwnProperty(atomicUnit)) { if (denominator) { value = value / (group[atomicUnit] / group[targetUnit]); diff --git a/packages/less/src/less/tree/extend.js b/packages/less/src/less/tree/extend.js index 6e10246bf..5468a5526 100644 --- a/packages/less/src/less/tree/extend.js +++ b/packages/less/src/less/tree/extend.js @@ -35,6 +35,8 @@ Extend.prototype = Object.assign(new Node(), { return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); }, + // remove when Nodes have JSDoc types + // eslint-disable-next-line no-unused-vars clone(context) { return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); }, diff --git a/packages/less/src/less/tree/import.js b/packages/less/src/less/tree/import.js index 00cfc7037..abafa3d9f 100644 --- a/packages/less/src/less/tree/import.js +++ b/packages/less/src/less/tree/import.js @@ -31,7 +31,7 @@ const Import = function(path, features, options, index, currentFileInfo, visibil this.css = !this.options.less || this.options.inline; } else { const pathValue = this.getPath(); - if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { + if (pathValue && /[#.&?]css([?;].*)?$/.test(pathValue)) { this.css = true; } } diff --git a/packages/less/src/less/tree/js-eval-node.js b/packages/less/src/less/tree/js-eval-node.js index 8874f5f18..e57a22140 100644 --- a/packages/less/src/less/tree/js-eval-node.js +++ b/packages/less/src/less/tree/js-eval-node.js @@ -29,8 +29,8 @@ JsEvalNode.prototype = Object.assign(new Node(), { const variables = context.frames[0].variables(); for (const k in variables) { + // eslint-disable-next-line no-prototype-builtins if (variables.hasOwnProperty(k)) { - /* jshint loopfunc:true */ evalContext[k.slice(1)] = { value: variables[k].value, toJS: function () { diff --git a/packages/less/src/less/tree/namespace-value.js b/packages/less/src/less/tree/namespace-value.js index adbd9ea36..fd96ef612 100644 --- a/packages/less/src/less/tree/namespace-value.js +++ b/packages/less/src/less/tree/namespace-value.js @@ -14,7 +14,7 @@ NamespaceValue.prototype = Object.assign(new Node(), { type: 'NamespaceValue', eval(context) { - let i, j, name, rules = this.value.eval(context); + let i, name, rules = this.value.eval(context); for (i = 0; i < this.lookups.length; i++) { name = this.lookups[i]; diff --git a/packages/less/src/less/tree/node.js b/packages/less/src/less/tree/node.js index 4aadc261c..a57390307 100644 --- a/packages/less/src/less/tree/node.js +++ b/packages/less/src/less/tree/node.js @@ -1,10 +1,8 @@ -import * as utils from '../utils'; - /** * The reason why Node is a class and other nodes simply do not extend * from Node (since we're transpiling) is due to this issue: * - * https://github.com/less/less.js/issues/3434 + * @see https://github.com/less/less.js/issues/3434 */ class Node { constructor() { @@ -50,6 +48,8 @@ class Node { toCSS(context) { const strs = []; this.genCSS(context, { + // remove when genCSS has JSDoc types + // eslint-disable-next-line no-unused-vars add: function(chunk, fileInfo, index) { strs.push(chunk); }, diff --git a/packages/less/src/less/tree/quoted.js b/packages/less/src/less/tree/quoted.js index 7c96c0ecd..cb0d56b12 100644 --- a/packages/less/src/less/tree/quoted.js +++ b/packages/less/src/less/tree/quoted.js @@ -1,8 +1,6 @@ import Node from './node'; import Variable from './variable'; import Property from './property'; -import * as utils from '../utils'; - const Quoted = function(str, content, escaped, index, currentFileInfo) { this.escaped = (escaped === undefined) ? true : escaped; diff --git a/packages/less/src/less/tree/ruleset.js b/packages/less/src/less/tree/ruleset.js index dfd044932..b0d0a4b57 100644 --- a/packages/less/src/less/tree/ruleset.js +++ b/packages/less/src/less/tree/ruleset.js @@ -44,7 +44,6 @@ Ruleset.prototype = Object.assign(new Node(), { }, eval(context) { - const that = this; let selectors; let selCnt; let selector; @@ -61,7 +60,7 @@ Ruleset.prototype = Object.assign(new Node(), { for (i = 0; i < selCnt; i++) { selector = this.selectors[i].eval(context); - for (var j = 0; j < selector.elements.length; j++) { + for (let j = 0; j < selector.elements.length; j++) { if (selector.elements[j].isVariable) { hasVariable = true; break; @@ -81,7 +80,7 @@ Ruleset.prototype = Object.assign(new Node(), { } this.parse.parseNode( toParseSelectors.join(','), - ["selectors"], + ['selectors'], selectors[0].getIndex(), selectors[0].fileInfo(), function(err, result) { @@ -200,7 +199,7 @@ Ruleset.prototype = Object.assign(new Node(), { if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { rsRules.splice(i--, 1); - for (var j = 0; (subRule = rule.rules[j]); j++) { + for (let j = 0; (subRule = rule.rules[j]); j++) { if (subRule instanceof Node) { subRule.copyVisibilityInfo(rule.visibilityInfo()); if (!(subRule instanceof Declaration) || !subRule.variable) { @@ -295,6 +294,7 @@ Ruleset.prototype = Object.assign(new Node(), { if (r.type === 'Import' && r.root && r.root.variables) { const vars = r.root.variables(); for (const name in vars) { + // eslint-disable-next-line no-prototype-builtins if (vars.hasOwnProperty(name)) { hash[name] = r.root.variable(name); } diff --git a/packages/less/src/less/tree/selector.js b/packages/less/src/less/tree/selector.js index d098cc2bc..6dbceb025 100644 --- a/packages/less/src/less/tree/selector.js +++ b/packages/less/src/less/tree/selector.js @@ -96,7 +96,7 @@ Selector.prototype = Object.assign(new Node(), { let elements = this.elements.map( function(v) { return v.combinator.value + (v.value.value || v.value); - }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); + }).join('').match(/[,&#*.\w-]([\w-]|(\\.))*/g); if (elements) { if (elements[0] === '&') { diff --git a/packages/less/src/less/tree/unit.js b/packages/less/src/less/tree/unit.js index 3943ad2c6..946b098fd 100644 --- a/packages/less/src/less/tree/unit.js +++ b/packages/less/src/less/tree/unit.js @@ -78,7 +78,7 @@ Unit.prototype = Object.assign(new Node(), { let groupName; mapUnit = function (atomicUnit) { - /* jshint loopfunc:true */ + // eslint-disable-next-line no-prototype-builtins if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { result[groupName] = atomicUnit; } @@ -87,6 +87,7 @@ Unit.prototype = Object.assign(new Node(), { }; for (groupName in unitConversions) { + // eslint-disable-next-line no-prototype-builtins if (unitConversions.hasOwnProperty(groupName)) { group = unitConversions[groupName]; @@ -116,6 +117,7 @@ Unit.prototype = Object.assign(new Node(), { this.denominator = []; for (atomicUnit in counter) { + // eslint-disable-next-line no-prototype-builtins if (counter.hasOwnProperty(atomicUnit)) { const count = counter[atomicUnit]; diff --git a/packages/less/src/less/tree/url.js b/packages/less/src/less/tree/url.js index f0f329cab..90f73d935 100644 --- a/packages/less/src/less/tree/url.js +++ b/packages/less/src/less/tree/url.js @@ -1,7 +1,7 @@ import Node from './node'; function escapePath(path) { - return path.replace(/[\(\)'"\s]/g, function(match) { return `\\${match}`; }); + return path.replace(/[()'"\s]/g, function(match) { return `\\${match}`; }); } const URL = function(val, index, currentFileInfo, isEvald) { @@ -33,7 +33,7 @@ URL.prototype = Object.assign(new Node(), { rootpath = this.fileInfo() && this.fileInfo().rootpath; if (typeof rootpath === 'string' && typeof val.value === 'string' && - context.pathRequiresRewrite(val.value)) { + context.pathRequiresRewrite(val.value)) { if (!val.quote) { rootpath = escapePath(rootpath); } diff --git a/packages/less/src/less/utils.js b/packages/less/src/less/utils.js index b723ab2ac..f78d611a6 100644 --- a/packages/less/src/less/utils.js +++ b/packages/less/src/less/utils.js @@ -35,7 +35,7 @@ export function copyArray(arr) { export function clone(obj) { const cloned = {}; for (const prop in obj) { - if (obj.hasOwnProperty(prop)) { + if (Object.prototype.hasOwnProperty.call(obj, prop)) { cloned[prop] = obj[prop]; } } @@ -100,7 +100,7 @@ export function copyOptions(obj1, obj2) { export function merge(obj1, obj2) { for (const prop in obj2) { - if (obj2.hasOwnProperty(prop)) { + if (Object.prototype.hasOwnProperty.call(obj2, prop)) { obj1[prop] = obj2[prop]; } } diff --git a/packages/less/src/less/visitors/extend-visitor.js b/packages/less/src/less/visitors/extend-visitor.js index 04a538f08..91bcb8081 100644 --- a/packages/less/src/less/visitors/extend-visitor.js +++ b/packages/less/src/less/visitors/extend-visitor.js @@ -1,3 +1,7 @@ +/* eslint-disable no-unused-vars */ +/** + * @todo - Remove unused when JSDoc types are added for visitor methods + */ import tree from '../tree'; import Visitor from './visitor'; import logger from '../logger'; diff --git a/packages/less/src/less/visitors/import-visitor.js b/packages/less/src/less/visitors/import-visitor.js index 1f102d85f..29a661bff 100644 --- a/packages/less/src/less/visitors/import-visitor.js +++ b/packages/less/src/less/visitors/import-visitor.js @@ -1,3 +1,7 @@ +/* eslint-disable no-unused-vars */ +/** + * @todo - Remove unused when JSDoc types are added for visitor methods + */ import contexts from '../contexts'; import Visitor from './visitor'; import ImportSequencer from './import-sequencer'; diff --git a/packages/less/src/less/visitors/join-selector-visitor.js b/packages/less/src/less/visitors/join-selector-visitor.js index 6ec312709..1dd47e904 100644 --- a/packages/less/src/less/visitors/join-selector-visitor.js +++ b/packages/less/src/less/visitors/join-selector-visitor.js @@ -1,3 +1,7 @@ +/* eslint-disable no-unused-vars */ +/** + * @todo - Remove unused when JSDoc types are added for visitor methods + */ import Visitor from './visitor'; class JoinSelectorVisitor { diff --git a/packages/less/src/less/visitors/to-css-visitor.js b/packages/less/src/less/visitors/to-css-visitor.js index 6654f8a82..54ddd6398 100644 --- a/packages/less/src/less/visitors/to-css-visitor.js +++ b/packages/less/src/less/visitors/to-css-visitor.js @@ -1,3 +1,7 @@ +/* eslint-disable no-unused-vars */ +/** + * @todo - Remove unused when JSDoc types are added for visitor methods + */ import tree from '../tree'; import Visitor from './visitor'; diff --git a/packages/less/tsconfig.json b/packages/less/tsconfig.json index 3b3051324..9878b5110 100644 --- a/packages/less/tsconfig.json +++ b/packages/less/tsconfig.json @@ -7,6 +7,7 @@ "inlineSources": true, "esModuleInterop": true, "importHelpers": true, + "noImplicitAny": true, "target": "ES5" }, "ts-node": {