// ==UserScript==
// @name Web选择
// @name:en Web Select
// @name:zh-TW Web捕獲
// @namespace http://howardzhangdqs.eu.org/
// @source https://github.com/Howardzhangdqs/web-select
// @version 0.2.4
// @description 由于Web选择太好用,微软就把他砍掉了。本脚本实现了Web选择的部分功能。按下Alt+S即可选择文本。
// @description:en Due to the ease with which the "web select" was used, Microsoft cut it off. This script implements some functions of "web select". Press Alt+S to select text.
// @description:zh-TW 由於Web選擇功能非常實用,微軟就將它砍掉了。本腳本實現了Web選擇的部分功能。按下Alt+S即可選擇文本。
// @author HowardZhangdqs
// @match *://*/*
// @license MIT
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABsUExURf///xYWFgMDAw4ODgICAh8fHw4ODQAAAA8PD9LS0gEBAR4eHgcHBwoKCgUFBQgICCAgICgoKCwsLB0dHSQkJCYmJvv7+vr6+ZiYlyMjIhwcHJaWlBsbGxgYGAYGBnV2dfz9/BAQEHR0cw0NDWBB0hYAAAFaSURBVFjD7VbZkoMgEARBwNvNsfed///HAJoUq3Ga1a0tH+ynQXragWmtYWzDelEopXzQmgu+/Jorxe9gOtceNjI6gF2X14hC0ic8MZYPBIJwGqonlSzIsHhkkQpu/xlVqKa3D3b7QJ+RLqHAlyRIisICaqkAXYE9YYKMAijYaTGU/0dWu+4+eL9DcjOm1J1DZZQP2jFF6qtARBvNiJK65FxK+TlTwOWnfXyaIZDZB9UvnHhT4HWpQLoJ/KGANcUH/h98EwJzvsSVCST6HiUMKT8EWtyFguyCWdrGxQJHLKCRkYDCzv2+yC644cCY7r78eCOEEd2aC+OHjh3lg2CIGI44TTh8TBupZx0nRxyBnFi4xGYw4rxc1uVKv4U9JGW0M96xeQiFHLoPnNLNtm+LrknTFWIBrgGhQm/oBoSUfAF9S1IjIKdUIF9iO5FF8ChL7it5EzVnG1aMM5cYFmmzQuXPAAAAAElFTkSuQmCC
// @grant none
// ==/UserScript==
(() => {
var UnselectedBoxStyle = {
border: "1px solid #fff",
outline: "1px dashed #000",
outlineOffset: "-1px",
zIndex: "99999",
};
var SelectedBoxStyle = {
border: "1px solid #fff",
outline: "1px solid #000",
outlineOffset: "0",
zIndex: "99999",
};
var SelectBoxStyle = {
position: "fixed",
outline: "3px dashed white",
zIndex: "99999",
};
var addStylesheetRules = function (dom, decls) {
if (dom instanceof HTMLElement) dom = [dom];
for (var i in decls) {
for (var _i = 0, dom_1 = dom; _i < dom_1.length; _i++) {
var j = dom_1[_i];
j.style[i] = decls[i];
}
}
};
var makeButton = function (top, left) {
var button = document.createElement("button");
button.innerText = "Web选择";
button.style.position = "fixed";
if (top) button.style.top = "".concat(top, "px");
else button.style.bottom = "10px";
if (left) button.style.left = "".concat(left, "px");
else button.style.right = "10px";
button.style.zIndex = "99999";
button.style.padding = "10px";
button.style.borderRadius = "10px";
button.style.background = "#fff";
button.style.color = "#000";
button.style.border = "1px solid #000";
button.style.cursor = "pointer";
document.body.appendChild(button);
return button;
};
var getElementsPosition = function () {
var elements = [];
var allElements = document.querySelectorAll("*");
allElements.forEach(function (element) {
var _a = element.getBoundingClientRect(),
top = _a.top,
left = _a.left,
width = _a.width,
height = _a.height;
if (top && left && width && height && element.innerText)
elements.push({
top: top,
left: left,
width: width,
height: height,
text: element.innerText,
src: element,
});
});
return elements;
};
var makeDiv = function (_a) {
var top = _a.top,
left = _a.left,
width = _a.width,
height = _a.height,
text = _a.text,
src = _a.src;
var div = document.createElement("div");
div.style.position = "fixed";
div.style.top = "".concat(top, "px");
div.style.left = "".concat(left, "px");
div.style.width = "".concat(width, "px");
div.style.height = "".concat(height, "px");
addStylesheetRules(div, UnselectedBoxStyle);
div.style.zIndex = "99999";
document.body.appendChild(div);
return {
top: top,
left: left,
width: width,
height: height,
text: text,
el: div,
src: src,
};
};
var dragSelect = function (allBoxes) {
return new Promise(function (resolve, reject) {
var div = document.createElement("div");
addStylesheetRules(div, SelectBoxStyle);
document.body.appendChild(div);
var mask = [];
var selectedBox = {
_p1: [0, 0],
_p2: [0, 0],
set p1(val) {
this._p1[0] = Math.floor(val[0]);
this._p1[1] = Math.floor(val[1]);
this.runwatch();
},
set p2(val) {
this._p2[0] = Math.floor(val[0]);
this._p2[1] = Math.floor(val[1]);
this.runwatch();
},
get p1() {
return this._p1;
},
get p2() {
return this._p2;
},
get top() {
return Math.min(this._p1[0], this._p2[0]);
},
get left() {
return Math.min(this._p1[1], this._p2[1]);
},
get width() {
return Math.abs(this._p1[1] - this._p2[1]);
},
get height() {
return Math.abs(this._p1[0] - this._p2[0]);
},
watchfn: [],
watch: function (callback) {
this.watchfn.push(callback);
},
unwatch: function (callback) {
this.watchfn = this.watchfn.filter(function (fn) {
return fn !== callback;
});
},
runwatch: function () {
for (var _i = 0, _a = this.watchfn; _i < _a.length; _i++) {
var fn = _a[_i];
fn(this);
}
},
};
var makeMask = function () {
var mask1 = document.createElement("div");
var mask2 = document.createElement("div");
var mask3 = document.createElement("div");
var mask4 = document.createElement("div");
addStylesheetRules([mask1, mask2, mask3, mask4], {
position: "fixed",
top: "0",
left: "0",
background: "#0007",
zIndex: "99997",
});
selectedBox.watch(function () {
addStylesheetRules(mask1, {
top: "0",
left: "0",
width: "".concat(selectedBox.left, "px"),
height: "100%",
});
addStylesheetRules(mask2, {
top: "0",
left: "".concat(selectedBox.left, "px"),
width: "".concat(selectedBox.width, "px"),
height: "".concat(selectedBox.top, "px"),
});
addStylesheetRules(mask3, {
top: "".concat(
selectedBox.top + selectedBox.height,
"px",
),
left: "".concat(selectedBox.left, "px"),
width: "".concat(selectedBox.width, "px"),
height: "calc(100% - ".concat(
selectedBox.top + selectedBox.height,
"px)",
),
});
addStylesheetRules(mask4, {
top: "0px",
left: "".concat(
selectedBox.left + selectedBox.width,
"px",
),
width: "calc(100% - ".concat(
selectedBox.left + selectedBox.width,
"px)",
),
height: "100vh",
});
});
document.body.appendChild(mask1);
document.body.appendChild(mask2);
document.body.appendChild(mask3);
document.body.appendChild(mask4);
return [mask1, mask2, mask3, mask4];
};
var mouseDown = function (e) {
e.preventDefault();
mask.push.apply(mask, makeMask());
div.style.display = "block";
selectedBox.p1 = [e.clientY, e.clientX];
selectedBox.p2 = [e.clientY, e.clientX];
div.style.top = "".concat(selectedBox.top, "px");
div.style.left = "".concat(selectedBox.left, "px");
div.style.width = "0";
div.style.height = "0";
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);
};
var getSelectedElements = function () {
return allBoxes.filter(function (el) {
if (
el.left < selectedBox.left ||
el.top < selectedBox.top ||
el.left + el.width >
selectedBox.left + selectedBox.width ||
el.top + el.height >
selectedBox.top + selectedBox.height
) {
return false;
}
return true;
});
};
var mouseMove = function (e) {
e.preventDefault();
selectedBox.p2 = [e.clientY, e.clientX];
div.style.top = "".concat(selectedBox.top, "px");
div.style.left = "".concat(selectedBox.left, "px");
div.style.width = "".concat(selectedBox.width, "px");
div.style.height = "".concat(selectedBox.height, "px");
var selectedElements = getSelectedElements();
for (
var _i = 0, allBoxes_1 = allBoxes;
_i < allBoxes_1.length;
_i++
) {
var el = allBoxes_1[_i];
if (selectedElements.includes(el)) {
addStylesheetRules(el.el, SelectedBoxStyle);
} else {
addStylesheetRules(el.el, UnselectedBoxStyle);
}
}
console.log(
selectedElements
.sort(function (a, b) {
return b.left - a.left;
})
.sort(function (a, b) {
return b.top - a.top;
}),
);
};
var mouseUp = function (e) {
document.removeEventListener("mousemove", mouseMove);
document.removeEventListener("mouseup", mouseUp);
document.removeEventListener("mousedown", mouseDown);
div.remove();
for (var _i = 0, mask_1 = mask; _i < mask_1.length; _i++) {
var i = mask_1[_i];
i.remove();
}
addStylesheetRules(document.body, { pointerEvents: "" });
resolve({
top: parseInt(div.style.top),
left: parseInt(div.style.left),
width: parseInt(div.style.width),
height: parseInt(div.style.height),
el: getSelectedElements(),
});
};
document.addEventListener("mousedown", mouseDown);
document.addEventListener("mouseup", mouseUp);
addStylesheetRules(document.body, { pointerEvents: "none" });
});
};
var isChild = function (parent, child) {
var node = child.parentNode;
while (node !== null) {
if (node === parent) return true;
node = node.parentNode;
}
return false;
};
var __awaiter =
(undefined && undefined.__awaiter) ||
function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P
? value
: new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done
? resolve(result.value)
: adopt(result.value).then(fulfilled, rejected);
}
step(
(generator = generator.apply(
thisArg,
_arguments || [],
)).next(),
);
});
};
var __generator =
(undefined && undefined.__generator) ||
function (thisArg, body) {
var _ = {
label: 0,
sent: function () {
if (t[0] & 1) throw t[1];
return t[1];
},
trys: [],
ops: [],
},
f,
y,
t,
g;
return (
(g = { next: verb(0), throw: verb(1), return: verb(2) }),
typeof Symbol === "function" &&
(g[Symbol.iterator] = function () {
return this;
}),
g
);
function verb(n) {
return function (v) {
return step([n, v]);
};
}
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while ((g && ((g = 0), op[0] && (_ = 0)), _))
try {
if (
((f = 1),
y &&
(t =
op[0] & 2
? y["return"]
: op[0]
? y["throw"] ||
((t = y["return"]) && t.call(y), 0)
: y.next) &&
!(t = t.call(y, op[1])).done)
)
return t;
if (((y = 0), t)) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return { value: op[1], done: false };
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (
!((t = _.trys),
(t = t.length > 0 && t[t.length - 1])) &&
(op[0] === 6 || op[0] === 2)
) {
_ = 0;
continue;
}
if (
op[0] === 3 &&
(!t || (op[1] > t[0] && op[1] < t[3]))
) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2]) _.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
} catch (e) {
op = [6, e];
y = 0;
} finally {
f = t = 0;
}
if (op[0] & 5) throw op[1];
return { value: op[0] ? op[1] : void 0, done: true };
}
};
var main = function () {
return __awaiter(void 0, void 0, void 0, function () {
var mask,
quit,
ElementPositions,
allBoxes,
_i,
ElementPositions_1,
position,
selectedBox,
_a,
allBoxes_1,
div,
filtered;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
mask = document.createElement("div");
addStylesheetRules(mask, {
position: "fixed",
top: "0",
left: "0",
inlineSize: "100%",
blockSize: "100%",
zIndex: "99998",
background: "#0007",
});
quit = function () {};
ElementPositions = getElementsPosition();
console.log(ElementPositions);
allBoxes = [];
for (
_i = 0, ElementPositions_1 = ElementPositions;
_i < ElementPositions_1.length;
_i++
) {
position = ElementPositions_1[_i];
allBoxes.push(makeDiv(position));
}
return [4, dragSelect(allBoxes)];
case 1:
selectedBox = _b.sent();
for (
_a = 0, allBoxes_1 = allBoxes;
_a < allBoxes_1.length;
_a++
) {
div = allBoxes_1[_a];
div.el.remove();
}
filtered = selectedBox.el
.filter(function (val, index, arr) {
console.log(val, index, arr);
for (
var _i = 0, arr_1 = arr;
_i < arr_1.length;
_i++
) {
var i = arr_1[_i];
if (isChild(i.src, val.src)) return false;
}
return true;
})
.sort(function (a, b) {
return a.left - b.left;
})
.sort(function (a, b) {
return a.top - b.top;
});
console.log(
filtered.map(function (el) {
return el.text;
}),
);
navigator.clipboard.writeText(
filtered
.map(function (el) {
return el.text;
})
.join("\n\n"),
);
return [2];
}
});
});
};
window.addEventListener("keydown", function (e) {
if (e.key === "s" && e.altKey && !e.ctrlKey && !e.shiftKey) main();
});
})();