-
Notifications
You must be signed in to change notification settings - Fork 781
/
p-as-heading-evaluate.js
111 lines (91 loc) · 2.93 KB
/
p-as-heading-evaluate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
import { findUpVirtual } from '../../commons/dom';
function normalizeFontWeight(weight) {
switch (weight) {
case 'lighter':
return 100;
case 'normal':
return 400;
case 'bold':
return 700;
case 'bolder':
return 900;
}
weight = parseInt(weight);
return !isNaN(weight) ? weight : 400;
}
function getTextContainer(elm) {
let nextNode = elm;
const outerText = elm.textContent.trim();
let innerText = outerText;
while (innerText === outerText && nextNode !== undefined) {
let i = -1;
elm = nextNode;
if (elm.children.length === 0) {
return elm;
}
do {
// find the first non-empty child
i++;
innerText = elm.children[i].textContent.trim();
} while (innerText === '' && i + 1 < elm.children.length);
nextNode = elm.children[i];
}
return elm;
}
function getStyleValues(node) {
const style = window.getComputedStyle(getTextContainer(node));
return {
fontWeight: normalizeFontWeight(style.getPropertyValue('font-weight')),
fontSize: parseInt(style.getPropertyValue('font-size')),
isItalic: style.getPropertyValue('font-style') === 'italic'
};
}
function isHeaderStyle(styleA, styleB, margins) {
return margins.reduce((out, margin) => {
return (
out ||
((!margin.size || styleA.fontSize / margin.size > styleB.fontSize) &&
(!margin.weight ||
styleA.fontWeight - margin.weight > styleB.fontWeight) &&
(!margin.italic || (styleA.isItalic && !styleB.isItalic)))
);
}, false);
}
function pAsHeadingEvaluate(node, options, virtualNode) {
const siblings = Array.from(node.parentNode.children);
const currentIndex = siblings.indexOf(node);
options = options || {};
const margins = options.margins || [];
const nextSibling = siblings
.slice(currentIndex + 1)
.find(elm => elm.nodeName.toUpperCase() === 'P');
const prevSibling = siblings
.slice(0, currentIndex)
.reverse()
.find(elm => elm.nodeName.toUpperCase() === 'P');
const currStyle = getStyleValues(node);
const nextStyle = nextSibling ? getStyleValues(nextSibling) : null;
const prevStyle = prevSibling ? getStyleValues(prevSibling) : null;
const optionsPassLength = options.passLength;
const optionsFailLength = options.failLength;
const headingLength = node.textContent.trim().length;
const paragraphLength = nextSibling?.textContent.trim().length;
if (headingLength > paragraphLength * optionsPassLength) {
return true;
}
if (!nextStyle || !isHeaderStyle(currStyle, nextStyle, margins)) {
return true;
}
const blockquote = findUpVirtual(virtualNode, 'blockquote');
if (blockquote && blockquote.nodeName.toUpperCase() === 'BLOCKQUOTE') {
return undefined;
}
if (prevStyle && !isHeaderStyle(currStyle, prevStyle, margins)) {
return undefined;
}
if (headingLength > paragraphLength * optionsFailLength) {
return undefined;
}
return false;
}
export default pAsHeadingEvaluate;