|
|
import { domEach } from '../utils.js'; |
|
|
import { isTag, type Element, type AnyNode } from 'domhandler'; |
|
|
import type { Cheerio } from '../cheerio.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function css<T extends AnyNode>( |
|
|
this: Cheerio<T>, |
|
|
names?: string[], |
|
|
): Record<string, string> | undefined; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function css<T extends AnyNode>( |
|
|
this: Cheerio<T>, |
|
|
name: string, |
|
|
): string | undefined; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function css<T extends AnyNode>( |
|
|
this: Cheerio<T>, |
|
|
prop: string, |
|
|
val: |
|
|
| string |
|
|
| ((this: Element, i: number, style: string) => string | undefined), |
|
|
): Cheerio<T>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function css<T extends AnyNode>( |
|
|
this: Cheerio<T>, |
|
|
map: Record<string, string>, |
|
|
): Cheerio<T>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function css<T extends AnyNode>( |
|
|
this: Cheerio<T>, |
|
|
prop?: string | string[] | Record<string, string>, |
|
|
val?: |
|
|
| string |
|
|
| ((this: Element, i: number, style: string) => string | undefined), |
|
|
): Cheerio<T> | Record<string, string> | string | undefined { |
|
|
if ( |
|
|
(prop != null && val != null) || |
|
|
|
|
|
(typeof prop === 'object' && !Array.isArray(prop)) |
|
|
) { |
|
|
return domEach(this, (el, i) => { |
|
|
if (isTag(el)) { |
|
|
|
|
|
setCss(el, prop as string, val, i); |
|
|
} |
|
|
}); |
|
|
} |
|
|
|
|
|
if (this.length === 0) { |
|
|
return undefined; |
|
|
} |
|
|
|
|
|
return getCss(this[0], prop as string); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setCss( |
|
|
el: Element, |
|
|
prop: string | Record<string, string>, |
|
|
value: |
|
|
| string |
|
|
| ((this: Element, i: number, style: string) => string | undefined) |
|
|
| undefined, |
|
|
idx: number, |
|
|
) { |
|
|
if (typeof prop === 'string') { |
|
|
const styles = getCss(el); |
|
|
|
|
|
const val = |
|
|
typeof value === 'function' ? value.call(el, idx, styles[prop]) : value; |
|
|
|
|
|
if (val === '') { |
|
|
delete styles[prop]; |
|
|
} else if (val != null) { |
|
|
styles[prop] = val; |
|
|
} |
|
|
|
|
|
el.attribs['style'] = stringify(styles); |
|
|
} else if (typeof prop === 'object') { |
|
|
const keys = Object.keys(prop); |
|
|
for (let i = 0; i < keys.length; i++) { |
|
|
const k = keys[i]; |
|
|
setCss(el, k, prop[k], i); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getCss(el: AnyNode, props?: string[]): Record<string, string>; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function getCss(el: AnyNode, prop: string): string | undefined; |
|
|
function getCss( |
|
|
el: AnyNode, |
|
|
prop?: string | string[], |
|
|
): Record<string, string> | string | undefined { |
|
|
if (!el || !isTag(el)) return; |
|
|
|
|
|
const styles = parse(el.attribs['style']); |
|
|
if (typeof prop === 'string') { |
|
|
return styles[prop]; |
|
|
} |
|
|
if (Array.isArray(prop)) { |
|
|
const newStyles: Record<string, string> = {}; |
|
|
for (const item of prop) { |
|
|
if (styles[item] != null) { |
|
|
newStyles[item] = styles[item]; |
|
|
} |
|
|
} |
|
|
return newStyles; |
|
|
} |
|
|
return styles; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function stringify(obj: Record<string, string>): string { |
|
|
return Object.keys(obj).reduce( |
|
|
(str, prop) => `${str}${str ? ' ' : ''}${prop}: ${obj[prop]};`, |
|
|
'', |
|
|
); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function parse(styles: string): Record<string, string> { |
|
|
styles = (styles || '').trim(); |
|
|
|
|
|
if (!styles) return {}; |
|
|
|
|
|
const obj: Record<string, string> = {}; |
|
|
|
|
|
let key: string | undefined; |
|
|
|
|
|
for (const str of styles.split(';')) { |
|
|
const n = str.indexOf(':'); |
|
|
|
|
|
if (n < 1 || n === str.length - 1) { |
|
|
const trimmed = str.trimEnd(); |
|
|
if (trimmed.length > 0 && key !== undefined) { |
|
|
obj[key] += `;${trimmed}`; |
|
|
} |
|
|
} else { |
|
|
key = str.slice(0, n).trim(); |
|
|
obj[key] = str.slice(n + 1).trim(); |
|
|
} |
|
|
} |
|
|
|
|
|
return obj; |
|
|
} |
|
|
|