Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/mq4-hover-shim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Rebert <code@rebertia.com>2015-01-01 06:28:13 +0300
committerChris Rebert <code@rebertia.com>2015-01-01 06:43:22 +0300
commit0e97ce1c2f135cf49d5c2f1ddce4ad2576a89b83 (patch)
treeb34e41f6e8a07dd6ac907983a7ff0f496cae6d8f /src/nodejs
initial checkin
Diffstat (limited to 'src/nodejs')
-rw-r--r--src/nodejs/postprocessor.js82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/nodejs/postprocessor.js b/src/nodejs/postprocessor.js
new file mode 100644
index 0000000..2173bec
--- /dev/null
+++ b/src/nodejs/postprocessor.js
@@ -0,0 +1,82 @@
+/*eslint-env node */
+/*!
+ * Postprocessor for shimming @media (hover: hover) from Media Queries Level 4
+ * https://github.com/cvrebert/mq4-hover-hover-shim
+ * Copyright 2014 Christopher Rebert
+ * Licensed under MIT (https://github.com/cvrebert/mq4-hover-hover-shim/blob/master/LICENSE.txt)
+ */
+
+'use strict';
+
+var postcss = require('postcss');
+var mediaQuery = require('css-mediaquery');
+
+
+// Checks whether the at-rule is: @media (hover: hover) {...}
+function isSimpleMediaHoverHover(atRule) {
+ var mediaOrs = mediaQuery.parse(atRule.params);
+ if (mediaOrs.length > 1) {
+ return false;
+ }
+ var mediaAnds = mediaOrs[0];
+ if (mediaAnds.inverse) {
+ return false;
+ }
+ if (mediaAnds.expressions.length > 1) {
+ return false;
+ }
+ var mediaExpr = mediaAnds.expressions[0];
+ return mediaExpr.feature === 'hover' && mediaExpr.value === 'hover';
+}
+
+function replaceWithItsChildren(atRule) {
+ atRule.each(function (child) {
+ child.moveBefore(atRule);
+ });
+ atRule.removeSelf();
+}
+
+// Prefixes each selector in the given rule with the given prefix string
+function prefixSelectorsWith(rule, selectorPrefix) {
+ // Yes, this parsing is horribly naive.
+
+ // We don't use rule.selectors because it's "some kind of hack" per https://github.com/postcss/postcss/issues/37
+ // and it doesn't preserve inter-selector whitespace.
+ var selectorsWithWhitespace = rule.selector.split(',');
+
+ var revisedSelectors = selectorsWithWhitespace.map(function (selectorWithWhitespace) {
+ var quadruple = /^(\s*)(\S.*\S)(\s*)$/.exec(selectorWithWhitespace);
+ if (quadruple === null) {
+ // Skip weirdness
+ return selectorWithWhitespace;
+ }
+
+ var prefixWhitespace = quadruple[1];
+ var selector = quadruple[2];
+ var suffixWhitespace = quadruple[3];
+
+ var revisedSelector = prefixWhitespace + selectorPrefix + selector + suffixWhitespace;
+ return revisedSelector;
+ });
+ rule.selector = revisedSelectors.join(',');
+}
+
+
+module.exports = postcss(function process(css, opts) {
+ var hoverSelectorPrefix = opts.hoverSelectorPrefix;
+ if ((typeof hoverSelectorPrefix) !== 'string') {
+ throw new Error('hoverSelectorPrefix option must be a string');
+ }
+
+ css.eachAtRule('media', function (atRule) {
+ if (!isSimpleMediaHoverHover(atRule)) {
+ return;
+ }
+
+ atRule.eachRule(function (rule) {
+ prefixSelectorsWith(rule, hoverSelectorPrefix);
+ });
+
+ replaceWithItsChildren(atRule);
+ });
+});