Skip to content

Instantly share code, notes, and snippets.

@tusbar
Last active March 5, 2018 14:58
Show Gist options
  • Save tusbar/2b59d321d9ab4be29582e6c2795fd8ab to your computer and use it in GitHub Desktop.
Save tusbar/2b59d321d9ab4be29582e6c2795fd8ab to your computer and use it in GitHub Desktop.
styled-jsx
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var GLOBAL_ATTRIBUTE = exports.GLOBAL_ATTRIBUTE = 'global';
var STYLE_ATTRIBUTE = exports.STYLE_ATTRIBUTE = 'jsx';
var STYLE_COMPONENT = exports.STYLE_COMPONENT = '_JSXStyle';
var STYLE_COMPONENT_CSS = exports.STYLE_COMPONENT_CSS = 'css';
var STYLE_COMPONENT_DYNAMIC = exports.STYLE_COMPONENT_DYNAMIC = 'dynamic';
var STYLE_COMPONENT_ID = exports.STYLE_COMPONENT_ID = 'styleId';
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.booleanOption = exports.processCss = exports.combinePlugins = exports.addSourceMaps = exports.makeSourceMapGenerator = exports.makeStyledJsxTag = exports.cssToBabelType = exports.templateLiteralFromPreprocessedCss = exports.computeClassNames = exports.getJSXStyleInfo = exports.validateExternalExpressions = exports.isDynamic = exports.validateExpressionVisitor = exports.findStyles = exports.isStyledJsx = exports.isGlobalEl = exports.getScope = exports.addClassName = exports.hashString = undefined;
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 _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 _babelTypes = require('babel-types');
var t = _interopRequireWildcard(_babelTypes);
var _stringHash = require('string-hash');
var _stringHash2 = _interopRequireDefault(_stringHash);
var _sourceMap = require('source-map');
var _convertSourceMap = require('convert-source-map');
var _convertSourceMap2 = _interopRequireDefault(_convertSourceMap);
var _styleTransform = require('./lib/style-transform');
var _styleTransform2 = _interopRequireDefault(_styleTransform);
var _constants = require('./_constants');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var concat = function concat(a, b) {
return t.binaryExpression('+', a, b);
};
var and = function and(a, b) {
return t.logicalExpression('&&', a, b);
};
var or = function or(a, b) {
return t.logicalExpression('||', a, b);
};
var joinSpreads = function joinSpreads(spreads) {
return spreads.reduce(function (acc, curr) {
return or(acc, curr);
});
};
var hashString = exports.hashString = function hashString(str) {
return String((0, _stringHash2.default)(str));
};
var addClassName = exports.addClassName = function addClassName(path, jsxId) {
var jsxIdWithSpace = concat(jsxId, t.stringLiteral(' '));
var attributes = path.get('attributes');
var spreads = [];
var className = null;
// Find className and collect spreads
for (var i = attributes.length - 1, attr; attr = attributes[i]; i--) {
var node = attr.node;
if (t.isJSXSpreadAttribute(attr)) {
var name = node.argument.name;
var attrNameDotClassName = t.memberExpression(t.isMemberExpression(node.argument) ? node.argument : t.identifier(name), t.identifier('className'));
spreads.push(
// `${name}.className != null && ${name}.className`
and(t.binaryExpression('!=', attrNameDotClassName, t.nullLiteral()), attrNameDotClassName));
continue;
}
if (t.isJSXAttribute(attr) && node.name.name === 'className') {
className = attributes[i];
// found className break the loop
break;
}
}
if (className) {
var newClassName = className.node.value.expression || className.node.value;
newClassName = t.isStringLiteral(newClassName) || t.isTemplateLiteral(newClassName) ? newClassName : or(newClassName, t.stringLiteral(''));
className.remove();
className = t.jSXExpressionContainer(spreads.length === 0 ? concat(jsxIdWithSpace, newClassName) : concat(jsxIdWithSpace, or(joinSpreads(spreads), newClassName)));
} else {
className = t.jSXExpressionContainer(spreads.length === 0 ? jsxId : concat(jsxIdWithSpace, or(joinSpreads(spreads), t.stringLiteral(''))));
}
path.node.attributes.push(t.jSXAttribute(t.jSXIdentifier('className'), className));
};
var getScope = exports.getScope = function getScope(path) {
return (path.findParent(function (path) {
return path.isFunctionDeclaration() || path.isArrowFunctionExpression() || path.isClassMethod();
}) || path).scope;
};
var isGlobalEl = exports.isGlobalEl = function isGlobalEl(el) {
return el.attributes.some(function (_ref) {
var name = _ref.name;
return name && name.name === _constants.GLOBAL_ATTRIBUTE;
});
};
var isStyledJsx = exports.isStyledJsx = function isStyledJsx(_ref2) {
var el = _ref2.node;
return t.isJSXElement(el) && el.openingElement.name.name === 'style' && el.openingElement.attributes.some(function (attr) {
return attr.name.name === _constants.STYLE_ATTRIBUTE;
});
};
var findStyles = exports.findStyles = function findStyles(path) {
if (isStyledJsx(path)) {
var node = path.node;
return isGlobalEl(node.openingElement) ? [path] : [];
}
return path.get('children').filter(isStyledJsx);
};
// The following visitor ensures that MemberExpressions and Identifiers
// are not in the scope of the current Method (render) or function (Component).
var validateExpressionVisitor = exports.validateExpressionVisitor = {
MemberExpression: function MemberExpression(path, scope) {
var node = path.node;
if (t.isIdentifier(node.property) && t.isThisExpression(node.object) && (node.property.name === 'props' || node.property.name === 'state' || node.property.name === 'context') || t.isIdentifier(node.object) && scope.hasOwnBinding(node.object.name)) {
throw path.buildCodeFrameError('Expected a constant ' + 'as part of the template literal expression ' + '(eg: <style jsx>{`p { color: ${myColor}`}</style>), ' + ('but got a MemberExpression: this.' + node.property.name));
}
},
Identifier: function Identifier(path, scope) {
var name = path.node.name;
if (t.isMemberExpression(path.parentPath) && scope.hasOwnBinding(name)) {
return;
}
var targetScope = path.scope;
var isDynamicBinding = false;
// Traversing scope chain in order to find current variable.
// If variable has no parent scope and it's `const` then we can interp. it
// as static in order to optimize styles.
// `let` and `var` can be changed during runtime.
while (targetScope) {
if (targetScope.hasOwnBinding(name)) {
var binding = targetScope.bindings[name];
isDynamicBinding = binding.scope.parent !== null || binding.kind !== 'const';
break;
}
targetScope = targetScope.parent;
}
if (isDynamicBinding) {
throw path.buildCodeFrameError('Expected `' + name + '` ' + 'to not come from the closest scope.\n' + 'Styled JSX encourages the use of constants ' + 'instead of `props` or dynamic values ' + 'which are better set via inline styles or `className` toggling. ' + 'See https://github.com/zeit/styled-jsx#dynamic-styles');
}
}
};
// Use `validateExpressionVisitor` to determine whether the `expr`ession has dynamic values.
var isDynamic = exports.isDynamic = function isDynamic(expr, scope) {
try {
expr.traverse(validateExpressionVisitor, scope);
return false;
} catch (err) {}
return true;
};
var validateExternalExpressionsVisitor = {
Identifier: function Identifier(path) {
if (t.isMemberExpression(path.parentPath)) {
return;
}
var name = path.node.name;
if (!path.scope.hasBinding(name)) {
throw path.buildCodeFrameError(path.getSource());
}
},
MemberExpression: function MemberExpression(path) {
var node = path.node;
if (!t.isIdentifier(node.object)) {
return;
}
if (!path.scope.hasBinding(node.object.name)) {
throw path.buildCodeFrameError(path.getSource());
}
},
ThisExpression: function ThisExpression(path) {
throw new Error(path.parentPath.getSource());
}
};
var validateExternalExpressions = exports.validateExternalExpressions = function validateExternalExpressions(path) {
try {
path.traverse(validateExternalExpressionsVisitor);
} catch (err) {
throw path.buildCodeFrameError('\n Found an `undefined` or invalid value in your styles: `' + err.message + '`.\n\n If you are trying to use dynamic styles in external files this is unfortunately not possible yet.\n Please put the dynamic parts alongside the component. E.g.\n\n <button>\n <style jsx>{externalStylesReference}</style>\n <style jsx>{`\n button { background-color: ${' + err.message + '} }\n `}</style>\n </button>\n ');
}
};
var getJSXStyleInfo = exports.getJSXStyleInfo = function getJSXStyleInfo(expr, scope) {
var node = expr.node;
var location = node.loc;
// Assume string literal
if (t.isStringLiteral(node)) {
return {
hash: hashString(node.value),
css: node.value,
expressions: [],
dynamic: false,
location: location
};
}
// Simple template literal without expressions
if (node.expressions.length === 0) {
return {
hash: hashString(node.quasis[0].value.cooked),
css: node.quasis[0].value.cooked,
expressions: [],
dynamic: false,
location: location
};
}
// Special treatment for template literals that contain expressions:
//
// Expressions are replaced with a placeholder
// so that the CSS compiler can parse and
// transform the css source string
// without having to know about js literal expressions.
// Later expressions are restored.
//
// e.g.
// p { color: ${myConstant}; }
// becomes
// p { color: %%styled-jsx-placeholder-${id}%%; }
var quasis = node.quasis,
expressions = node.expressions;
var hash = hashString(expr.getSource().slice(1, -1));
var dynamic = scope ? isDynamic(expr, scope) : false;
var css = quasis.reduce(function (css, quasi, index) {
return '' + css + quasi.value.cooked + (quasis.length === index + 1 ? '' : '%%styled-jsx-placeholder-' + index + '%%');
}, '');
return {
hash: hash,
css: css,
expressions: expressions,
dynamic: dynamic,
location: location
};
};
var computeClassNames = exports.computeClassNames = function computeClassNames(styles, externalJsxId) {
if (styles.length === 0) {
return {
className: externalJsxId
};
}
var hashes = styles.reduce(function (acc, styles) {
if (styles.dynamic === false) {
acc.static.push(styles.hash);
} else {
acc.dynamic.push(styles);
}
return acc;
}, {
static: [],
dynamic: []
});
var staticClassName = 'jsx-' + hashString(hashes.static.join(','));
// Static and optionally external classes. E.g.
// '[jsx-externalClasses] jsx-staticClasses'
if (hashes.dynamic.length === 0) {
return {
staticClassName: staticClassName,
className: externalJsxId ? concat(t.stringLiteral(staticClassName + ' '), externalJsxId) : t.stringLiteral(staticClassName)
};
}
// _JSXStyle.dynamic([ ['1234', [props.foo, bar, fn(props)]], ... ])
var dynamic = t.callExpression(
// Callee: _JSXStyle.dynamic
t.memberExpression(t.identifier(_constants.STYLE_COMPONENT), t.identifier('dynamic')),
// Arguments
[t.arrayExpression(hashes.dynamic.map(function (styles) {
return t.arrayExpression([t.stringLiteral(hashString(styles.hash + staticClassName)), t.arrayExpression(styles.expressions)]);
}))]);
// Dynamic and optionally external classes. E.g.
// '[jsx-externalClasses] ' + _JSXStyle.dynamic([ ['1234', [props.foo, bar, fn(props)]], ... ])
if (hashes.static.length === 0) {
return {
staticClassName: staticClassName,
className: externalJsxId ? concat(concat(externalJsxId, t.stringLiteral(' ')), dynamic) : dynamic
};
}
// Static, dynamic and optionally external classes. E.g.
// '[jsx-externalClasses] jsx-staticClasses ' + _JSXStyle.dynamic([ ['5678', [props.foo, bar, fn(props)]], ... ])
return {
staticClassName: staticClassName,
className: externalJsxId ? concat(concat(externalJsxId, t.stringLiteral(' ' + staticClassName + ' ')), dynamic) : concat(t.stringLiteral(staticClassName + ' '), dynamic)
};
};
var templateLiteralFromPreprocessedCss = exports.templateLiteralFromPreprocessedCss = function templateLiteralFromPreprocessedCss(css, expressions) {
var quasis = [];
var finalExpressions = [];
var parts = css.split(/(?:%%styled-jsx-placeholder-(\d+)%%)/g);
if (parts.length === 1) {
return t.stringLiteral(css);
}
parts.forEach(function (part, index) {
if (index % 2 > 0) {
// This is necessary because, after preprocessing, declarations might have been alterate.
// eg. properties are auto prefixed and therefore expressions need to match.
finalExpressions.push(expressions[part]);
} else {
quasis.push(part);
}
});
return t.templateLiteral(quasis.map(function (quasi, index) {
return t.templateElement({
raw: quasi,
cooked: quasi
}, quasis.length === index + 1);
}), finalExpressions);
};
var cssToBabelType = exports.cssToBabelType = function cssToBabelType(css) {
if (typeof css === 'string') {
return t.stringLiteral(css);
} else if (Array.isArray(css)) {
return t.arrayExpression(css);
}
return css;
};
var makeStyledJsxTag = exports.makeStyledJsxTag = function makeStyledJsxTag(id, transformedCss) {
var expressions = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
var css = cssToBabelType(transformedCss);
var attributes = [t.jSXAttribute(t.jSXIdentifier(_constants.STYLE_COMPONENT_ID), t.jSXExpressionContainer(typeof id === 'string' ? t.stringLiteral(id) : id)), t.jSXAttribute(t.jSXIdentifier(_constants.STYLE_COMPONENT_CSS), t.jSXExpressionContainer(css))];
if (expressions.length > 0) {
attributes.push(t.jSXAttribute(t.jSXIdentifier(_constants.STYLE_COMPONENT_DYNAMIC), t.jSXExpressionContainer(t.arrayExpression(expressions))));
}
return t.jSXElement(t.jSXOpeningElement(t.jSXIdentifier(_constants.STYLE_COMPONENT), attributes, true), null, []);
};
var makeSourceMapGenerator = exports.makeSourceMapGenerator = function makeSourceMapGenerator(file) {
var filename = file.opts.sourceFileName;
var generator = new _sourceMap.SourceMapGenerator({
file: filename,
sourceRoot: file.opts.sourceRoot
});
generator.setSourceContent(filename, file.code);
return generator;
};
var addSourceMaps = exports.addSourceMaps = function addSourceMaps(code, generator, filename) {
var sourceMaps = [_convertSourceMap2.default.fromObject(generator).toComment({ multiline: true }), '/*@ sourceURL=' + filename + ' */'];
if (Array.isArray(code)) {
return code.concat(sourceMaps);
}
return [code].concat(sourceMaps).join('\n');
};
var combinePlugins = exports.combinePlugins = function combinePlugins(plugins) {
if (!plugins) {
return function (css) {
return css;
};
}
if (!Array.isArray(plugins) || plugins.some(function (p) {
return !Array.isArray(p) && typeof p !== 'string';
})) {
throw new Error('`plugins` must be an array of plugins names (string) or an array `[plugin-name, {options}]`');
}
return plugins.map(function (plugin, i) {
var options = {};
if (Array.isArray(plugin)) {
options = plugin[1] || {};
plugin = plugin[0];
if (Object.prototype.hasOwnProperty.call(options, 'babel')) {
throw new Error('\n Error while trying to register the styled-jsx plugin: ' + plugin + '\n The option name `babel` is reserved.\n ');
}
}
// eslint-disable-next-line import/no-dynamic-require
var p = require(plugin);
if (p.default) {
p = p.default;
}
var type = typeof p === 'undefined' ? 'undefined' : _typeof(p);
if (type !== 'function') {
throw new Error('Expected plugin ' + plugins[i] + ' to be a function but instead got ' + type);
}
return {
plugin: p,
options: options
};
}).reduce(function (previous, _ref3) {
var plugin = _ref3.plugin,
options = _ref3.options;
return function (css, babelOptions) {
return plugin(previous ? previous(css, babelOptions) : css, _extends({}, options, {
babel: babelOptions
}));
};
}, null);
};
var getPrefix = function getPrefix(isDynamic, id) {
return isDynamic ? '.__jsx-style-dynamic-selector' : '.' + id;
};
var processCss = exports.processCss = function processCss(stylesInfo, options) {
var hash = stylesInfo.hash,
css = stylesInfo.css,
expressions = stylesInfo.expressions,
dynamic = stylesInfo.dynamic,
location = stylesInfo.location,
fileInfo = stylesInfo.fileInfo,
isGlobal = stylesInfo.isGlobal,
plugins = stylesInfo.plugins,
vendorPrefixes = stylesInfo.vendorPrefixes;
var staticClassName = stylesInfo.staticClassName || 'jsx-' + hashString(hash);
var splitRules = options.splitRules;
var useSourceMaps = Boolean(fileInfo.sourceMaps) && !splitRules;
var pluginsOptions = {
location: {
start: _extends({}, location.start),
end: _extends({}, location.end)
},
vendorPrefixes: vendorPrefixes,
sourceMaps: useSourceMaps,
isGlobal: isGlobal,
filename: fileInfo.filename
};
var transformedCss = void 0;
if (useSourceMaps) {
var generator = makeSourceMapGenerator(fileInfo.file);
var filename = fileInfo.sourceFileName;
transformedCss = addSourceMaps((0, _styleTransform2.default)(isGlobal ? '' : getPrefix(dynamic, staticClassName), plugins(css, pluginsOptions), {
generator: generator,
offset: location.start,
filename: filename,
splitRules: splitRules,
vendorPrefixes: vendorPrefixes
}), generator, filename);
} else {
transformedCss = (0, _styleTransform2.default)(isGlobal ? '' : getPrefix(dynamic, staticClassName), plugins(css, pluginsOptions), { splitRules: splitRules, vendorPrefixes: vendorPrefixes });
}
if (expressions.length > 0) {
if (typeof transformedCss === 'string') {
transformedCss = templateLiteralFromPreprocessedCss(transformedCss, expressions);
} else {
transformedCss = transformedCss.map(function (transformedCss) {
return templateLiteralFromPreprocessedCss(transformedCss, expressions);
});
}
} else if (Array.isArray(transformedCss)) {
transformedCss = transformedCss.map(function (transformedCss) {
return t.stringLiteral(transformedCss);
});
}
return {
hash: dynamic ? hashString(hash + staticClassName) : hashString(hash),
css: transformedCss,
expressions: dynamic && expressions
};
};
var booleanOption = exports.booleanOption = function booleanOption(opts) {
var ret = void 0;
opts.some(function (opt) {
if (typeof opt === 'boolean') {
ret = opt;
return true;
}
return false;
});
return ret;
};
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.visitor = undefined;
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; };
exports.default = function () {
return _extends({
Program: function Program(path, state) {
var vendorPrefix = (0, _utils.booleanOption)([state.opts.vendorPrefix, state.file.opts.vendorPrefix]);
state.opts.vendorPrefix = typeof vendorPrefix === 'boolean' ? vendorPrefix : true;
var sourceMaps = (0, _utils.booleanOption)([state.opts.sourceMaps, state.file.opts.sourceMaps]);
state.opts.sourceMaps = Boolean(sourceMaps);
if (!state.plugins) {
var _state$opts2 = state.opts,
_sourceMaps = _state$opts2.sourceMaps,
_vendorPrefix = _state$opts2.vendorPrefix;
state.plugins = (0, _utils.combinePlugins)(state.opts.plugins, {
sourceMaps: _sourceMaps || state.file.opts.sourceMaps,
vendorPrefix: typeof _vendorPrefix === 'boolean' ? _vendorPrefix : true
});
}
}
}, visitor);
};
var _babelTypes = require('babel-types');
var t = _interopRequireWildcard(_babelTypes);
var _utils = require('./_utils');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
var isModuleExports = t.buildMatchMemberExpression('module.exports');
function processTaggedTemplateExpression(_ref) {
var path = _ref.path,
fileInfo = _ref.fileInfo,
splitRules = _ref.splitRules,
plugins = _ref.plugins,
vendorPrefix = _ref.vendorPrefix;
var templateLiteral = path.get('quasi');
// Check whether there are undefined references or references to this.something (e.g. props or state)
(0, _utils.validateExternalExpressions)(templateLiteral);
var stylesInfo = (0, _utils.getJSXStyleInfo)(templateLiteral);
var globalStyles = (0, _utils.processCss)(_extends({}, stylesInfo, {
hash: stylesInfo.hash + '0',
fileInfo: fileInfo,
isGlobal: true,
plugins: plugins,
vendorPrefix: vendorPrefix
}), { splitRules: splitRules });
var scopedStyles = (0, _utils.processCss)(_extends({}, stylesInfo, {
hash: stylesInfo.hash + '1',
fileInfo: fileInfo,
isGlobal: false,
plugins: plugins,
vendorPrefix: vendorPrefix
}), { splitRules: splitRules });
var id = path.parentPath.node.id;
var baseExportName = id ? id.name : 'default';
var parentPath = baseExportName === 'default' ? path.parentPath : path.findParent(function (path) {
return path.isVariableDeclaration() || path.isAssignmentExpression() && isModuleExports(path.get('left').node);
});
if (baseExportName !== 'default' && !parentPath.parentPath.isProgram()) {
parentPath = parentPath.parentPath;
}
var hashesAndScoped = {
hash: globalStyles.hash,
scoped: (0, _utils.cssToBabelType)(scopedStyles.css),
scopedHash: scopedStyles.hash
};
var globalCss = (0, _utils.cssToBabelType)(globalStyles.css);
// default exports
if (baseExportName === 'default') {
var defaultExportIdentifier = path.scope.generateUidIdentifier('defaultExport');
parentPath.insertBefore(t.variableDeclaration('const', [t.variableDeclarator(defaultExportIdentifier, t.isArrayExpression(globalCss) ? globalCss : t.newExpression(t.identifier('String'), [globalCss]))]));
parentPath.insertBefore(makeHashesAndScopedCssPaths(defaultExportIdentifier, hashesAndScoped));
path.replaceWith(defaultExportIdentifier);
return;
}
// named exports
parentPath.insertAfter(makeHashesAndScopedCssPaths(t.identifier(baseExportName), hashesAndScoped));
path.replaceWith(t.isArrayExpression(globalCss) ? globalCss : t.newExpression(t.identifier('String'), [globalCss]));
}
function makeHashesAndScopedCssPaths(exportIdentifier, data) {
return Object.keys(data).map(function (key) {
var value = typeof data[key] === 'string' ? t.stringLiteral(data[key]) : data[key];
return t.expressionStatement(t.assignmentExpression('=', t.memberExpression(exportIdentifier, t.identifier('__' + key)), value));
});
}
var visitor = exports.visitor = {
ImportDeclaration: function ImportDeclaration(path, state) {
if (path.node.source.value !== 'styled-jsx/css') {
return;
}
var tagName = path.node.specifiers[0].local.name;
var binding = path.scope.getBinding(tagName);
if (!binding || !Array.isArray(binding.referencePaths)) {
return;
}
var taggedTemplateExpressions = binding.referencePaths.map(function (ref) {
return ref.parentPath;
}).filter(function (path) {
return path.isTaggedTemplateExpression();
});
if (taggedTemplateExpressions.length === 0) {
return;
}
var _state$opts = state.opts,
vendorPrefix = _state$opts.vendorPrefix,
sourceMaps = _state$opts.sourceMaps;
taggedTemplateExpressions.forEach(function (path) {
processTaggedTemplateExpression({
path: path,
fileInfo: {
file: state.file,
sourceFileName: state.file.opts.sourceFileName,
sourceMaps: sourceMaps
},
splitRules: typeof state.opts.optimizeForSpeed === 'boolean' ? state.opts.optimizeForSpeed : process.env.NODE_ENV === 'production',
plugins: state.plugins,
vendorPrefix: vendorPrefix
});
});
// Finally remove the import
path.remove();
}
};
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
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; }; // Packages
exports.default = function (_ref) {
var t = _ref.types;
return {
inherits: _babelPluginSyntaxJsx2.default,
visitor: _extends({
JSXOpeningElement: function JSXOpeningElement(path, state) {
var el = path.node;
var _ref2 = el.name || {},
name = _ref2.name;
if (!state.hasJSXStyle) {
return;
}
if (state.ignoreClosing === null) {
// We keep a counter of elements inside so that we
// can keep track of when we exit the parent to reset state
// note: if we wished to add an option to turn off
// selectors to reach parent elements, it would suffice to
// set this to `1` and do an early return instead
state.ignoreClosing = 0;
}
if (name && name !== 'style' && name !== _constants.STYLE_COMPONENT && name.charAt(0) !== name.charAt(0).toUpperCase()) {
if (state.className) {
(0, _utils.addClassName)(path, state.className);
}
}
state.ignoreClosing++;
// Next visit will be: JSXElement exit()
},
JSXElement: {
enter: function enter(path, state) {
if (state.hasJSXStyle !== null) {
return;
}
var styles = (0, _utils.findStyles)(path);
if (styles.length === 0) {
return;
}
state.styles = [];
state.externalStyles = [];
var scope = (0, _utils.getScope)(path);
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = styles[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var style = _step.value;
// Compute children excluding whitespace
var children = style.get('children').filter(function (c) {
return t.isJSXExpressionContainer(c.node) ||
// Ignore whitespace around the expression container
t.isJSXText(c.node) && c.node.value.trim() !== '';
});
if (children.length !== 1) {
throw path.buildCodeFrameError('Expected one child under ' + ('JSX Style tag, but got ' + children.length + ' ') + '(eg: <style jsx>{`hi`}</style>)');
}
var child = children[0];
if (!t.isJSXExpressionContainer(child)) {
throw path.buildCodeFrameError('Expected a child of ' + 'type JSXExpressionContainer under JSX Style tag ' + ('(eg: <style jsx>{`hi`}</style>), got ' + child.type));
}
var expression = child.get('expression');
if (t.isIdentifier(expression)) {
var idName = expression.node.name;
if (expression.scope.hasBinding(idName)) {
var externalStylesIdentifier = t.identifier(idName);
var isGlobal = (0, _utils.isGlobalEl)(style.get('openingElement').node);
state.externalStyles.push([t.memberExpression(externalStylesIdentifier, t.identifier(isGlobal ? '__hash' : '__scopedHash')), externalStylesIdentifier, isGlobal]);
continue;
}
throw path.buildCodeFrameError('The Identifier ' + ('`' + expression.getSource() + '` is either `undefined` or ') + 'it is not an external StyleSheet reference i.e. ' + 'it doesn\'t come from an `import` or `require` statement');
}
if (!t.isTemplateLiteral(expression) && !t.isStringLiteral(expression)) {
throw path.buildCodeFrameError('Expected a template ' + 'literal or String literal as the child of the ' + 'JSX Style tag (eg: <style jsx>{`some css`}</style>),' + (' but got ' + expression.type));
}
state.styles.push((0, _utils.getJSXStyleInfo)(expression, scope));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
var externalJsxId = void 0;
if (state.externalStyles.length > 0) {
var expressions = state.externalStyles
// Remove globals
.filter(function (s) {
return !s[2];
}).map(function (s) {
return s[0];
});
var expressionsLength = expressions.length;
if (expressionsLength === 0) {
externalJsxId = null;
} else {
// Construct a template literal of this form:
// `jsx-${styles.__scopedHash} jsx-${otherStyles.__scopedHash}`
externalJsxId = t.templateLiteral([t.templateElement({ raw: 'jsx-', cooked: 'jsx-' })].concat(_toConsumableArray([].concat(_toConsumableArray(new Array(expressionsLength - 1))).map(function () {
return t.templateElement({ raw: ' jsx-', cooked: ' jsx-' });
})), [t.templateElement({ raw: '', cooked: '' }, true)]), expressions);
}
}
if (state.styles.length > 0 || externalJsxId) {
var _computeClassNames = (0, _utils.computeClassNames)(state.styles, externalJsxId),
staticClassName = _computeClassNames.staticClassName,
className = _computeClassNames.className;
state.className = className;
state.staticClassName = staticClassName;
}
state.hasJSXStyle = true;
state.file.hasJSXStyle = true;
// Next visit will be: JSXOpeningElement
},
exit: function exit(path, state) {
var isGlobal = (0, _utils.isGlobalEl)(path.node.openingElement);
if (state.hasJSXStyle && ! --state.ignoreClosing && !isGlobal) {
state.hasJSXStyle = null;
state.className = null;
state.externalJsxId = null;
}
if (!state.hasJSXStyle || !(0, _utils.isStyledJsx)(path)) {
return;
}
if (state.ignoreClosing > 1) {
var styleTagSrc = void 0;
try {
styleTagSrc = path.getSource();
} catch (err) {}
throw path.buildCodeFrameError('Detected nested style tag' + (styleTagSrc ? ': \n\n' + styleTagSrc + '\n\n' : ' ') + 'styled-jsx only allows style tags ' + 'to be direct descendants (children) of the outermost ' + 'JSX element i.e. the subtree root.');
}
if (state.externalStyles.length > 0 && path.get('children').filter(function (child) {
if (!t.isJSXExpressionContainer(child)) {
return false;
}
var expression = child.get('expression');
return expression && expression.isIdentifier();
}).length === 1) {
var _state$externalStyles = state.externalStyles.shift(),
_state$externalStyles2 = _slicedToArray(_state$externalStyles, 3),
id = _state$externalStyles2[0],
_css = _state$externalStyles2[1],
_isGlobal = _state$externalStyles2[2];
path.replaceWith((0, _utils.makeStyledJsxTag)(id, _isGlobal ? _css : t.memberExpression(t.identifier(_css.name), t.identifier('__scoped'))));
return;
}
var _state$opts = state.opts,
vendorPrefixes = _state$opts.vendorPrefixes,
sourceMaps = _state$opts.sourceMaps;
var stylesInfo = _extends({}, state.styles.shift(), {
fileInfo: {
file: state.file,
sourceFileName: state.file.opts.sourceFileName || state.file.sourceFileName,
sourceMaps: sourceMaps,
filename: state.file.opts.filename || state.file.filename
},
staticClassName: state.staticClassName,
isGlobal: isGlobal,
plugins: state.plugins,
vendorPrefixes: vendorPrefixes
});
var splitRules = typeof state.opts.optimizeForSpeed === 'boolean' ? state.opts.optimizeForSpeed : process.env.NODE_ENV === 'production';
var _processCss = (0, _utils.processCss)(stylesInfo, {
splitRules: splitRules
}),
hash = _processCss.hash,
css = _processCss.css,
expressions = _processCss.expressions;
path.replaceWith((0, _utils.makeStyledJsxTag)(hash, css, expressions));
}
},
Program: {
enter: function enter(path, state) {
state.hasJSXStyle = null;
state.ignoreClosing = null;
state.file.hasJSXStyle = false;
var vendorPrefixes = (0, _utils.booleanOption)([state.opts.vendorPrefixes, state.file.opts.vendorPrefixes]);
state.opts.vendorPrefixes = typeof vendorPrefixes === 'boolean' ? vendorPrefixes : true;
var sourceMaps = (0, _utils.booleanOption)([state.opts.sourceMaps, state.file.opts.sourceMaps]);
state.opts.sourceMaps = Boolean(sourceMaps);
if (!state.plugins) {
state.plugins = (0, _utils.combinePlugins)(state.opts.plugins, {
sourceMaps: state.opts.sourceMaps,
vendorPrefixes: state.opts.vendorPrefixes
});
}
},
exit: function exit(_ref3, state) {
var node = _ref3.node,
scope = _ref3.scope;
if (!(state.file.hasJSXStyle && !scope.hasBinding(_constants.STYLE_COMPONENT))) {
return;
}
var importDeclaration = t.importDeclaration([t.importDefaultSpecifier(t.identifier(_constants.STYLE_COMPONENT))], t.stringLiteral('styled-jsx/style'));
node.body.unshift(importDeclaration);
}
}
}, _babelExternal.visitor)
};
};
var _babelPluginSyntaxJsx = require('babel-plugin-syntax-jsx');
var _babelPluginSyntaxJsx2 = _interopRequireDefault(_babelPluginSyntaxJsx);
var _babelExternal = require('./babel-external');
var _utils = require('./_utils');
var _constants = require('./_constants');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
'use strict';
var Stylis = require('stylis');
var stylisRuleSheet = require('stylis-rule-sheet');
var stylis = new Stylis();
function disableNestingPlugin() {
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var context = args[0],
_args$ = args[3],
parent = _args$ === undefined ? [] : _args$,
line = args[4],
column = args[5];
if (context === 2) {
// replace null characters and trim
parent = (parent[0] || '').replace(/\u0000/g, '').trim();
if (parent.length > 0 && parent.charAt(0) !== '@') {
throw new Error('Nesting detected at ' + line + ':' + column + '. ' + 'Unfortunately nesting is not supported by styled-jsx.');
}
}
}
var generator = void 0;
var filename = void 0;
var offset = void 0;
function sourceMapsPlugin() {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var context = args[0],
line = args[4],
column = args[5],
length = args[6];
// Pre-processed, init source map
if (context === -1 && generator !== undefined) {
generator.addMapping({
generated: {
line: 1,
column: 0
},
source: filename,
original: offset
});
return;
}
// Post-processed
if (context === -2 && generator !== undefined) {
generator = undefined;
offset = undefined;
filename = undefined;
return;
}
// Selector/property, update source map
if ((context === 1 || context === 2) && generator !== undefined) {
generator.addMapping({
generated: {
line: 1,
column: length
},
source: filename,
original: {
line: line + offset.line,
column: column + offset.column
}
});
}
}
/**
* splitRulesPlugin
* Used to split a blob of css into an array of rules
* that can inserted via sheet.insertRule
*/
var splitRules = [];
var splitRulesPlugin = stylisRuleSheet(function (rule) {
splitRules.push(rule);
});
stylis.use(disableNestingPlugin);
stylis.use(sourceMapsPlugin);
stylis.use(splitRulesPlugin);
stylis.set({
cascade: false,
compress: true
});
/**
* Public transform function
*
* @param {String} hash
* @param {String} styles
* @param {Object} settings
* @return {string}
*/
function transform(hash, styles) {
var settings = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
generator = settings.generator;
offset = settings.offset;
filename = settings.filename;
splitRules = [];
stylis.set({
prefix: typeof settings.vendorPrefixes === 'boolean' ? settings.vendorPrefixes : true
});
stylis(hash, styles);
if (settings.splitRules) {
return splitRules;
}
return splitRules.join('');
}
module.exports = transform;
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/*
Based on Glamor's sheet
https://github.com/threepointone/glamor/blob/667b480d31b3721a905021b26e1290ce92ca2879/src/sheet.js
*/
var isProd = process.env && process.env.NODE_ENV === 'production';
var isString = function isString(o) {
return Object.prototype.toString.call(o) === '[object String]';
};
var StyleSheet = function () {
function StyleSheet() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$name = _ref.name,
name = _ref$name === undefined ? 'stylesheet' : _ref$name,
_ref$optimizeForSpeed = _ref.optimizeForSpeed,
optimizeForSpeed = _ref$optimizeForSpeed === undefined ? isProd : _ref$optimizeForSpeed,
_ref$isBrowser = _ref.isBrowser,
isBrowser = _ref$isBrowser === undefined ? typeof window !== 'undefined' : _ref$isBrowser;
_classCallCheck(this, StyleSheet);
invariant(isString(name), '`name` must be a string');
this._name = name;
this._deletedRulePlaceholder = '#' + name + '-deleted-rule____{}';
invariant(typeof optimizeForSpeed === 'boolean', '`optimizeForSpeed` must be a boolean');
this._optimizeForSpeed = optimizeForSpeed;
this._isBrowser = isBrowser;
this._serverSheet = undefined;
this._tags = [];
this._injected = false;
this._rulesCount = 0;
}
_createClass(StyleSheet, [{
key: 'setOptimizeForSpeed',
value: function setOptimizeForSpeed(bool) {
invariant(typeof bool === 'boolean', '`setOptimizeForSpeed` accepts a boolean');
invariant(this._rulesCount === 0, 'optimizeForSpeed cannot be when rules have already been inserted');
this.flush();
this._optimizeForSpeed = bool;
this.inject();
}
}, {
key: 'isOptimizeForSpeed',
value: function isOptimizeForSpeed() {
return this._optimizeForSpeed;
}
}, {
key: 'inject',
value: function inject() {
var _this = this;
invariant(!this._injected, 'sheet already injected');
this._injected = true;
if (this._isBrowser && this._optimizeForSpeed) {
this._tags[0] = this.makeStyleTag(this._name);
this._optimizeForSpeed = 'insertRule' in this.getSheet();
if (!this._optimizeForSpeed) {
if (!isProd) {
console.warn('StyleSheet: optimizeForSpeed mode not supported falling back to standard mode.'); // eslint-disable-line no-console
}
this.flush();
this._injected = true;
}
return;
}
this._serverSheet = {
cssRules: [],
insertRule: function insertRule(rule, index) {
if (typeof index === 'number') {
_this._serverSheet.cssRules[index] = { cssText: rule };
} else {
_this._serverSheet.cssRules.push({ cssText: rule });
}
return index;
},
deleteRule: function deleteRule(index) {
_this._serverSheet.cssRules[index] = null;
}
};
}
}, {
key: 'getSheetForTag',
value: function getSheetForTag(tag) {
if (tag.sheet) {
return tag.sheet;
}
// this weirdness brought to you by firefox
for (var i = 0; i < document.styleSheets.length; i++) {
if (document.styleSheets[i].ownerNode === tag) {
return document.styleSheets[i];
}
}
}
}, {
key: 'getSheet',
value: function getSheet() {
return this.getSheetForTag(this._tags[this._tags.length - 1]);
}
}, {
key: 'insertRule',
value: function insertRule(rule, index) {
invariant(isString(rule), '`insertRule` accepts only strings');
if (!this._isBrowser) {
if (typeof index !== 'number') {
index = this._serverSheet.cssRules.length;
}
this._serverSheet.insertRule(rule, index);
return this._rulesCount++;
}
if (this._optimizeForSpeed) {
var sheet = this.getSheet();
if (typeof index !== 'number') {
index = sheet.cssRules.length;
}
// this weirdness for perf, and chrome's weird bug
// https://stackoverflow.com/questions/20007992/chrome-suddenly-stopped-accepting-insertrule
try {
sheet.insertRule(rule, index);
} catch (err) {
if (!isProd) {
console.warn('StyleSheet: illegal rule: \n\n' + rule + '\n\nSee https://stackoverflow.com/q/20007992 for more info'); // eslint-disable-line no-console
}
return -1;
}
} else {
var insertionPoint = this._tags[index];
this._tags.push(this.makeStyleTag(this._name, rule, insertionPoint));
}
return this._rulesCount++;
}
}, {
key: 'replaceRule',
value: function replaceRule(index, rule) {
if (this._optimizeForSpeed || !this._isBrowser) {
var sheet = this._isBrowser ? this.getSheet() : this._serverSheet;
if (!rule.trim()) {
rule = this._deletedRulePlaceholder;
}
if (!sheet.cssRules[index]) {
// @TBD Should we throw an error?
return index;
}
sheet.deleteRule(index);
try {
sheet.insertRule(rule, index);
} catch (err) {
if (!isProd) {
console.warn('StyleSheet: illegal rule: \n\n' + rule + '\n\nSee https://stackoverflow.com/q/20007992 for more info'); // eslint-disable-line no-console
}
// In order to preserve the indices we insert a deleteRulePlaceholder
sheet.insertRule(this._deletedRulePlaceholder, index);
}
} else {
var tag = this._tags[index];
invariant(tag, 'old rule at index `' + index + '` not found');
tag.textContent = rule;
}
return index;
}
}, {
key: 'deleteRule',
value: function deleteRule(index) {
if (!this._isBrowser) {
this._serverSheet.deleteRule(index);
return;
}
if (this._optimizeForSpeed) {
this.replaceRule(index, '');
} else {
var tag = this._tags[index];
invariant(tag, 'rule at index `' + index + '` not found');
tag.parentNode.removeChild(tag);
this._tags[index] = null;
}
}
}, {
key: 'flush',
value: function flush() {
this._injected = false;
this._rulesCount = 0;
if (this._isBrowser) {
this._tags.forEach(function (tag) {
return tag && tag.parentNode.removeChild(tag);
});
this._tags = [];
} else {
// simpler on server
this._serverSheet.cssRules = [];
}
}
}, {
key: 'cssRules',
value: function cssRules() {
var _this2 = this;
if (!this._isBrowser) {
return this._serverSheet.cssRules;
}
return this._tags.reduce(function (rules, tag) {
if (tag) {
rules = rules.concat(_this2.getSheetForTag(tag).cssRules.map(function (rule) {
return rule.cssText === _this2._deletedRulePlaceholder ? null : rule;
}));
} else {
rules.push(null);
}
return rules;
}, []);
}
}, {
key: 'makeStyleTag',
value: function makeStyleTag(name, cssString, relativeToTag) {
if (cssString) {
invariant(isString(cssString), 'makeStyleTag acceps only strings as second parameter');
}
var tag = document.createElement('style');
tag.type = 'text/css';
tag.setAttribute('data-' + name, '');
if (cssString) {
tag.appendChild(document.createTextNode(cssString));
}
var head = document.head || document.getElementsByTagName('head')[0];
if (relativeToTag) {
head.insertBefore(tag, relativeToTag);
} else {
head.appendChild(tag);
}
return tag;
}
}, {
key: 'length',
get: function get() {
return this._rulesCount;
}
}]);
return StyleSheet;
}();
exports.default = StyleSheet;
function invariant(condition, message) {
if (!condition) {
throw new Error('StyleSheet: ' + message + '.');
}
}
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
exports.default = flushToReact;
exports.flushToHTML = flushToHTML;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _style = require('./style');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function flushToReact() {
var mem = (0, _style.flush)();
var arr = [];
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = mem[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _ref = _step.value;
var _ref2 = _slicedToArray(_ref, 2);
var id = _ref2[0];
var css = _ref2[1];
arr.push(_react2.default.createElement('style', {
id: '__' + id,
// Avoid warnings upon render with a key
key: '__' + id,
dangerouslySetInnerHTML: {
__html: css
}
}));
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator.return) {
_iterator.return();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
return arr;
}
function flushToHTML() {
var mem = (0, _style.flush)();
var html = '';
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = mem[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var _ref3 = _step2.value;
var _ref4 = _slicedToArray(_ref3, 2);
var id = _ref4[0];
var css = _ref4[1];
html += '<style id="__' + id + '">' + css + '</style>';
}
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2.return) {
_iterator2.return();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
return html;
}
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
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; }; }();
exports.flush = flush;
var _react = require('react');
var _stylesheetRegistry = require('./stylesheet-registry');
var _stylesheetRegistry2 = _interopRequireDefault(_stylesheetRegistry);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(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; }
function _inherits(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 styleSheetRegistry = new _stylesheetRegistry2.default();
var JSXStyle = function (_Component) {
_inherits(JSXStyle, _Component);
function JSXStyle() {
_classCallCheck(this, JSXStyle);
return _possibleConstructorReturn(this, (JSXStyle.__proto__ || Object.getPrototypeOf(JSXStyle)).apply(this, arguments));
}
_createClass(JSXStyle, [{
key: 'componentWillMount',
value: function componentWillMount() {
styleSheetRegistry.add(this.props);
}
}, {
key: 'shouldComponentUpdate',
value: function shouldComponentUpdate(nextProps) {
return this.props.css !== nextProps.css;
}
// To avoid FOUC, we process new changes
// on `componentWillUpdate` rather than `componentDidUpdate`.
}, {
key: 'componentWillUpdate',
value: function componentWillUpdate(nextProps) {
styleSheetRegistry.update(this.props, nextProps);
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
styleSheetRegistry.remove(this.props);
}
}, {
key: 'render',
value: function render() {
return null;
}
}], [{
key: 'dynamic',
value: function dynamic(info) {
return info.map(function (tagInfo) {
var _tagInfo = _slicedToArray(tagInfo, 2),
baseId = _tagInfo[0],
props = _tagInfo[1];
return styleSheetRegistry.computeId(baseId, props);
}).join(' ');
}
}]);
return JSXStyle;
}(_react.Component);
exports.default = JSXStyle;
function flush() {
var cssRules = styleSheetRegistry.cssRules();
styleSheetRegistry.flush();
return new Map(cssRules);
}
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _stringHash = require('string-hash');
var _stringHash2 = _interopRequireDefault(_stringHash);
var _stylesheet = require('./lib/stylesheet');
var _stylesheet2 = _interopRequireDefault(_stylesheet);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var sanitize = function sanitize(rule) {
return rule.replace(/\/style/g, '\\/style');
};
var StyleSheetRegistry = function () {
function StyleSheetRegistry() {
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$styleSheet = _ref.styleSheet,
styleSheet = _ref$styleSheet === undefined ? null : _ref$styleSheet,
_ref$optimizeForSpeed = _ref.optimizeForSpeed,
optimizeForSpeed = _ref$optimizeForSpeed === undefined ? false : _ref$optimizeForSpeed,
_ref$isBrowser = _ref.isBrowser,
isBrowser = _ref$isBrowser === undefined ? typeof window !== 'undefined' : _ref$isBrowser;
_classCallCheck(this, StyleSheetRegistry);
this._sheet = styleSheet || new _stylesheet2.default({
name: 'styled-jsx',
optimizeForSpeed: optimizeForSpeed
});
this._sheet.inject();
if (styleSheet && typeof optimizeForSpeed === 'boolean') {
this._sheet.setOptimizeForSpeed(optimizeForSpeed);
this._optimizeForSpeed = this._sheet.isOptimizeForSpeed();
}
this._isBrowser = isBrowser;
this._fromServer = undefined;
this._indices = {};
this._instancesCounts = {};
this.computeId = this.createComputeId();
this.computeSelector = this.createComputeSelector();
}
_createClass(StyleSheetRegistry, [{
key: 'add',
value: function add(props) {
var _this = this;
if (undefined === this._optimizeForSpeed) {
this._optimizeForSpeed = Array.isArray(props.css);
this._sheet.setOptimizeForSpeed(this._optimizeForSpeed);
this._optimizeForSpeed = this._sheet.isOptimizeForSpeed();
}
if (this._isBrowser && !this._fromServer) {
this._fromServer = this.selectFromServer();
this._instancesCounts = Object.keys(this._fromServer).reduce(function (acc, tagName) {
acc[tagName] = 0;
return acc;
}, {});
}
var _getIdAndRules = this.getIdAndRules(props),
styleId = _getIdAndRules.styleId,
rules = _getIdAndRules.rules;
// Deduping: just increase the instances count.
if (styleId in this._instancesCounts) {
this._instancesCounts[styleId] += 1;
return;
}
var indices = rules.map(function (rule) {
return _this._sheet.insertRule(rule);
})
// Filter out invalid rules
.filter(function (index) {
return index !== -1;
});
if (indices.length > 0) {
this._indices[styleId] = indices;
this._instancesCounts[styleId] = 1;
}
}
}, {
key: 'remove',
value: function remove(props) {
var _this2 = this;
var _getIdAndRules2 = this.getIdAndRules(props),
styleId = _getIdAndRules2.styleId;
invariant(styleId in this._instancesCounts, 'styleId: `' + styleId + '` not found');
this._instancesCounts[styleId] -= 1;
if (this._instancesCounts[styleId] < 1) {
var tagFromServer = this._fromServer && this._fromServer[styleId];
if (tagFromServer) {
tagFromServer.parentNode.removeChild(tagFromServer);
delete this._fromServer[styleId];
} else {
this._indices[styleId].forEach(function (index) {
return _this2._sheet.deleteRule(index);
});
delete this._indices[styleId];
}
delete this._instancesCounts[styleId];
}
}
}, {
key: 'update',
value: function update(props, nextProps) {
this.add(nextProps);
this.remove(props);
}
}, {
key: 'flush',
value: function flush() {
this._sheet.flush();
this._sheet.inject();
this._fromServer = undefined;
this._indices = {};
this._instancesCounts = {};
this.computeId = this.createComputeId();
this.computeSelector = this.createComputeSelector();
}
}, {
key: 'cssRules',
value: function cssRules() {
var _this3 = this;
var fromServer = this._fromServer ? Object.keys(this._fromServer).map(function (styleId) {
return [styleId, _this3._fromServer[styleId]];
}) : [];
var cssRules = this._sheet.cssRules();
return fromServer.concat(Object.keys(this._indices).map(function (styleId) {
return [styleId, _this3._indices[styleId].map(function (index) {
return cssRules[index].cssText;
}).join('\n')];
}));
}
/**
* createComputeId
*
* Creates a function to compute and memoize a jsx id from a basedId and optionally props.
*/
}, {
key: 'createComputeId',
value: function createComputeId() {
var cache = {};
return function (baseId, props) {
if (!props) {
return 'jsx-' + baseId;
}
var propsToString = String(props);
var key = baseId + propsToString;
// return `jsx-${hashString(`${baseId}-${propsToString}`)}`
if (!cache[key]) {
cache[key] = 'jsx-' + (0, _stringHash2.default)(baseId + '-' + propsToString);
}
return cache[key];
};
}
/**
* createComputeSelector
*
* Creates a function to compute and memoize dynamic selectors.
*/
}, {
key: 'createComputeSelector',
value: function createComputeSelector() {
var selectoPlaceholderRegexp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : /__jsx-style-dynamic-selector/g;
var cache = {};
return function (id, css) {
// Sanitize SSR-ed CSS.
// Client side code doesn't need to be sanitized since we use
// document.createTextNode (dev) and the CSSOM api sheet.insertRule (prod).
if (!this._isBrowser) {
css = sanitize(css);
}
var idcss = id + css;
if (!cache[idcss]) {
cache[idcss] = css.replace(selectoPlaceholderRegexp, id);
}
return cache[idcss];
};
}
}, {
key: 'getIdAndRules',
value: function getIdAndRules(props) {
var _this4 = this;
if (props.dynamic) {
var styleId = this.computeId(props.styleId, props.dynamic);
return {
styleId: styleId,
rules: Array.isArray(props.css) ? props.css.map(function (rule) {
return _this4.computeSelector(styleId, rule);
}) : [this.computeSelector(styleId, props.css)]
};
}
return {
styleId: this.computeId(props.styleId),
rules: Array.isArray(props.css) ? props.css : [props.css]
};
}
/**
* selectFromServer
*
* Collects style tags from the document with id __jsx-XXX
*/
}, {
key: 'selectFromServer',
value: function selectFromServer() {
var elements = Array.prototype.slice.call(document.querySelectorAll('[id^="__jsx-"]'));
return elements.reduce(function (acc, element) {
var id = element.id.slice(2);
acc[id] = element;
return acc;
}, {});
}
}]);
return StyleSheetRegistry;
}();
exports.default = StyleSheetRegistry;
function invariant(condition, message) {
if (!condition) {
throw new Error('StyleSheetRegistry: ' + message + '.');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment