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
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.util = (function() {
// eslint-disable-line no-unused-vars
const exports = {};
/** Removes a node from its document, if it's a node and the node is attached to a parent */
exports.removeNode = function(el) {
if (el && el.parentNode) {
el.remove();
}
};
/** Truncates the X coordinate to the document size */
exports.truncateX = function(x) {
const max = Math.max(
document.documentElement.clientWidth,
document.body.clientWidth,
document.documentElement.scrollWidth,
document.body.scrollWidth
);
if (x < 0) {
return 0;
} else if (x > max) {
return max;
}
return x;
};
/** Truncates the Y coordinate to the document size */
exports.truncateY = function(y) {
const max = Math.max(
document.documentElement.clientHeight,
document.body.clientHeight,
document.documentElement.scrollHeight,
document.body.scrollHeight
);
if (y < 0) {
return 0;
} else if (y > max) {
return max;
}
return y;
};
// Pixels of wiggle the captured region gets in captureSelectedText:
const CAPTURE_WIGGLE = 10;
const ELEMENT_NODE = document.ELEMENT_NODE;
exports.captureEnclosedText = function(box) {
const scrollX = window.scrollX;
const scrollY = window.scrollY;
const text = [];
function traverse(el) {
let elBox = el.getBoundingClientRect();
elBox = {
top: elBox.top + scrollY,
bottom: elBox.bottom + scrollY,
left: elBox.left + scrollX,
right: elBox.right + scrollX,
};
if (
elBox.bottom < box.top ||
elBox.top > box.bottom ||
elBox.right < box.left ||
elBox.left > box.right
) {
// Totally outside of the box
return;
}
if (
elBox.bottom > box.bottom + CAPTURE_WIGGLE ||
elBox.top < box.top - CAPTURE_WIGGLE ||
elBox.right > box.right + CAPTURE_WIGGLE ||
elBox.left < box.left - CAPTURE_WIGGLE
) {
// Partially outside the box
for (let i = 0; i < el.childNodes.length; i++) {
const child = el.childNodes[i];
if (child.nodeType === ELEMENT_NODE) {
traverse(child);
}
}
return;
}
addText(el);
}
function addText(el) {
let t;
if (el.tagName === "IMG") {
t = el.getAttribute("alt") || el.getAttribute("title");
} else if (el.tagName === "A") {
t = el.innerText;
if (
el.getAttribute("href") &&
!el.getAttribute("href").startsWith("#")
) {
t += " (" + el.href + ")";
}
} else {
t = el.innerText;
}
if (t) {
text.push(t);
}
}
traverse(document.body);
if (text.length) {
let result = text.join("\n");
result = result.replace(/^\s+/, "");
result = result.replace(/\s+$/, "");
result = result.replace(/[ \t]+\n/g, "\n");
return result;
}
return null;
};
return exports;
})();
null;
|