给CSS适配人员用的辅助工具函数
As of
ეს სკრიპტი არ უნდა იყოს პირდაპირ დაინსტალირებული. ეს ბიბლიოთეკაა, სხვა სკრიპტებისთვის უნდა ჩართეთ მეტა-დირექტივაში // @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)
- }