afrododi
Version:
Framework-agnostic async-compatible CSS-in-JS with support for server-side rendering, browser prefixing, and minimum CSS generation
1,473 lines (1,227 loc) • 94.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function hash(str) {
var hash = 5381,
i = str.length;
while(i) {
hash = (hash * 33) ^ str.charCodeAt(--i);
}
/* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
* integers. Since we want the results to be always positive, convert the
* signed int to an unsigned by doing an unsigned bitshift. */
return hash >>> 0;
}
var stringHash = hash;
/* ::
type ObjectMap = { [id:string]: any };
*/
var UPPERCASE_RE = /([A-Z])/g;
var UPPERCASE_RE_TO_KEBAB = function UPPERCASE_RE_TO_KEBAB(match /* : string */) {
return (/* : string */'-' + String(match.toLowerCase())
);
};
var kebabifyStyleName = function kebabifyStyleName(string /* : string */) /* : string */{
var result = string.replace(UPPERCASE_RE, UPPERCASE_RE_TO_KEBAB);
if (result[0] === 'm' && result[1] === 's' && result[2] === '-') {
return '-' + String(result);
}
return result;
};
/**
* CSS properties which accept numbers but are not in units of "px".
* Taken from React's CSSProperty.js
*/
var isUnitlessNumber = {
animationIterationCount: true,
borderImageOutset: true,
borderImageSlice: true,
borderImageWidth: true,
boxFlex: true,
boxFlexGroup: true,
boxOrdinalGroup: true,
columnCount: true,
flex: true,
flexGrow: true,
flexPositive: true,
flexShrink: true,
flexNegative: true,
flexOrder: true,
gridRow: true,
gridColumn: true,
fontWeight: true,
lineClamp: true,
lineHeight: true,
opacity: true,
order: true,
orphans: true,
tabSize: true,
widows: true,
zIndex: true,
zoom: true,
// SVG-related properties
fillOpacity: true,
floodOpacity: true,
stopOpacity: true,
strokeDasharray: true,
strokeDashoffset: true,
strokeMiterlimit: true,
strokeOpacity: true,
strokeWidth: true
};
/**
* Taken from React's CSSProperty.js
*
* @param {string} prefix vendor-specific prefix, eg: Webkit
* @param {string} key style name, eg: transitionDuration
* @return {string} style name prefixed with `prefix`, properly camelCased, eg:
* WebkitTransitionDuration
*/
function prefixKey(prefix, key) {
return prefix + key.charAt(0).toUpperCase() + key.substring(1);
}
/**
* Support style names that may come passed in prefixed by adding permutations
* of vendor prefixes.
* Taken from React's CSSProperty.js
*/
var prefixes = ['Webkit', 'ms', 'Moz', 'O'];
// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
// infinite loop, because it iterates over the newly added props too.
// Taken from React's CSSProperty.js
Object.keys(isUnitlessNumber).forEach(function (prop) {
prefixes.forEach(function (prefix) {
isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
});
});
var stringifyValue = function stringifyValue(key /* : string */
, prop /* : any */
) /* : string */{
if (typeof prop === "number") {
if (isUnitlessNumber[key]) {
return "" + prop;
} else {
return prop + "px";
}
} else {
return '' + prop;
}
};
var stringifyAndImportantifyValue = function stringifyAndImportantifyValue(key /* : string */
, prop /* : any */
) {
return (/* : string */importantify(stringifyValue(key, prop))
);
};
// Turn a string into a hash string of base-36 values (using letters and numbers)
// eslint-disable-next-line no-unused-vars
var hashString = function hashString(string /* : string */, key /* : ?string */) {
return (/* string */stringHash(string).toString(36)
);
};
// Hash a javascript object using JSON.stringify. This is very fast, about 3
// microseconds on my computer for a sample object:
// http://jsperf.com/test-hashfnv32a-hash/5
//
// Note that this uses JSON.stringify to stringify the objects so in order for
// this to produce consistent hashes browsers need to have a consistent
// ordering of objects. Ben Alpert says that Facebook depends on this, so we
// can probably depend on this too.
var hashObject = function hashObject(object /* : ObjectMap */) {
return (/* : string */hashString(JSON.stringify(object))
);
};
// Given a single style value string like the "b" from "a: b;", adds !important
// to generate "b !important".
var importantify = function importantify(string /* : string */) {
return (/* : string */
// Bracket string character access is very fast, and in the default case we
// normally don't expect there to be "!important" at the end of the string
// so we can use this simple check to take an optimized path. If there
// happens to be a "!" in this position, we follow up with a more thorough
// check.
string[string.length - 10] === '!' && string.slice(-11) === ' !important' ? string : String(string) + ' !important'
);
};
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
function unwrapExports (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x.default : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
// Use the fastest means possible to execute a task in its own turn, with
// priority over other events including IO, animation, reflow, and redraw
// events in browsers.
//
// An exception thrown by a task will permanently interrupt the processing of
// subsequent tasks. The higher level `asap` function ensures that if an
// exception is thrown by a task, that the task queue will continue flushing as
// soon as possible, but if you use `rawAsap` directly, you are responsible to
// either ensure that no exceptions are thrown from your task, or to manually
// call `rawAsap.requestFlush` if an exception is thrown.
var browserRaw = rawAsap;
function rawAsap(task) {
if (!queue.length) {
requestFlush();
}
// Equivalent to push, but avoids a function call.
queue[queue.length] = task;
}
var queue = [];
// `requestFlush` is an implementation-specific method that attempts to kick
// off a `flush` event as quickly as possible. `flush` will attempt to exhaust
// the event queue before yielding to the browser's own event loop.
var requestFlush;
// The position of the next task to execute in the task queue. This is
// preserved between calls to `flush` so that it can be resumed if
// a task throws an exception.
var index = 0;
// If a task schedules additional tasks recursively, the task queue can grow
// unbounded. To prevent memory exhaustion, the task queue will periodically
// truncate already-completed tasks.
var capacity = 1024;
// The flush function processes all tasks that have been scheduled with
// `rawAsap` unless and until one of those tasks throws an exception.
// If a task throws an exception, `flush` ensures that its state will remain
// consistent and will resume where it left off when called again.
// However, `flush` does not make any arrangements to be called again if an
// exception is thrown.
function flush() {
while (index < queue.length) {
var currentIndex = index;
// Advance the index before calling the task. This ensures that we will
// begin flushing on the next task the task throws an error.
index = index + 1;
queue[currentIndex].call();
// Prevent leaking memory for long chains of recursive calls to `asap`.
// If we call `asap` within tasks scheduled by `asap`, the queue will
// grow, but to avoid an O(n) walk for every task we execute, we don't
// shift tasks off the queue after they have been executed.
// Instead, we periodically shift 1024 tasks off the queue.
if (index > capacity) {
// Manually shift all values starting at the index back to the
// beginning of the queue.
for (var scan = 0, newLength = queue.length - index; scan < newLength; scan++) {
queue[scan] = queue[scan + index];
}
queue.length -= index;
index = 0;
}
}
queue.length = 0;
index = 0;
}
// `requestFlush` is implemented using a strategy based on data collected from
// every available SauceLabs Selenium web driver worker at time of writing.
// https://docs.google.com/spreadsheets/d/1mG-5UYGup5qxGdEMWkhP6BWCz053NUb2E1QoUTU16uA/edit#gid=783724593
// Safari 6 and 6.1 for desktop, iPad, and iPhone are the only browsers that
// have WebKitMutationObserver but not un-prefixed MutationObserver.
// Must use `global` or `self` instead of `window` to work in both frames and web
// workers. `global` is a provision of Browserify, Mr, Mrs, or Mop.
/* globals self */
var scope = typeof commonjsGlobal !== "undefined" ? commonjsGlobal : self;
var BrowserMutationObserver = scope.MutationObserver || scope.WebKitMutationObserver;
// MutationObservers are desirable because they have high priority and work
// reliably everywhere they are implemented.
// They are implemented in all modern browsers.
//
// - Android 4-4.3
// - Chrome 26-34
// - Firefox 14-29
// - Internet Explorer 11
// - iPad Safari 6-7.1
// - iPhone Safari 7-7.1
// - Safari 6-7
if (typeof BrowserMutationObserver === "function") {
requestFlush = makeRequestCallFromMutationObserver(flush);
// MessageChannels are desirable because they give direct access to the HTML
// task queue, are implemented in Internet Explorer 10, Safari 5.0-1, and Opera
// 11-12, and in web workers in many engines.
// Although message channels yield to any queued rendering and IO tasks, they
// would be better than imposing the 4ms delay of timers.
// However, they do not work reliably in Internet Explorer or Safari.
// Internet Explorer 10 is the only browser that has setImmediate but does
// not have MutationObservers.
// Although setImmediate yields to the browser's renderer, it would be
// preferrable to falling back to setTimeout since it does not have
// the minimum 4ms penalty.
// Unfortunately there appears to be a bug in Internet Explorer 10 Mobile (and
// Desktop to a lesser extent) that renders both setImmediate and
// MessageChannel useless for the purposes of ASAP.
// https://github.com/kriskowal/q/issues/396
// Timers are implemented universally.
// We fall back to timers in workers in most engines, and in foreground
// contexts in the following browsers.
// However, note that even this simple case requires nuances to operate in a
// broad spectrum of browsers.
//
// - Firefox 3-13
// - Internet Explorer 6-9
// - iPad Safari 4.3
// - Lynx 2.8.7
} else {
requestFlush = makeRequestCallFromTimer(flush);
}
// `requestFlush` requests that the high priority event queue be flushed as
// soon as possible.
// This is useful to prevent an error thrown in a task from stalling the event
// queue if the exception handled by Node.js’s
// `process.on("uncaughtException")` or by a domain.
rawAsap.requestFlush = requestFlush;
// To request a high priority event, we induce a mutation observer by toggling
// the text of a text node between "1" and "-1".
function makeRequestCallFromMutationObserver(callback) {
var toggle = 1;
var observer = new BrowserMutationObserver(callback);
var node = document.createTextNode("");
observer.observe(node, {characterData: true});
return function requestCall() {
toggle = -toggle;
node.data = toggle;
};
}
// The message channel technique was discovered by Malte Ubl and was the
// original foundation for this library.
// http://www.nonblocking.io/2011/06/windownexttick.html
// Safari 6.0.5 (at least) intermittently fails to create message ports on a
// page's first load. Thankfully, this version of Safari supports
// MutationObservers, so we don't need to fall back in that case.
// function makeRequestCallFromMessageChannel(callback) {
// var channel = new MessageChannel();
// channel.port1.onmessage = callback;
// return function requestCall() {
// channel.port2.postMessage(0);
// };
// }
// For reasons explained above, we are also unable to use `setImmediate`
// under any circumstances.
// Even if we were, there is another bug in Internet Explorer 10.
// It is not sufficient to assign `setImmediate` to `requestFlush` because
// `setImmediate` must be called *by name* and therefore must be wrapped in a
// closure.
// Never forget.
// function makeRequestCallFromSetImmediate(callback) {
// return function requestCall() {
// setImmediate(callback);
// };
// }
// Safari 6.0 has a problem where timers will get lost while the user is
// scrolling. This problem does not impact ASAP because Safari 6.0 supports
// mutation observers, so that implementation is used instead.
// However, if we ever elect to use timers in Safari, the prevalent work-around
// is to add a scroll event listener that calls for a flush.
// `setTimeout` does not call the passed callback if the delay is less than
// approximately 7 in web workers in Firefox 8 through 18, and sometimes not
// even then.
function makeRequestCallFromTimer(callback) {
return function requestCall() {
// We dispatch a timeout with a specified delay of 0 for engines that
// can reliably accommodate that request. This will usually be snapped
// to a 4 milisecond delay, but once we're flushing, there's no delay
// between events.
var timeoutHandle = setTimeout(handleTimer, 0);
// However, since this timer gets frequently dropped in Firefox
// workers, we enlist an interval handle that will try to fire
// an event 20 times per second until it succeeds.
var intervalHandle = setInterval(handleTimer, 50);
function handleTimer() {
// Whichever timer succeeds will cancel both timers and
// execute the callback.
clearTimeout(timeoutHandle);
clearInterval(intervalHandle);
callback();
}
};
}
// This is for `asap.js` only.
// Its name will be periodically randomized to break any code that depends on
// its existence.
rawAsap.makeRequestCallFromTimer = makeRequestCallFromTimer;
// rawAsap provides everything we need except exception management.
// RawTasks are recycled to reduce GC churn.
var freeTasks = [];
// We queue errors to ensure they are thrown in right order (FIFO).
// Array-as-queue is good enough here, since we are just dealing with exceptions.
var pendingErrors = [];
var requestErrorThrow = browserRaw.makeRequestCallFromTimer(throwFirstError);
function throwFirstError() {
if (pendingErrors.length) {
throw pendingErrors.shift();
}
}
/**
* Calls a task as soon as possible after returning, in its own event, with priority
* over other events like animation, reflow, and repaint. An error thrown from an
* event will not interrupt, nor even substantially slow down the processing of
* other events, but will be rather postponed to a lower priority event.
* @param {{call}} task A callable object, typically a function that takes no
* arguments.
*/
var browserAsap = asap;
function asap(task) {
var rawTask;
if (freeTasks.length) {
rawTask = freeTasks.pop();
} else {
rawTask = new RawTask();
}
rawTask.task = task;
browserRaw(rawTask);
}
// We wrap tasks with recyclable task objects. A task object implements
// `call`, just like a function.
function RawTask() {
this.task = null;
}
// The sole purpose of wrapping the task is to catch the exception and recycle
// the task object after its single use.
RawTask.prototype.call = function () {
try {
this.task.call();
} catch (error) {
if (asap.onerror) {
// This hook exists purely for testing purposes.
// Its name will be periodically randomized to break any code that
// depends on its existence.
asap.onerror(error);
} else {
// In a web browser, exceptions are not fatal. However, to avoid
// slowing down the queue of pending tasks, we rethrow the error in a
// lower priority turn.
pendingErrors.push(error);
requestErrorThrow();
}
} finally {
this.task = null;
freeTasks[freeTasks.length] = this;
}
};
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 _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"); } }
var MAP_EXISTS = typeof Map !== 'undefined';
var OrderedElements = function () {
/* ::
elements: {[string]: any};
keyOrder: string[];
*/
function OrderedElements() {
_classCallCheck(this, OrderedElements);
this.elements = {};
this.keyOrder = [];
}
_createClass(OrderedElements, [{
key: 'forEach',
value: function () {
function forEach(callback /* : (string, any) => void */) {
for (var i = 0; i < this.keyOrder.length; i++) {
// (value, key) to match Map's API
callback(this.elements[this.keyOrder[i]], this.keyOrder[i]);
}
}
return forEach;
}()
}, {
key: 'set',
value: function () {
function set(key /* : string */, value /* : any */, shouldReorder /* : ?boolean */) {
if (!this.elements.hasOwnProperty(key)) {
this.keyOrder.push(key);
} else if (shouldReorder) {
var index = this.keyOrder.indexOf(key);
this.keyOrder.splice(index, 1);
this.keyOrder.push(key);
}
if (value == null) {
this.elements[key] = value;
return;
}
if (MAP_EXISTS && value instanceof Map || value instanceof OrderedElements) {
// We have found a nested Map, so we need to recurse so that all
// of the nested objects and Maps are merged properly.
var nested = this.elements.hasOwnProperty(key) ? this.elements[key] : new OrderedElements();
value.forEach(function (value, key) {
nested.set(key, value, shouldReorder);
});
this.elements[key] = nested;
return;
}
if (!Array.isArray(value) && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object') {
// We have found a nested object, so we need to recurse so that all
// of the nested objects and Maps are merged properly.
var _nested = this.elements.hasOwnProperty(key) ? this.elements[key] : new OrderedElements();
var keys = Object.keys(value);
for (var i = 0; i < keys.length; i += 1) {
_nested.set(keys[i], value[keys[i]], shouldReorder);
}
this.elements[key] = _nested;
return;
}
this.elements[key] = value;
}
return set;
}()
}, {
key: 'get',
value: function () {
function get(key /* : string */) /* : any */{
return this.elements[key];
}
return get;
}()
}, {
key: 'has',
value: function () {
function has(key /* : string */) /* : boolean */{
return this.elements.hasOwnProperty(key);
}
return has;
}()
}, {
key: 'addStyleType',
value: function () {
function addStyleType(styleType /* : any */) /* : void */{
var _this = this;
if (MAP_EXISTS && styleType instanceof Map || styleType instanceof OrderedElements) {
styleType.forEach(function (value, key) {
_this.set(key, value, true);
});
} else {
var keys = Object.keys(styleType);
for (var i = 0; i < keys.length; i++) {
this.set(keys[i], styleType[keys[i]], true);
}
}
}
return addStyleType;
}()
}]);
return OrderedElements;
}();
var capitalizeString_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = capitalizeString;
function capitalizeString(str) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
module.exports = exports["default"];
});
unwrapExports(capitalizeString_1);
var prefixProperty_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = prefixProperty;
var _capitalizeString2 = _interopRequireDefault(capitalizeString_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function prefixProperty(prefixProperties, property, style) {
if (prefixProperties.hasOwnProperty(property)) {
var newStyle = {};
var requiredPrefixes = prefixProperties[property];
var capitalizedProperty = (0, _capitalizeString2.default)(property);
var keys = Object.keys(style);
for (var i = 0; i < keys.length; i++) {
var styleProperty = keys[i];
if (styleProperty === property) {
for (var j = 0; j < requiredPrefixes.length; j++) {
newStyle[requiredPrefixes[j] + capitalizedProperty] = style[property];
}
}
newStyle[styleProperty] = style[styleProperty];
}
return newStyle;
}
return style;
}
module.exports = exports['default'];
});
unwrapExports(prefixProperty_1);
var prefixValue_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = prefixValue;
function prefixValue(plugins, property, value, style, metaData) {
for (var i = 0, len = plugins.length; i < len; ++i) {
var processedValue = plugins[i](property, value, style, metaData);
// we can stop processing if a value is returned
// as all plugin criteria are unique
if (processedValue) {
return processedValue;
}
}
}
module.exports = exports["default"];
});
unwrapExports(prefixValue_1);
var addNewValuesOnly_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = addNewValuesOnly;
function addIfNew(list, value) {
if (list.indexOf(value) === -1) {
list.push(value);
}
}
function addNewValuesOnly(list, values) {
if (Array.isArray(values)) {
for (var i = 0, len = values.length; i < len; ++i) {
addIfNew(list, values[i]);
}
} else {
addIfNew(list, values);
}
}
module.exports = exports["default"];
});
unwrapExports(addNewValuesOnly_1);
var isObject_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = isObject;
function isObject(value) {
return value instanceof Object && !Array.isArray(value);
}
module.exports = exports["default"];
});
unwrapExports(isObject_1);
var createPrefixer_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = createPrefixer;
var _prefixProperty2 = _interopRequireDefault(prefixProperty_1);
var _prefixValue2 = _interopRequireDefault(prefixValue_1);
var _addNewValuesOnly2 = _interopRequireDefault(addNewValuesOnly_1);
var _isObject2 = _interopRequireDefault(isObject_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function createPrefixer(_ref) {
var prefixMap = _ref.prefixMap,
plugins = _ref.plugins;
function prefixAll(style) {
for (var property in style) {
var value = style[property];
// handle nested objects
if ((0, _isObject2.default)(value)) {
style[property] = prefixAll(value);
// handle array values
} else if (Array.isArray(value)) {
var combinedValue = [];
for (var i = 0, len = value.length; i < len; ++i) {
var processedValue = (0, _prefixValue2.default)(plugins, property, value[i], style, prefixMap);
(0, _addNewValuesOnly2.default)(combinedValue, processedValue || value[i]);
}
// only modify the value if it was touched
// by any plugin to prevent unnecessary mutations
if (combinedValue.length > 0) {
style[property] = combinedValue;
}
} else {
var _processedValue = (0, _prefixValue2.default)(plugins, property, value, style, prefixMap);
// only modify the value if it was touched
// by any plugin to prevent unnecessary mutations
if (_processedValue) {
style[property] = _processedValue;
}
style = (0, _prefixProperty2.default)(prefixMap, property, style);
}
}
return style;
}
return prefixAll;
}
module.exports = exports['default'];
});
var createPrefixer = unwrapExports(createPrefixer_1);
var isPrefixedValue_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = isPrefixedValue;
var regex = /-webkit-|-moz-|-ms-/;
function isPrefixedValue(value) {
return typeof value === 'string' && regex.test(value);
}
module.exports = exports['default'];
});
unwrapExports(isPrefixedValue_1);
var calc_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = calc;
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var prefixes = ['-webkit-', '-moz-', ''];
function calc(property, value) {
if (typeof value === 'string' && !(0, _isPrefixedValue2.default)(value) && value.indexOf('calc(') > -1) {
return prefixes.map(function (prefix) {
return value.replace(/calc\(/g, prefix + 'calc(');
});
}
}
module.exports = exports['default'];
});
unwrapExports(calc_1);
var crossFade_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = crossFade;
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// http://caniuse.com/#search=cross-fade
var prefixes = ['-webkit-', ''];
function crossFade(property, value) {
if (typeof value === 'string' && !(0, _isPrefixedValue2.default)(value) && value.indexOf('cross-fade(') > -1) {
return prefixes.map(function (prefix) {
return value.replace(/cross-fade\(/g, prefix + 'cross-fade(');
});
}
}
module.exports = exports['default'];
});
unwrapExports(crossFade_1);
var cursor_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = cursor;
var prefixes = ['-webkit-', '-moz-', ''];
var values = {
'zoom-in': true,
'zoom-out': true,
grab: true,
grabbing: true
};
function cursor(property, value) {
if (property === 'cursor' && values.hasOwnProperty(value)) {
return prefixes.map(function (prefix) {
return prefix + value;
});
}
}
module.exports = exports['default'];
});
unwrapExports(cursor_1);
var filter_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = filter;
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// http://caniuse.com/#feat=css-filter-function
var prefixes = ['-webkit-', ''];
function filter(property, value) {
if (typeof value === 'string' && !(0, _isPrefixedValue2.default)(value) && value.indexOf('filter(') > -1) {
return prefixes.map(function (prefix) {
return value.replace(/filter\(/g, prefix + 'filter(');
});
}
}
module.exports = exports['default'];
});
unwrapExports(filter_1);
var flex_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = flex;
var values = {
flex: ['-webkit-box', '-moz-box', '-ms-flexbox', '-webkit-flex', 'flex'],
'inline-flex': ['-webkit-inline-box', '-moz-inline-box', '-ms-inline-flexbox', '-webkit-inline-flex', 'inline-flex']
};
function flex(property, value) {
if (property === 'display' && values.hasOwnProperty(value)) {
return values[value];
}
}
module.exports = exports['default'];
});
unwrapExports(flex_1);
var flexboxIE_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = flexboxIE;
var alternativeValues = {
'space-around': 'distribute',
'space-between': 'justify',
'flex-start': 'start',
'flex-end': 'end'
};
var alternativeProps = {
alignContent: 'msFlexLinePack',
alignSelf: 'msFlexItemAlign',
alignItems: 'msFlexAlign',
justifyContent: 'msFlexPack',
order: 'msFlexOrder',
flexGrow: 'msFlexPositive',
flexShrink: 'msFlexNegative',
flexBasis: 'msFlexPreferredSize'
};
function flexboxIE(property, value, style) {
if (alternativeProps.hasOwnProperty(property)) {
style[alternativeProps[property]] = alternativeValues[value] || value;
}
}
module.exports = exports['default'];
});
unwrapExports(flexboxIE_1);
var flexboxOld_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = flexboxOld;
var alternativeValues = {
'space-around': 'justify',
'space-between': 'justify',
'flex-start': 'start',
'flex-end': 'end',
'wrap-reverse': 'multiple',
wrap: 'multiple',
flex: 'box',
'inline-flex': 'inline-box'
};
var alternativeProps = {
alignItems: 'WebkitBoxAlign',
justifyContent: 'WebkitBoxPack',
flexWrap: 'WebkitBoxLines',
flexGrow: 'WebkitBoxFlex'
};
function flexboxOld(property, value, style) {
if (property === 'flexDirection' && typeof value === 'string') {
if (value.indexOf('column') > -1) {
style.WebkitBoxOrient = 'vertical';
} else {
style.WebkitBoxOrient = 'horizontal';
}
if (value.indexOf('reverse') > -1) {
style.WebkitBoxDirection = 'reverse';
} else {
style.WebkitBoxDirection = 'normal';
}
}
if (alternativeProps.hasOwnProperty(property)) {
style[alternativeProps[property]] = alternativeValues[value] || value;
}
}
module.exports = exports['default'];
});
unwrapExports(flexboxOld_1);
var gradient_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = gradient;
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var prefixes = ['-webkit-', '-moz-', ''];
var values = /linear-gradient|radial-gradient|repeating-linear-gradient|repeating-radial-gradient/gi;
function gradient(property, value) {
if (typeof value === 'string' && !(0, _isPrefixedValue2.default)(value) && values.test(value)) {
return prefixes.map(function (prefix) {
return value.replace(values, function (grad) {
return prefix + grad;
});
});
}
}
module.exports = exports['default'];
});
unwrapExports(gradient_1);
var imageSet_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = imageSet;
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// http://caniuse.com/#feat=css-image-set
var prefixes = ['-webkit-', ''];
function imageSet(property, value) {
if (typeof value === 'string' && !(0, _isPrefixedValue2.default)(value) && value.indexOf('image-set(') > -1) {
return prefixes.map(function (prefix) {
return value.replace(/image-set\(/g, prefix + 'image-set(');
});
}
}
module.exports = exports['default'];
});
unwrapExports(imageSet_1);
var position_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = position;
function position(property, value) {
if (property === 'position' && value === 'sticky') {
return ['-webkit-sticky', 'sticky'];
}
}
module.exports = exports['default'];
});
unwrapExports(position_1);
var sizing_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = sizing;
var prefixes = ['-webkit-', '-moz-', ''];
var properties = {
maxHeight: true,
maxWidth: true,
width: true,
height: true,
columnWidth: true,
minWidth: true,
minHeight: true
};
var values = {
'min-content': true,
'max-content': true,
'fill-available': true,
'fit-content': true,
'contain-floats': true
};
function sizing(property, value) {
if (properties.hasOwnProperty(property) && values.hasOwnProperty(value)) {
return prefixes.map(function (prefix) {
return prefix + value;
});
}
}
module.exports = exports['default'];
});
unwrapExports(sizing_1);
var uppercasePattern = /[A-Z]/g;
var msPattern = /^ms-/;
var cache = {};
function hyphenateStyleName(string) {
return string in cache
? cache[string]
: cache[string] = string
.replace(uppercasePattern, '-$&')
.toLowerCase()
.replace(msPattern, '-ms-');
}
var hyphenateStyleName_1 = hyphenateStyleName;
var hyphenateProperty_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = hyphenateProperty;
var _hyphenateStyleName2 = _interopRequireDefault(hyphenateStyleName_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function hyphenateProperty(property) {
return (0, _hyphenateStyleName2.default)(property);
}
module.exports = exports['default'];
});
unwrapExports(hyphenateProperty_1);
var transition_1 = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = transition;
var _hyphenateProperty2 = _interopRequireDefault(hyphenateProperty_1);
var _isPrefixedValue2 = _interopRequireDefault(isPrefixedValue_1);
var _capitalizeString2 = _interopRequireDefault(capitalizeString_1);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var properties = {
transition: true,
transitionProperty: true,
WebkitTransition: true,
WebkitTransitionProperty: true,
MozTransition: true,
MozTransitionProperty: true
};
var prefixMapping = {
Webkit: '-webkit-',
Moz: '-moz-',
ms: '-ms-'
};
function prefixValue(value, propertyPrefixMap) {
if ((0, _isPrefixedValue2.default)(value)) {
return value;
}
// only split multi values, not cubic beziers
var multipleValues = value.split(/,(?![^()]*(?:\([^()]*\))?\))/g);
for (var i = 0, len = multipleValues.length; i < len; ++i) {
var singleValue = multipleValues[i];
var values = [singleValue];
for (var property in propertyPrefixMap) {
var dashCaseProperty = (0, _hyphenateProperty2.default)(property);
if (singleValue.indexOf(dashCaseProperty) > -1 && dashCaseProperty !== 'order') {
var prefixes = propertyPrefixMap[property];
for (var j = 0, pLen = prefixes.length; j < pLen; ++j) {
// join all prefixes and create a new value
values.unshift(singleValue.replace(dashCaseProperty, prefixMapping[prefixes[j]] + dashCaseProperty));
}
}
}
multipleValues[i] = values.join(',');
}
return multipleValues.join(',');
}
function transition(property, value, style, propertyPrefixMap) {
// also check for already prefixed transitions
if (typeof value === 'string' && properties.hasOwnProperty(property)) {
var outputValue = prefixValue(value, propertyPrefixMap);
// if the property is already prefixed
var webkitOutput = outputValue.split(/,(?![^()]*(?:\([^()]*\))?\))/g).filter(function (val) {
return !/-moz-|-ms-/.test(val);
}).join(',');
if (property.indexOf('Webkit') > -1) {
return webkitOutput;
}
var mozOutput = outputValue.split(/,(?![^()]*(?:\([^()]*\))?\))/g).filter(function (val) {
return !/-webkit-|-ms-/.test(val);
}).join(',');
if (property.indexOf('Moz') > -1) {
return mozOutput;
}
style['Webkit' + (0, _capitalizeString2.default)(property)] = webkitOutput;
style['Moz' + (0, _capitalizeString2.default)(property)] = mozOutput;
return outputValue;
}
}
module.exports = exports['default'];
});
unwrapExports(transition_1);
var w = ["Webkit"];
var m = ["Moz"];
var ms = ["ms"];
var wm = ["Webkit", "Moz"];
var wms = ["Webkit", "ms"];
var wmms = ["Webkit", "Moz", "ms"];
var staticPrefixData = {
plugins: [calc_1, crossFade_1, cursor_1, filter_1, flex_1, flexboxIE_1, flexboxOld_1, gradient_1, imageSet_1, position_1, sizing_1, transition_1],
prefixMap: { "transform": wms, "transformOrigin": wms, "transformOriginX": wms, "transformOriginY": wms, "backfaceVisibility": w, "perspective": w, "perspectiveOrigin": w, "transformStyle": w, "transformOriginZ": w, "animation": w, "animationDelay": w, "animationDirection": w, "animationFillMode": w, "animationDuration": w, "animationIterationCount": w, "animationName": w, "animationPlayState": w, "animationTimingFunction": w, "appearance": wm, "userSelect": wmms, "fontKerning": w, "textEmphasisPosition": w, "textEmphasis": w, "textEmphasisStyle": w, "textEmphasisColor": w, "boxDecorationBreak": w, "clipPath": w, "maskImage": w, "maskMode": w, "maskRepeat": w, "maskPosition": w, "maskClip": w, "maskOrigin": w, "maskSize": w, "maskComposite": w, "mask": w, "maskBorderSource": w, "maskBorderMode": w, "maskBorderSlice": w, "maskBorderWidth": w, "maskBorderOutset": w, "maskBorderRepeat": w, "maskBorder": w, "maskType": w, "textDecorationStyle": wm, "textDecorationSkip": wm, "textDecorationLine": wm, "textDecorationColor": wm, "filter": w, "fontFeatureSettings": wm, "breakAfter": wmms, "breakBefore": wmms, "breakInside": wmms, "columnCount": wm, "columnFill": wm, "columnGap": wm, "columnRule": wm, "columnRuleColor": wm, "columnRuleStyle": wm, "columnRuleWidth": wm, "columns": wm, "columnSpan": wm, "columnWidth": wm, "writingMode": wms, "flex": wms, "flexBasis": w, "flexDirection": wms, "flexGrow": w, "flexFlow": wms, "flexShrink": w, "flexWrap": wms, "alignContent": w, "alignItems": w, "alignSelf": w, "justifyContent": w, "order": w, "transitionDelay": w, "transitionDuration": w, "transitionProperty": w, "transitionTimingFunction": w, "backdropFilter": w, "scrollSnapType": wms, "scrollSnapPointsX": wms, "scrollSnapPointsY": wms, "scrollSnapDestination": wms, "scrollSnapCoordinate": wms, "shapeImageThreshold": w, "shapeImageMargin": w, "shapeImageOutside": w, "hyphens": wmms, "flowInto": wms, "flowFrom": wms, "regionFragment": wms, "textOrientation": w, "boxSizing": m, "textAlignLast": m, "tabSize": m, "wrapFlow": ms, "wrapThrough": ms, "wrapMargin": ms, "touchAction": ms, "gridTemplateColumns": ms, "gridTemplateRows": ms, "gridTemplateAreas": ms, "gridTemplate": ms, "gridAutoColumns": ms, "gridAutoRows": ms, "gridAutoFlow": ms, "grid": ms, "gridRowStart": ms, "gridColumnStart": ms, "gridRowEnd": ms, "gridRow": ms, "gridColumn": ms, "gridColumnEnd": ms, "gridColumnGap": ms, "gridRowGap": ms, "gridArea": ms, "gridGap": ms, "textSizeAdjust": ["ms", "Webkit"], "borderImage": w, "borderImageOutset": w, "borderImageRepeat": w, "borderImageSlice": w, "borderImageSource": w, "borderImageWidth": w }
};
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); } }
var prefixAll = createPrefixer(staticPrefixData);
/* ::
import type { SheetDefinition } from './index.js';
type StringHandlers = { [id:string]: Function };
type SelectorCallback = (selector: string) => string[];
export type SelectorHandler = (
selector: string,
baseSelector: string,
callback: SelectorCallback
) => string[] | string | null;
*/
/**
* `selectorHandlers` are functions which handle special selectors which act
* differently than normal style definitions. These functions look at the
* current selector and can generate CSS for the styles in their subtree by
* calling the callback with a new selector.
*
* For example, when generating styles with a base selector of '.foo' and the
* following styles object:
*
* {
* ':nth-child(2n)': {
* ':hover': {
* color: 'red'
* }
* }
* }
*
* when we reach the ':hover' style, we would call our selector handlers like
*
* handler(':hover', '.foo:nth-child(2n)', callback)
*
* Since our `pseudoSelectors` handles ':hover' styles, that handler would call
* the callback like
*
* callback('.foo:nth-child(2n):hover')
*
* to generate its subtree `{ color: 'red' }` styles with a
* '.foo:nth-child(2n):hover' selector. The callback would return an array of CSS
* rules like
*
* ['.foo:nth-child(2n):hover{color:red !important;}']
*
* and the handler would then return that resulting CSS.
*
* `defaultSelectorHandlers` is the list of default handlers used in a call to
* `generateCSS`.
*
* @name SelectorHandler
* @function
* @param {string} selector: The currently inspected selector. ':hover' in the
* example above.
* @param {string} baseSelector: The selector of the parent styles.
* '.foo:nth-child(2n)' in the example above.
* @param {function} generateSubtreeStyles: A function which can be called to
* generate CSS for the subtree of styles corresponding to the selector.
* Accepts a new baseSelector to use for generating those styles.
* @returns {string[] | string | null} The generated CSS for this selector, or
* null if we don't handle this selector.
*/
var defaultSelectorHandlers /* : SelectorHandler[] */ = [
// Handle pseudo-selectors, like :hover and :nth-child(3n)
function () {
function pseudoSelectors(selector, baseSelector, generateSubtreeStyles) {
if (selector[0] !== ":") {
return null;
}
return generateSubtreeStyles(baseSelector + selector);
}
return pseudoSelectors;
}(),
// Handle media queries (or font-faces)
function () {
function mediaQueries(selector, baseSelector, generateSubtreeStyles) {
if (selector[0] !== "@") {
return null;
}
// Generate the styles normally, and then wrap them in the media query.
var generated = generateSubtreeStyles(baseSelector);
return [String(selector) + '{' + String(generated.join('')) + '}'];
}
return mediaQueries;
}()];
/**
* Generate CSS for a selector and some styles.
*
* This function handles the media queries and pseudo selectors that can be used
* in afrododi styles.
*
* @param {string} selector: A base CSS selector for the styles to be generated
* with.
* @param {Object} styleTypes: A list of properties of the return type of
* StyleSheet.create, e.g. [styles.red, styles.blue].
* @param {Array.<SelectorHandler>} selectorHandlers: A list of selector
* handlers to use for handling special selectors. See
* `defaultSelectorHandlers`.
* @param stringHandlers: See `generateCSSRuleset`
* @param useImportant: See `generateCSSRuleset`
*
* To actually generate the CSS special-construct-less styles are passed to
* `generateCSSRuleset`.
*
* For instance, a call to
*
* generateCSS(".foo", [{
* color: "red",
* "@media screen": {
* height: 20,
* ":hover": {
* backgroundColor: "black"
* }
* },
* ":active": {
* fontWeight: "bold"
* }
* }], defaultSelectorHandlers);
*
* with the default `selectorHandlers` will make 5 calls to
* `generateCSSRuleset`:
*
* generateCSSRuleset(".foo", { color: "red" }, ...)
* generateCSSRuleset(".foo:active", { fontWeight: "bold" }, ...)
* // These 2 will be wrapped in @media screen {}
* generateCSSRuleset(".foo", { height: 20 }, ...)
* generateCSSRuleset(".foo:hover", { backgroundColor: "black" }, ...)
*/
var generateCSS = function generateCSS(selector /* : string */
, styleTypes /* : SheetDefinition[] */
, selectorHandlers /* : SelectorHandler[] */
, stringHandlers /* : StringHandlers */
, useImportant /* : boolean */
) /* : string[] */{
var merged = new OrderedElements();
for (var i = 0; i < styleTypes.length; i++) {
merged.addStyleType(styleTypes[i]);
}
var plainDeclarations = new OrderedElements();
var generatedStyles = [];
// TODO(emily): benchmark this to see if a plain for loop would be faster.
merged.forEach(function (val, key) {
// For each key, see if one of the selector handlers will handle these
// styles.
var foundHandler = selectorHandlers.some(function (handler) {
var result = handler(key, selector, function (newSelector) {
return generateCSS(newSelector, [val], selectorHandlers, stringHandlers, useImportant);
});
if (result != null) {
// If the handler returned something, add it to the generated
// CSS and stop looking for another handler.
if (Array.isArray(result)) {
generatedStyles.push.apply(generatedStyles, _toConsumableArray(result));
} else {
// eslint-disable-next-line
console.warn('WARNING: Selector handlers should return an array of rules.' + 'Returning a string containing multiple rules is deprecated.', handler);
generatedStyles.push('@media all {' + String(result) + '}');
}
return true;
}
});
// If none of the handlers handled it, add it to the list of plain
// style declarations.
if (!foundHandler) {
plainDeclarations.set(key, val, true);
}
});
var generatedRuleset = generateCSSRuleset(selector, plainDeclarations, stringHandlers, useImportant, selectorHandlers);
if (generatedRuleset) {
generatedStyles.unshift(generatedRuleset);
}
return generatedStyles;
};
/**
* Helper method of generateCSSRuleset to facilitate custom handling of certain
* CSS properties. Used for e.g. font families.
*
* See generateCSSRuleset for usage and documentation of paramater types.
*/
var runStringHandlers = function runStringHandlers(declarations /* : OrderedElements */
, stringHandlers /* : StringHandlers */
, selectorHandlers /* : SelectorHandler[] */
) /* : void */{
if (!stringHandlers) {
return;
}
var stringHandlerKeys = Object.keys(stringHandlers);
for (var i = 0; i < stringHandlerKeys.length; i++) {
var key = stringHandlerKeys[i];
if (declarations.has(key)) {
// A declaration exists for this particular string handler, so we
// need to let the string handler interpret the declaration first
// before proceeding.
//
// TODO(emily): Pass in a callback which generates CSS, similar to
// how our selector handlers work, instead of passing in
// `selectorHandlers` and have them make calls to `generateCSS`
// themselves. Right now, this is impractical because our string
// handlers are very specialized and do complex things.
declarations.set(key, stringHandlers[key](declarations.get(key), selectorHandlers),
// Preserve order here, since we are really replacing an
// unprocessed style with a processed style, not overriding an
// earlier style
false);
}
}
};
var transformRule = function transformRule(key /* : string */
, value /* : string */
, transformValue /* : function */
) {
return (/* : string */String(kebabifyStyleName(key)) + ':' + String(transformValue(key, value)) + ';'
);
};
var arrayToObjectKeysReducer = function arrayToObjectKeysReducer(acc, val) {
acc[val] = true;
return acc;
};
/**
* Generate a CSS ruleset with the selector and containing the declarations.
*
* This function assumes that the given declarations don't contain any s