UNPKG

html-minifier-next

Version:

Highly configurable, well-tested, JavaScript-based HTML minifier.

1,745 lines (1,481 loc) 2 MB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.HTMLMinifier = {})); })(this, (function (exports) { 'use strict'; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function getAugmentedNamespace(n) { if (Object.prototype.hasOwnProperty.call(n, '__esModule')) return n; var f = n.default; if (typeof f == "function") { var a = function a () { var isInstance = false; try { isInstance = this instanceof a; } catch {} if (isInstance) { return Reflect.construct(f, arguments, this.constructor); } return f.apply(this, arguments); }; a.prototype = f.prototype; } else a = {}; Object.defineProperty(a, '__esModule', {value: true}); Object.keys(n).forEach(function (k) { var d = Object.getOwnPropertyDescriptor(n, k); Object.defineProperty(a, k, d.get ? d : { enumerable: true, get: function () { return n[k]; } }); }); return a; } var global$1 = (typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}); // shim for using process in browser // based off https://github.com/defunctzombie/node-process/blob/master/browser.js function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } var cachedSetTimeout = defaultSetTimout; var cachedClearTimeout = defaultClearTimeout; if (typeof global$1.setTimeout === 'function') { cachedSetTimeout = setTimeout; } if (typeof global$1.clearTimeout === 'function') { cachedClearTimeout = clearTimeout; } function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations return setTimeout(fun, 0); } // if setTimeout wasn't available but was latter defined if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) { cachedSetTimeout = setTimeout; return setTimeout(fun, 0); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } } } function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations return clearTimeout(marker); } // if clearTimeout wasn't available but was latter defined if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) { cachedClearTimeout = clearTimeout; return clearTimeout(marker); } try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); } } } var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { if (!draining || !currentQueue) { return; } draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = runTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; runClearTimeout(timeout); } function nextTick(fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { runTimeout(drainQueue); } } // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; var title = 'browser'; var platform$1 = 'browser'; var browser = true; var env = {}; var argv = []; var version = ''; // empty string to avoid regexp issues var versions = {}; var release$1 = {}; var config = {}; function noop$1() {} var on = noop$1; var addListener = noop$1; var once = noop$1; var off = noop$1; var removeListener = noop$1; var removeAllListeners = noop$1; var emit = noop$1; function binding(name) { throw new Error('process.binding is not supported'); } function cwd () { return '/' } function chdir (dir) { throw new Error('process.chdir is not supported'); }function umask() { return 0; } // from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js var performance = global$1.performance || {}; var performanceNow = performance.now || performance.mozNow || performance.msNow || performance.oNow || performance.webkitNow || function(){ return (new Date()).getTime() }; // generate timestamp or delta // see http://nodejs.org/api/process.html#process_process_hrtime function hrtime(previousTimestamp){ var clocktime = performanceNow.call(performance)*1e-3; var seconds = Math.floor(clocktime); var nanoseconds = Math.floor((clocktime%1)*1e9); if (previousTimestamp) { seconds = seconds - previousTimestamp[0]; nanoseconds = nanoseconds - previousTimestamp[1]; if (nanoseconds<0) { seconds--; nanoseconds += 1e9; } } return [seconds,nanoseconds] } var startTime = new Date(); function uptime$1() { var currentTime = new Date(); var dif = currentTime - startTime; return dif / 1000; } var browser$1 = { nextTick: nextTick, title: title, browser: browser, env: env, argv: argv, version: version, versions: versions, on: on, addListener: addListener, once: once, off: off, removeListener: removeListener, removeAllListeners: removeAllListeners, emit: emit, binding: binding, cwd: cwd, chdir: chdir, umask: umask, hrtime: hrtime, platform: platform$1, release: release$1, config: config, uptime: uptime$1 }; var clean = {exports: {}}; var optimize$3; var hasRequiredOptimize$3; function requireOptimize$3 () { if (hasRequiredOptimize$3) return optimize$3; hasRequiredOptimize$3 = 1; function level0Optimize(tokens) { // noop as level 0 means no optimizations! return tokens; } optimize$3 = level0Optimize; return optimize$3; } var naturalCompare_1; var hasRequiredNaturalCompare; function requireNaturalCompare () { if (hasRequiredNaturalCompare) return naturalCompare_1; hasRequiredNaturalCompare = 1; // adapted from http://nedbatchelder.com/blog/200712.html#e20071211T054956 var NUMBER_PATTERN = /([0-9]+)/; function naturalCompare(value1, value2) { var keys1 = ('' + value1).split(NUMBER_PATTERN).map(tryParseInt); var keys2 = ('' + value2).split(NUMBER_PATTERN).map(tryParseInt); var key1; var key2; var compareFirst = Math.min(keys1.length, keys2.length); var i, l; for (i = 0, l = compareFirst; i < l; i++) { key1 = keys1[i]; key2 = keys2[i]; if (key1 != key2) { return key1 > key2 ? 1 : -1; } } return keys1.length > keys2.length ? 1 : (keys1.length == keys2.length ? 0 : -1); } function tryParseInt(value) { return ('' + parseInt(value)) == value ? parseInt(value) : value; } naturalCompare_1 = naturalCompare; return naturalCompare_1; } var sortSelectors_1; var hasRequiredSortSelectors; function requireSortSelectors () { if (hasRequiredSortSelectors) return sortSelectors_1; hasRequiredSortSelectors = 1; var naturalCompare = requireNaturalCompare(); function naturalSorter(scope1, scope2) { return naturalCompare(scope1[1], scope2[1]); } function standardSorter(scope1, scope2) { return scope1[1] > scope2[1] ? 1 : -1; } function sortSelectors(selectors, method) { switch (method) { case 'natural': return selectors.sort(naturalSorter); case 'standard': return selectors.sort(standardSorter); case 'none': case false: return selectors; } } sortSelectors_1 = sortSelectors; return sortSelectors_1; } var override_1; var hasRequiredOverride; function requireOverride () { if (hasRequiredOverride) return override_1; hasRequiredOverride = 1; function override(source1, source2) { var target = {}; var key1; var key2; var item; for (key1 in source1) { item = source1[key1]; if (Array.isArray(item)) { target[key1] = item.slice(0); } else if (typeof item == 'object' && item !== null) { target[key1] = override(item, {}); } else { target[key1] = item; } } for (key2 in source2) { item = source2[key2]; if (key2 in target && Array.isArray(item)) { target[key2] = item.slice(0); } else if (key2 in target && typeof item == 'object' && item !== null) { target[key2] = override(target[key2], item); } else { target[key2] = item; } } return target; } override_1 = override; return override_1; } /* The MIT License (MIT) Copyright (c) 2016 CoderPuppy Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var _endianness; function endianness() { if (typeof _endianness === 'undefined') { var a = new ArrayBuffer(2); var b = new Uint8Array(a); var c = new Uint16Array(a); b[0] = 1; b[1] = 2; if (c[0] === 258) { _endianness = 'BE'; } else if (c[0] === 513){ _endianness = 'LE'; } else { throw new Error('unable to figure out endianess'); } } return _endianness; } function hostname() { if (typeof global$1.location !== 'undefined') { return global$1.location.hostname } else return ''; } function loadavg() { return []; } function uptime() { return 0; } function freemem() { return Number.MAX_VALUE; } function totalmem() { return Number.MAX_VALUE; } function cpus() { return []; } function type() { return 'Browser'; } function release () { if (typeof global$1.navigator !== 'undefined') { return global$1.navigator.appVersion; } return ''; } function networkInterfaces () { return {}; } function getNetworkInterfaces () { return {}; } function arch() { return 'javascript'; } function platform() { return 'browser'; } function tmpDir() { return '/tmp'; } var tmpdir = tmpDir; var EOL = '\n'; function homedir(){ return '$HOME' } var _polyfillNode_os = { homedir: homedir, EOL: EOL, arch: arch, platform: platform, tmpdir: tmpdir, tmpDir: tmpDir, networkInterfaces:networkInterfaces, getNetworkInterfaces: getNetworkInterfaces, release: release, type: type, cpus: cpus, totalmem: totalmem, freemem: freemem, uptime: uptime, loadavg: loadavg, hostname: hostname, endianness: endianness, }; var _polyfillNode_os$1 = /*#__PURE__*/Object.freeze({ __proto__: null, EOL: EOL, arch: arch, cpus: cpus, default: _polyfillNode_os, endianness: endianness, freemem: freemem, getNetworkInterfaces: getNetworkInterfaces, homedir: homedir, hostname: hostname, loadavg: loadavg, networkInterfaces: networkInterfaces, platform: platform, release: release, tmpDir: tmpDir, tmpdir: tmpdir, totalmem: totalmem, type: type, uptime: uptime }); var require$$1$2 = /*@__PURE__*/getAugmentedNamespace(_polyfillNode_os$1); var format$3; var hasRequiredFormat$1; function requireFormat$1 () { if (hasRequiredFormat$1) return format$3; hasRequiredFormat$1 = 1; var override = requireOverride(); function getSystemLineBreak() { var systemLineBreak = '\n'; try { var os = require$$1$2; systemLineBreak = os.EOL; } catch (_) { // no op } return systemLineBreak; } var Breaks = { AfterAtRule: 'afterAtRule', AfterBlockBegins: 'afterBlockBegins', AfterBlockEnds: 'afterBlockEnds', AfterComment: 'afterComment', AfterProperty: 'afterProperty', AfterRuleBegins: 'afterRuleBegins', AfterRuleEnds: 'afterRuleEnds', BeforeBlockEnds: 'beforeBlockEnds', BetweenSelectors: 'betweenSelectors' }; var BreakWith = { CarriageReturnLineFeed: '\r\n', LineFeed: '\n', System: getSystemLineBreak() }; var IndentWith = { Space: ' ', Tab: '\t' }; var Spaces = { AroundSelectorRelation: 'aroundSelectorRelation', BeforeBlockBegins: 'beforeBlockBegins', BeforeValue: 'beforeValue' }; var DEFAULTS = { breaks: breaks(false), breakWith: BreakWith.System, indentBy: 0, indentWith: IndentWith.Space, spaces: spaces(false), wrapAt: false, semicolonAfterLastProperty: false }; var BEAUTIFY_ALIAS = 'beautify'; var KEEP_BREAKS_ALIAS = 'keep-breaks'; var OPTION_SEPARATOR = ';'; var OPTION_NAME_VALUE_SEPARATOR = ':'; var HASH_VALUES_OPTION_SEPARATOR = ','; var HASH_VALUES_NAME_VALUE_SEPARATOR = '='; var FALSE_KEYWORD_1 = 'false'; var FALSE_KEYWORD_2 = 'off'; var TRUE_KEYWORD_1 = 'true'; var TRUE_KEYWORD_2 = 'on'; function breaks(value) { var breakOptions = {}; breakOptions[Breaks.AfterAtRule] = value; breakOptions[Breaks.AfterBlockBegins] = value; breakOptions[Breaks.AfterBlockEnds] = value; breakOptions[Breaks.AfterComment] = value; breakOptions[Breaks.AfterProperty] = value; breakOptions[Breaks.AfterRuleBegins] = value; breakOptions[Breaks.AfterRuleEnds] = value; breakOptions[Breaks.BeforeBlockEnds] = value; breakOptions[Breaks.BetweenSelectors] = value; return breakOptions; } function spaces(value) { var spaceOptions = {}; spaceOptions[Spaces.AroundSelectorRelation] = value; spaceOptions[Spaces.BeforeBlockBegins] = value; spaceOptions[Spaces.BeforeValue] = value; return spaceOptions; } function formatFrom(source) { if (source === undefined || source === false) { return false; } if (typeof source == 'object' && 'breakWith' in source) { source = override(source, { breakWith: mapBreakWith(source.breakWith) }); } if (typeof source == 'object' && 'indentBy' in source) { source = override(source, { indentBy: parseInt(source.indentBy) }); } if (typeof source == 'object' && 'indentWith' in source) { source = override(source, { indentWith: mapIndentWith(source.indentWith) }); } if (typeof source == 'object') { return remapBreaks(override(DEFAULTS, source)); } if (typeof source == 'string' && source == BEAUTIFY_ALIAS) { return remapBreaks( override(DEFAULTS, { breaks: breaks(true), indentBy: 2, spaces: spaces(true) }) ); } if (typeof source == 'string' && source == KEEP_BREAKS_ALIAS) { return remapBreaks( override(DEFAULTS, { breaks: { afterAtRule: true, afterBlockBegins: true, afterBlockEnds: true, afterComment: true, afterRuleEnds: true, beforeBlockEnds: true } }) ); } if (typeof source == 'string') { return remapBreaks(override(DEFAULTS, toHash(source))); } return DEFAULTS; } function toHash(string) { return string .split(OPTION_SEPARATOR) .reduce(function(accumulator, directive) { var parts = directive.split(OPTION_NAME_VALUE_SEPARATOR); var name = parts[0]; var value = parts[1]; if (name == 'breaks' || name == 'spaces') { accumulator[name] = hashValuesToHash(value); } else if (name == 'indentBy' || name == 'wrapAt') { accumulator[name] = parseInt(value); } else if (name == 'indentWith') { accumulator[name] = mapIndentWith(value); } else if (name == 'breakWith') { accumulator[name] = mapBreakWith(value); } return accumulator; }, {}); } function hashValuesToHash(string) { return string .split(HASH_VALUES_OPTION_SEPARATOR) .reduce(function(accumulator, directive) { var parts = directive.split(HASH_VALUES_NAME_VALUE_SEPARATOR); var name = parts[0]; var value = parts[1]; accumulator[name] = normalizeValue(value); return accumulator; }, {}); } function normalizeValue(value) { switch (value) { case FALSE_KEYWORD_1: case FALSE_KEYWORD_2: return false; case TRUE_KEYWORD_1: case TRUE_KEYWORD_2: return true; default: return value; } } function mapBreakWith(value) { switch (value) { case 'windows': case 'crlf': case BreakWith.CarriageReturnLineFeed: return BreakWith.CarriageReturnLineFeed; case 'unix': case 'lf': case BreakWith.LineFeed: return BreakWith.LineFeed; default: return BreakWith.System; } } function mapIndentWith(value) { switch (value) { case 'space': return IndentWith.Space; case 'tab': return IndentWith.Tab; default: return value; } } function remapBreaks(source) { for (var key in Breaks) { var breakName = Breaks[key]; var breakValue = source.breaks[breakName]; if (breakValue === true) { source.breaks[breakName] = source.breakWith; } else if (breakValue === false) { source.breaks[breakName] = ''; } else { source.breaks[breakName] = source.breakWith.repeat(parseInt(breakValue)); } } return source; } format$3 = { Breaks: Breaks, Spaces: Spaces, formatFrom: formatFrom }; return format$3; } var marker; var hasRequiredMarker; function requireMarker () { if (hasRequiredMarker) return marker; hasRequiredMarker = 1; var Marker = { ASTERISK: '*', AT: '@', BACK_SLASH: '\\', CARRIAGE_RETURN: '\r', CLOSE_CURLY_BRACKET: '}', CLOSE_ROUND_BRACKET: ')', CLOSE_SQUARE_BRACKET: ']', COLON: ':', COMMA: ',', DOUBLE_QUOTE: '"', EXCLAMATION: '!', FORWARD_SLASH: '/', INTERNAL: '-clean-css-', NEW_LINE_NIX: '\n', OPEN_CURLY_BRACKET: '{', OPEN_ROUND_BRACKET: '(', OPEN_SQUARE_BRACKET: '[', SEMICOLON: ';', SINGLE_QUOTE: '\'', SPACE: ' ', TAB: '\t', UNDERSCORE: '_' }; marker = Marker; return marker; } var formatPosition_1; var hasRequiredFormatPosition; function requireFormatPosition () { if (hasRequiredFormatPosition) return formatPosition_1; hasRequiredFormatPosition = 1; function formatPosition(metadata) { var line = metadata[0]; var column = metadata[1]; var source = metadata[2]; return source ? source + ':' + line + ':' + column : line + ':' + column; } formatPosition_1 = formatPosition; return formatPosition_1; } var tidyRules_1; var hasRequiredTidyRules; function requireTidyRules () { if (hasRequiredTidyRules) return tidyRules_1; hasRequiredTidyRules = 1; var Spaces = requireFormat$1().Spaces; var Marker = requireMarker(); var formatPosition = requireFormatPosition(); var CASE_ATTRIBUTE_PATTERN = /[\s"'][iI]\s*\]/; var CASE_RESTORE_PATTERN = /([\d\w])([iI])\]/g; var DOUBLE_QUOTE_CASE_PATTERN = /="([a-zA-Z][a-zA-Z\d\-_]+)"([iI])/g; var DOUBLE_QUOTE_PATTERN = /="([a-zA-Z][a-zA-Z\d\-_]+)"(\s|\])/g; var HTML_COMMENT_PATTERN = /^(?:(?:<!--|-->)\s*)+/; var SINGLE_QUOTE_CASE_PATTERN = /='([a-zA-Z][a-zA-Z\d\-_]+)'([iI])/g; var SINGLE_QUOTE_PATTERN = /='([a-zA-Z][a-zA-Z\d\-_]+)'(\s|\])/g; var RELATION_PATTERN = /[>+~]/; var WHITESPACE_PATTERN = /\s/; var ASTERISK_PLUS_HTML_HACK = '*+html '; var ASTERISK_FIRST_CHILD_PLUS_HTML_HACK = '*:first-child+html '; var LESS_THAN = '<'; var PSEUDO_CLASSES_WITH_SELECTORS = [ ':current', ':future', ':has', ':host', ':host-context', ':is', ':not', ':past', ':where' ]; function hasInvalidCharacters(value) { var isEscaped; var isInvalid = false; var character; var isQuote = false; var i, l; for (i = 0, l = value.length; i < l; i++) { character = value[i]; if (isEscaped) ; else if (character == Marker.SINGLE_QUOTE || character == Marker.DOUBLE_QUOTE) { isQuote = !isQuote; } else if (!isQuote && (character == Marker.CLOSE_CURLY_BRACKET || character == Marker.EXCLAMATION || character == LESS_THAN || character == Marker.SEMICOLON) ) { isInvalid = true; break; } else if (!isQuote && i === 0 && RELATION_PATTERN.test(character)) { isInvalid = true; break; } isEscaped = character == Marker.BACK_SLASH; } return isInvalid; } function removeWhitespace(value, format) { var stripped = []; var character; var isNewLineNix; var isNewLineWin; var isEscaped; var wasEscaped; var isQuoted; var isSingleQuoted; var isDoubleQuoted; var isAttribute; var isRelation; var isWhitespace; var isSpaceAwarePseudoClass; var roundBracketLevel = 0; var wasComma = false; var wasRelation = false; var wasWhitespace = false; var withCaseAttribute = CASE_ATTRIBUTE_PATTERN.test(value); var spaceAroundRelation = format && format.spaces[Spaces.AroundSelectorRelation]; var i, l; for (i = 0, l = value.length; i < l; i++) { character = value[i]; isNewLineNix = character == Marker.NEW_LINE_NIX; isNewLineWin = character == Marker.NEW_LINE_NIX && value[i - 1] == Marker.CARRIAGE_RETURN; isQuoted = isSingleQuoted || isDoubleQuoted; isRelation = !isAttribute && !isEscaped && roundBracketLevel === 0 && RELATION_PATTERN.test(character); isWhitespace = WHITESPACE_PATTERN.test(character); isSpaceAwarePseudoClass = roundBracketLevel == 1 && character == Marker.CLOSE_ROUND_BRACKET ? false : isSpaceAwarePseudoClass || (roundBracketLevel === 0 && character == Marker.COLON && isPseudoClassWithSelectors(value, i)); if (wasEscaped && isQuoted && isNewLineWin) { // swallow escaped new windows lines in comments stripped.pop(); stripped.pop(); } else if (isEscaped && isQuoted && isNewLineNix) { // swallow escaped new *nix lines in comments stripped.pop(); } else if (isEscaped) { stripped.push(character); } else if (character == Marker.OPEN_SQUARE_BRACKET && !isQuoted) { stripped.push(character); isAttribute = true; } else if (character == Marker.CLOSE_SQUARE_BRACKET && !isQuoted) { stripped.push(character); isAttribute = false; } else if (character == Marker.OPEN_ROUND_BRACKET && !isQuoted) { stripped.push(character); roundBracketLevel++; } else if (character == Marker.CLOSE_ROUND_BRACKET && !isQuoted) { stripped.push(character); roundBracketLevel--; } else if (character == Marker.SINGLE_QUOTE && !isQuoted) { stripped.push(character); isSingleQuoted = true; } else if (character == Marker.DOUBLE_QUOTE && !isQuoted) { stripped.push(character); isDoubleQuoted = true; } else if (character == Marker.SINGLE_QUOTE && isQuoted) { stripped.push(character); isSingleQuoted = false; } else if (character == Marker.DOUBLE_QUOTE && isQuoted) { stripped.push(character); isDoubleQuoted = false; } else if (isWhitespace && wasRelation && !spaceAroundRelation) { continue; } else if (!isWhitespace && wasRelation && spaceAroundRelation) { stripped.push(Marker.SPACE); stripped.push(character); } else if (isWhitespace && !wasWhitespace && wasComma && roundBracketLevel > 0 && isSpaceAwarePseudoClass) ; else if (isWhitespace && !wasWhitespace && roundBracketLevel > 0 && isSpaceAwarePseudoClass) { stripped.push(character); } else if (isWhitespace && (isAttribute || roundBracketLevel > 0) && !isQuoted) ; else if (isWhitespace && wasWhitespace && !isQuoted) ; else if ((isNewLineWin || isNewLineNix) && (isAttribute || roundBracketLevel > 0) && isQuoted) ; else if (isRelation && wasWhitespace && !spaceAroundRelation) { stripped.pop(); stripped.push(character); } else if (isRelation && !wasWhitespace && spaceAroundRelation) { stripped.push(Marker.SPACE); stripped.push(character); } else if (isWhitespace) { stripped.push(Marker.SPACE); } else { stripped.push(character); } wasEscaped = isEscaped; isEscaped = character == Marker.BACK_SLASH; wasRelation = isRelation; wasWhitespace = isWhitespace; wasComma = character == Marker.COMMA; } return withCaseAttribute ? stripped.join('').replace(CASE_RESTORE_PATTERN, '$1 $2]') : stripped.join(''); } function isPseudoClassWithSelectors(value, colonPosition) { var pseudoClass = value.substring(colonPosition, value.indexOf(Marker.OPEN_ROUND_BRACKET, colonPosition)); return PSEUDO_CLASSES_WITH_SELECTORS.indexOf(pseudoClass) > -1; } function removeQuotes(value) { if (value.indexOf('\'') == -1 && value.indexOf('"') == -1) { return value; } return value .replace(SINGLE_QUOTE_CASE_PATTERN, '=$1 $2') .replace(SINGLE_QUOTE_PATTERN, '=$1$2') .replace(DOUBLE_QUOTE_CASE_PATTERN, '=$1 $2') .replace(DOUBLE_QUOTE_PATTERN, '=$1$2'); } function replacePseudoClasses(value) { return value .replace('nth-child(1)', 'first-child') .replace('nth-of-type(1)', 'first-of-type') .replace('nth-of-type(even)', 'nth-of-type(2n)') .replace('nth-child(even)', 'nth-child(2n)') .replace('nth-of-type(2n+1)', 'nth-of-type(odd)') .replace('nth-child(2n+1)', 'nth-child(odd)') .replace('nth-last-child(1)', 'last-child') .replace('nth-last-of-type(1)', 'last-of-type') .replace('nth-last-of-type(even)', 'nth-last-of-type(2n)') .replace('nth-last-child(even)', 'nth-last-child(2n)') .replace('nth-last-of-type(2n+1)', 'nth-last-of-type(odd)') .replace('nth-last-child(2n+1)', 'nth-last-child(odd)'); } function tidyRules(rules, removeUnsupported, adjacentSpace, format, warnings) { var list = []; var repeated = []; function removeHTMLComment(rule, match) { warnings.push('HTML comment \'' + match + '\' at ' + formatPosition(rule[2][0]) + '. Removing.'); return ''; } for (var i = 0, l = rules.length; i < l; i++) { var rule = rules[i]; var reduced = rule[1]; reduced = reduced.replace(HTML_COMMENT_PATTERN, removeHTMLComment.bind(null, rule)); if (hasInvalidCharacters(reduced)) { warnings.push('Invalid selector \'' + rule[1] + '\' at ' + formatPosition(rule[2][0]) + '. Ignoring.'); continue; } reduced = removeWhitespace(reduced, format); reduced = removeQuotes(reduced); if (adjacentSpace && reduced.indexOf('nav') > 0) { reduced = reduced.replace(/\+nav(\S|$)/, '+ nav$1'); } if (removeUnsupported && reduced.indexOf(ASTERISK_PLUS_HTML_HACK) > -1) { continue; } if (removeUnsupported && reduced.indexOf(ASTERISK_FIRST_CHILD_PLUS_HTML_HACK) > -1) { continue; } if (reduced.indexOf('*') > -1) { reduced = reduced .replace(/\*([:#.[])/g, '$1') .replace(/^(:first-child)?\+html/, '*$1+html'); } if (repeated.indexOf(reduced) > -1) { continue; } reduced = replacePseudoClasses(reduced); rule[1] = reduced; repeated.push(reduced); list.push(rule); } if (list.length == 1 && list[0][1].length === 0) { warnings.push('Empty selector \'' + list[0][1] + '\' at ' + formatPosition(list[0][2][0]) + '. Ignoring.'); list = []; } return list; } tidyRules_1 = tidyRules; return tidyRules_1; } var tidyBlock_1; var hasRequiredTidyBlock; function requireTidyBlock () { if (hasRequiredTidyBlock) return tidyBlock_1; hasRequiredTidyBlock = 1; var SUPPORTED_COMPACT_BLOCK_MATCHER = /^@media\W/; var SUPPORTED_QUOTE_REMOVAL_MATCHER = /^@(?:keyframes|-moz-keyframes|-o-keyframes|-webkit-keyframes)\W/; function tidyBlock(values, spaceAfterClosingBrace) { var withoutSpaceAfterClosingBrace; var withoutQuotes; var i; for (i = values.length - 1; i >= 0; i--) { withoutSpaceAfterClosingBrace = !spaceAfterClosingBrace && SUPPORTED_COMPACT_BLOCK_MATCHER.test(values[i][1]); withoutQuotes = SUPPORTED_QUOTE_REMOVAL_MATCHER.test(values[i][1]); values[i][1] = values[i][1] .replace(/\n|\r\n/g, ' ') .replace(/\s+/g, ' ') .replace(/(,|:|\() /g, '$1') .replace(/ \)/g, ')'); if (withoutQuotes) { values[i][1] = values[i][1] .replace(/'([a-zA-Z][a-zA-Z\d\-_]+)'/, '$1') .replace(/"([a-zA-Z][a-zA-Z\d\-_]+)"/, '$1'); } if (withoutSpaceAfterClosingBrace) { values[i][1] = values[i][1] .replace(/\) /g, ')'); } } return values; } tidyBlock_1 = tidyBlock; return tidyBlock_1; } var tidyAtRule_1; var hasRequiredTidyAtRule; function requireTidyAtRule () { if (hasRequiredTidyAtRule) return tidyAtRule_1; hasRequiredTidyAtRule = 1; function tidyAtRule(value) { return value .replace(/\s+/g, ' ') .replace(/url\(\s+/g, 'url(') .replace(/\s+\)/g, ')') .trim(); } tidyAtRule_1 = tidyAtRule; return tidyAtRule_1; } var hack; var hasRequiredHack; function requireHack () { if (hasRequiredHack) return hack; hasRequiredHack = 1; var Hack = { ASTERISK: 'asterisk', BANG: 'bang', BACKSLASH: 'backslash', UNDERSCORE: 'underscore' }; hack = Hack; return hack; } var removeUnused_1; var hasRequiredRemoveUnused; function requireRemoveUnused () { if (hasRequiredRemoveUnused) return removeUnused_1; hasRequiredRemoveUnused = 1; function removeUnused(properties) { for (var i = properties.length - 1; i >= 0; i--) { var property = properties[i]; if (property.unused) { property.all.splice(property.position, 1); } } } removeUnused_1 = removeUnused; return removeUnused_1; } var restoreFromOptimizing_1; var hasRequiredRestoreFromOptimizing; function requireRestoreFromOptimizing () { if (hasRequiredRestoreFromOptimizing) return restoreFromOptimizing_1; hasRequiredRestoreFromOptimizing = 1; var Hack = requireHack(); var Marker = requireMarker(); var ASTERISK_HACK = '*'; var BACKSLASH_HACK = '\\'; var IMPORTANT_TOKEN = '!important'; var UNDERSCORE_HACK = '_'; var BANG_HACK = '!ie'; function restoreFromOptimizing(properties, restoreCallback) { var property; var restored; var current; var i; for (i = properties.length - 1; i >= 0; i--) { property = properties[i]; if (property.dynamic && property.important) { restoreImportant(property); continue; } if (property.dynamic) { continue; } if (property.unused) { continue; } if (!property.dirty && !property.important && !property.hack) { continue; } if (property.optimizable && restoreCallback) { restored = restoreCallback(property); property.value = restored; } else { restored = property.value; } if (property.important) { restoreImportant(property); } if (property.hack) { restoreHack(property); } if ('all' in property) { current = property.all[property.position]; current[1][1] = property.name; current.splice(2, current.length - 1); Array.prototype.push.apply(current, restored); } } } function restoreImportant(property) { property.value[property.value.length - 1][1] += IMPORTANT_TOKEN; } function restoreHack(property) { if (property.hack[0] == Hack.UNDERSCORE) { property.name = UNDERSCORE_HACK + property.name; } else if (property.hack[0] == Hack.ASTERISK) { property.name = ASTERISK_HACK + property.name; } else if (property.hack[0] == Hack.BACKSLASH) { property.value[property.value.length - 1][1] += BACKSLASH_HACK + property.hack[1]; } else if (property.hack[0] == Hack.BANG) { property.value[property.value.length - 1][1] += Marker.SPACE + BANG_HACK; } } restoreFromOptimizing_1 = restoreFromOptimizing; return restoreFromOptimizing_1; } var token; var hasRequiredToken; function requireToken () { if (hasRequiredToken) return token; hasRequiredToken = 1; var Token = { AT_RULE: 'at-rule', // e.g. `@import`, `@charset` AT_RULE_BLOCK: 'at-rule-block', // e.g. `@font-face{...}` AT_RULE_BLOCK_SCOPE: 'at-rule-block-scope', // e.g. `@font-face` COMMENT: 'comment', // e.g. `/* comment */` NESTED_BLOCK: 'nested-block', // e.g. `@media screen{...}`, `@keyframes animation {...}` NESTED_BLOCK_SCOPE: 'nested-block-scope', // e.g. `@media`, `@keyframes` PROPERTY: 'property', // e.g. `color:red` PROPERTY_BLOCK: 'property-block', // e.g. `--var:{color:red}` PROPERTY_NAME: 'property-name', // e.g. `color` PROPERTY_VALUE: 'property-value', // e.g. `red` RAW: 'raw', // e.g. anything between /* clean-css ignore:start */ and /* clean-css ignore:end */ comments RULE: 'rule', // e.g `div > a{...}` RULE_SCOPE: 'rule-scope' // e.g `div > a` }; token = Token; return token; } var wrapForOptimizing; var hasRequiredWrapForOptimizing; function requireWrapForOptimizing () { if (hasRequiredWrapForOptimizing) return wrapForOptimizing; hasRequiredWrapForOptimizing = 1; var Hack = requireHack(); var Marker = requireMarker(); var Token = requireToken(); var Match = { ASTERISK: '*', BACKSLASH: '\\', BANG: '!', BANG_SUFFIX_PATTERN: /!\w+$/, IMPORTANT_TOKEN_PATTERN: new RegExp('!important$', 'i'), IMPORTANT_WORD_PATTERN: new RegExp('important$', 'i'), SUFFIX_BANG_PATTERN: /!$/, UNDERSCORE: '_', VARIABLE_REFERENCE_PATTERN: /var\(--.+\)$/ }; function wrapAll(properties, skipProperties) { var wrapped = []; var single; var property; var i; for (i = properties.length - 1; i >= 0; i--) { property = properties[i]; if (property[0] != Token.PROPERTY) { continue; } if (skipProperties && skipProperties.indexOf(property[1][1]) > -1) { continue; } single = wrapSingle(property); single.all = properties; single.position = i; wrapped.unshift(single); } return wrapped; } function someVariableReferences(property) { var i, l; var value; // skipping `property` and property name tokens for (i = 2, l = property.length; i < l; i++) { value = property[i]; if (value[0] != Token.PROPERTY_VALUE) { continue; } if (isVariableReference(value[1])) { return true; } } return false; } function isVariableReference(value) { return Match.VARIABLE_REFERENCE_PATTERN.test(value); } function isMultiplex(property) { var value; var i, l; for (i = 3, l = property.length; i < l; i++) { value = property[i]; if (value[0] == Token.PROPERTY_VALUE && (value[1] == Marker.COMMA || value[1] == Marker.FORWARD_SLASH)) { return true; } } return false; } function hackFrom(property) { var match = false; var name = property[1][1]; var lastValue = property[property.length - 1]; if (name[0] == Match.UNDERSCORE) { match = [Hack.UNDERSCORE]; } else if (name[0] == Match.ASTERISK) { match = [Hack.ASTERISK]; } else if (lastValue[1][0] == Match.BANG && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN)) { match = [Hack.BANG]; } else if (lastValue[1].indexOf(Match.BANG) > 0 && !lastValue[1].match(Match.IMPORTANT_WORD_PATTERN) && Match.BANG_SUFFIX_PATTERN.test(lastValue[1])) { match = [Hack.BANG]; } else if (lastValue[1].indexOf(Match.BACKSLASH) > 0 && lastValue[1].indexOf(Match.BACKSLASH) == lastValue[1].length - Match.BACKSLASH.length - 1) { match = [Hack.BACKSLASH, lastValue[1].substring(lastValue[1].indexOf(Match.BACKSLASH) + 1)]; } else if (lastValue[1].indexOf(Match.BACKSLASH) === 0 && lastValue[1].length == 2) { match = [Hack.BACKSLASH, lastValue[1].substring(1)]; } return match; } function isImportant(property) { if (property.length < 3) { return false; } var lastValue = property[property.length - 1]; if (Match.IMPORTANT_TOKEN_PATTERN.test(lastValue[1])) { return true; } if (Match.IMPORTANT_WORD_PATTERN.test(lastValue[1]) && Match.SUFFIX_BANG_PATTERN.test(property[property.length - 2][1])) { return true; } return false; } function stripImportant(property) { var lastValue = property[property.length - 1]; var oneButLastValue = property[property.length - 2]; if (Match.IMPORTANT_TOKEN_PATTERN.test(lastValue[1])) { lastValue[1] = lastValue[1].replace(Match.IMPORTANT_TOKEN_PATTERN, ''); } else { lastValue[1] = lastValue[1].replace(Match.IMPORTANT_WORD_PATTERN, ''); oneButLastValue[1] = oneButLastValue[1].replace(Match.SUFFIX_BANG_PATTERN, ''); } if (lastValue[1].length === 0) { property.pop(); } if (oneButLastValue[1].length === 0) { property.pop(); } } function stripPrefixHack(property) { property[1][1] = property[1][1].substring(1); } function stripSuffixHack(property, hackFrom) { var lastValue = property[property.length - 1]; lastValue[1] = lastValue[1] .substring(0, lastValue[1].indexOf(hackFrom[0] == Hack.BACKSLASH ? Match.BACKSLASH : Match.BANG)) .trim(); if (lastValue[1].length === 0) { property.pop(); } } function wrapSingle(property) { var importantProperty = isImportant(property); if (importantProperty) { stripImportant(property); } var whichHack = hackFrom(property); if (whichHack[0] == Hack.ASTERISK || whichHack[0] == Hack.UNDERSCORE) { stripPrefixHack(property); } else if (whichHack[0] == Hack.BACKSLASH || whichHack[0] == Hack.BANG) { stripSuffixHack(property, whichHack); } return { block: property[2] && property[2][0] == Token.PROPERTY_BLOCK, components: [], dirty: false, dynamic: someVariableReferences(property), hack: whichHack, important: importantProperty, name: property[1][1], multiplex: property.length > 3 ? isMultiplex(property) : false, optimizable: true, position: 0, shorthand: false, unused: false, value: property.slice(2) }; } wrapForOptimizing = { all: wrapAll, single: wrapSingle }; return wrapForOptimizing; } var invalidPropertyError; var hasRequiredInvalidPropertyError; function requireInvalidPropertyError () { if (hasRequiredInvalidPropertyError) return invalidPropertyError; hasRequiredInvalidPropertyError = 1; function InvalidPropertyError(message) { this.name = 'InvalidPropertyError'; this.message = message; this.stack = (new Error()).stack; } InvalidPropertyError.prototype = Object.create(Error.prototype); InvalidPropertyError.prototype.constructor = InvalidPropertyError; invalidPropertyError = InvalidPropertyError; return invalidPropertyError; } var breakUp; var hasRequiredBreakUp; function requireBreakUp () { if (hasRequiredBreakUp) return breakUp; hasRequiredBreakUp = 1; var InvalidPropertyError = requireInvalidPropertyError(); var wrapSingle = requireWrapForOptimizing().single; var Token = requireToken(); var Marker = requireMarker(); var formatPosition = requireFormatPosition(); function _anyIsInherit(values) { var i, l; for (i = 0, l = values.length; i < l; i++) { if (values[i][1] == 'inherit') { return true; } } return false; } function _colorFilter(validator) { return function(value) { return value[1] == 'invert' || validator.isColor(value[1]) || validator.isPrefixed(value[1]); }; } function _styleFilter(validator) { return function(value) { return value[1] != 'inherit' && validator.isStyleKeyword(value[1]) && !validator.isColorFunction(value[1]); }; } function _wrapDefault(name, property, configuration) { var descriptor = configuration[name]; if (descriptor.doubleValues && descriptor.defaultValue.length == 2) { return wrapSingle([ Token.PROPERTY, [Token.PROPERTY_NAME, name], [Token.PROPERTY_VALUE, descriptor.defaultValue[0]], [Token.PROPERTY_VALUE, descriptor.defaultValue[1]] ]); } if (descriptor.doubleValues && descriptor.defaultValue.length == 1) { return wrapSingle([ Token.PROPERTY, [Token.PROPERTY_NAME, name], [Token.PROPERTY_VALUE, descriptor.defaultValue[0]] ]); } return wrapSingle([ Token.PROPERTY, [Token.PROPERTY_NAME, name], [Token.PROPERTY_VALUE, descriptor.defaultValue] ]); } function _widthFilter(validator) { return function(value) { return value[1] != 'inherit' && (validator.isWidth(value[1]) || validator.isUnit(value[1]) || validator.isDynamicUnit(value[1])) && !validator.isStyleKeyword(value[1]) && !validator.isColorFunction(value[1]); }; } function animation(property, configuration, validator) { var duration = _wrapDefault(property.name + '-duration', property, configuration); var timing = _wrapDefault(property.name + '-timing-function', property, configuration); var delay = _wrapDefault(property.name + '-delay', property, configuration); var iteration = _wrapDefault(property.name + '-iteration-count', property, configuration); var direction = _wrapDefault(property.name + '-direction', property, configuration); var fill = _wrapDefault(property.name + '-fill-mode', property, configuration); var play = _wrapDefault(property.name + '-play-state', property, configuration); var name = _wrapDefault(property.name + '-name', property, configuration); var components = [duration, timing, delay, iteration, direction, fill, play, name]; var values = property.value; var value; var durationSet = false; var timingSet = false; var delaySet = false; var iterationSet = false; var directionSet = false; var fillSet = false; var playSet = false; var nameSet = false; var i; var l; if (property.value.length == 1 && property.value[0][1] == 'inherit') { // eslint-disable-next-line max-len duration.value = timing.value = delay.value = iteration.value = direction.value = fill.value = play.value = name.value = property.value; return components; } if (values.length > 1 && _anyIsInherit(values)) { throw new InvalidPropertyError('Invalid animation values at ' + formatPosition(values[0][2][0]) + '. Ignoring.'); } for (i = 0, l = values.length; i < l; i++) { value = values[i]; if (validator.isTime(value[1]) && !durationSet) { duration.value = [value]; durationSet = true; } else if (validator.isTime(value[1]) && !delaySet) { delay.value = [value]; delaySet = true; } else if ((validator.isGlobal(value[1]) || validator.isTimingFunction(value[1])) && !timingSet) { timing.value = [value]; timingSet = true; } else if ((validator.isAnimationIterationCountKeyword(value[1]) || validator.isPositiveNumber(value[1])) && !iterationSet) { iteration.value = [value]; iterationSet = true; } else if (validator.isAnimationDirectionKeyword(value[1]) && !directionSet) { direction.value = [value]; directionSet = true; } else if (validator.isAnimationFillModeKeyword(value[1]) && !fillSet) { fill.value = [value]; fillSet = true; } else if (validator.isAnimationPlayStateKeyword(value[1]) && !playSet) { play.value = [value]; playSet = true; } else if ((validator.isAnimationNameKeyword(value[1]) || validator.isIdentifier(value[1])) && !nameSet) { name.value = [value]; nameSet = true; } else { throw new InvalidPropertyError('Invalid animation value at ' + formatPosition(value[2][0]) + '. Ignoring.'); } } return components; } function background(property, configuration, validator) { var image = _wrapDefault('background-image', property, configuration); var position = _wrapDefault('background-position', property, configuration); var size = _wrapDefault('background-size', property, configuration); var repeat = _wrapDefault('background-repeat', property, configuration); var attachment = _wrapDefault('background-attachment', property, configuration); var origin = _wrapDefault('background-origin', property, configuration); var clip = _wrapDefault('background-clip', property, configuration); var color = _wrapDefault('background-color', property, configuration); var components = [image, position, size, repeat, attachment, origin, clip, color]; var values = property.value; var positionSet = false; var clipSet = false; var originSet = false; var repeatSet = false; var anyValueSet = false; if (property.value.length == 1 && property.value[0][1] == 'inherit') { // NOTE: 'inherit' is not a valid value for background-attachment color.value = image.value = repeat.value = position.value = size.value = origin.value = clip.value = property.value; return components; } if (property.value.length == 1 && property.value[0][1] == '0 0') { return components; } for (var i = values.length - 1; i >= 0; i--) { var value = values[i]; if (validator.isBackgroundAttachmentKeyword(value[1])) { attachment.value = [value]; anyValueSet = true; } else if (validator.isBackgroundClipKeyword(value[1]) || validator.isBackgroundOriginKeyword(value[1])) { if (clipSet) { origin.value = [value]; originSet = true; } else { clip.value = [value]; clipSet = true; } anyValueSet = true; } else if (validator.isBackgroundRepeatKeyword(value[1])) { if (repeatSet) { repeat.value.unshift(value); } else { repeat.value = [value]; repeatSet = true; } anyValueSet = true; } else if (validator.isBackgroundPositionKeyword(value[1]) || validator.isBackgroundSizeKeyword(value[1]) || validator.isUnit(value[1])