@blackglory/match
v0.4.1
Published
A module for matching nodes from pages
Readme
match
A module for matching elements from pages.
Install
npm install --save @blackglory/match
# or
yarn add @blackglory/matchUsage
Match only
import { matchElement, element, css, childNodes, textNode, children, multiple } from '@blackglory/match'
import { parseNodes, getBySelector } from 'extra-dom'
const div = parseNodes(`
<div>
<header>Heading</header>
<article>
<p>Paragraph1</p>
<p>Paragraph2</p>
</article>
</div>
`.trim())[0] as Element
const header = getBySelector.call(div, 'header')
const result = matchElement(
header
, element(
css`header`
, childNodes(
textNode()
)
)
, element(
css`article`
, children(
multiple([1, Infinity], element(
css`p`
, childNodes(
textNode()
)
))
)
)
)
// {}Match and collect nodes
import { matchElement, element, css, childNodes, textNode, children, multiple } from '@blackglory/match'
import { parseNodes, getBySelector } from 'extra-dom'
const div = parseNodes(`
<div>
<header>Heading</header>
<article>
<p>Paragraph1</p>
<p>Paragraph2</p>
</article>
</div>
`.trim())[0] as Element
const header = getBySelector.call(div, 'header')
const result = matchElement(
header
, element(
css`header`
, childNodes(
textNode`heading`()
)
)
, element(
css`article`
, children(
multiple([1, Infinity], element(
css`p`
, childNodes(
textNode`paragraph`()
)
))
)
)
)
// {
// heading: [object Text "Heading"]
// , paragraph: [
// [object Text "Paragraph1"]
// , [object Text "Paragraph2"]
// ]
// }API
interface IContext {
readonly document: Document
readonly next: (node: Node, distance?: number) => Node | undefined
readonly collection: {
[name: string]: Node | Node[]
}
}
interface IReadonlyContext {
readonly document: Document
readonly next: (node: Node, distance?: number) => Node | undefined
readonly collection: {
readonly [name: string]: Node | Node[]
}
}
type IMatcher<T extends Node> =
| ITerminalMatcher<T>
| INestedMatcher<T>
| ISkipMatcher<T>
type ITerminalMatcher<T extends Node> = (
this: IReadonlyContext<T>
, node: T
) => boolean
type INestedMatcher<T extends Node> = (
this: IReadonlyContext<T>
, node: T
) => boolean
type ISkipMatcher<T extends Node> = (
this: IReadonlyContext<T>
, node: T
) => number | falsematch
function match(
this: void | Document
, node: Node
, ...matchers: Array<IMatcher<Node>>
): Record<string, Arrayable<Node>> | nullmatchElement
function matchElement(
this: void | Document
, element: Element
, ...matchers: Array<IMatcher<Element>>
): Record<string, Arrayable<Node>> | nullMatchers
anyOf
function anyOf<T extends Node>(
...matchers: [
INestedMatcher<T> | ITerminalMatcher<T>
, INestedMatcher<T> | ITerminalMatcher<T>
, ...Array<INestedMatcher<T> | ITerminalMatcher<T>>
]
): INestedMatcher<T>childNodes
function childNodes(...matchers: Array<IMatcher<Node>>): INestedMatcher<Node>children
function children(...matchers: Array<IMatcher<Element>>): INestedMatcher<Element>css
function css(
strings: TemplateStringsArray
, ...values: string[]
): ITerminalMatcher<Element>
function css(selector: string): ITerminalMatcher<Element>element
function element(
strings: TemplateStringsArray
, ...values: string[]
): (
...matchers: Array<
| INestedMatcher<Element>
| ITerminalMatcher<Element>
>
) => INestedMatcher<Node>
function element(
name: string
, ...matchers: Array<INestedMatcher<Element>>
): INestedMatcher<Node>
function element(
...matchers: Array<INestedMatcher<Element>>
): INestedMatcher<Node>multiple
interface IMultipleOptions {
greedy: boolean
}
function multiple<T extends Node>(
range: [min: number, max: number]
, matcher: INestedMatcher<T> | ITerminalMatcher<T>
, options: IMultipleOptions = { greedy: true }
): ISkipMatcher<T>node
function node(
strings: TemplateStringsArray
, ...values: string[]
): (
...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>
) => INestedMatcher<Node>
function node(
name: string
, ...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>
): INestedMatcher<Node>
function node(
...matchers: Array<INestedMatcher<Node> | ITerminalMatcher<Node>>
): INestedMatcher<Node>optional
function optional<T extends Node>(
matcher: INestedMatcher<T> | ITerminalMatcher<T>
): ISkipMatcher<T>repeat
function repeat<T extends Node>(
times: number
, matcher: INestedMatcher<T> | ITerminalMatcher<T>
): ISkipMatcher<T>tap
function tap<T extends Node, U extends ReturnType<IMatcher<any>>>(
matcher: (this: IReadonlyContext, node: T) => U
, callback: (value: U) => void
): (this: IReadonlyContext, node: T) => UtextContentEquals
interface ITextContentEqualsOptions {
caseSensitive?: boolean
trim?: boolean
}
function textContentEquals(
text: string
, {
caseSensitive = true
, trim = false
}: ITextContentEqualsOptions = {}
): ITerminalMatcher<Node>textContentIncludes
interface ITextContentIncludesOptions {
caseSensitive?: boolean
trim?: boolean
}
function textContentIncludes(
searchString: string
, {
caseSensitive = true
, trim = false
}: ITextContentIncludesOptions = {}
): ITerminalMatcher<Node>textContentMatches
interface ITextContentMatchesOptions {
trim?: boolean
}
function textContentMatches(
pattern: RegExp
, { trim = false }: ITextContentMatchesOptions = {}
): ITerminalMatcher<Node>textNode
function textNode(
strings: TemplateStringsArray
, ...values: string[]
): (...matchers: Array<ITerminalMatcher<Node>>) => INestedMatcher<Node>
function textNode(
name: string
, ...matchers: Array<ITerminalMatcher<Node>>
): INestedMatcher<Node>
function textNode(
...matchers: Array<ITerminalMatcher<Node>>
): INestedMatcher<Node>xpath
function xpath(
strings: TemplateStringsArray
, ...values: string[]
): ITerminalMatcher<Node>
function xpath(experssion: string): ITerminalMatcher<Node>