forked from VolodymyrBaydalka/docxjs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjavascript.ts
More file actions
100 lines (79 loc) · 2.77 KB
/
Copy pathjavascript.ts
File metadata and controls
100 lines (79 loc) · 2.77 KB
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
import { Length } from "./document/common";
import { ParagraphTab } from "./document/paragraph";
interface TabStop {
pos: number;
leader: string;
style: string;
}
const defaultTab: TabStop = { pos: 0, leader: "none", style: "left" };
const maxTabs = 50;
export function computePixelToPoint(container: HTMLElement = document.body) {
const temp = document.createElement("div");
temp.style.width = '100pt';
container.appendChild(temp);
const result = 100 / temp.offsetWidth;
container.removeChild(temp);
return result
}
export function updateTabStop(elem: HTMLElement, tabs: ParagraphTab[], defaultTabSize: Length, pixelToPoint: number = 72 / 96) {
const p = elem.closest("p");
const ebb = elem.getBoundingClientRect();
const pbb = p.getBoundingClientRect();
const pcs = getComputedStyle(p);
const tabStops = tabs?.length > 0 ? tabs.map(t => ({
pos: lengthToPoint(t.position),
leader: t.leader,
style: t.style
})).sort((a, b) => a.pos - b.pos) : [defaultTab];
const lastTab = tabStops[tabStops.length - 1];
const pWidthPt = pbb.width * pixelToPoint;
const size = lengthToPoint(defaultTabSize);
let pos = lastTab.pos + size;
if (pos < pWidthPt) {
for (; pos < pWidthPt && tabStops.length < maxTabs; pos += size) {
tabStops.push({ ...defaultTab, pos: pos });
}
}
const marginLeft = parseFloat(pcs.marginLeft);
const pOffset = pbb.left + marginLeft;
const left = (ebb.left - pOffset) * pixelToPoint;
const tab = tabStops.find(t => t.style != "clear" && t.pos > left);
if(tab == null)
return;
let width: number = 1;
if (tab.style == "right" || tab.style == "center") {
const tabStops = Array.from(p.querySelectorAll(`.${elem.className}`));
const nextIdx = tabStops.indexOf(elem) + 1;
const range = document.createRange();
range.setStart(elem, 1);
if (nextIdx < tabStops.length) {
range.setEndBefore(tabStops[nextIdx]);
} else {
range.setEndAfter(p);
}
const mul = tab.style == "center" ? 0.5 : 1;
const nextBB = range.getBoundingClientRect();
const offset = nextBB.left + mul * nextBB.width - (pbb.left - marginLeft);
width = tab.pos - offset * pixelToPoint;
} else {
width = tab.pos - left;
}
elem.innerHTML = " ";
elem.style.textDecoration = "inherit";
elem.style.wordSpacing = `${width.toFixed(0)}pt`;
switch (tab.leader) {
case "dot":
case "middleDot":
elem.style.textDecoration = "underline";
elem.style.textDecorationStyle = "dotted";
break;
case "hyphen":
case "heavy":
case "underscore":
elem.style.textDecoration = "underline";
break;
}
}
function lengthToPoint(length: Length): number {
return parseFloat(length);
}