UNPKG

@wordpress/block-editor

Version:
137 lines (107 loc) 4.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = useSimulatedMediaQuery; var _lodash = require("lodash"); var _cssMediaquery = require("css-mediaquery"); var _element = require("@wordpress/element"); var _url = require("@wordpress/url"); /** * External dependencies */ /** * WordPress dependencies */ const ENABLED_MEDIA_QUERY = '(min-width:0px)'; const DISABLED_MEDIA_QUERY = '(min-width:999999px)'; const VALID_MEDIA_QUERY_REGEX = /\((min|max)-width:[^\(]*?\)/g; function getStyleSheetsThatMatchHostname() { var _window$document$styl, _window, _window$document; if (typeof window === 'undefined') { return []; } return (0, _lodash.filter)((_window$document$styl = (_window = window) === null || _window === void 0 ? void 0 : (_window$document = _window.document) === null || _window$document === void 0 ? void 0 : _window$document.styleSheets) !== null && _window$document$styl !== void 0 ? _window$document$styl : [], styleSheet => { if (!styleSheet.href) { return false; } return (0, _url.getProtocol)(styleSheet.href) === window.location.protocol && (0, _url.getAuthority)(styleSheet.href) === window.location.host; }); } function isReplaceableMediaRule(rule) { if (!rule.media) { return false; } // Need to use "media.mediaText" instead of "conditionText" for IE support. return !!rule.media.mediaText.match(VALID_MEDIA_QUERY_REGEX); } function replaceRule(styleSheet, newRuleText, index) { styleSheet.deleteRule(index); styleSheet.insertRule(newRuleText, index); } function replaceMediaQueryWithWidthEvaluation(ruleText, widthValue) { return ruleText.replace(VALID_MEDIA_QUERY_REGEX, matchedSubstring => { if ((0, _cssMediaquery.match)(matchedSubstring, { type: 'screen', width: widthValue })) { return ENABLED_MEDIA_QUERY; } return DISABLED_MEDIA_QUERY; }); } /** * Function that manipulates media queries from stylesheets to simulate a given * viewport width. * * @param {string} marker CSS selector string defining start and end of * manipulable styles. * @param {number?} width Viewport width to simulate. If provided null, the * stylesheets will not be modified. */ function useSimulatedMediaQuery(marker, width) { (0, _element.useEffect)(() => { if (!width) { return; } const styleSheets = getStyleSheetsThatMatchHostname(); const originalStyles = []; styleSheets.forEach((styleSheet, styleSheetIndex) => { let relevantSection = false; for (let ruleIndex = 0; ruleIndex < styleSheet.cssRules.length; ++ruleIndex) { const rule = styleSheet.cssRules[ruleIndex]; if (rule.type !== window.CSSRule.STYLE_RULE && rule.type !== window.CSSRule.MEDIA_RULE) { continue; } if (!relevantSection && !!rule.cssText.match(new RegExp(`#start-${marker}`))) { relevantSection = true; } if (relevantSection && !!rule.cssText.match(new RegExp(`#end-${marker}`))) { relevantSection = false; } if (!relevantSection || !isReplaceableMediaRule(rule)) { continue; } const ruleText = rule.cssText; if (!originalStyles[styleSheetIndex]) { originalStyles[styleSheetIndex] = []; } originalStyles[styleSheetIndex][ruleIndex] = ruleText; replaceRule(styleSheet, replaceMediaQueryWithWidthEvaluation(ruleText, width), ruleIndex); } }); return () => { originalStyles.forEach((rulesCollection, styleSheetIndex) => { if (!rulesCollection) { return; } for (let ruleIndex = 0; ruleIndex < rulesCollection.length; ++ruleIndex) { const originalRuleText = rulesCollection[ruleIndex]; if (originalRuleText) { replaceRule(styleSheets[styleSheetIndex], originalRuleText, ruleIndex); } } }); }; }, [width]); } //# sourceMappingURL=index.js.map