mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 14:58:37 +09:00
Backport Basilisk internal userscripts
This commit is contained in:
parent
15bec18421
commit
5c168f64fc
23 changed files with 2648 additions and 0 deletions
|
|
@ -0,0 +1,365 @@
|
|||
// 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/.
|
||||
// ==UserScript==
|
||||
// @name Intl.Segmenter Polyfill (minimal)
|
||||
// @namespace internal-userscripts
|
||||
// @description Provides a minimal Intl.Segmenter implementation for environments without native support.
|
||||
// @match *://*/*
|
||||
// @grant none
|
||||
// @run-at document-start
|
||||
// ==/UserScript==
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
var global =
|
||||
(typeof globalThis !== "undefined" && globalThis) ||
|
||||
(typeof window !== "undefined" && window) ||
|
||||
(typeof self !== "undefined" && self) ||
|
||||
this;
|
||||
if (typeof global.Intl !== "object" || global.Intl == null) {
|
||||
global.Intl = {};
|
||||
}
|
||||
if (typeof global.Intl.Segmenter === "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
var GRANULARITY_VALUES = { grapheme: true, word: true, sentence: true };
|
||||
var LOCALE_MATCHER_VALUES = { lookup: true, "best fit": true };
|
||||
var FALLBACK_WORD_LIKE = /^[A-Za-z0-9_]+$/;
|
||||
var FALLBACK_WORD_SPLIT = /[A-Za-z0-9_]+|[\s]+|[^\s]/g;
|
||||
var COMBINING_MARK_RANGES = [
|
||||
[0x0300, 0x036f],
|
||||
[0x1ab0, 0x1aff],
|
||||
[0x1dc0, 0x1dff],
|
||||
[0x20d0, 0x20ff],
|
||||
[0xfe20, 0xfe2f],
|
||||
];
|
||||
|
||||
var unicodeGraphemeRegex = null;
|
||||
var unicodeWordSplit = null;
|
||||
var unicodeWordLike = null;
|
||||
try {
|
||||
unicodeGraphemeRegex = new RegExp(
|
||||
"(?:\\P{Mark}\\p{Mark}*|\\p{Mark}+)",
|
||||
"gu",
|
||||
);
|
||||
unicodeWordSplit = new RegExp("[\\p{L}\\p{N}\\p{M}_]+|[\\s]+|[^\\s]", "gu");
|
||||
unicodeWordLike = new RegExp("^[\\p{L}\\p{N}\\p{M}_]+$", "u");
|
||||
} catch (e) {}
|
||||
|
||||
function canonicalizeLocales(locales) {
|
||||
if (typeof global.Intl.getCanonicalLocales === "function") {
|
||||
return global.Intl.getCanonicalLocales(locales);
|
||||
}
|
||||
if (locales == null) {
|
||||
return [];
|
||||
}
|
||||
if (Array.isArray(locales)) {
|
||||
return locales.map(function (locale) {
|
||||
return String(locale);
|
||||
});
|
||||
}
|
||||
return [String(locales)];
|
||||
}
|
||||
|
||||
function defaultLocale() {
|
||||
try {
|
||||
if (typeof global.Intl.DateTimeFormat === "function") {
|
||||
return global.Intl.DateTimeFormat().resolvedOptions().locale;
|
||||
}
|
||||
} catch (e) {}
|
||||
if (typeof navigator !== "undefined" && navigator.language) {
|
||||
return String(navigator.language);
|
||||
}
|
||||
return "en-US";
|
||||
}
|
||||
|
||||
function toStringValue(value) {
|
||||
if (typeof value === "symbol") {
|
||||
throw new TypeError("Cannot convert a Symbol value to a string");
|
||||
}
|
||||
return String(value);
|
||||
}
|
||||
|
||||
function readCodePoint(str, index) {
|
||||
var first = str.charCodeAt(index);
|
||||
if (first >= 0xd800 && first <= 0xdbff && index + 1 < str.length) {
|
||||
var second = str.charCodeAt(index + 1);
|
||||
if (second >= 0xdc00 && second <= 0xdfff) {
|
||||
return {
|
||||
codePoint: ((first - 0xd800) << 10) + (second - 0xdc00) + 0x10000,
|
||||
length: 2,
|
||||
};
|
||||
}
|
||||
}
|
||||
return { codePoint: first, length: 1 };
|
||||
}
|
||||
|
||||
function isCombiningMark(codePoint) {
|
||||
for (var i = 0; i < COMBINING_MARK_RANGES.length; i++) {
|
||||
var range = COMBINING_MARK_RANGES[i];
|
||||
if (codePoint >= range[0] && codePoint <= range[1]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function segmentGrapheme(string) {
|
||||
var segments = [];
|
||||
var i = 0;
|
||||
|
||||
if (unicodeGraphemeRegex) {
|
||||
var match;
|
||||
unicodeGraphemeRegex.lastIndex = 0;
|
||||
while ((match = unicodeGraphemeRegex.exec(string))) {
|
||||
segments.push({
|
||||
segment: match[0],
|
||||
index: match.index,
|
||||
});
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
while (i < string.length) {
|
||||
var start = i;
|
||||
var current = readCodePoint(string, i);
|
||||
i += current.length;
|
||||
while (i < string.length) {
|
||||
var next = readCodePoint(string, i);
|
||||
if (!isCombiningMark(next.codePoint)) {
|
||||
break;
|
||||
}
|
||||
i += next.length;
|
||||
}
|
||||
segments.push({
|
||||
segment: string.slice(start, i),
|
||||
index: start,
|
||||
});
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
function segmentWord(string) {
|
||||
var segments = [];
|
||||
var regex = unicodeWordSplit || FALLBACK_WORD_SPLIT;
|
||||
var match;
|
||||
|
||||
regex.lastIndex = 0;
|
||||
while ((match = regex.exec(string))) {
|
||||
segments.push({
|
||||
segment: match[0],
|
||||
index: match.index,
|
||||
});
|
||||
}
|
||||
return segments;
|
||||
}
|
||||
|
||||
function isSentenceTerminal(ch) {
|
||||
return ch === "." || ch === "!" || ch === "?";
|
||||
}
|
||||
|
||||
function isWhitespaceChar(ch) {
|
||||
return (
|
||||
ch === " " || ch === "\t" || ch === "\r" || ch === "\n" || ch === "\f"
|
||||
);
|
||||
}
|
||||
|
||||
function segmentSentence(string) {
|
||||
var segments = [];
|
||||
var start = 0;
|
||||
var i = 0;
|
||||
|
||||
if (!string) {
|
||||
return segments;
|
||||
}
|
||||
|
||||
while (i < string.length) {
|
||||
if (isSentenceTerminal(string.charAt(i))) {
|
||||
i++;
|
||||
while (i < string.length && isSentenceTerminal(string.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
while (i < string.length && isWhitespaceChar(string.charAt(i))) {
|
||||
i++;
|
||||
}
|
||||
segments.push({
|
||||
segment: string.slice(start, i),
|
||||
index: start,
|
||||
});
|
||||
start = i;
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if (start < string.length) {
|
||||
segments.push({
|
||||
segment: string.slice(start),
|
||||
index: start,
|
||||
});
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
function segmentString(string, granularity) {
|
||||
if (granularity === "word") {
|
||||
return segmentWord(string);
|
||||
}
|
||||
if (granularity === "sentence") {
|
||||
return segmentSentence(string);
|
||||
}
|
||||
return segmentGrapheme(string);
|
||||
}
|
||||
|
||||
function isWordLikeSegment(segment) {
|
||||
if (unicodeWordLike) {
|
||||
return unicodeWordLike.test(segment);
|
||||
}
|
||||
return FALLBACK_WORD_LIKE.test(segment);
|
||||
}
|
||||
|
||||
function requireSegmenter(value) {
|
||||
if (
|
||||
value == null ||
|
||||
(typeof value !== "object" && typeof value !== "function") ||
|
||||
!GRANULARITY_VALUES[value._granularity]
|
||||
) {
|
||||
throw new TypeError(
|
||||
"Method Intl.Segmenter.prototype called on incompatible receiver",
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function SegmentIterator(segments) {
|
||||
this._segments = segments;
|
||||
this._index = 0;
|
||||
}
|
||||
|
||||
SegmentIterator.prototype.next = function () {
|
||||
if (this._index >= this._segments.length) {
|
||||
return { value: undefined, done: true };
|
||||
}
|
||||
var value = this._segments[this._index];
|
||||
this._index += 1;
|
||||
return { value: value, done: false };
|
||||
};
|
||||
|
||||
if (typeof Symbol !== "undefined" && Symbol.iterator) {
|
||||
SegmentIterator.prototype[Symbol.iterator] = function () {
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
function Segments(input, segments) {
|
||||
this._input = input;
|
||||
this._segments = segments;
|
||||
}
|
||||
|
||||
Segments.prototype.containing = function (index) {
|
||||
if (index == null) {
|
||||
return undefined;
|
||||
}
|
||||
var position = Number(index);
|
||||
if (!isFinite(position)) {
|
||||
return undefined;
|
||||
}
|
||||
position = Math.floor(position);
|
||||
for (var i = 0; i < this._segments.length; i++) {
|
||||
var segment = this._segments[i];
|
||||
if (
|
||||
position >= segment.index &&
|
||||
position < segment.index + segment.segment.length
|
||||
) {
|
||||
return segment;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
if (typeof Symbol !== "undefined" && Symbol.iterator) {
|
||||
Segments.prototype[Symbol.iterator] = function () {
|
||||
return new SegmentIterator(this._segments);
|
||||
};
|
||||
}
|
||||
|
||||
function Segmenter(locales, options) {
|
||||
if (!(this instanceof Segmenter)) {
|
||||
throw new TypeError("Intl.Segmenter must be called with new");
|
||||
}
|
||||
|
||||
if (options == null) {
|
||||
options = {};
|
||||
} else if (typeof options !== "object") {
|
||||
options = Object(options);
|
||||
}
|
||||
|
||||
var granularity =
|
||||
options.granularity == null ? "grapheme" : String(options.granularity);
|
||||
if (!GRANULARITY_VALUES[granularity]) {
|
||||
throw new RangeError("Invalid granularity");
|
||||
}
|
||||
if (
|
||||
options.localeMatcher != null &&
|
||||
!LOCALE_MATCHER_VALUES[String(options.localeMatcher)]
|
||||
) {
|
||||
throw new RangeError("Invalid localeMatcher");
|
||||
}
|
||||
|
||||
var localeList = canonicalizeLocales(locales);
|
||||
this._locale = localeList.length ? localeList[0] : defaultLocale();
|
||||
this._granularity = granularity;
|
||||
}
|
||||
|
||||
Segmenter.supportedLocalesOf = function (locales, options) {
|
||||
if (options != null && typeof options === "object") {
|
||||
var localeMatcher = options.localeMatcher;
|
||||
if (
|
||||
localeMatcher != null &&
|
||||
!LOCALE_MATCHER_VALUES[String(localeMatcher)]
|
||||
) {
|
||||
throw new RangeError("Invalid localeMatcher");
|
||||
}
|
||||
}
|
||||
return canonicalizeLocales(locales);
|
||||
};
|
||||
|
||||
Segmenter.prototype.resolvedOptions = function () {
|
||||
var self = requireSegmenter(this);
|
||||
return {
|
||||
locale: self._locale,
|
||||
granularity: self._granularity,
|
||||
};
|
||||
};
|
||||
|
||||
Segmenter.prototype.segment = function (input) {
|
||||
var self = requireSegmenter(this);
|
||||
var string = toStringValue(input);
|
||||
var entries = segmentString(string, self._granularity);
|
||||
var segments = [];
|
||||
|
||||
for (var i = 0; i < entries.length; i++) {
|
||||
var part = entries[i];
|
||||
segments.push({
|
||||
segment: part.segment,
|
||||
index: part.index,
|
||||
input: string,
|
||||
isWordLike:
|
||||
self._granularity === "word"
|
||||
? isWordLikeSegment(part.segment)
|
||||
: undefined,
|
||||
});
|
||||
}
|
||||
|
||||
return new Segments(string, segments);
|
||||
};
|
||||
|
||||
global.Intl.Segmenter = Segmenter;
|
||||
try {
|
||||
global.__internalUserscriptsIntlSegmenterPolyfill = true;
|
||||
} catch (e) {}
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue