'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } var hyphenate = _interopDefault(require('fbjs/lib/hyphenateStyleName')); var React = require('react'); var React__default = _interopDefault(React); var supportsColor = _interopDefault(require('supports-color')); var transformDeclPairs = _interopDefault(require('css-to-react-native')); var PropTypes = _interopDefault(require('prop-types')); var hoist = _interopDefault(require('hoist-non-react-statics')); var reactIs = require('react-is'); var reactPrimitives = _interopDefault(require('react-primitives')); // Source: https://github.com/garycourt/murmurhash-js/blob/master/murmurhash2_gc.js function murmurhash(str) { var l = str.length | 0, h = l | 0, i = 0, k; while (l >= 4) { k = str.charCodeAt(i) & 0xff | (str.charCodeAt(++i) & 0xff) << 8 | (str.charCodeAt(++i) & 0xff) << 16 | (str.charCodeAt(++i) & 0xff) << 24; k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16); k ^= k >>> 24; k = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16); h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16) ^ k; l -= 4; ++i; } switch (l) { case 3: h ^= (str.charCodeAt(i + 2) & 0xff) << 16; case 2: h ^= (str.charCodeAt(i + 1) & 0xff) << 8; case 1: h ^= str.charCodeAt(i) & 0xff; h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16); } h ^= h >>> 13; h = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16); h ^= h >>> 15; return h >>> 0; } var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var inherits = function (subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }; var objectWithoutProperties = function (obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }; var possibleConstructorReturn = function (self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }; // var isPlainObject = (function (x) { return (typeof x === 'undefined' ? 'undefined' : _typeof(x)) === 'object' && x.constructor === Object; }); // /** * Parse errors.md and turn it into a simple hash of code: message */ var ERRORS = process.env.NODE_ENV !== 'production' ? { "1": "Cannot create styled-component for component: %s.\n\n", "2": "Can't collect styles once you've consumed a `ServerStyleSheet`'s styles! `ServerStyleSheet` is a one off instance for each server-side render cycle.\n\n* Are you trying to reuse it across renders?\n* Are you accidentally calling collectStyles twice?\n\n", "3": "Streaming SSR is only supported in a Node.js environment; Please do not try to call this method in the browser.\n\n", "4": "The `StyleSheetManager` expects a valid target or sheet prop!\n\n* Does this error occur on the client and is your target falsy?\n* Does this error occur on the server and is the sheet falsy?\n\n", "5": "The clone method cannot be used on the client!\n\n* Are you running in a client-like environment on the server?\n* Are you trying to run SSR on the client?\n\n", "6": "Trying to insert a new style tag, but the given Node is unmounted!\n\n* Are you using a custom target that isn't mounted?\n* Does your document not have a valid head element?\n* Have you accidentally removed a style tag manually?\n\n", "7": "ThemeProvider: Please return an object from your \"theme\" prop function, e.g.\n\n```js\ntheme={() => ({})}\n```\n\n", "8": "ThemeProvider: Please make your \"theme\" prop an object.\n\n", "9": "Missing document ``\n\n", "10": "Cannot find a StyleSheet instance. Usually this happens if there are multiple copies of styled-components loaded at once. Check out this issue for how to troubleshoot and fix the common cases where this situation can happen: https://github.com/styled-components/styled-components/issues/1941#issuecomment-417862021\n\n", "11": "A plain React class (%s) has been interpolated into styles, probably as a component selector (https://www.styled-components.com/docs/advanced#referring-to-other-components). Only styled-component classes can be targeted in this fashion." } : {}; /** * super basic version of sprintf */ function format() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } var a = args[0]; var b = []; var c = void 0; for (c = 1; c < args.length; c += 1) { b.push(args[c]); } b.forEach(function (d) { a = a.replace(/%[a-z]/, d); }); return a; } /** * Create an error file out of errors.md for development and a simple web link to the full errors * in production mode. */ var StyledComponentsError = function (_Error) { inherits(StyledComponentsError, _Error); function StyledComponentsError(code) { classCallCheck(this, StyledComponentsError); for (var _len2 = arguments.length, interpolations = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { interpolations[_key2 - 1] = arguments[_key2]; } if (process.env.NODE_ENV === 'production') { var _this = possibleConstructorReturn(this, _Error.call(this, 'An error occurred. See https://github.com/styled-components/styled-components/blob/master/src/utils/errors.md#' + code + ' for more information. ' + (interpolations ? 'Additional arguments: ' + interpolations.join(', ') : ''))); } else { var _this = possibleConstructorReturn(this, _Error.call(this, format.apply(undefined, [ERRORS[code]].concat(interpolations)))); } return possibleConstructorReturn(_this); } return StyledComponentsError; }(Error); // var objToCss = function objToCss(obj, prevKey) { var css = Object.keys(obj).filter(function (key) { var chunk = obj[key]; return chunk !== undefined && chunk !== null && chunk !== false && chunk !== ''; }).map(function (key) { if (isPlainObject(obj[key])) return objToCss(obj[key], key); return hyphenate(key) + ': ' + obj[key] + ';'; }).join(' '); return prevKey ? prevKey + ' {\n ' + css + '\n}' : css; }; var flatten = function flatten(chunks, executionContext) { return chunks.reduce(function (ruleSet, chunk) { /* Remove falsey values */ if (chunk === undefined || chunk === null || chunk === false || chunk === '') { return ruleSet; } /* Flatten ruleSet */ if (Array.isArray(chunk)) { ruleSet.push.apply(ruleSet, flatten(chunk, executionContext)); return ruleSet; } /* Handle other components */ if (chunk.hasOwnProperty('styledComponentId')) { // $FlowFixMe not sure how to make this pass ruleSet.push('.' + chunk.styledComponentId); return ruleSet; } /* Either execute or defer the function */ if (typeof chunk === 'function') { if (executionContext) { var nextChunk = chunk(executionContext); /* Throw if a React Element was given styles */ if (React__default.isValidElement(nextChunk)) { var elementName = chunk.displayName || chunk.name; throw new StyledComponentsError(11, elementName); } ruleSet.push.apply(ruleSet, flatten([nextChunk], executionContext)); } else ruleSet.push(chunk); return ruleSet; } /* Handle objects */ ruleSet.push( // $FlowFixMe have to add %checks somehow to isPlainObject isPlainObject(chunk) ? objToCss(chunk) : chunk.toString()); return ruleSet; }, []); }; var printed = {}; function warnOnce(message) { if (printed[message]) return; printed[message] = true; if (typeof console !== 'undefined' && console.warn) console.warn(message); } var SINGLE_QUOTE = '\''.charCodeAt(0); var DOUBLE_QUOTE = '"'.charCodeAt(0); var BACKSLASH = '\\'.charCodeAt(0); var SLASH = '/'.charCodeAt(0); var NEWLINE = '\n'.charCodeAt(0); var SPACE = ' '.charCodeAt(0); var FEED = '\f'.charCodeAt(0); var TAB = '\t'.charCodeAt(0); var CR = '\r'.charCodeAt(0); var OPEN_SQUARE = '['.charCodeAt(0); var CLOSE_SQUARE = ']'.charCodeAt(0); var OPEN_PARENTHESES = '('.charCodeAt(0); var CLOSE_PARENTHESES = ')'.charCodeAt(0); var OPEN_CURLY = '{'.charCodeAt(0); var CLOSE_CURLY = '}'.charCodeAt(0); var SEMICOLON = ';'.charCodeAt(0); var ASTERISK = '*'.charCodeAt(0); var COLON = ':'.charCodeAt(0); var AT = '@'.charCodeAt(0); var RE_AT_END = /[ \n\t\r\f\{\(\)'"\\;/\[\]#]/g; var RE_WORD_END = /[ \n\t\r\f\(\)\{\}:;@!'"\\\]\[#]|\/(?=\*)/g; var RE_BAD_BRACKET = /.[\\\/\("'\n]/; function tokenize(input) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; var tokens = []; var css = input.css.valueOf(); var ignore = options.ignoreErrors; var code = void 0, next = void 0, quote = void 0, lines = void 0, last = void 0, content = void 0, escape = void 0, nextLine = void 0, nextOffset = void 0, escaped = void 0, escapePos = void 0, prev = void 0, n = void 0; var length = css.length; var offset = -1; var line = 1; var pos = 0; function unclosed(what) { throw input.error('Unclosed ' + what, line, pos - offset); } while (pos < length) { code = css.charCodeAt(pos); if (code === NEWLINE || code === FEED || code === CR && css.charCodeAt(pos + 1) !== NEWLINE) { offset = pos; line += 1; } switch (code) { case NEWLINE: case SPACE: case TAB: case CR: case FEED: next = pos; do { next += 1; code = css.charCodeAt(next); if (code === NEWLINE) { offset = next; line += 1; } } while (code === SPACE || code === NEWLINE || code === TAB || code === CR || code === FEED); tokens.push(['space', css.slice(pos, next)]); pos = next - 1; break; case OPEN_SQUARE: tokens.push(['[', '[', line, pos - offset]); break; case CLOSE_SQUARE: tokens.push([']', ']', line, pos - offset]); break; case OPEN_CURLY: tokens.push(['{', '{', line, pos - offset]); break; case CLOSE_CURLY: tokens.push(['}', '}', line, pos - offset]); break; case COLON: tokens.push([':', ':', line, pos - offset]); break; case SEMICOLON: tokens.push([';', ';', line, pos - offset]); break; case OPEN_PARENTHESES: prev = tokens.length ? tokens[tokens.length - 1][1] : ''; n = css.charCodeAt(pos + 1); if (prev === 'url' && n !== SINGLE_QUOTE && n !== DOUBLE_QUOTE && n !== SPACE && n !== NEWLINE && n !== TAB && n !== FEED && n !== CR) { next = pos; do { escaped = false; next = css.indexOf(')', next + 1); if (next === -1) { if (ignore) { next = pos; break; } else { unclosed('bracket'); } } escapePos = next; while (css.charCodeAt(escapePos - 1) === BACKSLASH) { escapePos -= 1; escaped = !escaped; } } while (escaped); tokens.push(['brackets', css.slice(pos, next + 1), line, pos - offset, line, next - offset]); pos = next; } else { next = css.indexOf(')', pos + 1); content = css.slice(pos, next + 1); if (next === -1 || RE_BAD_BRACKET.test(content)) { tokens.push(['(', '(', line, pos - offset]); } else { tokens.push(['brackets', content, line, pos - offset, line, next - offset]); pos = next; } } break; case CLOSE_PARENTHESES: tokens.push([')', ')', line, pos - offset]); break; case SINGLE_QUOTE: case DOUBLE_QUOTE: quote = code === SINGLE_QUOTE ? '\'' : '"'; next = pos; do { escaped = false; next = css.indexOf(quote, next + 1); if (next === -1) { if (ignore) { next = pos + 1; break; } else { unclosed('quote'); } } escapePos = next; while (css.charCodeAt(escapePos - 1) === BACKSLASH) { escapePos -= 1; escaped = !escaped; } } while (escaped); content = css.slice(pos, next + 1); lines = content.split('\n'); last = lines.length - 1; if (last > 0) { nextLine = line + last; nextOffset = next - lines[last].length; } else { nextLine = line; nextOffset = offset; } tokens.push(['string', css.slice(pos, next + 1), line, pos - offset, nextLine, next - nextOffset]); offset = nextOffset; line = nextLine; pos = next; break; case AT: RE_AT_END.lastIndex = pos + 1; RE_AT_END.test(css); if (RE_AT_END.lastIndex === 0) { next = css.length - 1; } else { next = RE_AT_END.lastIndex - 2; } tokens.push(['at-word', css.slice(pos, next + 1), line, pos - offset, line, next - offset]); pos = next; break; case BACKSLASH: next = pos; escape = true; while (css.charCodeAt(next + 1) === BACKSLASH) { next += 1; escape = !escape; } code = css.charCodeAt(next + 1); if (escape && code !== SLASH && code !== SPACE && code !== NEWLINE && code !== TAB && code !== CR && code !== FEED) { next += 1; } tokens.push(['word', css.slice(pos, next + 1), line, pos - offset, line, next - offset]); pos = next; break; default: if (code === SLASH && css.charCodeAt(pos + 1) === ASTERISK) { next = css.indexOf('*/', pos + 2) + 1; if (next === 0) { if (ignore) { next = css.length; } else { unclosed('comment'); } } content = css.slice(pos, next + 1); lines = content.split('\n'); last = lines.length - 1; if (last > 0) { nextLine = line + last; nextOffset = next - lines[last].length; } else { nextLine = line; nextOffset = offset; } tokens.push(['comment', content, line, pos - offset, nextLine, next - nextOffset]); offset = nextOffset; line = nextLine; pos = next; } else { RE_WORD_END.lastIndex = pos + 1; RE_WORD_END.test(css); if (RE_WORD_END.lastIndex === 0) { next = css.length - 1; } else { next = RE_WORD_END.lastIndex - 2; } tokens.push(['word', css.slice(pos, next + 1), line, pos - offset, line, next - offset]); pos = next; } break; } pos++; } return tokens; } var HIGHLIGHT_THEME = { 'brackets': [36, 39], // cyan 'string': [31, 39], // red 'at-word': [31, 39], // red 'comment': [90, 39], // gray '{': [32, 39], // green '}': [32, 39], // green ':': [1, 22], // bold ';': [1, 22], // bold '(': [1, 22], // bold ')': [1, 22] // bold }; function code(color) { return '\x1B[' + color + 'm'; } function terminalHighlight(css) { var tokens = tokenize(new Input(css), { ignoreErrors: true }); var result = []; tokens.forEach(function (token) { var color = HIGHLIGHT_THEME[token[0]]; if (color) { result.push(token[1].split(/\r?\n/).map(function (i) { return code(color[0]) + i + code(color[1]); }).join('\n')); } else { result.push(token[1]); } }); return result.join(''); } /** * The CSS parser throws this error for broken CSS. * * Custom parsers can throw this error for broken custom syntax using * the {@link Node#error} method. * * PostCSS will use the input source map to detect the original error location. * If you wrote a Sass file, compiled it to CSS and then parsed it with PostCSS, * PostCSS will show the original position in the Sass file. * * If you need the position in the PostCSS input * (e.g., to debug the previous compiler), use `error.input.file`. * * @example * // Catching and checking syntax error * try { * postcss.parse('a{') * } catch (error) { * if ( error.name === 'CssSyntaxError' ) { * error //=> CssSyntaxError * } * } * * @example * // Raising error from plugin * throw node.error('Unknown variable', { plugin: 'postcss-vars' }); */ var CssSyntaxError = function () { /** * @param {string} message - error message * @param {number} [line] - source line of the error * @param {number} [column] - source column of the error * @param {string} [source] - source code of the broken file * @param {string} [file] - absolute path to the broken file * @param {string} [plugin] - PostCSS plugin name, if error came from plugin */ function CssSyntaxError(message, line, column, source, file, plugin) { classCallCheck(this, CssSyntaxError); /** * @member {string} - Always equal to `'CssSyntaxError'`. You should * always check error type * by `error.name === 'CssSyntaxError'` instead of * `error instanceof CssSyntaxError`, because * npm could have several PostCSS versions. * * @example * if ( error.name === 'CssSyntaxError' ) { * error //=> CssSyntaxError * } */ this.name = 'CssSyntaxError'; /** * @member {string} - Error message. * * @example * error.message //=> 'Unclosed block' */ this.reason = message; if (file) { /** * @member {string} - Absolute path to the broken file. * * @example * error.file //=> 'a.sass' * error.input.file //=> 'a.css' */ this.file = file; } if (source) { /** * @member {string} - Source code of the broken file. * * @example * error.source //=> 'a { b {} }' * error.input.column //=> 'a b { }' */ this.source = source; } if (plugin) { /** * @member {string} - Plugin name, if error came from plugin. * * @example * error.plugin //=> 'postcss-vars' */ this.plugin = plugin; } if (typeof line !== 'undefined' && typeof column !== 'undefined') { /** * @member {number} - Source line of the error. * * @example * error.line //=> 2 * error.input.line //=> 4 */ this.line = line; /** * @member {number} - Source column of the error. * * @example * error.column //=> 1 * error.input.column //=> 4 */ this.column = column; } this.setMessage(); if (Error.captureStackTrace) { Error.captureStackTrace(this, CssSyntaxError); } } CssSyntaxError.prototype.setMessage = function setMessage() { /** * @member {string} - Full error text in the GNU error format * with plugin, file, line and column. * * @example * error.message //=> 'a.css:1:1: Unclosed block' */ this.message = this.plugin ? this.plugin + ': ' : ''; this.message += this.file ? this.file : ''; if (typeof this.line !== 'undefined') { this.message += ':' + this.line + ':' + this.column; } this.message += ': ' + this.reason; }; /** * Returns a few lines of CSS source that caused the error. * * If the CSS has an input source map without `sourceContent`, * this method will return an empty string. * * @param {boolean} [color] whether arrow will be colored red by terminal * color codes. By default, PostCSS will detect * color support by `process.stdout.isTTY` * and `process.env.NODE_DISABLE_COLORS`. * * @example * error.showSourceCode() //=> " 4 | } * // 5 | a { * // > 6 | bad * // | ^ * // 7 | } * // 8 | b {" * * @return {string} few lines of CSS source that caused the error */ CssSyntaxError.prototype.showSourceCode = function showSourceCode(color) { var _this = this; if (!this.source) return ''; var css = this.source; if (typeof color === 'undefined') color = supportsColor; if (color) css = terminalHighlight(css); var lines = css.split(/\r?\n/); var start = Math.max(this.line - 3, 0); var end = Math.min(this.line + 2, lines.length); var maxWidth = String(end).length; return lines.slice(start, end).map(function (line, index) { var number = start + 1 + index; var padded = (' ' + number).slice(-maxWidth); var gutter = ' ' + padded + ' | '; if (number === _this.line) { var spacing = gutter.replace(/\d/g, ' ') + line.slice(0, _this.column - 1).replace(/[^\t]/g, ' '); return '>' + gutter + line + '\n ' + spacing + '^'; } else { return ' ' + gutter + line; } }).join('\n'); }; /** * Returns error position, message and source code of the broken part. * * @example * error.toString() //=> "CssSyntaxError: app.css:1:1: Unclosed block * // > 1 | a { * // | ^" * * @return {string} error position, message and source code */ CssSyntaxError.prototype.toString = function toString() { var code = this.showSourceCode(); if (code) { code = '\n\n' + code + '\n'; } return this.name + ': ' + this.message + code; }; createClass(CssSyntaxError, [{ key: 'generated', get: function get$$1() { warnOnce('CssSyntaxError#generated is depreacted. Use input instead.'); return this.input; } /** * @memberof CssSyntaxError# * @member {Input} input - Input object with PostCSS internal information * about input file. If input has source map * from previous tool, PostCSS will use origin * (for example, Sass) source. You can use this * object to get PostCSS input source. * * @example * error.input.file //=> 'a.css' * error.file //=> 'a.sass' */ }]); return CssSyntaxError; }(); /* eslint-disable valid-jsdoc */ var defaultRaw = { colon: ': ', indent: ' ', beforeDecl: '\n', beforeRule: '\n', beforeOpen: ' ', beforeClose: '\n', beforeComment: '\n', after: '\n', emptyBody: '', commentLeft: ' ', commentRight: ' ' }; function capitalize(str) { return str[0].toUpperCase() + str.slice(1); } var Stringifier = function () { function Stringifier(builder) { classCallCheck(this, Stringifier); this.builder = builder; } Stringifier.prototype.stringify = function stringify(node, semicolon) { this[node.type](node, semicolon); }; Stringifier.prototype.root = function root(node) { this.body(node); if (node.raws.after) this.builder(node.raws.after); }; Stringifier.prototype.comment = function comment(node) { var left = this.raw(node, 'left', 'commentLeft'); var right = this.raw(node, 'right', 'commentRight'); this.builder('/*' + left + node.text + right + '*/', node); }; Stringifier.prototype.decl = function decl(node, semicolon) { var between = this.raw(node, 'between', 'colon'); var string = node.prop + between + this.rawValue(node, 'value'); if (node.important) { string += node.raws.important || ' !important'; } if (semicolon) string += ';'; this.builder(string, node); }; Stringifier.prototype.rule = function rule(node) { this.block(node, this.rawValue(node, 'selector')); }; Stringifier.prototype.atrule = function atrule(node, semicolon) { var name = '@' + node.name; var params = node.params ? this.rawValue(node, 'params') : ''; if (typeof node.raws.afterName !== 'undefined') { name += node.raws.afterName; } else if (params) { name += ' '; } if (node.nodes) { this.block(node, name + params); } else { var end = (node.raws.between || '') + (semicolon ? ';' : ''); this.builder(name + params + end, node); } }; Stringifier.prototype.body = function body(node) { var last = node.nodes.length - 1; while (last > 0) { if (node.nodes[last].type !== 'comment') break; last -= 1; } var semicolon = this.raw(node, 'semicolon'); for (var i = 0; i < node.nodes.length; i++) { var child = node.nodes[i]; var before = this.raw(child, 'before'); if (before) this.builder(before); this.stringify(child, last !== i || semicolon); } }; Stringifier.prototype.block = function block(node, start) { var between = this.raw(node, 'between', 'beforeOpen'); this.builder(start + between + '{', node, 'start'); var after = void 0; if (node.nodes && node.nodes.length) { this.body(node); after = this.raw(node, 'after'); } else { after = this.raw(node, 'after', 'emptyBody'); } if (after) this.builder(after); this.builder('}', node, 'end'); }; Stringifier.prototype.raw = function raw(node, own, detect) { var value = void 0; if (!detect) detect = own; // Already had if (own) { value = node.raws[own]; if (typeof value !== 'undefined') return value; } var parent = node.parent; // Hack for first rule in CSS if (detect === 'before') { if (!parent || parent.type === 'root' && parent.first === node) { return ''; } } // Floating child without parent if (!parent) return defaultRaw[detect]; // Detect style by other nodes var root = node.root(); if (!root.rawCache) root.rawCache = {}; if (typeof root.rawCache[detect] !== 'undefined') { return root.rawCache[detect]; } if (detect === 'before' || detect === 'after') { return this.beforeAfter(node, detect); } else { var method = 'raw' + capitalize(detect); if (this[method]) { value = this[method](root, node); } else { root.walk(function (i) { value = i.raws[own]; if (typeof value !== 'undefined') return false; }); } } if (typeof value === 'undefined') value = defaultRaw[detect]; root.rawCache[detect] = value; return value; }; Stringifier.prototype.rawSemicolon = function rawSemicolon(root) { var value = void 0; root.walk(function (i) { if (i.nodes && i.nodes.length && i.last.type === 'decl') { value = i.raws.semicolon; if (typeof value !== 'undefined') return false; } }); return value; }; Stringifier.prototype.rawEmptyBody = function rawEmptyBody(root) { var value = void 0; root.walk(function (i) { if (i.nodes && i.nodes.length === 0) { value = i.raws.after; if (typeof value !== 'undefined') return false; } }); return value; }; Stringifier.prototype.rawIndent = function rawIndent(root) { if (root.raws.indent) return root.raws.indent; var value = void 0; root.walk(function (i) { var p = i.parent; if (p && p !== root && p.parent && p.parent === root) { if (typeof i.raws.before !== 'undefined') { var parts = i.raws.before.split('\n'); value = parts[parts.length - 1]; value = value.replace(/[^\s]/g, ''); return false; } } }); return value; }; Stringifier.prototype.rawBeforeComment = function rawBeforeComment(root, node) { var value = void 0; root.walkComments(function (i) { if (typeof i.raws.before !== 'undefined') { value = i.raws.before; if (value.indexOf('\n') !== -1) { value = value.replace(/[^\n]+$/, ''); } return false; } }); if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeDecl'); } return value; }; Stringifier.prototype.rawBeforeDecl = function rawBeforeDecl(root, node) { var value = void 0; root.walkDecls(function (i) { if (typeof i.raws.before !== 'undefined') { value = i.raws.before; if (value.indexOf('\n') !== -1) { value = value.replace(/[^\n]+$/, ''); } return false; } }); if (typeof value === 'undefined') { value = this.raw(node, null, 'beforeRule'); } return value; }; Stringifier.prototype.rawBeforeRule = function rawBeforeRule(root) { var value = void 0; root.walk(function (i) { if (i.nodes && (i.parent !== root || root.first !== i)) { if (typeof i.raws.before !== 'undefined') { value = i.raws.before; if (value.indexOf('\n') !== -1) { value = value.replace(/[^\n]+$/, ''); } return false; } } }); return value; }; Stringifier.prototype.rawBeforeClose = function rawBeforeClose(root) { var value = void 0; root.walk(function (i) { if (i.nodes && i.nodes.length > 0) { if (typeof i.raws.after !== 'undefined') { value = i.raws.after; if (value.indexOf('\n') !== -1) { value = value.replace(/[^\n]+$/, ''); } return false; } } }); return value; }; Stringifier.prototype.rawBeforeOpen = function rawBeforeOpen(root) { var value = void 0; root.walk(function (i) { if (i.type !== 'decl') { value = i.raws.between; if (typeof value !== 'undefined') return false; } }); return value; }; Stringifier.prototype.rawColon = function rawColon(root) { var value = void 0; root.walkDecls(function (i) { if (typeof i.raws.between !== 'undefined') { value = i.raws.between.replace(/[^\s:]/g, ''); return false; } }); return value; }; Stringifier.prototype.beforeAfter = function beforeAfter(node, detect) { var value = void 0; if (node.type === 'decl') { value = this.raw(node, null, 'beforeDecl'); } else if (node.type === 'comment') { value = this.raw(node, null, 'beforeComment'); } else if (detect === 'before') { value = this.raw(node, null, 'beforeRule'); } else { value = this.raw(node, null, 'beforeClose'); } var buf = node.parent; var depth = 0; while (buf && buf.type !== 'root') { depth += 1; buf = buf.parent; } if (value.indexOf('\n') !== -1) { var indent = this.raw(node, null, 'indent'); if (indent.length) { for (var step = 0; step < depth; step++) { value += indent; } } } return value; }; Stringifier.prototype.rawValue = function rawValue(node, prop) { var value = node[prop]; var raw = node.raws[prop]; if (raw && raw.value === value) { return raw.raw; } else { return value; } }; return Stringifier; }(); function stringify(node, builder) { var str = new Stringifier(builder); str.stringify(node); } /** * @typedef {object} position * @property {number} line - source line in file * @property {number} column - source column in file */ /** * @typedef {object} source * @property {Input} input - {@link Input} with input file * @property {position} start - The starting position of the node’s source * @property {position} end - The ending position of the node’s source */ var cloneNode = function cloneNode(obj, parent) { var cloned = new obj.constructor(); for (var i in obj) { if (!obj.hasOwnProperty(i)) continue; var value = obj[i]; var type = typeof value === 'undefined' ? 'undefined' : _typeof(value); if (i === 'parent' && type === 'object') { if (parent) cloned[i] = parent; } else if (i === 'source') { cloned[i] = value; } else if (value instanceof Array) { cloned[i] = value.map(function (j) { return cloneNode(j, cloned); }); } else if (i !== 'before' && i !== 'after' && i !== 'between' && i !== 'semicolon') { if (type === 'object' && value !== null) value = cloneNode(value); cloned[i] = value; } } return cloned; }; /** * All node classes inherit the following common methods. * * @abstract */ var Node = function () { /** * @param {object} [defaults] - value for node properties */ function Node() { var defaults$$1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; classCallCheck(this, Node); this.raws = {}; for (var name in defaults$$1) { this[name] = defaults$$1[name]; } } /** * Returns a CssSyntaxError instance containing the original position * of the node in the source, showing line and column numbers and also * a small excerpt to facilitate debugging. * * If present, an input source map will be used to get the original position * of the source, even from a previous compilation step * (e.g., from Sass compilation). * * This method produces very useful error messages. * * @param {string} message - error description * @param {object} [opts] - options * @param {string} opts.plugin - plugin name that created this error. * PostCSS will set it automatically. * @param {string} opts.word - a word inside a node’s string that should * be highlighted as the source of the error * @param {number} opts.index - an index inside a node’s string that should * be highlighted as the source of the error * * @return {CssSyntaxError} error object to throw it * * @example * if ( !variables[name] ) { * throw decl.error('Unknown variable ' + name, { word: name }); * // CssSyntaxError: postcss-vars:a.sass:4:3: Unknown variable $black * // color: $black * // a * // ^ * // background: white * } */ Node.prototype.error = function error(message) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.source) { var pos = this.positionBy(opts); return this.source.input.error(message, pos.line, pos.column, opts); } else { return new CssSyntaxError(message); } }; /** * This method is provided as a convenience wrapper for {@link Result#warn}. * * @param {Result} result - the {@link Result} instance * that will receive the warning * @param {string} text - warning message * @param {object} [opts] - options * @param {string} opts.plugin - plugin name that created this warning. * PostCSS will set it automatically. * @param {string} opts.word - a word inside a node’s string that should * be highlighted as the source of the warning * @param {number} opts.index - an index inside a node’s string that should * be highlighted as the source of the warning * * @return {Warning} created warning object * * @example * const plugin = postcss.plugin('postcss-deprecated', () => { * return (root, result) => { * root.walkDecls('bad', decl => { * decl.warn(result, 'Deprecated property bad'); * }); * }; * }); */ Node.prototype.warn = function warn(result, text, opts) { var data = { node: this }; for (var i in opts) { data[i] = opts[i]; }return result.warn(text, data); }; /** * Removes the node from its parent and cleans the parent properties * from the node and its children. * * @example * if ( decl.prop.match(/^-webkit-/) ) { * decl.remove(); * } * * @return {Node} node to make calls chain */ Node.prototype.remove = function remove() { if (this.parent) { this.parent.removeChild(this); } this.parent = undefined; return this; }; /** * Returns a CSS string representing the node. * * @param {stringifier|syntax} [stringifier] - a syntax to use * in string generation * * @return {string} CSS string of this node * * @example * postcss.rule({ selector: 'a' }).toString() //=> "a {}" */ Node.prototype.toString = function toString() { var stringifier = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : stringify; if (stringifier.stringify) stringifier = stringifier.stringify; var result = ''; stringifier(this, function (i) { result += i; }); return result; }; /** * Returns a clone of the node. * * The resulting cloned node and its (cloned) children will have * a clean parent and code style properties. * * @param {object} [overrides] - new properties to override in the clone. * * @example * const cloned = decl.clone({ prop: '-moz-' + decl.prop }); * cloned.raws.before //=> undefined * cloned.parent //=> undefined * cloned.toString() //=> -moz-transform: scale(0) * * @return {Node} clone of the node */ Node.prototype.clone = function clone() { var overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cloned = cloneNode(this); for (var name in overrides) { cloned[name] = overrides[name]; } return cloned; }; /** * Shortcut to clone the node and insert the resulting cloned node * before the current node. * * @param {object} [overrides] - new properties to override in the clone. * * @example * decl.cloneBefore({ prop: '-moz-' + decl.prop }); * * @return {Node} - new node */ Node.prototype.cloneBefore = function cloneBefore() { var overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cloned = this.clone(overrides); this.parent.insertBefore(this, cloned); return cloned; }; /** * Shortcut to clone the node and insert the resulting cloned node * after the current node. * * @param {object} [overrides] - new properties to override in the clone. * * @return {Node} - new node */ Node.prototype.cloneAfter = function cloneAfter() { var overrides = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var cloned = this.clone(overrides); this.parent.insertAfter(this, cloned); return cloned; }; /** * Inserts node(s) before the current node and removes the current node. * * @param {...Node} nodes - node(s) to replace current one * * @example * if ( atrule.name == 'mixin' ) { * atrule.replaceWith(mixinRules[atrule.params]); * } * * @return {Node} current node to methods chain */ Node.prototype.replaceWith = function replaceWith() { var _this = this; if (this.parent) { for (var _len = arguments.length, nodes = Array(_len), _key = 0; _key < _len; _key++) { nodes[_key] = arguments[_key]; } nodes.forEach(function (node) { _this.parent.insertBefore(_this, node); }); this.remove(); } return this; }; /** * Removes the node from its current parent and inserts it * at the end of `newParent`. * * This will clean the `before` and `after` code {@link Node#raws} data * from the node and replace them with the indentation style of `newParent`. * It will also clean the `between` property * if `newParent` is in another {@link Root}. * * @param {Container} newParent - container node where the current node * will be moved * * @example * atrule.moveTo(atrule.root()); * * @return {Node} current node to methods chain */ Node.prototype.moveTo = function moveTo(newParent) { this.cleanRaws(this.root() === newParent.root()); this.remove(); newParent.append(this); return this; }; /** * Removes the node from its current parent and inserts it into * a new parent before `otherNode`. * * This will also clean the node’s code style properties just as it would * in {@link Node#moveTo}. * * @param {Node} otherNode - node that will be before current node * * @return {Node} current node to methods chain */ Node.prototype.moveBefore = function moveBefore(otherNode) { this.cleanRaws(this.root() === otherNode.root()); this.remove(); otherNode.parent.insertBefore(otherNode, this); return this; }; /** * Removes the node from its current parent and inserts it into * a new parent after `otherNode`. * * This will also clean the node’s code style properties just as it would * in {@link Node#moveTo}. * * @param {Node} otherNode - node that will be after current node * * @return {Node} current node to methods chain */ Node.prototype.moveAfter = function moveAfter(otherNode) { this.cleanRaws(this.root() === otherNode.root()); this.remove(); otherNode.parent.insertAfter(otherNode, this); return this; }; /** * Returns the next child of the node’s parent. * Returns `undefined` if the current node is the last child. * * @return {Node|undefined} next node * * @example * if ( comment.text === 'delete next' ) { * const next = comment.next(); * if ( next ) { * next.remove(); * } * } */ Node.prototype.next = function next() { var index = this.parent.index(this); return this.parent.nodes[index + 1]; }; /** * Returns the previous child of the node’s parent. * Returns `undefined` if the current node is the first child. * * @return {Node|undefined} previous node * * @example * const annotation = decl.prev(); * if ( annotation.type == 'comment' ) { * readAnnotation(annotation.text); * } */ Node.prototype.prev = function prev() { var index = this.parent.index(this); return this.parent.nodes[index - 1]; }; Node.prototype.toJSON = function toJSON() { var fixed = {}; for (var name in this) { if (!this.hasOwnProperty(name)) continue; if (name === 'parent') continue; var value = this[name]; if (value instanceof Array) { fixed[name] = value.map(function (i) { if ((typeof i === 'undefined' ? 'undefined' : _typeof(i)) === 'object' && i.toJSON) { return i.toJSON(); } else { return i; } }); } else if ((typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && value.toJSON) { fixed[name] = value.toJSON(); } else { fixed[name] = value; } } return fixed; }; /** * Returns a {@link Node#raws} value. If the node is missing * the code style property (because the node was manually built or cloned), * PostCSS will try to autodetect the code style property by looking * at other nodes in the tree. * * @param {string} prop - name of code style property * @param {string} [defaultType] - name of default value, it can be missed * if the value is the same as prop * * @example * const root = postcss.parse('a { background: white }'); * root.nodes[0].append({ prop: 'color', value: 'black' }); * root.nodes[0].nodes[1].raws.before //=> undefined * root.nodes[0].nodes[1].raw('before') //=> ' ' * * @return {string} code style value */ Node.prototype.raw = function raw(prop, defaultType) { var str = new Stringifier(); return str.raw(this, prop, defaultType); }; /** * Finds the Root instance of the node’s tree. * * @example * root.nodes[0].nodes[0].root() === root * * @return {Root} root parent */ Node.prototype.root = function root() { var result = this; while (result.parent) { result = result.parent; }return result; }; Node.prototype.cleanRaws = function cleanRaws(keepBetween) { delete this.raws.before; delete this.raws.after; if (!keepBetween) delete this.raws.between; }; Node.prototype.positionInside = function positionInside(index) { var string = this.toString(); var column = this.source.start.column; var line = this.source.start.line; for (var i = 0; i < index; i++) { if (string[i] === '\n') { column = 1; line += 1; } else { column += 1; } } return { line: line, column: column }; }; Node.prototype.positionBy = function positionBy(opts) { var pos = this.source.start; if (opts.index) { pos = this.positionInside(opts.index); } else if (opts.word) { var index = this.toString().indexOf(opts.word); if (index !== -1) pos = this.positionInside(index); } return pos; }; Node.prototype.removeSelf = function removeSelf() { warnOnce('Node#removeSelf is deprecated. Use Node#remove.'); return this.remove(); }; Node.prototype.replace = function replace(nodes) { warnOnce('Node#replace is deprecated. Use Node#replaceWith'); return this.replaceWith(nodes); }; Node.prototype.style = function style(own, detect) { warnOnce('Node#style() is deprecated. Use Node#raw()'); return this.raw(own, detect); }; Node.prototype.cleanStyles = function cleanStyles(keepBetween) { warnOnce('Node#cleanStyles() is deprecated. Use Node#cleanRaws()'); return this.cleanRaws(keepBetween); }; createClass(Node, [{ key: 'before', get: function get$$1() { warnOnce('Node#before is deprecated. Use Node#raws.before'); return this.raws.before; }, set: function set$$1(val) { warnOnce('Node#before is deprecated. Use Node#raws.before'); this.raws.before = val; } }, { key: 'between', get: function get$$1() { warnOnce('Node#between is deprecated. Use Node#raws.between'); return this.raws.between; }, set: function set$$1(val) { warnOnce('Node#between is deprecated. Use Node#raws.between'); this.raws.between = val; } /** * @memberof Node# * @member {string} type - String representing the node’s type. * Possible values are `root`, `atrule`, `rule`, * `decl`, or `comment`. * * @example * postcss.decl({ prop: 'color', value: 'black' }).type //=> 'decl' */ /** * @memberof Node# * @member {Container} parent - the node’s parent node. * * @example * root.nodes[0].parent == root; */ /** * @memberof Node# * @member {source} source - the input source of the node * * The property is used in source map generation. * * If you create a node manually (e.g., with `postcss.decl()`), * that node will not have a `source` property and will be absent * from the source map. For this reason, the plugin developer should * consider cloning nodes to create new ones (in which case the new node’s * source will reference the original, cloned node) or setting * the `source` property manually. * * ```js * // Bad * const prefixed = postcss.decl({ * prop: '-moz-' + decl.prop, * value: decl.value * }); * * // Good * const prefixed = decl.clone({ prop: '-moz-' + decl.prop }); * ``` * * ```js * if ( atrule.name == 'add-link' ) { * const rule = postcss.rule({ selector: 'a', source: atrule.source }); * atrule.parent.insertBefore(atrule, rule); * } * ``` * * @example * decl.source.input.from //=> '/home/ai/a.sass' * decl.source.start //=> { line: 10, column: 2 } * decl.source.end //=> { line: 10, column: 12 } */ /** * @memberof Node# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `before`: the space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). * * `after`: the space symbols after the last child of the node * to the end of the node. * * `between`: the symbols between the property and value * for declarations, selector and `{` for rules, or last parameter * and `{` for at-rules. * * `semicolon`: contains true if the last child has * an (optional) semicolon. * * `afterName`: the space between the at-rule name and its parameters. * * `left`: the space symbols between `/*` and the comment’s text. * * `right`: the space symbols between the comment’s text * and */. * * `important`: the content of the important statement, * if it is not just `!important`. * * PostCSS cleans selectors, declaration values and at-rule parameters * from comments and extra spaces, but it stores origin content in raws * properties. As such, if you don’t change a declaration’s value, * PostCSS will use the raw value with comments. * * @example * const root = postcss.parse('a {\n color:black\n}') * root.first.first.raws //=> { before: '\n ', between: ':' } */ }]); return Node; }(); /** * Represents a CSS declaration. * * @extends Node * * @example * const root = postcss.parse('a { color: black }'); * const decl = root.first.first; * decl.type //=> 'decl' * decl.toString() //=> ' color: black' */ var Declaration = function (_Node) { inherits(Declaration, _Node); function Declaration(defaults$$1) { classCallCheck(this, Declaration); var _this = possibleConstructorReturn(this, _Node.call(this, defaults$$1)); _this.type = 'decl'; return _this; } createClass(Declaration, [{ key: '_value', get: function get$$1() { warnOnce('Node#_value was deprecated. Use Node#raws.value'); return this.raws.value; }, set: function set$$1(val) { warnOnce('Node#_value was deprecated. Use Node#raws.value'); this.raws.value = val; } }, { key: '_important', get: function get$$1() { warnOnce('Node#_important was deprecated. Use Node#raws.important'); return this.raws.important; }, set: function set$$1(val) { warnOnce('Node#_important was deprecated. Use Node#raws.important'); this.raws.important = val; } /** * @memberof Declaration# * @member {string} prop - the declaration’s property name * * @example * const root = postcss.parse('a { color: black }'); * const decl = root.first.first; * decl.prop //=> 'color' */ /** * @memberof Declaration# * @member {string} value - the declaration’s value * * @example * const root = postcss.parse('a { color: black }'); * const decl = root.first.first; * decl.value //=> 'black' */ /** * @memberof Declaration# * @member {boolean} important - `true` if the declaration * has an !important annotation. * * @example * const root = postcss.parse('a { color: black !important; color: red }'); * root.first.first.important //=> true * root.first.last.important //=> undefined */ /** * @memberof Declaration# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `before`: the space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). * * `between`: the symbols between the property and value * for declarations, selector and `{` for rules, or last parameter * and `{` for at-rules. * * `important`: the content of the important statement, * if it is not just `!important`. * * PostCSS cleans declaration from comments and extra spaces, * but it stores origin content in raws properties. * As such, if you don’t change a declaration’s value, * PostCSS will use the raw value with comments. * * @example * const root = postcss.parse('a {\n color:black\n}') * root.first.first.raws //=> { before: '\n ', between: ':' } */ }]); return Declaration; }(Node); /** * Represents a comment between declarations or statements (rule and at-rules). * * Comments inside selectors, at-rule parameters, or declaration values * will be stored in the `raws` properties explained above. * * @extends Node */ var Comment = function (_Node) { inherits(Comment, _Node); function Comment(defaults$$1) { classCallCheck(this, Comment); var _this = possibleConstructorReturn(this, _Node.call(this, defaults$$1)); _this.type = 'comment'; return _this; } createClass(Comment, [{ key: 'left', get: function get$$1() { warnOnce('Comment#left was deprecated. Use Comment#raws.left'); return this.raws.left; }, set: function set$$1(val) { warnOnce('Comment#left was deprecated. Use Comment#raws.left'); this.raws.left = val; } }, { key: 'right', get: function get$$1() { warnOnce('Comment#right was deprecated. Use Comment#raws.right'); return this.raws.right; }, set: function set$$1(val) { warnOnce('Comment#right was deprecated. Use Comment#raws.right'); this.raws.right = val; } /** * @memberof Comment# * @member {string} text - the comment’s text */ /** * @memberof Comment# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `before`: the space symbols before the node. * * `left`: the space symbols between `/*` and the comment’s text. * * `right`: the space symbols between the comment’s text. */ }]); return Comment; }(Node); var Parser = function () { function Parser(input) { classCallCheck(this, Parser); this.input = input; this.pos = 0; this.root = new Root(); this.current = this.root; this.spaces = ''; this.semicolon = false; this.root.source = { input: input, start: { line: 1, column: 1 } }; } Parser.prototype.tokenize = function tokenize$$1() { this.tokens = tokenize(this.input); }; Parser.prototype.loop = function loop() { var token = void 0; while (this.pos < this.tokens.length) { token = this.tokens[this.pos]; switch (token[0]) { case 'space': case ';': this.spaces += token[1]; break; case '}': this.end(token); break; case 'comment': this.comment(token); break; case 'at-word': this.atrule(token); break; case '{': this.emptyRule(token); break; default: this.other(); break; } this.pos += 1; } this.endFile(); }; Parser.prototype.comment = function comment(token) { var node = new Comment(); this.init(node, token[2], token[3]); node.source.end = { line: token[4], column: token[5] }; var text = token[1].slice(2, -2); if (/^\s*$/.test(text)) { node.text = ''; node.raws.left = text; node.raws.right = ''; } else { var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/); node.text = match[2]; node.raws.left = match[1]; node.raws.right = match[3]; } }; Parser.prototype.emptyRule = function emptyRule(token) { var node = new Rule(); this.init(node, token[2], token[3]); node.selector = ''; node.raws.between = ''; this.current = node; }; Parser.prototype.other = function other() { var token = void 0; var end = false; var type = null; var colon = false; var bracket = null; var brackets = []; var start = this.pos; while (this.pos < this.tokens.length) { token = this.tokens[this.pos]; type = token[0]; if (type === '(' || type === '[') { if (!bracket) bracket = token; brackets.push(type === '(' ? ')' : ']'); } else if (brackets.length === 0) { if (type === ';') { if (colon) { this.decl(this.tokens.slice(start, this.pos + 1)); return; } else { break; } } else if (type === '{') { this.rule(this.tokens.slice(start, this.pos + 1)); return; } else if (type === '}') { this.pos -= 1; end = true; break; } else if (type === ':') { colon = true; } } else if (type === brackets[brackets.length - 1]) { brackets.pop(); if (brackets.length === 0) bracket = null; } this.pos += 1; } if (this.pos === this.tokens.length) { this.pos -= 1; end = true; } if (brackets.length > 0) this.unclosedBracket(bracket); if (end && colon) { while (this.pos > start) { token = this.tokens[this.pos][0]; if (token !== 'space' && token !== 'comment') break; this.pos -= 1; } this.decl(this.tokens.slice(start, this.pos + 1)); return; } this.unknownWord(start); }; Parser.prototype.rule = function rule(tokens) { tokens.pop(); var node = new Rule(); this.init(node, tokens[0][2], tokens[0][3]); node.raws.between = this.spacesFromEnd(tokens); this.raw(node, 'selector', tokens); this.current = node; }; Parser.prototype.decl = function decl(tokens) { var node = new Declaration(); this.init(node); var last = tokens[tokens.length - 1]; if (last[0] === ';') { this.semicolon = true; tokens.pop(); } if (last[4]) { node.source.end = { line: last[4], column: last[5] }; } else { node.source.end = { line: last[2], column: last[3] }; } while (tokens[0][0] !== 'word') { node.raws.before += tokens.shift()[1]; } node.source.start = { line: tokens[0][2], column: tokens[0][3] }; node.prop = ''; while (tokens.length) { var type = tokens[0][0]; if (type === ':' || type === 'space' || type === 'comment') { break; } node.prop += tokens.shift()[1]; } node.raws.between = ''; var token = void 0; while (tokens.length) { token = tokens.shift(); if (token[0] === ':') { node.raws.between += token[1]; break; } else { node.raws.between += token[1]; } } if (node.prop[0] === '_' || node.prop[0] === '*') { node.raws.before += node.prop[0]; node.prop = node.prop.slice(1); } node.raws.between += this.spacesFromStart(tokens); this.precheckMissedSemicolon(tokens); for (var i = tokens.length - 1; i > 0; i--) { token = tokens[i]; if (token[1] === '!important') { node.important = true; var string = this.stringFrom(tokens, i); string = this.spacesFromEnd(tokens) + string; if (string !== ' !important') node.raws.important = string; break; } else if (token[1] === 'important') { var cache = tokens.slice(0); var str = ''; for (var j = i; j > 0; j--) { var _type = cache[j][0]; if (str.trim().indexOf('!') === 0 && _type !== 'space') { break; } str = cache.pop()[1] + str; } if (str.trim().indexOf('!') === 0) { node.important = true; node.raws.important = str; tokens = cache; } } if (token[0] !== 'space' && token[0] !== 'comment') { break; } } this.raw(node, 'value', tokens); if (node.value.indexOf(':') !== -1) this.checkMissedSemicolon(tokens); }; Parser.prototype.atrule = function atrule(token) { var node = new AtRule(); node.name = token[1].slice(1); if (node.name === '') { this.unnamedAtrule(node, token); } this.init(node, token[2], token[3]); var last = false; var open = false; var params = []; this.pos += 1; while (this.pos < this.tokens.length) { token = this.tokens[this.pos]; if (token[0] === ';') { node.source.end = { line: token[2], column: token[3] }; this.semicolon = true; break; } else if (token[0] === '{') { open = true; break; } else if (token[0] === '}') { this.end(token); break; } else { params.push(token); } this.pos += 1; } if (this.pos === this.tokens.length) { last = true; } node.raws.between = this.spacesFromEnd(params); if (params.length) { node.raws.afterName = this.spacesFromStart(params); this.raw(node, 'params', params); if (last) { token = params[params.length - 1]; node.source.end = { line: token[4], column: token[5] }; this.spaces = node.raws.between; node.raws.between = ''; } } else { node.raws.afterName = ''; node.params = ''; } if (open) { node.nodes = []; this.current = node; } }; Parser.prototype.end = function end(token) { if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon; } this.semicolon = false; this.current.raws.after = (this.current.raws.after || '') + this.spaces; this.spaces = ''; if (this.current.parent) { this.current.source.end = { line: token[2], column: token[3] }; this.current = this.current.parent; } else { this.unexpectedClose(token); } }; Parser.prototype.endFile = function endFile() { if (this.current.parent) this.unclosedBlock(); if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon; } this.current.raws.after = (this.current.raws.after || '') + this.spaces; }; // Helpers Parser.prototype.init = function init(node, line, column) { this.current.push(node); node.source = { start: { line: line, column: column }, input: this.input }; node.raws.before = this.spaces; this.spaces = ''; if (node.type !== 'comment') this.semicolon = false; }; Parser.prototype.raw = function raw(node, prop, tokens) { var token = void 0, type = void 0; var length = tokens.length; var value = ''; var clean = true; for (var i = 0; i < length; i += 1) { token = tokens[i]; type = token[0]; if (type === 'comment' || type === 'space' && i === length - 1) { clean = false; } else { value += token[1]; } } if (!clean) { var raw = tokens.reduce(function (all, i) { return all + i[1]; }, ''); node.raws[prop] = { value: value, raw: raw }; } node[prop] = value; }; Parser.prototype.spacesFromEnd = function spacesFromEnd(tokens) { var lastTokenType = void 0; var spaces = ''; while (tokens.length) { lastTokenType = tokens[tokens.length - 1][0]; if (lastTokenType !== 'space' && lastTokenType !== 'comment') break; spaces = tokens.pop()[1] + spaces; } return spaces; }; Parser.prototype.spacesFromStart = function spacesFromStart(tokens) { var next = void 0; var spaces = ''; while (tokens.length) { next = tokens[0][0]; if (next !== 'space' && next !== 'comment') break; spaces += tokens.shift()[1]; } return spaces; }; Parser.prototype.stringFrom = function stringFrom(tokens, from) { var result = ''; for (var i = from; i < tokens.length; i++) { result += tokens[i][1]; } tokens.splice(from, tokens.length - from); return result; }; Parser.prototype.colon = function colon(tokens) { var brackets = 0; var token = void 0, type = void 0, prev = void 0; for (var i = 0; i < tokens.length; i++) { token = tokens[i]; type = token[0]; if (type === '(') { brackets += 1; } else if (type === ')') { brackets -= 1; } else if (brackets === 0 && type === ':') { if (!prev) { this.doubleColon(token); } else if (prev[0] === 'word' && prev[1] === 'progid') { continue; } else { return i; } } prev = token; } return false; }; // Errors Parser.prototype.unclosedBracket = function unclosedBracket(bracket) { throw this.input.error('Unclosed bracket', bracket[2], bracket[3]); }; Parser.prototype.unknownWord = function unknownWord(start) { var token = this.tokens[start]; throw this.input.error('Unknown word', token[2], token[3]); }; Parser.prototype.unexpectedClose = function unexpectedClose(token) { throw this.input.error('Unexpected }', token[2], token[3]); }; Parser.prototype.unclosedBlock = function unclosedBlock() { var pos = this.current.source.start; throw this.input.error('Unclosed block', pos.line, pos.column); }; Parser.prototype.doubleColon = function doubleColon(token) { throw this.input.error('Double colon', token[2], token[3]); }; Parser.prototype.unnamedAtrule = function unnamedAtrule(node, token) { throw this.input.error('At-rule without name', token[2], token[3]); }; Parser.prototype.precheckMissedSemicolon = function precheckMissedSemicolon(tokens) { }; Parser.prototype.checkMissedSemicolon = function checkMissedSemicolon(tokens) { var colon = this.colon(tokens); if (colon === false) return; var founded = 0; var token = void 0; for (var j = colon - 1; j >= 0; j--) { token = tokens[j]; if (token[0] !== 'space') { founded += 1; if (founded === 2) break; } } throw this.input.error('Missed semicolon', token[2], token[3]); }; return Parser; }(); function parse(css, opts) { if (opts && opts.safe) { throw new Error('Option safe was removed. ' + 'Use parser: require("postcss-safe-parser")'); } var input = new Input(css, opts); var parser = new Parser(input); try { parser.tokenize(); parser.loop(); } catch (e) { if (e.name === 'CssSyntaxError' && opts && opts.from) { if (/\.scss$/i.test(opts.from)) { e.message += '\nYou tried to parse SCSS with ' + 'the standard CSS parser; ' + 'try again with the postcss-scss parser'; } else if (/\.less$/i.test(opts.from)) { e.message += '\nYou tried to parse Less with ' + 'the standard CSS parser; ' + 'try again with the postcss-less parser'; } } throw e; } return parser.root; } function cleanSource(nodes) { return nodes.map(function (i) { if (i.nodes) i.nodes = cleanSource(i.nodes); delete i.source; return i; }); } /** * @callback childCondition * @param {Node} node - container child * @param {number} index - child index * @param {Node[]} nodes - all container children * @return {boolean} */ /** * @callback childIterator * @param {Node} node - container child * @param {number} index - child index * @return {false|undefined} returning `false` will break iteration */ /** * The {@link Root}, {@link AtRule}, and {@link Rule} container nodes * inherit some common methods to help work with their children. * * Note that all containers can store any content. If you write a rule inside * a rule, PostCSS will parse it. * * @extends Node * @abstract */ var Container = function (_Node) { inherits(Container, _Node); function Container() { classCallCheck(this, Container); return possibleConstructorReturn(this, _Node.apply(this, arguments)); } Container.prototype.push = function push(child) { child.parent = this; this.nodes.push(child); return this; }; /** * Iterates through the container’s immediate children, * calling `callback` for each child. * * Returning `false` in the callback will break iteration. * * This method only iterates through the container’s immediate children. * If you need to recursively iterate through all the container’s descendant * nodes, use {@link Container#walk}. * * Unlike the for `{}`-cycle or `Array#forEach` this iterator is safe * if you are mutating the array of child nodes during iteration. * PostCSS will adjust the current index to match the mutations. * * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * const root = postcss.parse('a { color: black; z-index: 1 }'); * const rule = root.first; * * for ( let decl of rule.nodes ) { * decl.cloneBefore({ prop: '-webkit-' + decl.prop }); * // Cycle will be infinite, because cloneBefore moves the current node * // to the next index * } * * rule.each(decl => { * decl.cloneBefore({ prop: '-webkit-' + decl.prop }); * // Will be executed only for color and z-index * }); */ Container.prototype.each = function each(callback) { if (!this.lastEach) this.lastEach = 0; if (!this.indexes) this.indexes = {}; this.lastEach += 1; var id = this.lastEach; this.indexes[id] = 0; if (!this.nodes) return undefined; var index = void 0, result = void 0; while (this.indexes[id] < this.nodes.length) { index = this.indexes[id]; result = callback(this.nodes[index], index); if (result === false) break; this.indexes[id] += 1; } delete this.indexes[id]; return result; }; /** * Traverses the container’s descendant nodes, calling callback * for each node. * * Like container.each(), this method is safe to use * if you are mutating arrays during iteration. * * If you only need to iterate through the container’s immediate children, * use {@link Container#each}. * * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * root.walk(node => { * // Traverses all descendant nodes. * }); */ Container.prototype.walk = function walk(callback) { return this.each(function (child, i) { var result = callback(child, i); if (result !== false && child.walk) { result = child.walk(callback); } return result; }); }; /** * Traverses the container’s descendant nodes, calling callback * for each declaration node. * * If you pass a filter, iteration will only happen over declarations * with matching properties. * * Like {@link Container#each}, this method is safe * to use if you are mutating arrays during iteration. * * @param {string|RegExp} [prop] - string or regular expression * to filter declarations by property name * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * root.walkDecls(decl => { * checkPropertySupport(decl.prop); * }); * * root.walkDecls('border-radius', decl => { * decl.remove(); * }); * * root.walkDecls(/^background/, decl => { * decl.value = takeFirstColorFromGradient(decl.value); * }); */ Container.prototype.walkDecls = function walkDecls(prop, callback) { if (!callback) { callback = prop; return this.walk(function (child, i) { if (child.type === 'decl') { return callback(child, i); } }); } else if (prop instanceof RegExp) { return this.walk(function (child, i) { if (child.type === 'decl' && prop.test(child.prop)) { return callback(child, i); } }); } else { return this.walk(function (child, i) { if (child.type === 'decl' && child.prop === prop) { return callback(child, i); } }); } }; /** * Traverses the container’s descendant nodes, calling callback * for each rule node. * * If you pass a filter, iteration will only happen over rules * with matching selectors. * * Like {@link Container#each}, this method is safe * to use if you are mutating arrays during iteration. * * @param {string|RegExp} [selector] - string or regular expression * to filter rules by selector * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * const selectors = []; * root.walkRules(rule => { * selectors.push(rule.selector); * }); * console.log(`Your CSS uses ${selectors.length} selectors`); */ Container.prototype.walkRules = function walkRules(selector, callback) { if (!callback) { callback = selector; return this.walk(function (child, i) { if (child.type === 'rule') { return callback(child, i); } }); } else if (selector instanceof RegExp) { return this.walk(function (child, i) { if (child.type === 'rule' && selector.test(child.selector)) { return callback(child, i); } }); } else { return this.walk(function (child, i) { if (child.type === 'rule' && child.selector === selector) { return callback(child, i); } }); } }; /** * Traverses the container’s descendant nodes, calling callback * for each at-rule node. * * If you pass a filter, iteration will only happen over at-rules * that have matching names. * * Like {@link Container#each}, this method is safe * to use if you are mutating arrays during iteration. * * @param {string|RegExp} [name] - string or regular expression * to filter at-rules by name * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * root.walkAtRules(rule => { * if ( isOld(rule.name) ) rule.remove(); * }); * * let first = false; * root.walkAtRules('charset', rule => { * if ( !first ) { * first = true; * } else { * rule.remove(); * } * }); */ Container.prototype.walkAtRules = function walkAtRules(name, callback) { if (!callback) { callback = name; return this.walk(function (child, i) { if (child.type === 'atrule') { return callback(child, i); } }); } else if (name instanceof RegExp) { return this.walk(function (child, i) { if (child.type === 'atrule' && name.test(child.name)) { return callback(child, i); } }); } else { return this.walk(function (child, i) { if (child.type === 'atrule' && child.name === name) { return callback(child, i); } }); } }; /** * Traverses the container’s descendant nodes, calling callback * for each comment node. * * Like {@link Container#each}, this method is safe * to use if you are mutating arrays during iteration. * * @param {childIterator} callback - iterator receives each node and index * * @return {false|undefined} returns `false` if iteration was broke * * @example * root.walkComments(comment => { * comment.remove(); * }); */ Container.prototype.walkComments = function walkComments(callback) { return this.walk(function (child, i) { if (child.type === 'comment') { return callback(child, i); } }); }; /** * Inserts new nodes to the start of the container. * * @param {...(Node|object|string|Node[])} children - new nodes * * @return {Node} this node for methods chain * * @example * const decl1 = postcss.decl({ prop: 'color', value: 'black' }); * const decl2 = postcss.decl({ prop: 'background-color', value: 'white' }); * rule.append(decl1, decl2); * * root.append({ name: 'charset', params: '"UTF-8"' }); // at-rule * root.append({ selector: 'a' }); // rule * rule.append({ prop: 'color', value: 'black' }); // declaration * rule.append({ text: 'Comment' }) // comment * * root.append('a {}'); * root.first.append('color: black; z-index: 1'); */ Container.prototype.append = function append() { var _this2 = this; for (var _len = arguments.length, children = Array(_len), _key = 0; _key < _len; _key++) { children[_key] = arguments[_key]; } children.forEach(function (child) { var nodes = _this2.normalize(child, _this2.last); nodes.forEach(function (node) { return _this2.nodes.push(node); }); }); return this; }; /** * Inserts new nodes to the end of the container. * * @param {...(Node|object|string|Node[])} children - new nodes * * @return {Node} this node for methods chain * * @example * const decl1 = postcss.decl({ prop: 'color', value: 'black' }); * const decl2 = postcss.decl({ prop: 'background-color', value: 'white' }); * rule.prepend(decl1, decl2); * * root.append({ name: 'charset', params: '"UTF-8"' }); // at-rule * root.append({ selector: 'a' }); // rule * rule.append({ prop: 'color', value: 'black' }); // declaration * rule.append({ text: 'Comment' }) // comment * * root.append('a {}'); * root.first.append('color: black; z-index: 1'); */ Container.prototype.prepend = function prepend() { var _this3 = this; for (var _len2 = arguments.length, children = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { children[_key2] = arguments[_key2]; } children = children.reverse(); children.forEach(function (child) { var nodes = _this3.normalize(child, _this3.first, 'prepend').reverse(); nodes.forEach(function (node) { return _this3.nodes.unshift(node); }); for (var id in _this3.indexes) { _this3.indexes[id] = _this3.indexes[id] + nodes.length; } }); return this; }; Container.prototype.cleanRaws = function cleanRaws(keepBetween) { _Node.prototype.cleanRaws.call(this, keepBetween); if (this.nodes) { this.nodes.forEach(function (node) { return node.cleanRaws(keepBetween); }); } }; /** * Insert new node before old node within the container. * * @param {Node|number} exist - child or child’s index. * @param {Node|object|string|Node[]} add - new node * * @return {Node} this node for methods chain * * @example * rule.insertBefore(decl, decl.clone({ prop: '-webkit-' + decl.prop })); */ Container.prototype.insertBefore = function insertBefore(exist, add) { var _this4 = this; exist = this.index(exist); var type = exist === 0 ? 'prepend' : false; var nodes = this.normalize(add, this.nodes[exist], type).reverse(); nodes.forEach(function (node) { return _this4.nodes.splice(exist, 0, node); }); var index = void 0; for (var id in this.indexes) { index = this.indexes[id]; if (exist <= index) { this.indexes[id] = index + nodes.length; } } return this; }; /** * Insert new node after old node within the container. * * @param {Node|number} exist - child or child’s index * @param {Node|object|string|Node[]} add - new node * * @return {Node} this node for methods chain */ Container.prototype.insertAfter = function insertAfter(exist, add) { var _this5 = this; exist = this.index(exist); var nodes = this.normalize(add, this.nodes[exist]).reverse(); nodes.forEach(function (node) { return _this5.nodes.splice(exist + 1, 0, node); }); var index = void 0; for (var id in this.indexes) { index = this.indexes[id]; if (exist < index) { this.indexes[id] = index + nodes.length; } } return this; }; Container.prototype.remove = function remove(child) { if (typeof child !== 'undefined') { warnOnce('Container#remove is deprecated. ' + 'Use Container#removeChild'); this.removeChild(child); } else { _Node.prototype.remove.call(this); } return this; }; /** * Removes node from the container and cleans the parent properties * from the node and its children. * * @param {Node|number} child - child or child’s index * * @return {Node} this node for methods chain * * @example * rule.nodes.length //=> 5 * rule.removeChild(decl); * rule.nodes.length //=> 4 * decl.parent //=> undefined */ Container.prototype.removeChild = function removeChild(child) { child = this.index(child); this.nodes[child].parent = undefined; this.nodes.splice(child, 1); var index = void 0; for (var id in this.indexes) { index = this.indexes[id]; if (index >= child) { this.indexes[id] = index - 1; } } return this; }; /** * Removes all children from the container * and cleans their parent properties. * * @return {Node} this node for methods chain * * @example * rule.removeAll(); * rule.nodes.length //=> 0 */ Container.prototype.removeAll = function removeAll() { this.nodes.forEach(function (node) { return node.parent = undefined; }); this.nodes = []; return this; }; /** * Passes all declaration values within the container that match pattern * through callback, replacing those values with the returned result * of callback. * * This method is useful if you are using a custom unit or function * and need to iterate through all values. * * @param {string|RegExp} pattern - replace pattern * @param {object} opts - options to speed up the search * @param {string|string[]} opts.props - an array of property names * @param {string} opts.fast - string that’s used * to narrow down values and speed up the regexp search * @param {function|string} callback - string to replace pattern * or callback that returns a new * value. * The callback will receive * the same arguments as those * passed to a function parameter * of `String#replace`. * * @return {Node} this node for methods chain * * @example * root.replaceValues(/\d+rem/, { fast: 'rem' }, string => { * return 15 * parseInt(string) + 'px'; * }); */ Container.prototype.replaceValues = function replaceValues(pattern, opts, callback) { if (!callback) { callback = opts; opts = {}; } this.walkDecls(function (decl) { if (opts.props && opts.props.indexOf(decl.prop) === -1) return; if (opts.fast && decl.value.indexOf(opts.fast) === -1) return; decl.value = decl.value.replace(pattern, callback); }); return this; }; /** * Returns `true` if callback returns `true` * for all of the container’s children. * * @param {childCondition} condition - iterator returns true or false. * * @return {boolean} is every child pass condition * * @example * const noPrefixes = rule.every(i => i.prop[0] !== '-'); */ Container.prototype.every = function every(condition) { return this.nodes.every(condition); }; /** * Returns `true` if callback returns `true` for (at least) one * of the container’s children. * * @param {childCondition} condition - iterator returns true or false. * * @return {boolean} is some child pass condition * * @example * const hasPrefix = rule.some(i => i.prop[0] === '-'); */ Container.prototype.some = function some(condition) { return this.nodes.some(condition); }; /** * Returns a `child`’s index within the {@link Container#nodes} array. * * @param {Node} child - child of the current container. * * @return {number} child index * * @example * rule.index( rule.nodes[2] ) //=> 2 */ Container.prototype.index = function index(child) { if (typeof child === 'number') { return child; } else { return this.nodes.indexOf(child); } }; /** * The container’s first child. * * @type {Node} * * @example * rule.first == rules.nodes[0]; */ Container.prototype.normalize = function normalize(nodes, sample) { var _this6 = this; if (typeof nodes === 'string') { nodes = cleanSource(parse(nodes).nodes); } else if (!Array.isArray(nodes)) { if (nodes.type === 'root') { nodes = nodes.nodes; } else if (nodes.type) { nodes = [nodes]; } else if (nodes.prop) { if (typeof nodes.value === 'undefined') { throw new Error('Value field is missed in node creation'); } else if (typeof nodes.value !== 'string') { nodes.value = String(nodes.value); } nodes = [new Declaration(nodes)]; } else if (nodes.selector) { nodes = [new Rule(nodes)]; } else if (nodes.name) { nodes = [new AtRule(nodes)]; } else if (nodes.text) { nodes = [new Comment(nodes)]; } else { throw new Error('Unknown node type in node creation'); } } var processed = nodes.map(function (i) { if (typeof i.raws === 'undefined') i = _this6.rebuild(i); if (i.parent) i = i.clone(); if (typeof i.raws.before === 'undefined') { if (sample && typeof sample.raws.before !== 'undefined') { i.raws.before = sample.raws.before.replace(/[^\s]/g, ''); } } i.parent = _this6; return i; }); return processed; }; Container.prototype.rebuild = function rebuild(node, parent) { var _this7 = this; var fix = void 0; if (node.type === 'root') { fix = new Root(); } else if (node.type === 'atrule') { fix = new AtRule(); } else if (node.type === 'rule') { fix = new Rule(); } else if (node.type === 'decl') { fix = new Declaration(); } else if (node.type === 'comment') { fix = new Comment(); } for (var i in node) { if (i === 'nodes') { fix.nodes = node.nodes.map(function (j) { return _this7.rebuild(j, fix); }); } else if (i === 'parent' && parent) { fix.parent = parent; } else if (node.hasOwnProperty(i)) { fix[i] = node[i]; } } return fix; }; Container.prototype.eachInside = function eachInside(callback) { warnOnce('Container#eachInside is deprecated. ' + 'Use Container#walk instead.'); return this.walk(callback); }; Container.prototype.eachDecl = function eachDecl(prop, callback) { warnOnce('Container#eachDecl is deprecated. ' + 'Use Container#walkDecls instead.'); return this.walkDecls(prop, callback); }; Container.prototype.eachRule = function eachRule(selector, callback) { warnOnce('Container#eachRule is deprecated. ' + 'Use Container#walkRules instead.'); return this.walkRules(selector, callback); }; Container.prototype.eachAtRule = function eachAtRule(name, callback) { warnOnce('Container#eachAtRule is deprecated. ' + 'Use Container#walkAtRules instead.'); return this.walkAtRules(name, callback); }; Container.prototype.eachComment = function eachComment(callback) { warnOnce('Container#eachComment is deprecated. ' + 'Use Container#walkComments instead.'); return this.walkComments(callback); }; createClass(Container, [{ key: 'first', get: function get$$1() { if (!this.nodes) return undefined; return this.nodes[0]; } /** * The container’s last child. * * @type {Node} * * @example * rule.last == rule.nodes[rule.nodes.length - 1]; */ }, { key: 'last', get: function get$$1() { if (!this.nodes) return undefined; return this.nodes[this.nodes.length - 1]; } }, { key: 'semicolon', get: function get$$1() { warnOnce('Node#semicolon is deprecated. Use Node#raws.semicolon'); return this.raws.semicolon; }, set: function set$$1(val) { warnOnce('Node#semicolon is deprecated. Use Node#raws.semicolon'); this.raws.semicolon = val; } }, { key: 'after', get: function get$$1() { warnOnce('Node#after is deprecated. Use Node#raws.after'); return this.raws.after; }, set: function set$$1(val) { warnOnce('Node#after is deprecated. Use Node#raws.after'); this.raws.after = val; } /** * @memberof Container# * @member {Node[]} nodes - an array containing the container’s children * * @example * const root = postcss.parse('a { color: black }'); * root.nodes.length //=> 1 * root.nodes[0].selector //=> 'a' * root.nodes[0].nodes[0].prop //=> 'color' */ }]); return Container; }(Node); /** * Represents an at-rule. * * If it’s followed in the CSS by a {} block, this node will have * a nodes property representing its children. * * @extends Container * * @example * const root = postcss.parse('@charset "UTF-8"; @media print {}'); * * const charset = root.first; * charset.type //=> 'atrule' * charset.nodes //=> undefined * * const media = root.last; * media.nodes //=> [] */ var AtRule = function (_Container) { inherits(AtRule, _Container); function AtRule(defaults$$1) { classCallCheck(this, AtRule); var _this = possibleConstructorReturn(this, _Container.call(this, defaults$$1)); _this.type = 'atrule'; return _this; } AtRule.prototype.append = function append() { var _Container$prototype$; if (!this.nodes) this.nodes = []; for (var _len = arguments.length, children = Array(_len), _key = 0; _key < _len; _key++) { children[_key] = arguments[_key]; } return (_Container$prototype$ = _Container.prototype.append).call.apply(_Container$prototype$, [this].concat(children)); }; AtRule.prototype.prepend = function prepend() { var _Container$prototype$2; if (!this.nodes) this.nodes = []; for (var _len2 = arguments.length, children = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { children[_key2] = arguments[_key2]; } return (_Container$prototype$2 = _Container.prototype.prepend).call.apply(_Container$prototype$2, [this].concat(children)); }; createClass(AtRule, [{ key: 'afterName', get: function get$$1() { warnOnce('AtRule#afterName was deprecated. Use AtRule#raws.afterName'); return this.raws.afterName; }, set: function set$$1(val) { warnOnce('AtRule#afterName was deprecated. Use AtRule#raws.afterName'); this.raws.afterName = val; } }, { key: '_params', get: function get$$1() { warnOnce('AtRule#_params was deprecated. Use AtRule#raws.params'); return this.raws.params; }, set: function set$$1(val) { warnOnce('AtRule#_params was deprecated. Use AtRule#raws.params'); this.raws.params = val; } /** * @memberof AtRule# * @member {string} name - the at-rule’s name immediately follows the `@` * * @example * const root = postcss.parse('@media print {}'); * media.name //=> 'media' * const media = root.first; */ /** * @memberof AtRule# * @member {string} params - the at-rule’s parameters, the values * that follow the at-rule’s name but precede * any {} block * * @example * const root = postcss.parse('@media print, screen {}'); * const media = root.first; * media.params //=> 'print, screen' */ /** * @memberof AtRule# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `before`: the space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). * * `after`: the space symbols after the last child of the node * to the end of the node. * * `between`: the symbols between the property and value * for declarations, selector and `{` for rules, or last parameter * and `{` for at-rules. * * `semicolon`: contains true if the last child has * an (optional) semicolon. * * `afterName`: the space between the at-rule name and its parameters. * * PostCSS cleans at-rule parameters from comments and extra spaces, * but it stores origin content in raws properties. * As such, if you don’t change a declaration’s value, * PostCSS will use the raw value with comments. * * @example * const root = postcss.parse(' @media\nprint {\n}') * root.first.first.raws //=> { before: ' ', * // between: ' ', * // afterName: '\n', * // after: '\n' } */ }]); return AtRule; }(Container); /** * Contains helpers for safely splitting lists of CSS values, * preserving parentheses and quotes. * * @example * const list = postcss.list; * * @namespace list */ var list = { split: function split(string, separators, last) { var array = []; var current = ''; var split = false; var func = 0; var quote = false; var escape = false; for (var i = 0; i < string.length; i++) { var letter = string[i]; if (quote) { if (escape) { escape = false; } else if (letter === '\\') { escape = true; } else if (letter === quote) { quote = false; } } else if (letter === '"' || letter === '\'') { quote = letter; } else if (letter === '(') { func += 1; } else if (letter === ')') { if (func > 0) func -= 1; } else if (func === 0) { if (separators.indexOf(letter) !== -1) split = true; } if (split) { if (current !== '') array.push(current.trim()); current = ''; split = false; } else { current += letter; } } if (last || current !== '') array.push(current.trim()); return array; }, /** * Safely splits space-separated values (such as those for `background`, * `border-radius`, and other shorthand properties). * * @param {string} string - space-separated values * * @return {string[]} splitted values * * @example * postcss.list.space('1px calc(10% + 1px)') //=> ['1px', 'calc(10% + 1px)'] */ space: function space(string) { var spaces = [' ', '\n', '\t']; return list.split(string, spaces); }, /** * Safely splits comma-separated values (such as those for `transition-*` * and `background` properties). * * @param {string} string - comma-separated values * * @return {string[]} splitted values * * @example * postcss.list.comma('black, linear-gradient(white, black)') * //=> ['black', 'linear-gradient(white, black)'] */ comma: function comma(string) { var comma = ','; return list.split(string, [comma], true); } }; /** * Represents a CSS rule: a selector followed by a declaration block. * * @extends Container * * @example * const root = postcss.parse('a{}'); * const rule = root.first; * rule.type //=> 'rule' * rule.toString() //=> 'a{}' */ var Rule = function (_Container) { inherits(Rule, _Container); function Rule(defaults$$1) { classCallCheck(this, Rule); var _this = possibleConstructorReturn(this, _Container.call(this, defaults$$1)); _this.type = 'rule'; if (!_this.nodes) _this.nodes = []; return _this; } /** * An array containing the rule’s individual selectors. * Groups of selectors are split at commas. * * @type {string[]} * * @example * const root = postcss.parse('a, b { }'); * const rule = root.first; * * rule.selector //=> 'a, b' * rule.selectors //=> ['a', 'b'] * * rule.selectors = ['a', 'strong']; * rule.selector //=> 'a, strong' */ createClass(Rule, [{ key: 'selectors', get: function get$$1() { return list.comma(this.selector); }, set: function set$$1(values) { var match = this.selector ? this.selector.match(/,\s*/) : null; var sep = match ? match[0] : ',' + this.raw('between', 'beforeOpen'); this.selector = values.join(sep); } }, { key: '_selector', get: function get$$1() { warnOnce('Rule#_selector is deprecated. Use Rule#raws.selector'); return this.raws.selector; }, set: function set$$1(val) { warnOnce('Rule#_selector is deprecated. Use Rule#raws.selector'); this.raws.selector = val; } /** * @memberof Rule# * @member {string} selector - the rule’s full selector represented * as a string * * @example * const root = postcss.parse('a, b { }'); * const rule = root.first; * rule.selector //=> 'a, b' */ /** * @memberof Rule# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `before`: the space symbols before the node. It also stores `*` * and `_` symbols before the declaration (IE hack). * * `after`: the space symbols after the last child of the node * to the end of the node. * * `between`: the symbols between the property and value * for declarations, selector and `{` for rules, or last parameter * and `{` for at-rules. * * `semicolon`: contains true if the last child has * an (optional) semicolon. * * PostCSS cleans selectors from comments and extra spaces, * but it stores origin content in raws properties. * As such, if you don’t change a declaration’s value, * PostCSS will use the raw value with comments. * * @example * const root = postcss.parse('a {\n color:black\n}') * root.first.first.raws //=> { before: '', between: ' ', after: '\n' } */ }]); return Rule; }(Container); /** * Represents a plugin’s warning. It can be created using {@link Node#warn}. * * @example * if ( decl.important ) { * decl.warn(result, 'Avoid !important', { word: '!important' }); * } */ var Warning = function () { /** * @param {string} text - warning message * @param {Object} [opts] - warning options * @param {Node} opts.node - CSS node that caused the warning * @param {string} opts.word - word in CSS source that caused the warning * @param {number} opts.index - index in CSS node string that caused * the warning * @param {string} opts.plugin - name of the plugin that created * this warning. {@link Result#warn} fills * this property automatically. */ function Warning(text) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; classCallCheck(this, Warning); /** * @member {string} - Type to filter warnings from * {@link Result#messages}. Always equal * to `"warning"`. * * @example * const nonWarning = result.messages.filter(i => i.type !== 'warning') */ this.type = 'warning'; /** * @member {string} - The warning message. * * @example * warning.text //=> 'Try to avoid !important' */ this.text = text; if (opts.node && opts.node.source) { var pos = opts.node.positionBy(opts); /** * @member {number} - Line in the input file * with this warning’s source * * @example * warning.line //=> 5 */ this.line = pos.line; /** * @member {number} - Column in the input file * with this warning’s source. * * @example * warning.column //=> 6 */ this.column = pos.column; } for (var opt in opts) { this[opt] = opts[opt]; } } /** * Returns a warning position and message. * * @example * warning.toString() //=> 'postcss-lint:a.css:10:14: Avoid !important' * * @return {string} warning position and message */ Warning.prototype.toString = function toString() { if (this.node) { return this.node.error(this.text, { plugin: this.plugin, index: this.index, word: this.word }).message; } else if (this.plugin) { return this.plugin + ': ' + this.text; } else { return this.text; } }; /** * @memberof Warning# * @member {string} plugin - The name of the plugin that created * it will fill this property automatically. * this warning. When you call {@link Node#warn} * * @example * warning.plugin //=> 'postcss-important' */ /** * @memberof Warning# * @member {Node} node - Contains the CSS node that caused the warning. * * @example * warning.node.toString() //=> 'color: white !important' */ return Warning; }(); /** * @typedef {object} Message * @property {string} type - message type * @property {string} plugin - source PostCSS plugin name */ /** * Provides the result of the PostCSS transformations. * * A Result instance is returned by {@link LazyResult#then} * or {@link Root#toResult} methods. * * @example * postcss([cssnext]).process(css).then(function (result) { * console.log(result.css); * }); * * @example * var result2 = postcss.parse(css).toResult(); */ var Result = function () { /** * @param {Processor} processor - processor used for this transformation. * @param {Root} root - Root node after all transformations. * @param {processOptions} opts - options from the {@link Processor#process} * or {@link Root#toResult} */ function Result(processor, root, opts) { classCallCheck(this, Result); /** * @member {Processor} - The Processor instance used * for this transformation. * * @example * for ( let plugin of result.processor.plugins) { * if ( plugin.postcssPlugin === 'postcss-bad' ) { * throw 'postcss-good is incompatible with postcss-bad'; * } * }); */ this.processor = processor; /** * @member {Message[]} - Contains messages from plugins * (e.g., warnings or custom messages). * Each message should have type * and plugin properties. * * @example * postcss.plugin('postcss-min-browser', () => { * return (root, result) => { * var browsers = detectMinBrowsersByCanIUse(root); * result.messages.push({ * type: 'min-browser', * plugin: 'postcss-min-browser', * browsers: browsers * }); * }; * }); */ this.messages = []; /** * @member {Root} - Root node after all transformations. * * @example * root.toResult().root == root; */ this.root = root; /** * @member {processOptions} - Options from the {@link Processor#process} * or {@link Root#toResult} call * that produced this Result instance. * * @example * root.toResult(opts).opts == opts; */ this.opts = opts; /** * @member {string} - A CSS string representing of {@link Result#root}. * * @example * postcss.parse('a{}').toResult().css //=> "a{}" */ this.css = undefined; /** * @member {SourceMapGenerator} - An instance of `SourceMapGenerator` * class from the `source-map` library, * representing changes * to the {@link Result#root} instance. * * @example * result.map.toJSON() //=> { version: 3, file: 'a.css', … } * * @example * if ( result.map ) { * fs.writeFileSync(result.opts.to + '.map', result.map.toString()); * } */ this.map = undefined; } /** * Returns for @{link Result#css} content. * * @example * result + '' === result.css * * @return {string} string representing of {@link Result#root} */ Result.prototype.toString = function toString() { return this.css; }; /** * Creates an instance of {@link Warning} and adds it * to {@link Result#messages}. * * @param {string} text - warning message * @param {Object} [opts] - warning options * @param {Node} opts.node - CSS node that caused the warning * @param {string} opts.word - word in CSS source that caused the warning * @param {number} opts.index - index in CSS node string that caused * the warning * @param {string} opts.plugin - name of the plugin that created * this warning. {@link Result#warn} fills * this property automatically. * * @return {Warning} created warning */ Result.prototype.warn = function warn(text) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!opts.plugin) { if (this.lastPlugin && this.lastPlugin.postcssPlugin) { opts.plugin = this.lastPlugin.postcssPlugin; } } var warning = new Warning(text, opts); this.messages.push(warning); return warning; }; /** * Returns warnings from plugins. Filters {@link Warning} instances * from {@link Result#messages}. * * @example * result.warnings().forEach(warn => { * console.warn(warn.toString()); * }); * * @return {Warning[]} warnings from plugins */ Result.prototype.warnings = function warnings() { return this.messages.filter(function (i) { return i.type === 'warning'; }); }; /** * An alias for the {@link Result#css} property. * Use it with syntaxes that generate non-CSS output. * @type {string} * * @example * result.css === result.content; */ createClass(Result, [{ key: 'content', get: function get$$1() { return this.css; } }]); return Result; }(); function isPromise(obj) { return (typeof obj === 'undefined' ? 'undefined' : _typeof(obj)) === 'object' && typeof obj.then === 'function'; } /** * @callback onFulfilled * @param {Result} result */ /** * @callback onRejected * @param {Error} error */ /** * A Promise proxy for the result of PostCSS transformations. * * A `LazyResult` instance is returned by {@link Processor#process}. * * @example * const lazy = postcss([cssnext]).process(css); */ var LazyResult = function () { function LazyResult(processor, css, opts) { classCallCheck(this, LazyResult); this.stringified = false; this.processed = false; var root = void 0; if ((typeof css === 'undefined' ? 'undefined' : _typeof(css)) === 'object' && css.type === 'root') { root = css; } else if (css instanceof LazyResult || css instanceof Result) { root = css.root; if (css.map) { if (typeof opts.map === 'undefined') opts.map = {}; if (!opts.map.inline) opts.map.inline = false; opts.map.prev = css.map; } } else { var parser = parse; if (opts.syntax) parser = opts.syntax.parse; if (opts.parser) parser = opts.parser; if (parser.parse) parser = parser.parse; try { root = parser(css, opts); } catch (error) { this.error = error; } } this.result = new Result(processor, root, opts); } /** * Returns a {@link Processor} instance, which will be used * for CSS transformations. * @type {Processor} */ /** * Processes input CSS through synchronous plugins * and calls {@link Result#warnings()}. * * @return {Warning[]} warnings from plugins */ LazyResult.prototype.warnings = function warnings() { return this.sync().warnings(); }; /** * Alias for the {@link LazyResult#css} property. * * @example * lazy + '' === lazy.css; * * @return {string} output CSS */ LazyResult.prototype.toString = function toString() { return this.css; }; /** * Processes input CSS through synchronous and asynchronous plugins * and calls `onFulfilled` with a Result instance. If a plugin throws * an error, the `onRejected` callback will be executed. * * It implements standard Promise API. * * @param {onFulfilled} onFulfilled - callback will be executed * when all plugins will finish work * @param {onRejected} onRejected - callback will be execited on any error * * @return {Promise} Promise API to make queue * * @example * postcss([cssnext]).process(css).then(result => { * console.log(result.css); * }); */ LazyResult.prototype.then = function then(onFulfilled, onRejected) { return this.async().then(onFulfilled, onRejected); }; /** * Processes input CSS through synchronous and asynchronous plugins * and calls onRejected for each error thrown in any plugin. * * It implements standard Promise API. * * @param {onRejected} onRejected - callback will be execited on any error * * @return {Promise} Promise API to make queue * * @example * postcss([cssnext]).process(css).then(result => { * console.log(result.css); * }).catch(error => { * console.error(error); * }); */ LazyResult.prototype.catch = function _catch(onRejected) { return this.async().catch(onRejected); }; LazyResult.prototype.handleError = function handleError(error, plugin) { try { this.error = error; if (error.name === 'CssSyntaxError' && !error.plugin) { error.plugin = plugin.postcssPlugin; error.setMessage(); } else if (plugin.postcssVersion) { var pluginName = plugin.postcssPlugin; var pluginVer = plugin.postcssVersion; var runtimeVer = this.result.processor.version; var a = pluginVer.split('.'); var b = runtimeVer.split('.'); if (a[0] !== b[0] || parseInt(a[1]) > parseInt(b[1])) { warnOnce('Your current PostCSS version ' + 'is ' + runtimeVer + ', but ' + pluginName + ' ' + 'uses ' + pluginVer + '. Perhaps this is ' + 'the source of the error below.'); } } } catch (err) { if (console && console.error) console.error(err); } }; LazyResult.prototype.asyncTick = function asyncTick(resolve, reject) { var _this = this; if (this.plugin >= this.processor.plugins.length) { this.processed = true; return resolve(); } try { var plugin = this.processor.plugins[this.plugin]; var promise = this.run(plugin); this.plugin += 1; if (isPromise(promise)) { promise.then(function () { _this.asyncTick(resolve, reject); }).catch(function (error) { _this.handleError(error, plugin); _this.processed = true; reject(error); }); } else { this.asyncTick(resolve, reject); } } catch (error) { this.processed = true; reject(error); } }; LazyResult.prototype.async = function async() { var _this2 = this; if (this.processed) { return new Promise(function (resolve, reject) { if (_this2.error) { reject(_this2.error); } else { resolve(_this2.stringify()); } }); } if (this.processing) { return this.processing; } this.processing = new Promise(function (resolve, reject) { if (_this2.error) return reject(_this2.error); _this2.plugin = 0; _this2.asyncTick(resolve, reject); }).then(function () { _this2.processed = true; return _this2.stringify(); }); return this.processing; }; LazyResult.prototype.sync = function sync() { var _this3 = this; if (this.processed) return this.result; this.processed = true; if (this.processing) { throw new Error('Use process(css).then(cb) to work with async plugins'); } if (this.error) throw this.error; this.result.processor.plugins.forEach(function (plugin) { var promise = _this3.run(plugin); if (isPromise(promise)) { throw new Error('Use process(css).then(cb) to work with async plugins'); } }); return this.result; }; LazyResult.prototype.run = function run(plugin) { this.result.lastPlugin = plugin; try { return plugin(this.result.root, this.result); } catch (error) { this.handleError(error, plugin); throw error; } }; LazyResult.prototype.stringify = function stringify$$1() { if (this.stringified) return this.result; this.stringified = true; this.sync(); var opts = this.result.opts; var str = stringify; if (opts.syntax) str = opts.syntax.stringify; if (opts.stringifier) str = opts.stringifier; if (str.stringify) str = str.stringify; var result = ''; str(this.root, function (i) { result += i; }); this.result.css = result; return this.result; }; createClass(LazyResult, [{ key: 'processor', get: function get$$1() { return this.result.processor; } /** * Options from the {@link Processor#process} call. * @type {processOptions} */ }, { key: 'opts', get: function get$$1() { return this.result.opts; } /** * Processes input CSS through synchronous plugins, converts `Root` * to a CSS string and returns {@link Result#css}. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. This is why this method is only * for debug purpose, you should always use {@link LazyResult#then}. * * @type {string} * @see Result#css */ }, { key: 'css', get: function get$$1() { return this.stringify().css; } /** * An alias for the `css` property. Use it with syntaxes * that generate non-CSS output. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. This is why this method is only * for debug purpose, you should always use {@link LazyResult#then}. * * @type {string} * @see Result#content */ }, { key: 'content', get: function get$$1() { return this.stringify().content; } /** * Processes input CSS through synchronous plugins * and returns {@link Result#map}. * * This property will only work with synchronous plugins. * If the processor contains any asynchronous plugins * it will throw an error. This is why this method is only * for debug purpose, you should always use {@link LazyResult#then}. * * @type {SourceMapGenerator} * @see Result#map */ }, { key: 'map', get: function get$$1() { return this.stringify().map; } /** * Processes input CSS through synchronous plugins * and returns {@link Result#root}. * * This property will only work with synchronous plugins. If the processor * contains any asynchronous plugins it will throw an error. * * This is why this method is only for debug purpose, * you should always use {@link LazyResult#then}. * * @type {Root} * @see Result#root */ }, { key: 'root', get: function get$$1() { return this.sync().root; } /** * Processes input CSS through synchronous plugins * and returns {@link Result#messages}. * * This property will only work with synchronous plugins. If the processor * contains any asynchronous plugins it will throw an error. * * This is why this method is only for debug purpose, * you should always use {@link LazyResult#then}. * * @type {Message[]} * @see Result#messages */ }, { key: 'messages', get: function get$$1() { return this.sync().messages; } }]); return LazyResult; }(); /** * @callback builder * @param {string} part - part of generated CSS connected to this node * @param {Node} node - AST node * @param {"start"|"end"} [type] - node’s part type */ /** * @callback parser * * @param {string|toString} css - string with input CSS or any object * with toString() method, like a Buffer * @param {processOptions} [opts] - options with only `from` and `map` keys * * @return {Root} PostCSS AST */ /** * @callback stringifier * * @param {Node} node - start node for stringifing. Usually {@link Root}. * @param {builder} builder - function to concatenate CSS from node’s parts * or generate string and source map * * @return {void} */ /** * @typedef {object} syntax * @property {parser} parse - function to generate AST by string * @property {stringifier} stringify - function to generate string by AST */ /** * @typedef {object} toString * @property {function} toString */ /** * @callback pluginFunction * @param {Root} root - parsed input CSS * @param {Result} result - result to set warnings or check other plugins */ /** * @typedef {object} Plugin * @property {function} postcss - PostCSS plugin function */ /** * @typedef {object} processOptions * @property {string} from - the path of the CSS source file. * You should always set `from`, * because it is used in source map * generation and syntax error messages. * @property {string} to - the path where you’ll put the output * CSS file. You should always set `to` * to generate correct source maps. * @property {parser} parser - function to generate AST by string * @property {stringifier} stringifier - class to generate string by AST * @property {syntax} syntax - object with `parse` and `stringify` * @property {object} map - source map options * @property {boolean} map.inline - does source map should * be embedded in the output * CSS as a base64-encoded * comment * @property {string|object|false|function} map.prev - source map content * from a previous * processing step * (for example, Sass). * PostCSS will try to find * previous map * automatically, so you * could disable it by * `false` value. * @property {boolean} map.sourcesContent - does PostCSS should set * the origin content to map * @property {string|false} map.annotation - does PostCSS should set * annotation comment to map * @property {string} map.from - override `from` in map’s * `sources` */ /** * Contains plugins to process CSS. Create one `Processor` instance, * initialize its plugins, and then use that instance on numerous CSS files. * * @example * const processor = postcss([autoprefixer, precss]); * processor.process(css1).then(result => console.log(result.css)); * processor.process(css2).then(result => console.log(result.css)); */ var Processor = function () { /** * @param {Array.|Processor} plugins - PostCSS * plugins. See {@link Processor#use} for plugin format. */ function Processor() { var plugins = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; classCallCheck(this, Processor); /** * @member {string} - Current PostCSS version. * * @example * if ( result.processor.version.split('.')[0] !== '5' ) { * throw new Error('This plugin works only with PostCSS 5'); * } */ this.version = '5.2.0'; /** * @member {pluginFunction[]} - Plugins added to this processor. * * @example * const processor = postcss([autoprefixer, precss]); * processor.plugins.length //=> 2 */ this.plugins = this.normalize(plugins); } /** * Adds a plugin to be used as a CSS processor. * * PostCSS plugin can be in 4 formats: * * A plugin created by {@link postcss.plugin} method. * * A function. PostCSS will pass the function a @{link Root} * as the first argument and current {@link Result} instance * as the second. * * An object with a `postcss` method. PostCSS will use that method * as described in #2. * * Another {@link Processor} instance. PostCSS will copy plugins * from that instance into this one. * * Plugins can also be added by passing them as arguments when creating * a `postcss` instance (see [`postcss(plugins)`]). * * Asynchronous plugins should return a `Promise` instance. * * @param {Plugin|pluginFunction|Processor} plugin - PostCSS plugin * or {@link Processor} * with plugins * * @example * const processor = postcss() * .use(autoprefixer) * .use(precss); * * @return {Processes} current processor to make methods chain */ Processor.prototype.use = function use(plugin) { this.plugins = this.plugins.concat(this.normalize([plugin])); return this; }; /** * Parses source CSS and returns a {@link LazyResult} Promise proxy. * Because some plugins can be asynchronous it doesn’t make * any transformations. Transformations will be applied * in the {@link LazyResult} methods. * * @param {string|toString|Result} css - String with input CSS or * any object with a `toString()` * method, like a Buffer. * Optionally, send a {@link Result} * instance and the processor will * take the {@link Root} from it. * @param {processOptions} [opts] - options * * @return {LazyResult} Promise proxy * * @example * processor.process(css, { from: 'a.css', to: 'a.out.css' }) * .then(result => { * console.log(result.css); * }); */ Processor.prototype.process = function process(css) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return new LazyResult(this, css, opts); }; Processor.prototype.normalize = function normalize(plugins) { var normalized = []; plugins.forEach(function (i) { if (i.postcss) i = i.postcss; if ((typeof i === 'undefined' ? 'undefined' : _typeof(i)) === 'object' && Array.isArray(i.plugins)) { normalized = normalized.concat(i.plugins); } else if (typeof i === 'function') { normalized.push(i); } else { throw new Error(i + ' is not a PostCSS plugin'); } }); return normalized; }; return Processor; }(); /** * Represents a CSS file and contains all its parsed nodes. * * @extends Container * * @example * const root = postcss.parse('a{color:black} b{z-index:2}'); * root.type //=> 'root' * root.nodes.length //=> 2 */ var Root = function (_Container) { inherits(Root, _Container); function Root(defaults$$1) { classCallCheck(this, Root); var _this = possibleConstructorReturn(this, _Container.call(this, defaults$$1)); _this.type = 'root'; if (!_this.nodes) _this.nodes = []; return _this; } Root.prototype.removeChild = function removeChild(child) { child = this.index(child); if (child === 0 && this.nodes.length > 1) { this.nodes[1].raws.before = this.nodes[child].raws.before; } return _Container.prototype.removeChild.call(this, child); }; Root.prototype.normalize = function normalize(child, sample, type) { var nodes = _Container.prototype.normalize.call(this, child); if (sample) { if (type === 'prepend') { if (this.nodes.length > 1) { sample.raws.before = this.nodes[1].raws.before; } else { delete sample.raws.before; } } else if (this.first !== sample) { nodes.forEach(function (node) { node.raws.before = sample.raws.before; }); } } return nodes; }; /** * Returns a {@link Result} instance representing the root’s CSS. * * @param {processOptions} [opts] - options with only `to` and `map` keys * * @return {Result} result with current root’s CSS * * @example * const root1 = postcss.parse(css1, { from: 'a.css' }); * const root2 = postcss.parse(css2, { from: 'b.css' }); * root1.append(root2); * const result = root1.toResult({ to: 'all.css', map: true }); */ Root.prototype.toResult = function toResult() { var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var lazy = new LazyResult(new Processor(), this, opts); return lazy.stringify(); }; Root.prototype.remove = function remove(child) { warnOnce('Root#remove is deprecated. Use Root#removeChild'); this.removeChild(child); }; Root.prototype.prevMap = function prevMap() { warnOnce('Root#prevMap is deprecated. Use Root#source.input.map'); return this.source.input.map; }; /** * @memberof Root# * @member {object} raws - Information to generate byte-to-byte equal * node string as it was in the origin input. * * Every parser saves its own properties, * but the default CSS parser uses: * * * `after`: the space symbols after the last child to the end of file. * * `semicolon`: is the last child has an (optional) semicolon. * * @example * postcss.parse('a {}\n').raws //=> { after: '\n' } * postcss.parse('a {}').raws //=> { after: '' } */ return Root; }(Container); // import PreviousMap from './previous-map'; var sequence = 0; /** * @typedef {object} filePosition * @property {string} file - path to file * @property {number} line - source line in file * @property {number} column - source column in file */ /** * Represents the source CSS. * * @example * const root = postcss.parse(css, { from: file }); * const input = root.source.input; */ var Input = function () { /** * @param {string} css - input CSS source * @param {object} [opts] - {@link Processor#process} options */ function Input(css) { var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; classCallCheck(this, Input); /** * @member {string} - input CSS source * * @example * const input = postcss.parse('a{}', { from: file }).input; * input.css //=> "a{}"; */ this.css = css.toString(); if (this.css[0] === '\uFEFF' || this.css[0] === '\uFFFE') { this.css = this.css.slice(1); } if (opts.from) { if (/^\w+:\/\//.test(opts.from)) { /** * @member {string} - The absolute path to the CSS source file * defined with the `from` option. * * @example * const root = postcss.parse(css, { from: 'a.css' }); * root.source.input.file //=> '/home/ai/a.css' */ this.file = opts.from; } else { this.file = path.resolve(opts.from); } } /* let map = new PreviousMap(this.css, opts); if ( map.text ) { /!** * @member {PreviousMap} - The input source map passed from * a compilation step before PostCSS * (for example, from Sass compiler). * * @example * root.source.input.map.consumer().sources //=> ['a.sass'] *!/ this.map = map; let file = map.consumer().file; if ( !this.file && file ) this.file = this.mapResolve(file); } */ if (!this.file) { sequence += 1; /** * @member {string} - The unique ID of the CSS source. It will be * created if `from` option is not provided * (because PostCSS does not know the file path). * * @example * const root = postcss.parse(css); * root.source.input.file //=> undefined * root.source.input.id //=> "" */ this.id = ''; } if (this.map) this.map.file = this.from; } Input.prototype.error = function error(message, line, column) { var opts = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {}; var result = void 0; var origin = this.origin(line, column); if (origin) { result = new CssSyntaxError(message, origin.line, origin.column, origin.source, origin.file, opts.plugin); } else { result = new CssSyntaxError(message, line, column, this.css, this.file, opts.plugin); } result.input = { line: line, column: column, source: this.css }; if (this.file) result.input.file = this.file; return result; }; /** * Reads the input source map and returns a symbol position * in the input source (e.g., in a Sass file that was compiled * to CSS before being passed to PostCSS). * * @param {number} line - line in input CSS * @param {number} column - column in input CSS * * @return {filePosition} position in input source * * @example * root.source.input.origin(1, 1) //=> { file: 'a.css', line: 3, column: 1 } */ Input.prototype.origin = function origin(line, column) { if (!this.map) return false; var consumer = this.map.consumer(); var from = consumer.originalPositionFor({ line: line, column: column }); if (!from.source) return false; var result = { file: this.mapResolve(from.source), line: from.line, column: from.column }; var source = consumer.sourceContentFor(from.source); if (source) result.source = source; return result; }; Input.prototype.mapResolve = function mapResolve(file) { if (/^\w+:\/\//.test(file)) { return file; } else { return path.resolve(this.map.consumer().sourceRoot || '.', file); } }; /** * The CSS source identifier. Contains {@link Input#file} if the user * set the `from` option, or {@link Input#id} if they did not. * @type {string} * * @example * const root = postcss.parse(css, { from: 'a.css' }); * root.source.input.from //=> "/home/ai/a.css" * * const root = postcss.parse(css); * root.source.input.from //=> "" */ createClass(Input, [{ key: 'from', get: function get$$1() { return this.file || this.id; } }]); return Input; }(); var SafeParser = function (_Parser) { inherits(SafeParser, _Parser); function SafeParser() { classCallCheck(this, SafeParser); return possibleConstructorReturn(this, _Parser.apply(this, arguments)); } SafeParser.prototype.tokenize = function tokenize$$1() { this.tokens = tokenize(this.input, { ignoreErrors: true }); }; SafeParser.prototype.comment = function comment(token) { var node = new Comment(); this.init(node, token[2], token[3]); node.source.end = { line: token[4], column: token[5] }; var text = token[1].slice(2); if (text.slice(-2) === '*/') text = text.slice(0, -2); if (/^\s*$/.test(text)) { node.text = ''; node.raws.left = text; node.raws.right = ''; } else { var match = text.match(/^(\s*)([^]*[^\s])(\s*)$/); node.text = match[2]; node.raws.left = match[1]; node.raws.right = match[3]; } }; SafeParser.prototype.unclosedBracket = function unclosedBracket() {}; SafeParser.prototype.unknownWord = function unknownWord(start) { var buffer = this.tokens.slice(start, this.pos + 1); this.spaces += buffer.map(function (i) { return i[1]; }).join(''); }; SafeParser.prototype.unexpectedClose = function unexpectedClose() { this.current.raws.after += '}'; }; SafeParser.prototype.doubleColon = function doubleColon() {}; SafeParser.prototype.unnamedAtrule = function unnamedAtrule(node) { node.name = ''; }; SafeParser.prototype.precheckMissedSemicolon = function precheckMissedSemicolon(tokens) { var colon = this.colon(tokens); if (colon === false) return; var split = void 0; for (split = colon - 1; split >= 0; split--) { if (tokens[split][0] === 'word') break; } for (split -= 1; split >= 0; split--) { if (tokens[split][0] !== 'space') { split += 1; break; } } var other = tokens.splice(split, tokens.length - split); this.decl(other); }; SafeParser.prototype.checkMissedSemicolon = function checkMissedSemicolon() {}; SafeParser.prototype.endFile = function endFile() { if (this.current.nodes && this.current.nodes.length) { this.current.raws.semicolon = this.semicolon; } this.current.raws.after = (this.current.raws.after || '') + this.spaces; while (this.current.parent) { this.current = this.current.parent; this.current.raws.after = ''; } }; return SafeParser; }(Parser); function safeParse(css, opts) { var input = new Input(css, opts); var parser = new SafeParser(input); parser.tokenize(); parser.loop(); return parser.root; } // var generated = {}; /* InlineStyle takes arbitrary CSS and generates a flat object */ var _InlineStyle = (function (styleSheet) { var InlineStyle = function () { function InlineStyle(rules) { classCallCheck(this, InlineStyle); this.rules = rules; } InlineStyle.prototype.generateStyleObject = function generateStyleObject(executionContext) { var flatCSS = flatten(this.rules, executionContext).join(''); var hash = murmurhash(flatCSS); if (!generated[hash]) { var root = safeParse(flatCSS); var declPairs = []; root.each(function (node) { if (node.type === 'decl') { declPairs.push([node.prop, node.value]); } else if (node.type !== 'comment' && process.env.NODE_ENV !== 'production') { /* eslint-disable no-console */ console.warn('Node of type ' + node.type + ' not supported as an inline style'); } }); // RN currently does not support differing values for the corner radii of Image // components (but does for View). It is almost impossible to tell whether we'll have // support, so we'll just disable multiple values here. // https://github.com/styled-components/css-to-react-native/issues/11 var styleObject = transformDeclPairs(declPairs, ['borderRadius', 'borderWidth', 'borderColor', 'borderStyle']); var styles = styleSheet.create({ generated: styleObject }); generated[hash] = styles.generated; } return generated[hash]; }; return InlineStyle; }(); return InlineStyle; }); // var determineTheme = (function (props, fallbackTheme, defaultProps) { // Props should take precedence over ThemeProvider, which should take precedence over // defaultProps, but React automatically puts defaultProps on props. /* eslint-disable react/prop-types */ var isDefaultTheme = defaultProps && props.theme === defaultProps.theme; var theme = props.theme && !isDefaultTheme ? props.theme : fallbackTheme; /* eslint-enable */ return theme; }); // var EMPTY_ARRAY = Object.freeze([]); var EMPTY_OBJECT = Object.freeze({}); // function getComponentName(target) { return target.displayName || target.name || 'Component'; } // function isTag(target) /* : %checks */{ return typeof target === 'string'; } // function generateDisplayName(target) { return isTag(target) ? 'styled.' + target : 'Styled(' + getComponentName(target) + ')'; } // function isStyledComponent(target) /* : %checks */{ return ( // $FlowFixMe TODO: flow for styledComponentId typeof target === 'function' && typeof target.styledComponentId === 'string' ); } // function hasInInheritanceChain(child, parent) { var target = child; while (target) { target = Object.getPrototypeOf(target); if (target && target === parent) { return true; } } return false; } // // Helper to call a given function, only once var once = (function (cb) { var called = false; return function () { if (!called) { called = true; cb(); } }; }); // /** * Creates a broadcast that can be listened to, i.e. simple event emitter * * @see https://github.com/ReactTraining/react-broadcast */ var createBroadcast = function createBroadcast(initialState) { var listeners = {}; var id = 0; var state = initialState; function publish(nextState) { state = nextState; // eslint-disable-next-line guard-for-in, no-restricted-syntax for (var key in listeners) { var listener = listeners[key]; if (listener === undefined) { // eslint-disable-next-line no-continue continue; } listener(state); } } function subscribe(listener) { var currentId = id; listeners[currentId] = listener; id += 1; listener(state); return currentId; } function unsubscribe(unsubID) { listeners[unsubID] = undefined; } return { publish: publish, subscribe: subscribe, unsubscribe: unsubscribe }; }; var _contextShape, _ThemeProvider$contex; // NOTE: DO NOT CHANGE, changing this is a semver major change! var CHANNEL = '__styled-components__'; var CHANNEL_NEXT = CHANNEL + 'next__'; var CONTEXT_CHANNEL_SHAPE = PropTypes.shape({ getTheme: PropTypes.func, subscribe: PropTypes.func, unsubscribe: PropTypes.func }); var contextShape = (_contextShape = {}, _contextShape[CHANNEL] = PropTypes.func, _contextShape[CHANNEL_NEXT] = CONTEXT_CHANNEL_SHAPE, _contextShape); var warnChannelDeprecated = void 0; if (process.env.NODE_ENV !== 'production') { warnChannelDeprecated = once(function () { // eslint-disable-next-line no-console console.warn('Warning: Usage of `context.' + CHANNEL + '` as a function is deprecated. It will be replaced with the object on `.context.' + CHANNEL_NEXT + '` in a future version.'); }); } var isFunction = function isFunction(test) { return typeof test === 'function'; }; /** * Provide a theme to an entire react component tree via context and event listeners (have to do * both context and event emitter as pure components block context updates) */ var ThemeProvider = function (_Component) { inherits(ThemeProvider, _Component); function ThemeProvider() { classCallCheck(this, ThemeProvider); var _this = possibleConstructorReturn(this, _Component.call(this)); _this.unsubscribeToOuterId = -1; _this.getTheme = _this.getTheme.bind(_this); return _this; } ThemeProvider.prototype.componentWillMount = function componentWillMount() { var _this2 = this; // If there is a ThemeProvider wrapper anywhere around this theme provider, merge this theme // with the outer theme var outerContext = this.context[CHANNEL_NEXT]; if (outerContext !== undefined) { this.unsubscribeToOuterId = outerContext.subscribe(function (theme) { _this2.outerTheme = theme; if (_this2.broadcast !== undefined) { _this2.publish(_this2.props.theme); } }); } this.broadcast = createBroadcast(this.getTheme()); }; ThemeProvider.prototype.getChildContext = function getChildContext() { var _this3 = this, _babelHelpers$extends; return _extends({}, this.context, (_babelHelpers$extends = {}, _babelHelpers$extends[CHANNEL_NEXT] = { getTheme: this.getTheme, subscribe: this.broadcast.subscribe, unsubscribe: this.broadcast.unsubscribe }, _babelHelpers$extends[CHANNEL] = function (subscriber) { if (process.env.NODE_ENV !== 'production') { warnChannelDeprecated(); } // Patch the old `subscribe` provide via `CHANNEL` for older clients. var unsubscribeId = _this3.broadcast.subscribe(subscriber); return function () { return _this3.broadcast.unsubscribe(unsubscribeId); }; }, _babelHelpers$extends)); }; ThemeProvider.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { if (this.props.theme !== nextProps.theme) { this.publish(nextProps.theme); } }; ThemeProvider.prototype.componentWillUnmount = function componentWillUnmount() { if (this.unsubscribeToOuterId !== -1) { this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeToOuterId); } }; // Get the theme from the props, supporting both (outerTheme) => {} as well as object notation ThemeProvider.prototype.getTheme = function getTheme(passedTheme) { var theme = passedTheme || this.props.theme; if (isFunction(theme)) { var mergedTheme = theme(this.outerTheme); if (process.env.NODE_ENV !== 'production' && (mergedTheme === null || Array.isArray(mergedTheme) || (typeof mergedTheme === 'undefined' ? 'undefined' : _typeof(mergedTheme)) !== 'object')) { throw new StyledComponentsError(7); } return mergedTheme; } if (theme === null || Array.isArray(theme) || (typeof theme === 'undefined' ? 'undefined' : _typeof(theme)) !== 'object') { throw new StyledComponentsError(8); } return _extends({}, this.outerTheme, theme); }; ThemeProvider.prototype.publish = function publish(theme) { this.broadcast.publish(this.getTheme(theme)); }; ThemeProvider.prototype.render = function render() { if (!this.props.children) { return null; } return React__default.Children.only(this.props.children); }; return ThemeProvider; }(React.Component); ThemeProvider.childContextTypes = contextShape; ThemeProvider.contextTypes = (_ThemeProvider$contex = {}, _ThemeProvider$contex[CHANNEL_NEXT] = CONTEXT_CHANNEL_SHAPE, _ThemeProvider$contex); // var warnExtendDeprecated = function warnExtendDeprecated() {}; if (process.env.NODE_ENV !== 'production') { warnExtendDeprecated = once(function () { // eslint-disable-next-line no-console console.warn('Warning: The "extend" API will be removed in the upcoming v4.0 release. Use styled(StyledComponent) instead. You can find more information here: https://github.com/styled-components/styled-components/issues/1546'); }); } // $FlowFixMe var BaseStyledNativeComponent = function (_Component) { inherits(BaseStyledNativeComponent, _Component); function BaseStyledNativeComponent() { var _temp, _this, _ret; classCallCheck(this, BaseStyledNativeComponent); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _Component.call.apply(_Component, [this].concat(args))), _this), _this.attrs = {}, _this.state = { theme: null, generatedStyles: undefined }, _this.unsubscribeId = -1, _this.onRef = function (node) { // eslint-disable-next-line react/prop-types var innerRef = _this.props.innerRef; _this.root = node; if (typeof innerRef === 'function') { innerRef(node); } else if ((typeof innerRef === 'undefined' ? 'undefined' : _typeof(innerRef)) === 'object' && innerRef && innerRef.hasOwnProperty('current')) { innerRef.current = node; } }, _temp), possibleConstructorReturn(_this, _ret); } BaseStyledNativeComponent.prototype.unsubscribeFromContext = function unsubscribeFromContext() { if (this.unsubscribeId !== -1) { this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId); } }; BaseStyledNativeComponent.prototype.buildExecutionContext = function buildExecutionContext(theme, props) { var attrs = this.constructor.attrs; var context = _extends({}, props, { theme: theme }); if (attrs === undefined) { return context; } this.attrs = Object.keys(attrs).reduce(function (acc, key) { var attr = attrs[key]; // eslint-disable-next-line no-param-reassign acc[key] = typeof attr === 'function' && !hasInInheritanceChain(attr, React.Component) ? attr(context) : attr; return acc; }, {}); return _extends({}, context, this.attrs); }; BaseStyledNativeComponent.prototype.generateAndInjectStyles = function generateAndInjectStyles(theme, props) { var inlineStyle = this.constructor.inlineStyle; var executionContext = this.buildExecutionContext(theme, props); return inlineStyle.generateStyleObject(executionContext); }; BaseStyledNativeComponent.prototype.componentWillMount = function componentWillMount() { var _this2 = this; // If there is a theme in the context, subscribe to the event emitter. This // is necessary due to pure components blocking context updates, this circumvents // that by updating when an event is emitted var styledContext = this.context[CHANNEL_NEXT]; if (styledContext !== undefined) { var subscribe = styledContext.subscribe; this.unsubscribeId = subscribe(function (nextTheme) { // This will be called once immediately var theme = determineTheme(_this2.props, nextTheme, _this2.constructor.defaultProps); var generatedStyles = _this2.generateAndInjectStyles(theme, _this2.props); _this2.setState({ theme: theme, generatedStyles: generatedStyles }); }); } else { // eslint-disable-next-line react/prop-types var theme = this.props.theme || EMPTY_OBJECT; var generatedStyles = this.generateAndInjectStyles(theme, this.props); this.setState({ theme: theme, generatedStyles: generatedStyles }); } }; BaseStyledNativeComponent.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var _this3 = this; this.setState(function (prevState) { var theme = determineTheme(nextProps, prevState.theme, _this3.constructor.defaultProps); var generatedStyles = _this3.generateAndInjectStyles(theme, nextProps); return { theme: theme, generatedStyles: generatedStyles }; }); }; BaseStyledNativeComponent.prototype.componentWillUnmount = function componentWillUnmount() { this.unsubscribeFromContext(); }; BaseStyledNativeComponent.prototype.setNativeProps = function setNativeProps(nativeProps) { if (this.root !== undefined) { // $FlowFixMe this.root.setNativeProps(nativeProps); } else if (process.env.NODE_ENV !== 'production') { var displayName = this.constructor.displayName; // eslint-disable-next-line no-console console.warn('setNativeProps was called on a Styled Component wrapping a stateless functional component. ' + 'In this case no ref will be stored, and instead an innerRef prop will be passed on.\n' + ('Check whether the stateless functional component is passing on innerRef as a ref in ' + (displayName || 'UnknownStyledNativeComponent') + '.')); } }; BaseStyledNativeComponent.prototype.render = function render() { // eslint-disable-next-line react/prop-types var _props = this.props, children = _props.children, style = _props.style; var generatedStyles = this.state.generatedStyles; var target = this.constructor.target; var propsForElement = _extends({}, this.attrs, this.props, { style: [generatedStyles, style] }); if (!isStyledComponent(target) && ( // NOTE: We can't pass a ref to a stateless functional component typeof target !== 'function' || // $FlowFixMe TODO: flow for prototype target.prototype && 'isReactComponent' in target.prototype)) { propsForElement.ref = this.onRef; delete propsForElement.innerRef; } else { propsForElement.innerRef = this.onRef; } return React.createElement(target, propsForElement, children); }; return BaseStyledNativeComponent; }(React.Component); var _StyledNativeComponent = (function (constructWithOptions, InlineStyle) { var createStyledNativeComponent = function createStyledNativeComponent(target, options, rules) { var _options$isClass = options.isClass, isClass = _options$isClass === undefined ? !isTag(target) : _options$isClass, _options$displayName = options.displayName, displayName = _options$displayName === undefined ? generateDisplayName(target) : _options$displayName, _options$ParentCompon = options.ParentComponent, ParentComponent = _options$ParentCompon === undefined ? BaseStyledNativeComponent : _options$ParentCompon, extendingRules = options.rules, attrs = options.attrs; var inlineStyle = new InlineStyle(extendingRules === undefined ? rules : extendingRules.concat(rules)); var StyledNativeComponent = function (_ParentComponent) { inherits(StyledNativeComponent, _ParentComponent); function StyledNativeComponent() { classCallCheck(this, StyledNativeComponent); return possibleConstructorReturn(this, _ParentComponent.apply(this, arguments)); } StyledNativeComponent.withComponent = function withComponent(tag) { var _ = options.displayName, __ = options.componentId, optionsToCopy = objectWithoutProperties(options, ['displayName', 'componentId']); var newOptions = _extends({}, optionsToCopy, { ParentComponent: StyledNativeComponent }); return createStyledNativeComponent(tag, newOptions, rules); }; createClass(StyledNativeComponent, null, [{ key: 'extend', get: function get$$1() { var _ = options.displayName, __ = options.componentId, rulesFromOptions = options.rules, optionsToCopy = objectWithoutProperties(options, ['displayName', 'componentId', 'rules']); var newRules = rulesFromOptions === undefined ? rules : rulesFromOptions.concat(rules); var newOptions = _extends({}, optionsToCopy, { rules: newRules, ParentComponent: StyledNativeComponent }); warnExtendDeprecated(); return constructWithOptions(createStyledNativeComponent, target, newOptions); } }]); return StyledNativeComponent; }(ParentComponent); StyledNativeComponent.attrs = attrs; StyledNativeComponent.contextTypes = contextShape; StyledNativeComponent.displayName = displayName; StyledNativeComponent.inlineStyle = inlineStyle; StyledNativeComponent.styledComponentId = 'StyledNativeComponent'; StyledNativeComponent.target = target; if (isClass) { hoist(StyledNativeComponent, target, { // all SC-specific things should not be hoisted attrs: true, displayName: true, extend: true, inlineStyle: true, styledComponentId: true, target: true, withComponent: true }); } return StyledNativeComponent; }; return createStyledNativeComponent; }); // var _constructWithOptions = (function (css) { var constructWithOptions = function constructWithOptions(componentConstructor, tag) { var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : EMPTY_OBJECT; if (!reactIs.isValidElementType(tag)) { throw new StyledComponentsError(1, String(tag)); } /* This is callable directly as a template function */ // $FlowFixMe: Not typed to avoid destructuring arguments var templateFunction = function templateFunction() { return componentConstructor(tag, options, css.apply(undefined, arguments)); }; /* If config methods are called, wrap up a new template function and merge options */ templateFunction.withConfig = function (config) { return constructWithOptions(componentConstructor, tag, _extends({}, options, config)); }; templateFunction.attrs = function (attrs) { return constructWithOptions(componentConstructor, tag, _extends({}, options, { attrs: _extends({}, options.attrs || EMPTY_OBJECT, attrs) })); }; return templateFunction; }; return constructWithOptions; }); // var interleave = (function (strings, interpolations) { var result = [strings[0]]; for (var i = 0, len = interpolations.length; i < len; i += 1) { result.push(interpolations[i], strings[i + 1]); } return result; }); // var css = (function (styles) { for (var _len = arguments.length, interpolations = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { interpolations[_key - 1] = arguments[_key]; } if (typeof styles === 'function' || isPlainObject(styles)) { // $FlowFixMe return flatten(interleave(EMPTY_ARRAY, [styles].concat(interpolations))); } // $FlowFixMe return flatten(interleave(styles, interpolations)); }); // var withTheme = (function (Component) { var isStatelessFunctionalComponent = typeof Component === 'function' && // $FlowFixMe TODO: flow for prototype !(Component.prototype && 'isReactComponent' in Component.prototype); // NOTE: We can't pass a ref to a stateless functional component var shouldSetInnerRef = isStyledComponent(Component) || isStatelessFunctionalComponent; var WithTheme = function (_React$Component) { inherits(WithTheme, _React$Component); function WithTheme() { var _temp, _this, _ret; classCallCheck(this, WithTheme); for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return _ret = (_temp = (_this = possibleConstructorReturn(this, _React$Component.call.apply(_React$Component, [this].concat(args))), _this), _this.state = EMPTY_OBJECT, _this.unsubscribeId = -1, _temp), possibleConstructorReturn(_this, _ret); } // NOTE: This is so that isStyledComponent passes for the innerRef unwrapping WithTheme.prototype.componentWillMount = function componentWillMount() { var _this2 = this; var defaultProps = this.constructor.defaultProps; var styledContext = this.context[CHANNEL_NEXT]; var themeProp = determineTheme(this.props, undefined, defaultProps); if (styledContext === undefined && themeProp === undefined && process.env.NODE_ENV !== 'production') { // eslint-disable-next-line no-console console.warn('[withTheme] You are not using a ThemeProvider nor passing a theme prop or a theme in defaultProps'); } else if (styledContext === undefined && themeProp !== undefined) { this.setState({ theme: themeProp }); } else { var subscribe = styledContext.subscribe; this.unsubscribeId = subscribe(function (nextTheme) { var theme = determineTheme(_this2.props, nextTheme, defaultProps); _this2.setState({ theme: theme }); }); } }; WithTheme.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) { var defaultProps = this.constructor.defaultProps; this.setState(function (oldState) { var theme = determineTheme(nextProps, oldState.theme, defaultProps); return { theme: theme }; }); }; WithTheme.prototype.componentWillUnmount = function componentWillUnmount() { if (this.unsubscribeId !== -1) { this.context[CHANNEL_NEXT].unsubscribe(this.unsubscribeId); } }; WithTheme.prototype.render = function render() { var props = _extends({ theme: this.state.theme }, this.props); if (!shouldSetInnerRef) { props.ref = props.innerRef; delete props.innerRef; } return React__default.createElement(Component, props); }; return WithTheme; }(React__default.Component); WithTheme.contextTypes = contextShape; WithTheme.displayName = 'WithTheme(' + getComponentName(Component) + ')'; WithTheme.styledComponentId = 'withTheme'; return hoist(WithTheme, Component); }); // var constructWithOptions = _constructWithOptions(css); var InlineStyle = _InlineStyle(reactPrimitives.StyleSheet); var StyledNativeComponent = _StyledNativeComponent(constructWithOptions, InlineStyle); var styled = function styled(tag) { return constructWithOptions(StyledNativeComponent, tag); }; /* React native lazy-requires each of these modules for some reason, so let's * assume it's for a good reason and not eagerly load them all */ var aliases = 'Image Text Touchable View '; /* Define a getter for each alias which simply gets the reactNative component * and passes it to styled */ aliases.split(/\s+/m).forEach(function (alias) { return Object.defineProperty(styled, alias, { enumerable: true, configurable: false, get: function get() { return styled(reactPrimitives[alias]); } }); }); exports.css = css; exports.isStyledComponent = isStyledComponent; exports.ThemeProvider = ThemeProvider; exports.withTheme = withTheme; exports.default = styled; //# sourceMappingURL=styled-components-primitives.cjs.js.map