UNPKG

postcss-hover-media-feature

Version:

PostCSS plugin that extracts and wraps rules containing `:hover` pseudo-classes in `@media (hover: hover) {}` media queries

1 lines 6.16 kB
{"version":3,"file":"index.es.mjs","sources":["index.js"],"sourcesContent":["const selectorParser = require('postcss-selector-parser')\n\nconst selectorProcessor = selectorParser(selectors => {\n let hoverSelectors = []\n\n selectors.walk(selector => {\n if (\n selector.type === 'pseudo' &&\n selector.toString() === ':hover' &&\n selector.parent.value !== ':not' &&\n selector.parent.toString() !== ':hover'\n ) {\n hoverSelectors.push(selector.parent.toString())\n }\n })\n\n let nonHoverSelectors = selectors.reduce((acc, selector) => {\n if (hoverSelectors.includes(selector.toString())) {\n return acc\n }\n\n return [...acc, selector.toString()]\n }, [])\n\n return { hoverSelectors, nonHoverSelectors }\n})\n\nmodule.exports = ({\n fallback = false,\n fallbackSelector = 'html:not(.supports-touch)',\n rootSelectors = []\n} = {}) => {\n function createMediaQuery (rule, { AtRule }) {\n let media = new AtRule({ name: 'media', params: '(hover: hover)' })\n\n media.source = rule.source\n\n media.append(rule)\n\n return media\n }\n\n function isAlreadyNested (rule) {\n let container = rule.parent\n\n while (container !== null && container.type !== 'root') {\n if (\n container.type === 'atrule' &&\n container.params.includes('hover: hover')\n ) {\n return true\n }\n\n container = container.parent\n }\n\n return false\n }\n\n return {\n postcssPlugin: 'postcss-hover-media-feature',\n\n Rule (rule, { AtRule }) {\n if (\n !rule.selector.includes(':hover') ||\n isAlreadyNested(rule) ||\n rule.selector.includes(fallbackSelector)\n ) {\n return\n }\n\n let {\n hoverSelectors = [],\n nonHoverSelectors = []\n } = selectorProcessor.transformSync(rule.selector, { lossless: false })\n\n if (hoverSelectors.length === 0) {\n return\n }\n\n let mediaQuery = createMediaQuery(\n rule.clone({ selectors: hoverSelectors }),\n { AtRule }\n )\n\n rule.after(mediaQuery)\n\n if (fallback) {\n rule.before(\n rule.clone({\n selectors: hoverSelectors.map(hoverSelector => {\n if (\n rootSelectors.some(rootSelector =>\n hoverSelector.startsWith(rootSelector)\n )\n ) {\n return `${fallbackSelector}${hoverSelector}`\n }\n return `${fallbackSelector} ${hoverSelector}`\n })\n })\n )\n }\n\n if (nonHoverSelectors.length > 0) {\n rule.replaceWith(rule.clone({ selectors: nonHoverSelectors }))\n\n return\n }\n\n rule.remove()\n }\n }\n}\n\nmodule.exports.postcss = true\n"],"names":["selectorParser","require","selectorProcessor","selectors","hoverSelectors","walk","selector","type","toString","parent","value","push","nonHoverSelectors","reduce","acc","includes","module","exports","fallback","fallbackSelector","rootSelectors","createMediaQuery","rule","AtRule","media","name","params","source","append","isAlreadyNested","container","postcssPlugin","Rule","transformSync","lossless","length","mediaQuery","clone","after","before","map","hoverSelector","some","rootSelector","startsWith","replaceWith","remove","postcss"],"mappings":"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"}