您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
给CSS适配人员用的辅助工具函数
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greatest.deepsurf.us/scripts/439632/1015904/CSS%E6%94%B9%E7%BC%96%E7%BD%91%E9%A1%B5%E5%93%8D%E5%BA%94%E5%BC%8F%20%E9%80%82%E9%85%8D%E5%B7%A5%E4%BD%9C%E8%80%85.js
// ==UserScript== // @name CSS改编/网页响应式 适配工作者 // @version 0.55 // @description 给CSS适配人员用的辅助工具函数 // @description:en Helper functions for adaptation developers // @match *://*/* // @license The Unlicense // @namespace https://greatest.deepsurf.us/users/871942 // ==/UserScript== function extract_those_elements_whose_attributes_include_styles(doc = document, filterAttr) { const elems = [] elems.push(...[...doc.all].filter(el => (!filterAttr || el.hasAttribute(filterAttr)) && !/\b(a|img|span)\b/.test(el.localName) && (el.localName === 'iframe' ? elems.push(...extract_those_elements_whose_attributes_include_styles(el.contentDocument)) && false : el.attributes.style?.value))) return elems } function extractStyleToCssForm(elem) { let { localName, attributes: { id = '', class: className = '', style } } = elem if (specTags.has(localName)) { id = className = '' } else { localName = '' if (className) className = className.value.replace(/ |^/g, '.') if (id) { id = /[-]|auto|\bid\b/.test(id.value) ? '' : `#${id.value}` if (id) className = '' } } return `${localName}${id}${className} { ${style.value.replace(/(:) /g, '$1').replace(/;\b/g, '$& ').replace(/;$/, '')} }` } const specTags = new Set(['body']) unsafeWindow._extractCssOfModifiedInPage = function extractCssOfModifiedInPage(doc, { filterAttr = '', existing = 'user-custom' } = {}) { doc = doc.getRootNode() // `doc` can be an arbitrarily selected leaf node without having to pay attention to selecting `HTMLDocument` let orig = existing && doc instanceof Node && doc.querySelector(`style[${existing}]`)?.innerText || '' , new_ = extract_those_elements_whose_attributes_include_styles(doc, filterAttr).map(extractStyleToCssForm).join('\n') return { modified: mergeCommonCss(new_), merged: mergeCommonCss(orig + new_) } } function mergeCommonCss(css = '') { const re = { node: [/^(\s*)([^{}}]+)\s*\{([^}]+?)\s*\}(.*?)\2\{([^}]+?)\s*\}/ms, '$1$2{$3;$5 }$4'], nodes: [/([^{\n]+?)(\s*\{[^}]+\})(.*?)\s*([^{\n]+?)\2/s, '$1, $4$2$3'] } let merged Object.values(re).forEach(([mat, pla]) => { const merge = str => str.replace(mat, pla) merged = merge(css) while (css !== merged) merged = merge(css = merged) }) return merged } unsafeWindow._findOverflowedElems = function findOverflowedElems(rootElem) { if (!(rootElem instanceof HTMLElement)) throw TypeError('An entry element is required to be specified.') return [...rootElem.querySelectorAll('*')].filter(el => el.clientWidth > rootElem.clientWidth) }