mirror of
https://github.com/NohamR/safari-internal-js.git
synced 2026-02-22 02:45:41 +00:00
Add 26.2 versioned JS files and move 15.7 files
This commit is contained in:
30
26.2/js/forms/AutomaticPasswords.js
Normal file
30
26.2/js/forms/AutomaticPasswords.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//# sourceURL=__InjectedScript_AutomaticPasswords.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
"use strict";
|
||||||
|
class AutomaticPasswords {
|
||||||
|
removeAutomaticPasswordElements(t, e, o) {
|
||||||
|
for (let e of t)
|
||||||
|
FormMetadataJS.removeAutomaticStrongPasswordFromPasswordElement(e);
|
||||||
|
if (!o) return;
|
||||||
|
let r = document.activeElement,
|
||||||
|
a = e ? FormMetadataJS.formControlWithUniqueID(e) : null;
|
||||||
|
(a && a.blur(), a && a === r && a.focus());
|
||||||
|
}
|
||||||
|
blurControlWithID(t) {
|
||||||
|
let e = t ? FormMetadataJS.formControlWithUniqueID(t) : null;
|
||||||
|
e && e.blur();
|
||||||
|
}
|
||||||
|
setStrongPasswordElementViewableIfAppropriate(t, e) {
|
||||||
|
for (let o of t) {
|
||||||
|
let t = FormMetadataJS.formControlWithUniqueID(o);
|
||||||
|
if (!t) return;
|
||||||
|
if ("text" === t.type)
|
||||||
|
return (
|
||||||
|
FormMetadataJSController.setInputElementAutoFilledAndViewable(t, !1),
|
||||||
|
void FormMetadataJSController.setInputElementAutofilled(t, !1)
|
||||||
|
);
|
||||||
|
FormMetadataJSController.setInputElementAutoFilledAndViewable(t, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var AutomaticPasswordsJS = new AutomaticPasswords();
|
||||||
5188
26.2/js/forms/FormMetadata.js
Normal file
5188
26.2/js/forms/FormMetadata.js
Normal file
File diff suppressed because it is too large
Load Diff
674
26.2/js/forms/FormMetadataClassification.js
Normal file
674
26.2/js/forms/FormMetadataClassification.js
Normal file
@@ -0,0 +1,674 @@
|
|||||||
|
//# sourceURL=__InjectedScript_FormMetadataClassification.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
"use strict";
|
||||||
|
function datePlaceholderParser(e) {
|
||||||
|
for (const t of e) {
|
||||||
|
const e = t.toLowerCase();
|
||||||
|
if (e >= "a" && e <= "z" && !["d", "y", "m"].includes(e)) return null;
|
||||||
|
}
|
||||||
|
return e.includes("d")
|
||||||
|
? e.includes("yyyy")
|
||||||
|
? { year: "numeric", month: "2-digit", day: "2-digit" }
|
||||||
|
: { year: "2-digit", month: "2-digit", day: "2-digit" }
|
||||||
|
: e.includes("M")
|
||||||
|
? e.includes("yyyy")
|
||||||
|
? { year: "numeric", month: "2-digit" }
|
||||||
|
: { year: "2-digit", month: "2-digit" }
|
||||||
|
: e.includes("y")
|
||||||
|
? e.includes("yyyy")
|
||||||
|
? { year: "numeric" }
|
||||||
|
: { year: "2-digit" }
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
function referenceDateToDateFormat(e) {
|
||||||
|
let t = e.replace("12", "MM");
|
||||||
|
return (
|
||||||
|
(t = t.replace("30", "dd")),
|
||||||
|
(t = t.replace("1999", "y")),
|
||||||
|
(t = t.replace("99", "yy")),
|
||||||
|
t
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const WBSABAddressProperty = "Address",
|
||||||
|
WBSABPhoneProperty = "Phone",
|
||||||
|
_WBSABAddressZIPKey = "ZIP",
|
||||||
|
WBSFormControlMetadataDefaultMaxLength = 524288,
|
||||||
|
WBSIgnoredClassificationToken = "-sf-ignored",
|
||||||
|
WBSDateDayOrderedPartToken = "-sf-day",
|
||||||
|
WBSDateMonthOrderedPartToken = "-sf-month",
|
||||||
|
WBSDateYearOrderedPartToken = "-sf-year",
|
||||||
|
WBSGivenNameOrderedPartToken = "given-name",
|
||||||
|
WBSAdditionalNameOrderedPartToken = "additional-name",
|
||||||
|
WBSFamilyNameOrderedPartToken = "family-name",
|
||||||
|
WBSLocaleForCreditCardExpirationDate = "en-US-POSIX",
|
||||||
|
WBSCreditCardTypeClassificationToken = "cc-type",
|
||||||
|
WBSCreditCardHolderNameClassificationToken = "cc-name",
|
||||||
|
WBSCreditCardNumberClassificationToken = "cc-number",
|
||||||
|
WBSCreditCardExpirationClassificationToken = "cc-exp",
|
||||||
|
WBSCreditCardSecurityCodeClassificationToken = "cc-csc",
|
||||||
|
WBSCreditCardHolderNameClassificationDefaultOrderedParts = [
|
||||||
|
WBSGivenNameOrderedPartToken,
|
||||||
|
WBSAdditionalNameOrderedPartToken,
|
||||||
|
WBSFamilyNameOrderedPartToken,
|
||||||
|
],
|
||||||
|
WBSCreditCardExpirationClassificationDefaultOrderedParts = [
|
||||||
|
WBSDateMonthOrderedPartToken,
|
||||||
|
WBSDateYearOrderedPartToken,
|
||||||
|
],
|
||||||
|
WBSCredentialUsernameClassificationToken = "username",
|
||||||
|
WBSCredentialCurrentPasswordClassificationToken = "current-password",
|
||||||
|
WBSCredentialNewPasswordClassificationToken = "new-password",
|
||||||
|
WBSContactNameClassificationToken = "name",
|
||||||
|
WBSContactNameClassificationDefaultOrderedParts = [
|
||||||
|
WBSGivenNameOrderedPartToken,
|
||||||
|
WBSAdditionalNameOrderedPartToken,
|
||||||
|
WBSFamilyNameOrderedPartToken,
|
||||||
|
],
|
||||||
|
WBSNameOrderedPartTokensSet = new Set(
|
||||||
|
WBSContactNameClassificationDefaultOrderedParts,
|
||||||
|
),
|
||||||
|
WBSContactInstantMessageClassificationToken = "-sf-instant-message",
|
||||||
|
WBSContactPostalCodeClassificationToken = "postal-code",
|
||||||
|
WBSContactStreetAddressClassificationToken = "street-address",
|
||||||
|
WBSContactStreetAddressLine1OrderedPartToken = "address-line1",
|
||||||
|
WBSContactStreetAddressLine2OrderedPartToken = "address-line2",
|
||||||
|
WBSContactStreetAddressLine3OrderedPartToken = "address-line3",
|
||||||
|
WBSContactTelephoneClassificationToken = "tel",
|
||||||
|
WBSTelephoneCountryCodeOrderedPartToken = "tel-country-code",
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken = "tel-area-code",
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken = "tel-local-prefix",
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken = "tel-local-suffix",
|
||||||
|
WBSTelephoneExtensionOrderedPartToken = "tel-extension",
|
||||||
|
WBSTelephoneDefaultOrderedParts = [
|
||||||
|
WBSTelephoneCountryCodeOrderedPartToken,
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken,
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken,
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken,
|
||||||
|
WBSTelephoneExtensionOrderedPartToken,
|
||||||
|
],
|
||||||
|
WBSContactBirthdayClassificationToken = "bday",
|
||||||
|
WBSContactEmailClassificationToken = "email",
|
||||||
|
WBSDeviceEIDClassificationToken = "device-eid",
|
||||||
|
WBSDeviceIMEIClassificationToken = "device-imei",
|
||||||
|
AllowedControlTagsForStandaloneCreditCardCompositeExpirationControl = new Set(
|
||||||
|
["input", "select", "textarea"],
|
||||||
|
);
|
||||||
|
class FormMetadataClassification {
|
||||||
|
#e(e) {
|
||||||
|
return null != e && "object" == typeof e;
|
||||||
|
}
|
||||||
|
#t(e) {
|
||||||
|
return this.#e(e) && "string" == typeof e.ControlTagName;
|
||||||
|
}
|
||||||
|
#o(e) {
|
||||||
|
return this.#e(e) && "string" == typeof e.property;
|
||||||
|
}
|
||||||
|
fieldLooksLikeDateField(e) {
|
||||||
|
return !!(
|
||||||
|
e.ControlLooksLikeDayField ||
|
||||||
|
e.ControlLooksLikeMonthField ||
|
||||||
|
e.ControlLooksLikeYearField
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#r(e) {
|
||||||
|
let t = e.ControlMaxLength;
|
||||||
|
return (
|
||||||
|
(void 0 === t || t < 0 || t > WBSFormControlMetadataDefaultMaxLength) &&
|
||||||
|
(t = WBSFormControlMetadataDefaultMaxLength),
|
||||||
|
t
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fieldLooksLikeItExpectsDataOfSize(e, t) {
|
||||||
|
return (e.ControlSize ?? 0) <= t || this.#r(e) <= t;
|
||||||
|
}
|
||||||
|
fieldCouldBeCreditCardNumberContinuation(e, t) {
|
||||||
|
const o = 4;
|
||||||
|
if (t.length >= o) return !1;
|
||||||
|
if (!t[0]?.ControlLooksLikeCreditCardNumberField) return !1;
|
||||||
|
const r = 2;
|
||||||
|
if (e.ControlMaxLength === r) return !1;
|
||||||
|
if (e.ControlLooksLikeCreditCardNumberField) return !0;
|
||||||
|
if (e.ControlLooksLikeCreditCardSecurityCodeField) return !1;
|
||||||
|
if (e.ControlLooksLikeCreditCardCompositeExpirationDateField) return !1;
|
||||||
|
const n = 6;
|
||||||
|
if (!this.fieldLooksLikeItExpectsDataOfSize(e, n)) return !1;
|
||||||
|
const i = t.at(-1);
|
||||||
|
return !(i && !this.fieldLooksLikeItExpectsDataOfSize(i, n));
|
||||||
|
}
|
||||||
|
labelsCouldRepresentContinuation(e, t, o, r) {
|
||||||
|
return (
|
||||||
|
!(!e || !o) &&
|
||||||
|
(e === o ||
|
||||||
|
(!!t &&
|
||||||
|
(!r ||
|
||||||
|
(t.property === r.property &&
|
||||||
|
(!r.component || t.component === r.component)))))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#n(e) {
|
||||||
|
const t = [
|
||||||
|
WBSContactStreetAddressLine1OrderedPartToken,
|
||||||
|
WBSContactStreetAddressLine2OrderedPartToken,
|
||||||
|
WBSContactStreetAddressLine3OrderedPartToken,
|
||||||
|
],
|
||||||
|
o = [
|
||||||
|
WBSContactStreetAddressLine2OrderedPartToken,
|
||||||
|
WBSContactStreetAddressLine3OrderedPartToken,
|
||||||
|
];
|
||||||
|
if (e.AutocompleteTokens)
|
||||||
|
for (let o of e.AutocompleteTokens)
|
||||||
|
switch (o) {
|
||||||
|
case "street-address":
|
||||||
|
return t;
|
||||||
|
case "address-line1":
|
||||||
|
return [WBSContactStreetAddressLine1OrderedPartToken];
|
||||||
|
case "address-line2":
|
||||||
|
case "address-level2":
|
||||||
|
return [WBSContactStreetAddressLine2OrderedPartToken];
|
||||||
|
case "address-line3":
|
||||||
|
case "address-level1":
|
||||||
|
return [WBSContactStreetAddressLine3OrderedPartToken];
|
||||||
|
}
|
||||||
|
let r = e.ControlFieldName,
|
||||||
|
n = r?.indexOf("1") ?? -1,
|
||||||
|
i = r?.indexOf("2") ?? -1;
|
||||||
|
return -1 === n
|
||||||
|
? -1 === i
|
||||||
|
? t
|
||||||
|
: o
|
||||||
|
: -1 === i || n < i
|
||||||
|
? [WBSContactStreetAddressLine1OrderedPartToken]
|
||||||
|
: o;
|
||||||
|
}
|
||||||
|
fieldCouldBePhoneNumberContinuation(e, t) {
|
||||||
|
const o = 5;
|
||||||
|
if (t.length >= o) return !1;
|
||||||
|
if (t[0]?.AddressBookValueSpecifier?.property !== WBSABPhoneProperty)
|
||||||
|
return !1;
|
||||||
|
const r = 5;
|
||||||
|
return !!this.fieldLooksLikeItExpectsDataOfSize(e, r);
|
||||||
|
}
|
||||||
|
fieldCouldBePostCodeContinuation(e, t) {
|
||||||
|
const o = 3;
|
||||||
|
if (t.length >= o) return !1;
|
||||||
|
if (t[0]?.AddressBookValueSpecifier?.component != _WBSABAddressZIPKey)
|
||||||
|
return !1;
|
||||||
|
const r = 6;
|
||||||
|
return !!this.fieldLooksLikeItExpectsDataOfSize(e, r);
|
||||||
|
}
|
||||||
|
fieldLooksLikeSameDataType(e, t) {
|
||||||
|
const o = t.at(-1);
|
||||||
|
return (
|
||||||
|
!!this.labelsCouldRepresentContinuation(
|
||||||
|
o?.AddressBookLabel,
|
||||||
|
o?.AddressBookValueSpecifier,
|
||||||
|
e?.AddressBookLabel,
|
||||||
|
e?.AddressBookValueSpecifier,
|
||||||
|
) ||
|
||||||
|
!!(
|
||||||
|
o &&
|
||||||
|
this.fieldLooksLikeDateField(o) &&
|
||||||
|
this.fieldLooksLikeDateField(e)
|
||||||
|
) ||
|
||||||
|
!!this.fieldCouldBePhoneNumberContinuation(e, t) ||
|
||||||
|
!!this.fieldCouldBePostCodeContinuation(e, t) ||
|
||||||
|
!!this.fieldCouldBeCreditCardNumberContinuation(e, t)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#i(e) {
|
||||||
|
if (
|
||||||
|
(globalThis.DOMRect ||
|
||||||
|
(globalThis.DOMRect = class {
|
||||||
|
constructor(e, t, o, r) {
|
||||||
|
((this.left = e),
|
||||||
|
(this.right = e + o),
|
||||||
|
(this.top = t),
|
||||||
|
(this.bottom = t + r),
|
||||||
|
(this.width = o),
|
||||||
|
(this.height = r));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
e.ControlRectLeft ||
|
||||||
|
e.ControlRectTop ||
|
||||||
|
e.ControlRectWidth ||
|
||||||
|
e.ControlRectHeight)
|
||||||
|
)
|
||||||
|
return new DOMRect(
|
||||||
|
e.ControlRectLeft,
|
||||||
|
e.ControlRectTop,
|
||||||
|
e.ControlRectWidth,
|
||||||
|
e.ControlRectHeight,
|
||||||
|
);
|
||||||
|
let t = globalThis.FormMetadataJS?.formControlWithUniqueID(
|
||||||
|
e.ControlUniqueID,
|
||||||
|
);
|
||||||
|
return t ? t.getBoundingClientRect() : new DOMRect(0, 0, 0, 0);
|
||||||
|
}
|
||||||
|
fieldLooksLikeContinuation(e, t, o) {
|
||||||
|
if (!e.ControlIsTextField && "SELECT" !== e.ControlTagName.toUpperCase())
|
||||||
|
return !1;
|
||||||
|
if (!this.fieldLooksLikeSameDataType(e, t)) return !1;
|
||||||
|
if (o) return !0;
|
||||||
|
const r = this.#i(t.at(-1)),
|
||||||
|
n = this.#i(e);
|
||||||
|
if (Math.abs(r.top - n.top) > 3) return !1;
|
||||||
|
let i, a;
|
||||||
|
return (
|
||||||
|
r.left < n.left ? ((i = r), (a = n)) : ((i = n), (a = r)),
|
||||||
|
!(a.left - i.right > 60)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
continuingFieldsInFormControls(e, t, o, r) {
|
||||||
|
const n = [e[t]];
|
||||||
|
for (let i = t + 1; i < e.length; ++i) {
|
||||||
|
const t = e[i];
|
||||||
|
if (o && !t.ControlIsTextField) break;
|
||||||
|
if (!this.fieldLooksLikeContinuation(t, n, r)) break;
|
||||||
|
n.push(t);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
classifyControlsRelatedToNameParts(e, t, o) {
|
||||||
|
const r = e[t];
|
||||||
|
((r.ControlClassification = o),
|
||||||
|
(r.ControlOrderedParts = [r.AddressBookValueSpecifier?.classification]));
|
||||||
|
const n = new Set([r.AddressBookValueSpecifier?.classification]),
|
||||||
|
i = [e[t]];
|
||||||
|
for (let r = t + 1; r < e.length; ++r) {
|
||||||
|
const t = e[r];
|
||||||
|
if (!t.ControlIsTextField) break;
|
||||||
|
const a = t.AddressBookValueSpecifier?.classification;
|
||||||
|
if (!a) break;
|
||||||
|
if (!WBSNameOrderedPartTokensSet.has(a) || n.has(a)) break;
|
||||||
|
((t.ControlClassification = o),
|
||||||
|
(t.ControlOrderedParts = [a]),
|
||||||
|
n.add(a),
|
||||||
|
i.push(t));
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
identifyDateFields(e) {
|
||||||
|
let t,
|
||||||
|
o,
|
||||||
|
r,
|
||||||
|
n = !1;
|
||||||
|
for (let i of e)
|
||||||
|
if (i.ControlLooksLikeDayField) {
|
||||||
|
if (t) return [!1, null, null, null];
|
||||||
|
((t = i), (n = !0));
|
||||||
|
} else if (i.ControlLooksLikeMonthField) {
|
||||||
|
if (o) return [!1, null, null, null];
|
||||||
|
((o = i), (n = !0));
|
||||||
|
} else if (i.ControlLooksLikeYearField) {
|
||||||
|
if (r) return [!1, null, null, null];
|
||||||
|
((r = i), (n = !0));
|
||||||
|
}
|
||||||
|
return [n, r, o, t];
|
||||||
|
}
|
||||||
|
canonicalizedDateTemplate(e) {
|
||||||
|
if (e && (e = e.replace(/\s/g, "")).length && !/[^dmyDMY\/.-]/g.test(e))
|
||||||
|
return (e = (e = (e = e.replace(/D/g, "d")).replace(/m/g, "M")).replace(
|
||||||
|
/Y/g,
|
||||||
|
"y",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
classifyDateFields(e, t, o, r, n, i, a) {
|
||||||
|
if (e.length > 3) return !1;
|
||||||
|
if ((a || (a = navigator.language), 1 === e.length)) {
|
||||||
|
if (!e[0].ControlIsTextField) return !1;
|
||||||
|
let i = e[0].ControlRequiredFormatForDateTimeInput;
|
||||||
|
if (!i) {
|
||||||
|
const t = new Date(1999, 11, 30);
|
||||||
|
let o = this.#r(e[0]),
|
||||||
|
r = this.canonicalizedDateTemplate(e[0].ControlPlaceholder),
|
||||||
|
s = "";
|
||||||
|
if (r?.length) {
|
||||||
|
const e = datePlaceholderParser(r);
|
||||||
|
e &&
|
||||||
|
((s = new Intl.DateTimeFormat(a, e).format(t)),
|
||||||
|
(i = referenceDateToDateFormat(s)));
|
||||||
|
}
|
||||||
|
if (!s || s.length > o) {
|
||||||
|
const e = n
|
||||||
|
? [
|
||||||
|
{ year: "numeric", month: "2-digit", day: "2-digit" },
|
||||||
|
{ year: "2-digit", month: "2-digit", day: "2-digit" },
|
||||||
|
]
|
||||||
|
: [{ year: "2-digit", month: "2-digit" }];
|
||||||
|
for (const r of e)
|
||||||
|
if (
|
||||||
|
((s = new Intl.DateTimeFormat(a, r).format(t)),
|
||||||
|
(i = referenceDateToDateFormat(s)),
|
||||||
|
s.length <= o)
|
||||||
|
)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (s.length > o) return !1;
|
||||||
|
}
|
||||||
|
const s = [];
|
||||||
|
for (const e of i) {
|
||||||
|
let t;
|
||||||
|
("y" === e ? (t = o) : "M" === e ? (t = r) : "d" === e && (t = n),
|
||||||
|
t && !s.includes(t) && s.push(t));
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(e[0].ControlClassification = t),
|
||||||
|
(e[0].ControlOrderedParts = s),
|
||||||
|
(e[0].ControlRequiredFormatForDateTimeInput = i),
|
||||||
|
!0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let [s, l, d, C] = this.identifyDateFields(e);
|
||||||
|
if (!s) return !1;
|
||||||
|
if (C && !d) return !1;
|
||||||
|
let c = 0;
|
||||||
|
for (const a of e)
|
||||||
|
((a.ControlClassification = t),
|
||||||
|
(a.ControlContinuationID = i),
|
||||||
|
(a.ControlContinuationIndex = c++),
|
||||||
|
a === C
|
||||||
|
? (a.ControlOrderedParts = [n])
|
||||||
|
: a === d
|
||||||
|
? (a.ControlOrderedParts = [r])
|
||||||
|
: a === l && (a.ControlOrderedParts = [o]));
|
||||||
|
return !0;
|
||||||
|
}
|
||||||
|
classify(e) {
|
||||||
|
const t = e.FormControls,
|
||||||
|
o = t.length,
|
||||||
|
r = e.AutoFillFormType === WBSAutoFillFormTypeNewAccount,
|
||||||
|
n = e.AutoFillFormType === WBSAutoFillFormTypeChangePassword,
|
||||||
|
i = e.UsernameElementUniqueID,
|
||||||
|
a = e.PasswordElementUniqueID,
|
||||||
|
s = e.OldPasswordElementUniqueID,
|
||||||
|
l = e.ConfirmPasswordElementUniqueID;
|
||||||
|
for (let e of t)
|
||||||
|
(e.AutocompleteTokens || e.AddressBookLabel) &&
|
||||||
|
(e.AddressBookValueSpecifier =
|
||||||
|
FormMetadataJSController.specifierForAutocompleteTokensAndAddressBookLabel(
|
||||||
|
e.AutocompleteTokens,
|
||||||
|
e.AddressBookLabel,
|
||||||
|
));
|
||||||
|
let d = !1,
|
||||||
|
C = !1,
|
||||||
|
c = !1,
|
||||||
|
f = !1,
|
||||||
|
u = !1,
|
||||||
|
k = 0;
|
||||||
|
for (let S = 0, T = 1; S < o; S += T, T = 1) {
|
||||||
|
const o = t[S];
|
||||||
|
if (o.ControlLooksLikeIgnoredDataTypeField) {
|
||||||
|
o.ControlClassification = WBSIgnoredClassificationToken;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const h = o.ControlUniqueID;
|
||||||
|
if (h === a || h === l) {
|
||||||
|
o.ControlClassification =
|
||||||
|
r || n
|
||||||
|
? WBSCredentialNewPasswordClassificationToken
|
||||||
|
: WBSCredentialCurrentPasswordClassificationToken;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (h === s) {
|
||||||
|
o.ControlClassification =
|
||||||
|
WBSCredentialCurrentPasswordClassificationToken;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const B = o.AddressBookValueSpecifier?.classification;
|
||||||
|
if (B === WBSContactEmailClassificationToken) {
|
||||||
|
o.ControlClassification = WBSContactEmailClassificationToken;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (h === i) {
|
||||||
|
o.ControlClassification = WBSCredentialUsernameClassificationToken;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!C && o.ControlLooksLikeCreditCardCardholderField) {
|
||||||
|
if (((C = !0), B && WBSNameOrderedPartTokensSet.has(B))) {
|
||||||
|
const e = this.classifyControlsRelatedToNameParts(
|
||||||
|
t,
|
||||||
|
S,
|
||||||
|
WBSCreditCardHolderNameClassificationToken,
|
||||||
|
);
|
||||||
|
if (e.length > 1) {
|
||||||
|
let t = ++k,
|
||||||
|
o = 0;
|
||||||
|
for (let r of e)
|
||||||
|
((r.ControlContinuationID = t),
|
||||||
|
(r.ControlContinuationIndex = o++));
|
||||||
|
}
|
||||||
|
T = e.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
((o.ControlClassification = WBSCreditCardHolderNameClassificationToken),
|
||||||
|
(o.ControlOrderedParts =
|
||||||
|
WBSCreditCardHolderNameClassificationDefaultOrderedParts));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!d && o.ControlLooksLikeCreditCardNumberField) {
|
||||||
|
d = !0;
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !0, !1);
|
||||||
|
let o = 0,
|
||||||
|
r = e.length > 1 ? ++k : 0;
|
||||||
|
for (let t of e)
|
||||||
|
((t.ControlClassification = WBSCreditCardNumberClassificationToken),
|
||||||
|
(t.ControlContinuationID = r),
|
||||||
|
(t.ControlContinuationIndex = o++));
|
||||||
|
T = e.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const P =
|
||||||
|
this.fieldLooksLikeDateField(o) ||
|
||||||
|
o.ControlLooksLikeCreditCardCompositeExpirationDateField;
|
||||||
|
if (!c && P) {
|
||||||
|
let e = f || C || d;
|
||||||
|
if (
|
||||||
|
((e ||=
|
||||||
|
!o.ControlLooksLikeOneTimeCodeField &&
|
||||||
|
1 ===
|
||||||
|
t.filter((e) =>
|
||||||
|
AllowedControlTagsForStandaloneCreditCardCompositeExpirationControl.has(
|
||||||
|
e.ControlTagName.toLowerCase(),
|
||||||
|
),
|
||||||
|
).length),
|
||||||
|
e)
|
||||||
|
) {
|
||||||
|
c = !0;
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !1, !0);
|
||||||
|
let o = e.length > 1 ? ++k : 0;
|
||||||
|
(this.classifyDateFields(
|
||||||
|
e,
|
||||||
|
WBSCreditCardExpirationClassificationToken,
|
||||||
|
WBSDateYearOrderedPartToken,
|
||||||
|
WBSDateMonthOrderedPartToken,
|
||||||
|
void 0,
|
||||||
|
o,
|
||||||
|
WBSLocaleForCreditCardExpirationDate,
|
||||||
|
),
|
||||||
|
(T = e.length));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (u || !o.ControlLooksLikeCreditCardSecurityCodeField)
|
||||||
|
if (f || !o.ControlLooksLikeCreditCardTypeField)
|
||||||
|
if (B) {
|
||||||
|
const r = o.AddressBookValueSpecifier.classificationHint;
|
||||||
|
if (B === WBSContactNameClassificationToken) {
|
||||||
|
((o.ControlClassification = B),
|
||||||
|
(o.ControlOrderedParts =
|
||||||
|
WBSContactNameClassificationDefaultOrderedParts));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (WBSNameOrderedPartTokensSet.has(B)) {
|
||||||
|
const e = this.classifyControlsRelatedToNameParts(
|
||||||
|
t,
|
||||||
|
S,
|
||||||
|
WBSContactNameClassificationToken,
|
||||||
|
);
|
||||||
|
if (e.length > 1) {
|
||||||
|
let t = ++k,
|
||||||
|
o = 0;
|
||||||
|
for (let r of e)
|
||||||
|
((r.ControlContinuationID = t),
|
||||||
|
(r.ControlContinuationIndex = o++));
|
||||||
|
}
|
||||||
|
T = e.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (B === WBSContactPostalCodeClassificationToken) {
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !0, !1);
|
||||||
|
let o = e.length > 1 ? ++k : 0,
|
||||||
|
r = 0;
|
||||||
|
for (let t of e)
|
||||||
|
((t.ControlClassification =
|
||||||
|
WBSContactPostalCodeClassificationToken),
|
||||||
|
(t.ControlContinuationID = o),
|
||||||
|
(t.ControlContinuationIndex = r++));
|
||||||
|
T = e.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (B === WBSContactStreetAddressClassificationToken) {
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !0, !0);
|
||||||
|
let o = e.length > 1 ? ++k : 0,
|
||||||
|
r = 0;
|
||||||
|
for (let t of e)
|
||||||
|
((t.ControlClassification =
|
||||||
|
WBSContactStreetAddressClassificationToken),
|
||||||
|
(t.ControlContinuationID = o),
|
||||||
|
(t.ControlContinuationIndex = r++));
|
||||||
|
if (1 === e.length) {
|
||||||
|
let t = e[0];
|
||||||
|
t.ControlOrderedParts = this.#n(t);
|
||||||
|
} else
|
||||||
|
2 === e.length
|
||||||
|
? ((e[0].ControlOrderedParts = [
|
||||||
|
WBSContactStreetAddressLine1OrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSContactStreetAddressLine2OrderedPartToken,
|
||||||
|
WBSContactStreetAddressLine3OrderedPartToken,
|
||||||
|
]))
|
||||||
|
: e.length >= 3 &&
|
||||||
|
((e[0].ControlOrderedParts = [
|
||||||
|
WBSContactStreetAddressLine1OrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSContactStreetAddressLine2OrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[2].ControlOrderedParts = [
|
||||||
|
WBSContactStreetAddressLine3OrderedPartToken,
|
||||||
|
]));
|
||||||
|
T = e.length;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (B === WBSContactInstantMessageClassificationToken) {
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !0, !0);
|
||||||
|
(1 === e.length &&
|
||||||
|
((e[0].ControlClassification =
|
||||||
|
WBSContactInstantMessageClassificationToken),
|
||||||
|
r && (e[0].ControlClassificationHints = [r])),
|
||||||
|
(T = e.length));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (B.startsWith(WBSContactTelephoneClassificationToken)) {
|
||||||
|
const e = this.continuingFieldsInFormControls(t, S, !0, !1);
|
||||||
|
if (1 == e.length) {
|
||||||
|
((e[0].ControlClassification =
|
||||||
|
WBSContactTelephoneClassificationToken),
|
||||||
|
(e[0].ControlOrderedParts = WBSTelephoneDefaultOrderedParts),
|
||||||
|
r && (e[0].ControlClassificationHints = [r]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let o = ++k,
|
||||||
|
n = 0;
|
||||||
|
for (let t of e)
|
||||||
|
((t.ControlClassification =
|
||||||
|
WBSContactTelephoneClassificationToken),
|
||||||
|
(t.ControlContinuationID = o),
|
||||||
|
(t.ControlContinuationIndex = n++),
|
||||||
|
r && (t.ControlClassificationHints = [r]));
|
||||||
|
(2 === e.length
|
||||||
|
? ((e[0].ControlOrderedParts = [
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken,
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken,
|
||||||
|
]))
|
||||||
|
: 3 === e.length
|
||||||
|
? ((e[0].ControlOrderedParts = [
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[2].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken,
|
||||||
|
]))
|
||||||
|
: 4 === e.length
|
||||||
|
? ((e[0].ControlOrderedParts = [
|
||||||
|
WBSTelephoneCountryCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[2].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[3].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken,
|
||||||
|
]))
|
||||||
|
: ((e[0].ControlOrderedParts = [
|
||||||
|
WBSTelephoneCountryCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[1].ControlOrderedParts = [
|
||||||
|
WBSTelephoneAreaCodeOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[2].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalPrefixOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[3].ControlOrderedParts = [
|
||||||
|
WBSTelephoneLocalSuffixOrderedPartToken,
|
||||||
|
]),
|
||||||
|
(e[4].ControlOrderedParts = [
|
||||||
|
WBSTelephoneExtensionOrderedPartToken,
|
||||||
|
])),
|
||||||
|
(T = e.length));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (B === WBSContactBirthdayClassificationToken) {
|
||||||
|
const o = this.continuingFieldsInFormControls(t, S, !1, !1),
|
||||||
|
r = o.length > 1 ? ++k : void 0,
|
||||||
|
n =
|
||||||
|
e.RequestType === WBSFormMetadataRequestTesting
|
||||||
|
? "en-US"
|
||||||
|
: void 0;
|
||||||
|
(this.classifyDateFields(
|
||||||
|
o,
|
||||||
|
WBSContactBirthdayClassificationToken,
|
||||||
|
WBSDateYearOrderedPartToken,
|
||||||
|
WBSDateMonthOrderedPartToken,
|
||||||
|
WBSDateDayOrderedPartToken,
|
||||||
|
r,
|
||||||
|
n,
|
||||||
|
),
|
||||||
|
(T = o.length));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
o.ControlClassification = B;
|
||||||
|
} else
|
||||||
|
o.ControlLooksLikeEIDField
|
||||||
|
? (o.ControlClassification = WBSDeviceEIDClassificationToken)
|
||||||
|
: o.ControlLooksLikeIMEIField &&
|
||||||
|
(o.ControlClassification = WBSDeviceIMEIClassificationToken);
|
||||||
|
else
|
||||||
|
((f = !0),
|
||||||
|
(o.ControlClassification = WBSCreditCardTypeClassificationToken));
|
||||||
|
else
|
||||||
|
((u = !0),
|
||||||
|
(o.ControlClassification =
|
||||||
|
WBSCreditCardSecurityCodeClassificationToken));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
globalThis.FormMetadataClassificationJS = new FormMetadataClassification();
|
||||||
9051
26.2/js/forms/FormMetadataContactsAutoFillMappings.js
Normal file
9051
26.2/js/forms/FormMetadataContactsAutoFillMappings.js
Normal file
File diff suppressed because it is too large
Load Diff
617
26.2/js/forms/FormMetadataJSController.js
Normal file
617
26.2/js/forms/FormMetadataJSController.js
Normal file
@@ -0,0 +1,617 @@
|
|||||||
|
//# sourceURL=__InjectedScript_FormMetadataJSController.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
"use strict";
|
||||||
|
function addGlobalEventHandler(e, t) {
|
||||||
|
function* a(e) {
|
||||||
|
const t = document.createTreeWalker(
|
||||||
|
e,
|
||||||
|
NodeFilter.SHOW_ELEMENT,
|
||||||
|
function (e) {
|
||||||
|
return e.shadowRoot
|
||||||
|
? "user-agent" === e.shadowRoot.mode
|
||||||
|
? NodeFilter.FILTER_REJECT
|
||||||
|
: NodeFilter.FILTER_ACCEPT
|
||||||
|
: NodeFilter.FILTER_SKIP;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
for (; t.nextNode(); ) {
|
||||||
|
const e = t.currentNode;
|
||||||
|
(yield* a(e.shadowRoot), yield e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const o = "focus" === e || "blur" === e,
|
||||||
|
r = (() => {
|
||||||
|
switch (e) {
|
||||||
|
case "focus":
|
||||||
|
case "blur":
|
||||||
|
case "input":
|
||||||
|
return !0;
|
||||||
|
case "submit":
|
||||||
|
case "webkitassociateformcontrols":
|
||||||
|
return !1;
|
||||||
|
default:
|
||||||
|
throw new Error(`uncategorized event ${e}. Please categorize it`);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
let l = t;
|
||||||
|
if (
|
||||||
|
(o &&
|
||||||
|
(l = function (e) {
|
||||||
|
e.target === e.composedPath()[0] && t(e);
|
||||||
|
}),
|
||||||
|
window.addEventListener(e, t, { capture: !0 }),
|
||||||
|
!r || o)
|
||||||
|
) {
|
||||||
|
for (const t of a(document.documentElement))
|
||||||
|
t.shadowRoot.addEventListener(e, l, { capture: !0 });
|
||||||
|
window.addEventListener("webkitshadowrootattached", function (t) {
|
||||||
|
t.composedPath()[0].shadowRoot.addEventListener(e, l, { capture: !0 });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const WBSMinimumLogicalWidthToShowManualAutoFillButton = 100;
|
||||||
|
class FormMetadataFieldPatternMatcher {
|
||||||
|
searchRegularExpression;
|
||||||
|
constructor(e, t = !1) {
|
||||||
|
const a = (Array.isArray(e) ? e : Object.keys(e))
|
||||||
|
.toSorted((e, t) => t.length - e.length)
|
||||||
|
.map(RegExp.escape),
|
||||||
|
o = "(?=(\\W|$))",
|
||||||
|
r = "(?<=(\\W|^))";
|
||||||
|
this.searchRegularExpression = t
|
||||||
|
? new RegExp("(?:" + a.join("|") + ")" + o, "ig")
|
||||||
|
: new RegExp(r + "(?:" + a.join("|") + ")" + o, "ig");
|
||||||
|
}
|
||||||
|
longestMatch(e) {
|
||||||
|
const t = e.match(this.searchRegularExpression);
|
||||||
|
if (!t) return null;
|
||||||
|
let a = "";
|
||||||
|
for (const e of t) e.length > a.length && (a = e);
|
||||||
|
if (!a) return null;
|
||||||
|
const o = fieldLabelMap[a.toLowerCase()];
|
||||||
|
if (!o) return [a, "", "", ""];
|
||||||
|
const r = o.valueSpecifier;
|
||||||
|
return [a, r.property, r.category, r.parentProperty];
|
||||||
|
}
|
||||||
|
searchReverse(e) {
|
||||||
|
const t = e.match(this.searchRegularExpression);
|
||||||
|
if (!t) return null;
|
||||||
|
const a = t.at(-1);
|
||||||
|
if (!a) return null;
|
||||||
|
const o = fieldLabelMap[a.toLowerCase()];
|
||||||
|
if (!o) return [a, "", "", ""];
|
||||||
|
const r = o.valueSpecifier;
|
||||||
|
return [a, r.property, r.category, r.parentProperty];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class FormMetadataJSController {
|
||||||
|
static isDebugConsoleLoggingEnabled =
|
||||||
|
AutoFillControllerConfig.isDebugConsoleLoggingEnabled;
|
||||||
|
static _nextControlUniqueID = 1;
|
||||||
|
static get nextControlUniqueID() {
|
||||||
|
return this._nextControlUniqueID++;
|
||||||
|
}
|
||||||
|
static _nextFormUniqueID = 1;
|
||||||
|
static get nextFormUniqueID() {
|
||||||
|
return this._nextFormUniqueID++;
|
||||||
|
}
|
||||||
|
static regularExpressionsIndicatingNonAutoFillableFormType =
|
||||||
|
FormAutoFillKeywords.NonAutoFillableFormTypeRegularExpressions;
|
||||||
|
static loginFormTypePatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.LoginFormTypeKeywords,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static oneTimeCodeFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.OneTimeCodeFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static nonAccountPasswordSecureTextEntryFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.NonAccountPasswordSecureTextEntryFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static ignoredDataTypeFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.IgnoredDataTypeFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static oldPasswordFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.OldPasswordFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static confirmPasswordFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.ConfirmPasswordFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static confirmEmailFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.ConfirmEmailFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static showHideButtonLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.ShowHideButtonLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static searchFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(FormAutoFillKeywords.SearchFieldLabels),
|
||||||
|
];
|
||||||
|
static nonUsernameFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.NonUsernameFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static passwordFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.PasswordFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static usernameFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.UsernameFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static nonEmailFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.NonEmailFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static weakOneTimeCodeFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.WeakOneTimeCodeFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static codeButNotOneTimeCodeFieldLabelsPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.CodeButNotOneTimeCodeFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static dayFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.DayFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static monthFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.MonthFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static yearFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.YearFieldLabels,
|
||||||
|
!0,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static addressBookFieldLabelPatternMatchers =
|
||||||
|
newAddressBookFieldLabelPatternMatchers();
|
||||||
|
static emailFieldLabelPatternMatchers = newEmailFieldLabelPatternMatchers();
|
||||||
|
static creditCardNumberFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.numberFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static creditCardSecurityCodeFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.securityCodeFieldLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static creditCardCardholderFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.cardholderLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static creditCardTypeFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.cardTypeLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static nonCreditCardCardNumberFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.nonCreditCardNumberLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static creditCardCompositeExpirationDateFieldLabelPatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.creditCardAutoFill.compositeExpirationDateLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static newAccountFormTypePatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.NewAccountFormTypeKeywords,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static federatedSignInAffordancePatternMatchers = [
|
||||||
|
new FormMetadataFieldPatternMatcher(
|
||||||
|
FormAutoFillKeywords.FederatedSignInAffordanceLabels,
|
||||||
|
),
|
||||||
|
];
|
||||||
|
static mapOfKeywordsIndicatingLoginFormTypeToScoreForMatching =
|
||||||
|
FormAutoFillKeywords.LoginFormTypeKeywords;
|
||||||
|
static mapOfKeywordsIndicatingNewAccountFormTypeToScoreForMatching =
|
||||||
|
FormAutoFillKeywords.NewAccountFormTypeKeywords;
|
||||||
|
static mapOfKeywordsIndicatingChangePasswordFormTypeToScoreForMatching =
|
||||||
|
FormAutoFillKeywords.ChangePasswordFormTypeKeywords;
|
||||||
|
static regularExpressionsForForgotPasswordAffordance =
|
||||||
|
FormAutoFillKeywords.ForgotPasswordAffordanceRegularExpressions;
|
||||||
|
static regularExpressionsForForgotUserNameAffordance =
|
||||||
|
FormAutoFillKeywords.ForgotUserNameAffordanceRegularExpressions;
|
||||||
|
static regularExpressionsForForgotEmailAffordance =
|
||||||
|
FormAutoFillKeywords.ForgotEmailAffordanceRegularExpressions;
|
||||||
|
static specifierForAutocompleteTokensAndAddressBookLabel(e, t) {
|
||||||
|
if (e) {
|
||||||
|
if (!Array.isArray(e))
|
||||||
|
throw new Error("Expected an array of autocomplete tokens");
|
||||||
|
for (let t of e) {
|
||||||
|
const e = autocompleteTokenMap[t]?.valueSpecifier;
|
||||||
|
if (e) return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (t) {
|
||||||
|
const e = fieldLabelMap[t]?.valueSpecifier;
|
||||||
|
if (e) return e;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
autoFillButtonManager;
|
||||||
|
focusManager;
|
||||||
|
didAssociateFormControlsTimeout;
|
||||||
|
constructor() {
|
||||||
|
((this.focusManager = new FocusManager(this)),
|
||||||
|
this.focusManager.addEventListeners(),
|
||||||
|
(this.autoFillButtonManager = new AutoFillButtonManager(this)),
|
||||||
|
this.autoFillButtonManager.addEventListeners(),
|
||||||
|
(this.didAssociateFormControlsTimeout = null),
|
||||||
|
addGlobalEventHandler(
|
||||||
|
"webkitassociateformcontrols",
|
||||||
|
this.didAssociateFormControls.bind(this),
|
||||||
|
),
|
||||||
|
(this.shouldNotifyOnFormChanges = !1),
|
||||||
|
window.addEventListener("pagehide", () => {
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "pageHide",
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
didAssociateFormControls(e) {
|
||||||
|
if (!this.shouldNotifyOnFormChanges) return;
|
||||||
|
if (this.didAssociateFormControlsTimeout) return;
|
||||||
|
const t = e.composedPath()[0];
|
||||||
|
if ("hidden" === t.type || "button" === t.type) return;
|
||||||
|
const [a, o] = FormMetadataJS.formsAndMetadata(
|
||||||
|
WBSFormMetadataRequestPreFill,
|
||||||
|
);
|
||||||
|
this.didAssociateFormControlsTimeout = setTimeout(
|
||||||
|
this.sendDidAssociateFormControlsMessage.bind(this),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
sendDidAssociateFormControlsMessage() {
|
||||||
|
((this.didAssociateFormControlsTimeout = null),
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "didAssociateFormControls",
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
FormMetadataJS.clearTextFieldOrSelectElementMetadataCache();
|
||||||
|
}
|
||||||
|
textEditingStatus() {
|
||||||
|
const [e, t] = FormMetadataJS.visibleNonEmptyFormTextControls(),
|
||||||
|
a = e.filter((e) => e.lastChangeWasUserEdit),
|
||||||
|
o = t.filter((e) => e.lastChangeWasUserEdit),
|
||||||
|
r = document.body.onbeforeunload,
|
||||||
|
l = null != r;
|
||||||
|
return {
|
||||||
|
numberOfTextInputElements: a.length,
|
||||||
|
numberOfTextAreaElements: o.length,
|
||||||
|
hasOnBeforeUnloadEventHandler: l,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async fillFormWithPassword(e, t, a, o) {
|
||||||
|
const r = await FormMetadataJS.fillFormWithPassword(e, a, t);
|
||||||
|
for (let e of r) e.autofillVisibility = o ? "hidden" : "visible";
|
||||||
|
o && AutomaticPasswords.blurControlWithID(t);
|
||||||
|
}
|
||||||
|
static #e(e) {
|
||||||
|
const t = getComputedStyle(e).writingMode,
|
||||||
|
a = !("horizontal-tb" === t || "horizontal-bt" === t),
|
||||||
|
o = e.getBoundingClientRect();
|
||||||
|
return (
|
||||||
|
(a ? o.height : o.width) >=
|
||||||
|
WBSMinimumLogicalWidthToShowManualAutoFillButton
|
||||||
|
);
|
||||||
|
}
|
||||||
|
static #t(e) {
|
||||||
|
return !!FormMetadataJSController.#e(e) && e === innermostActiveElement();
|
||||||
|
}
|
||||||
|
showAutoFillButtonInControl(e, t) {
|
||||||
|
const a = FormMetadataJS.formControlWithUniqueID(e);
|
||||||
|
(FormMetadataJSController.#t(a) || "none" === t) &&
|
||||||
|
a._setAutofillButtonType(t);
|
||||||
|
}
|
||||||
|
setAutofillAvailable(e, t) {
|
||||||
|
const a = FormMetadataJS.formControlWithUniqueID(e);
|
||||||
|
a && (a.autofillAvailable = t);
|
||||||
|
}
|
||||||
|
setControlsAsAutoFilled(e, t) {
|
||||||
|
this.#a(e).forEach((e) => {
|
||||||
|
FormMetadataJSController.setInputElementAutofilled(e, t);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
blurControls(e) {
|
||||||
|
this.#a.forEach((e) => e.blur());
|
||||||
|
}
|
||||||
|
clearControls(e) {
|
||||||
|
this.#a.forEach(FormMetadataJS.clearField);
|
||||||
|
}
|
||||||
|
annotateForm(e, t) {
|
||||||
|
FormMetadataJS.annotateFormWithID(e, t);
|
||||||
|
}
|
||||||
|
formsMetadata(e) {
|
||||||
|
(e !== WBSFormMetadataRequestPreFill &&
|
||||||
|
e !== WBSFormMetadataRequestTesting) ||
|
||||||
|
(this.shouldNotifyOnFormChanges = !0);
|
||||||
|
let [t, a] = FormMetadataJS.formsAndMetadata(e);
|
||||||
|
for (const e of a)
|
||||||
|
for (const t of e.FormControls) {
|
||||||
|
const e = FormMetadataJS.formControlWithUniqueID(t.ControlUniqueID);
|
||||||
|
this.populateRectFieldsInFormElementMetadata(t, e);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
getMetadataForControl(e, t = WBSFormMetadataRequestNormal) {
|
||||||
|
const a = FormMetadataJS.formControlWithUniqueID(e);
|
||||||
|
return a ? this._getMetadataForControl(a, t) : [null, null];
|
||||||
|
}
|
||||||
|
getMetadataForForm(e) {
|
||||||
|
const [t, a] = FormMetadataJS.formsAndMetadata(
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
);
|
||||||
|
for (let o = 0; o < t.length; o++) if (t[o] === e) return a[o];
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
_getMetadataForControl(e, t) {
|
||||||
|
let [a, o] = FormMetadataJS.textFieldOrSelectElementMetadata(e, t, !1);
|
||||||
|
return (
|
||||||
|
this.populateRectFieldsInFormElementMetadata(a, e),
|
||||||
|
FormMetadataJS.clearTextFieldOrSelectElementMetadataCache(),
|
||||||
|
[a, o]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
focusControl(e, t = !1) {
|
||||||
|
const a = FormMetadataJS.formControlWithUniqueID(e);
|
||||||
|
a && (t ? FormMetadataJS._focusControlForStreamlinedLogin(a) : a.focus());
|
||||||
|
}
|
||||||
|
replaceRangeInControl(e, t, a, o, r) {
|
||||||
|
FormMetadataJS.replaceFormFieldRangeAndSelectTail(e, t, a, o, r);
|
||||||
|
const l = FormMetadataJS.formControlWithUniqueID(e);
|
||||||
|
if (l)
|
||||||
|
return FormMetadataJS.textFieldOrSelectElementMetadata(
|
||||||
|
l,
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
!0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
selectRangeInControl(e, t, a) {
|
||||||
|
FormMetadataJS.setFormFieldSelection(e, t, a);
|
||||||
|
}
|
||||||
|
static setInputElementSpellCheckEnabled(e, t) {
|
||||||
|
e.autofillSpellcheck = !!t;
|
||||||
|
}
|
||||||
|
static setInputElementAutofilled(e, t) {
|
||||||
|
((e.autofilled = t),
|
||||||
|
t && FormMetadataJSController.autoFilledFieldWithMetadata(e));
|
||||||
|
}
|
||||||
|
static setInputElementAutoFilledAndViewable(e, t) {
|
||||||
|
e.autofilledAndViewable = t;
|
||||||
|
}
|
||||||
|
static setInputElementAutofilledAndObscured(e, t) {
|
||||||
|
((e.autofilledAndObscured = t),
|
||||||
|
t && FormMetadataJSController.autoFilledFieldWithMetadata(e));
|
||||||
|
}
|
||||||
|
populateRectFieldsInFormElementMetadata(e, t) {
|
||||||
|
const a = t.getBoundingClientRect();
|
||||||
|
((e.ControlRectLeft = a.left),
|
||||||
|
(e.ControlRectTop = a.top),
|
||||||
|
(e.ControlRectWidth = a.width),
|
||||||
|
(e.ControlRectHeight = a.height));
|
||||||
|
}
|
||||||
|
#a(e) {
|
||||||
|
return e.flatMap(FormMetadataJS.formControlWithUniqueID);
|
||||||
|
}
|
||||||
|
static autoFilledFieldWithMetadata(e) {
|
||||||
|
let [t, a] = FormMetadataJS.textFieldOrSelectElementMetadata(
|
||||||
|
e,
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
!1,
|
||||||
|
);
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "autoFilledFieldWithMetadata",
|
||||||
|
controlMetadata: t,
|
||||||
|
formMetadata: a,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
static logicalFormObservedChangeIndicatingFormSubmission(e, t) {
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "formObservedChangeIndicatingFormSubmission",
|
||||||
|
formMetadata: e,
|
||||||
|
removedControlsMetadata: t,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class FieldMovementChecker {
|
||||||
|
textField;
|
||||||
|
textFieldMetadata;
|
||||||
|
formMetadata;
|
||||||
|
numberOfTimesFieldMovementTimerHasFired;
|
||||||
|
checkForFieldMovementTimeout;
|
||||||
|
pollingIntervals;
|
||||||
|
onFieldMoved;
|
||||||
|
constructor(e) {
|
||||||
|
((this.textField = null),
|
||||||
|
(this.textFieldMetadata = null),
|
||||||
|
(this.numberOfTimesFieldMovementTimerHasFired = 0),
|
||||||
|
(this.checkForFieldMovementTimeout = null),
|
||||||
|
(this.pollingIntervals = [10, 50, 100, 850]),
|
||||||
|
(this.onFieldMoved = e));
|
||||||
|
}
|
||||||
|
setTextFieldToMonitor(e, t, a) {
|
||||||
|
((this.textField = e),
|
||||||
|
(this.textFieldMetadata = t),
|
||||||
|
(this.formMetadata = a));
|
||||||
|
}
|
||||||
|
performNextCheckForFieldMovement() {
|
||||||
|
if (
|
||||||
|
((this.checkForFieldMovementTimeout = null),
|
||||||
|
!this.textField || !this.textFieldMetadata)
|
||||||
|
)
|
||||||
|
return void this.reset();
|
||||||
|
const e = this.textField.getBoundingClientRect();
|
||||||
|
(this.textFieldMetadata.ControlRectLeft != e.left ||
|
||||||
|
this.textFieldMetadata.ControlRectTop != e.top ||
|
||||||
|
this.textFieldMetadata.ControlRectWidth != e.width ||
|
||||||
|
this.textFieldMetadata.ControlRectHeight != e.height
|
||||||
|
? (this.onFieldMoved(
|
||||||
|
this.textField,
|
||||||
|
this.textFieldMetadata,
|
||||||
|
this.formMetadata,
|
||||||
|
),
|
||||||
|
(this.numberOfTimesFieldMovementTimerHasFired = 0))
|
||||||
|
: (this.numberOfTimesFieldMovementTimerHasFired += 1),
|
||||||
|
this.numberOfTimesFieldMovementTimerHasFired >=
|
||||||
|
this.pollingIntervals.length
|
||||||
|
? this.reset()
|
||||||
|
: this.scheduleNextCheckForFieldMovement());
|
||||||
|
}
|
||||||
|
reset() {
|
||||||
|
(this.checkForFieldMovementTimeout &&
|
||||||
|
window.clearTimeout(this.checkForFieldMovementTimeout),
|
||||||
|
(this.checkForFieldMovementTimeout = null));
|
||||||
|
}
|
||||||
|
scheduleNextCheckForFieldMovement() {
|
||||||
|
this.reset();
|
||||||
|
const e =
|
||||||
|
this.pollingIntervals[this.numberOfTimesFieldMovementTimerHasFired];
|
||||||
|
this.checkForFieldMovementTimeout = window.setTimeout(
|
||||||
|
this.performNextCheckForFieldMovement.bind(this),
|
||||||
|
e,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class FocusManager {
|
||||||
|
jsController;
|
||||||
|
fieldMovementChecker;
|
||||||
|
constructor(e) {
|
||||||
|
((this.jsController = e),
|
||||||
|
(this.fieldMovementChecker = new FieldMovementChecker(
|
||||||
|
this.handleElementFocused.bind(this),
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
addEventListeners() {
|
||||||
|
(addGlobalEventHandler("submit", this.submitEventHandler.bind(this)),
|
||||||
|
addGlobalEventHandler("focus", this.focusInEventHandler.bind(this)),
|
||||||
|
addGlobalEventHandler("blur", this.focusOutEventHandler.bind(this)),
|
||||||
|
addGlobalEventHandler("input", this.inputEventHandler.bind(this)));
|
||||||
|
}
|
||||||
|
static #o(e) {
|
||||||
|
for (const t of e.composedPath()) {
|
||||||
|
if (FormMetadataJS._isTextField(t)) return t;
|
||||||
|
if (t instanceof HTMLSelectElement) return t;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
focusInEventHandler(e) {
|
||||||
|
this.fieldMovementChecker.reset();
|
||||||
|
const t = FocusManager.#o(e);
|
||||||
|
if (!t) return;
|
||||||
|
let [a, o] = FormMetadataJS.textFieldOrSelectElementMetadata(
|
||||||
|
t,
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
!0,
|
||||||
|
);
|
||||||
|
a &&
|
||||||
|
(t.setUserInfo({ form: o, textField: a }),
|
||||||
|
this.fieldMovementChecker.setTextFieldToMonitor(t, a, o),
|
||||||
|
this.fieldMovementChecker.scheduleNextCheckForFieldMovement(),
|
||||||
|
this.handleElementFocused(t, a, o));
|
||||||
|
}
|
||||||
|
handleElementFocused(e, t, a) {
|
||||||
|
(this.jsController.populateRectFieldsInFormElementMetadata(t, e),
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "elementFocused",
|
||||||
|
focusedElementMetadata: t,
|
||||||
|
formMetadata: a,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
focusOutEventHandler(e) {
|
||||||
|
this.fieldMovementChecker.reset();
|
||||||
|
const t = FocusManager.#o(e);
|
||||||
|
if (!t) return;
|
||||||
|
let [a, o] = FormMetadataJS.textFieldOrSelectElementMetadata(
|
||||||
|
t,
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
!0,
|
||||||
|
);
|
||||||
|
a &&
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "elementBlurred",
|
||||||
|
focusedElementMetadata: a,
|
||||||
|
formMetadata: o,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
inputEventHandler(e) {
|
||||||
|
const t = FocusManager.#o(e);
|
||||||
|
if (!t) return;
|
||||||
|
let [a, o] = FormMetadataJS.textFieldOrSelectElementMetadata(
|
||||||
|
t,
|
||||||
|
WBSFormMetadataRequestTextChange,
|
||||||
|
!0,
|
||||||
|
);
|
||||||
|
a &&
|
||||||
|
(this.jsController.populateRectFieldsInFormElementMetadata(a, t),
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "elementInput",
|
||||||
|
focusedElementMetadata: a,
|
||||||
|
formMetadata: o,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
submitEventHandler(e) {
|
||||||
|
const t = e.target,
|
||||||
|
a = this.jsController.getMetadataForForm(t);
|
||||||
|
t.setUserInfo(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class AutoFillButtonManager {
|
||||||
|
jsController;
|
||||||
|
constructor(e) {
|
||||||
|
this.jsController = e;
|
||||||
|
}
|
||||||
|
addEventListeners() {
|
||||||
|
document.addEventListener(
|
||||||
|
"webkitautofillrequest",
|
||||||
|
this.webKitAutofillRequestEventHandler.bind(this),
|
||||||
|
{ capture: !0 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
webKitAutofillRequestEventHandler(e) {
|
||||||
|
const t = e.target;
|
||||||
|
let [a, o] = this.jsController._getMetadataForControl(
|
||||||
|
t,
|
||||||
|
WBSFormMetadataRequestNormal,
|
||||||
|
);
|
||||||
|
window.webkit.messageHandlers.controller.postMessage({
|
||||||
|
name: "manualAutoFillRequest",
|
||||||
|
focusedElementMetadata: a,
|
||||||
|
formMetadata: o,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let formMetadataJSController = new FormMetadataJSController();
|
||||||
42
26.2/js/forms/FormMetadataUtilities.js
Normal file
42
26.2/js/forms/FormMetadataUtilities.js
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
//# sourceURL=__InjectedScript_FormMetadataUtilities.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
// Copyright (c) 2025 Apple Inc. All rights reserved.
|
||||||
|
"use strict";
|
||||||
|
globalThis.FormMetadataUtilitiesJS = class {
|
||||||
|
static #t(t, e) {
|
||||||
|
const n = /([A-Za-z0-9])/;
|
||||||
|
let o = null,
|
||||||
|
s = -1,
|
||||||
|
i = -1;
|
||||||
|
const l = t.replaceAll(".", "").toLowerCase();
|
||||||
|
for (let t = 0; t < e.length; t++) {
|
||||||
|
const r = e[t].replaceAll(".", "").toLowerCase(),
|
||||||
|
a = r.indexOf(l);
|
||||||
|
if (-1 === a) continue;
|
||||||
|
if (a > 0 && n.test(r.charAt(a - 1))) continue;
|
||||||
|
let c = a + l.length;
|
||||||
|
(c < r.length && n.test(r.charAt(c))) ||
|
||||||
|
((!o || r.length < o.length) && ((o = r), (s = t), (i = a)));
|
||||||
|
}
|
||||||
|
return { index: s, startPosition: i };
|
||||||
|
}
|
||||||
|
static bestIndexToFillSelectControl(t, e) {
|
||||||
|
const n = t.length,
|
||||||
|
o = [];
|
||||||
|
for (let e = 0; e < n; e++) {
|
||||||
|
const n = t[e][1];
|
||||||
|
o.push(n);
|
||||||
|
}
|
||||||
|
let s = -1,
|
||||||
|
i = Number.MAX_SAFE_INTEGER;
|
||||||
|
for (let t = e.length - 1; t >= 0; t--) {
|
||||||
|
const n = e[t];
|
||||||
|
Number.MAX_SAFE_INTEGER;
|
||||||
|
const l = this.#t(n, o);
|
||||||
|
-1 !== l.index &&
|
||||||
|
l.startPosition < i &&
|
||||||
|
((i = l.startPosition), (s = l.index));
|
||||||
|
}
|
||||||
|
return -1 === s ? -1 : t[s][0];
|
||||||
|
}
|
||||||
|
};
|
||||||
374
26.2/js/forms/PasswordRulesParserJS.js
Normal file
374
26.2/js/forms/PasswordRulesParserJS.js
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
//# sourceURL=__InjectedScript_PasswordRulesParserJS.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
// Copyright (c) 2019 - 2022 Apple Inc. Licensed under MIT License.
|
||||||
|
"use strict";
|
||||||
|
function _isIdentifierCharacter(e) {
|
||||||
|
return (e >= "a" && e <= "z") || (e >= "A" && e <= "Z") || "-" === e;
|
||||||
|
}
|
||||||
|
function _isASCIIDigit(e) {
|
||||||
|
return e >= "0" && e <= "9";
|
||||||
|
}
|
||||||
|
function _isASCIIPrintableCharacter(e) {
|
||||||
|
return e >= " " && e <= "~";
|
||||||
|
}
|
||||||
|
function _isASCIIWhitespace(e) {
|
||||||
|
return " " === e || "\f" === e || "\n" === e || "\r" === e || "\t" === e;
|
||||||
|
}
|
||||||
|
function _bitSetIndexForCharacter(e) {
|
||||||
|
return e.codePointAt(0) - SPACE_CODE_POINT;
|
||||||
|
}
|
||||||
|
function _characterAtBitSetIndex(e) {
|
||||||
|
return String.fromCodePoint(e + SPACE_CODE_POINT);
|
||||||
|
}
|
||||||
|
function _markBitsForNamedCharacterClass(e, r) {
|
||||||
|
r.name === Identifier.UPPER
|
||||||
|
? e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter("A"),
|
||||||
|
_bitSetIndexForCharacter("Z") + 1,
|
||||||
|
)
|
||||||
|
: r.name === Identifier.LOWER
|
||||||
|
? e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter("a"),
|
||||||
|
_bitSetIndexForCharacter("z") + 1,
|
||||||
|
)
|
||||||
|
: r.name === Identifier.DIGIT
|
||||||
|
? e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter("0"),
|
||||||
|
_bitSetIndexForCharacter("9") + 1,
|
||||||
|
)
|
||||||
|
: r.name === Identifier.SPECIAL &&
|
||||||
|
(e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter(" "),
|
||||||
|
_bitSetIndexForCharacter("/") + 1,
|
||||||
|
),
|
||||||
|
e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter(":"),
|
||||||
|
_bitSetIndexForCharacter("@") + 1,
|
||||||
|
),
|
||||||
|
e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter("["),
|
||||||
|
_bitSetIndexForCharacter("`") + 1,
|
||||||
|
),
|
||||||
|
e.fill(
|
||||||
|
!0,
|
||||||
|
_bitSetIndexForCharacter("{"),
|
||||||
|
_bitSetIndexForCharacter("~") + 1,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
function _markBitsForCustomCharacterClass(e, r) {
|
||||||
|
for (let t of r.characters) e[_bitSetIndexForCharacter(t)] = !0;
|
||||||
|
}
|
||||||
|
function _canonicalizedPropertyValues(e, r) {
|
||||||
|
function t(e, r) {
|
||||||
|
let t = [];
|
||||||
|
for (
|
||||||
|
let n = _bitSetIndexForCharacter(e);
|
||||||
|
n <= _bitSetIndexForCharacter(r);
|
||||||
|
++n
|
||||||
|
)
|
||||||
|
a[n] && t.push(_characterAtBitSetIndex(n));
|
||||||
|
let i =
|
||||||
|
t.length ===
|
||||||
|
_bitSetIndexForCharacter(r) - _bitSetIndexForCharacter(e) + 1;
|
||||||
|
return (i || (n = n.concat(t)), i);
|
||||||
|
}
|
||||||
|
let a = new Array("~".codePointAt(0) - " ".codePointAt(0) + 1);
|
||||||
|
for (let r of e)
|
||||||
|
if (r instanceof NamedCharacterClass) {
|
||||||
|
if (r.name === Identifier.UNICODE)
|
||||||
|
return [new NamedCharacterClass(Identifier.UNICODE)];
|
||||||
|
if (r.name === Identifier.ASCII_PRINTABLE)
|
||||||
|
return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)];
|
||||||
|
_markBitsForNamedCharacterClass(a, r);
|
||||||
|
} else
|
||||||
|
r instanceof CustomCharacterClass &&
|
||||||
|
_markBitsForCustomCharacterClass(a, r);
|
||||||
|
let n = [],
|
||||||
|
i = t("A", "Z"),
|
||||||
|
l = t("a", "z"),
|
||||||
|
s = t("0", "9"),
|
||||||
|
u = !1,
|
||||||
|
c = !1,
|
||||||
|
o = !1,
|
||||||
|
_ = [];
|
||||||
|
for (
|
||||||
|
let e = _bitSetIndexForCharacter(" ");
|
||||||
|
e <= _bitSetIndexForCharacter("/");
|
||||||
|
++e
|
||||||
|
) {
|
||||||
|
if (!a[e]) continue;
|
||||||
|
let t = _characterAtBitSetIndex(e);
|
||||||
|
r && "-" === t ? (c = !0) : _.push(t);
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
let e = _bitSetIndexForCharacter(":");
|
||||||
|
e <= _bitSetIndexForCharacter("@");
|
||||||
|
++e
|
||||||
|
)
|
||||||
|
a[e] && _.push(_characterAtBitSetIndex(e));
|
||||||
|
for (
|
||||||
|
let e = _bitSetIndexForCharacter("[");
|
||||||
|
e <= _bitSetIndexForCharacter("`");
|
||||||
|
++e
|
||||||
|
) {
|
||||||
|
if (!a[e]) continue;
|
||||||
|
let t = _characterAtBitSetIndex(e);
|
||||||
|
r && "]" === t ? (o = !0) : _.push(t);
|
||||||
|
}
|
||||||
|
for (
|
||||||
|
let e = _bitSetIndexForCharacter("{");
|
||||||
|
e <= _bitSetIndexForCharacter("~");
|
||||||
|
++e
|
||||||
|
)
|
||||||
|
a[e] && _.push(_characterAtBitSetIndex(e));
|
||||||
|
(c && _.unshift("-"), o && _.push("]"));
|
||||||
|
let C =
|
||||||
|
_bitSetIndexForCharacter("/") -
|
||||||
|
_bitSetIndexForCharacter(" ") +
|
||||||
|
1 +
|
||||||
|
(_bitSetIndexForCharacter("@") - _bitSetIndexForCharacter(":") + 1) +
|
||||||
|
(_bitSetIndexForCharacter("`") - _bitSetIndexForCharacter("[") + 1) +
|
||||||
|
(_bitSetIndexForCharacter("~") - _bitSetIndexForCharacter("{") + 1);
|
||||||
|
((u = _.length === C), u || (n = n.concat(_)));
|
||||||
|
let h = [];
|
||||||
|
return i && l && s && u
|
||||||
|
? [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]
|
||||||
|
: (i && h.push(new NamedCharacterClass(Identifier.UPPER)),
|
||||||
|
l && h.push(new NamedCharacterClass(Identifier.LOWER)),
|
||||||
|
s && h.push(new NamedCharacterClass(Identifier.DIGIT)),
|
||||||
|
u && h.push(new NamedCharacterClass(Identifier.SPECIAL)),
|
||||||
|
n.length && h.push(new CustomCharacterClass(n)),
|
||||||
|
h);
|
||||||
|
}
|
||||||
|
function _indexOfNonWhitespaceCharacter(e, r = 0) {
|
||||||
|
let t = e.length;
|
||||||
|
for (; r < t && _isASCIIWhitespace(e[r]); ) ++r;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
function _parseIdentifier(e, r) {
|
||||||
|
let t = e.length,
|
||||||
|
a = [];
|
||||||
|
do {
|
||||||
|
let t = e[r];
|
||||||
|
if (!_isIdentifierCharacter(t)) break;
|
||||||
|
(a.push(t), ++r);
|
||||||
|
} while (r < t);
|
||||||
|
return [a.join(""), r];
|
||||||
|
}
|
||||||
|
function _isValidRequiredOrAllowedPropertyValueIdentifier(e) {
|
||||||
|
return e && Object.values(Identifier).includes(e.toLowerCase());
|
||||||
|
}
|
||||||
|
function _parseCustomCharacterClass(e, r) {
|
||||||
|
let t = e.length;
|
||||||
|
if (++r >= t) return [null, r];
|
||||||
|
let a = r,
|
||||||
|
n = [];
|
||||||
|
do {
|
||||||
|
let t = e[r];
|
||||||
|
if (_isASCIIPrintableCharacter(t)) {
|
||||||
|
if ("-" === t && r - a > 0) ++r;
|
||||||
|
else if ((n.push(t), ++r, t === CHARACTER_CLASS_END_SENTINEL)) break;
|
||||||
|
} else ++r;
|
||||||
|
} while (r < t);
|
||||||
|
return (r < t && e[r] !== CHARACTER_CLASS_END_SENTINEL) ||
|
||||||
|
(r == t && e[r - 1] == CHARACTER_CLASS_END_SENTINEL)
|
||||||
|
? (n.pop(), [n, r])
|
||||||
|
: r < t && e[r] == CHARACTER_CLASS_END_SENTINEL
|
||||||
|
? [n, r + 1]
|
||||||
|
: [null, r];
|
||||||
|
}
|
||||||
|
function _parsePasswordRequiredOrAllowedPropertyValue(e, r) {
|
||||||
|
let t = e.length,
|
||||||
|
a = [];
|
||||||
|
for (;;) {
|
||||||
|
if (_isIdentifierCharacter(e[r])) {
|
||||||
|
let t = r;
|
||||||
|
var [n, r] = _parseIdentifier(e, r);
|
||||||
|
if (!_isValidRequiredOrAllowedPropertyValueIdentifier(n))
|
||||||
|
return [null, t];
|
||||||
|
a.push(new NamedCharacterClass(n));
|
||||||
|
} else {
|
||||||
|
if (e[r] != CHARACTER_CLASS_START_SENTINEL) return [null, r];
|
||||||
|
var [n, r] = _parseCustomCharacterClass(e, r);
|
||||||
|
n && n.length && a.push(new CustomCharacterClass(n));
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
(r = _indexOfNonWhitespaceCharacter(e, r)) >= t ||
|
||||||
|
e[r] === PROPERTY_SEPARATOR
|
||||||
|
)
|
||||||
|
break;
|
||||||
|
if (e[r] !== PROPERTY_VALUE_SEPARATOR) return [null, r];
|
||||||
|
if ((r = _indexOfNonWhitespaceCharacter(e, r + 1)) >= t) return [null, r];
|
||||||
|
}
|
||||||
|
return [a, r];
|
||||||
|
}
|
||||||
|
function _parsePasswordRule(e, r) {
|
||||||
|
let t = e.length;
|
||||||
|
var a = r,
|
||||||
|
[n, r] = _parseIdentifier(e, r);
|
||||||
|
if (!Object.values(RuleName).includes(n)) return [null, a];
|
||||||
|
if (r >= t) return [null, r];
|
||||||
|
if (e[r] !== PROPERTY_VALUE_START_SENTINEL) return [null, r];
|
||||||
|
let i = { name: n, value: null };
|
||||||
|
if (
|
||||||
|
(r = _indexOfNonWhitespaceCharacter(e, r + 1)) >= t ||
|
||||||
|
e[r] === PROPERTY_SEPARATOR
|
||||||
|
)
|
||||||
|
return [new Rule(i.name, i.value), r];
|
||||||
|
switch (n) {
|
||||||
|
case RuleName.ALLOWED:
|
||||||
|
case RuleName.REQUIRED:
|
||||||
|
var [l, r] = _parsePasswordRequiredOrAllowedPropertyValue(e, r);
|
||||||
|
return (l && (i.value = l), [new Rule(i.name, i.value), r]);
|
||||||
|
case RuleName.MAX_CONSECUTIVE:
|
||||||
|
var [l, r] = _parseMaxConsecutivePropertyValue(e, r);
|
||||||
|
return (l && (i.value = l), [new Rule(i.name, i.value), r]);
|
||||||
|
case RuleName.MIN_LENGTH:
|
||||||
|
case RuleName.MAX_LENGTH:
|
||||||
|
var [l, r] = _parseMinLengthMaxLengthPropertyValue(e, r);
|
||||||
|
return (l && (i.value = l), [new Rule(i.name, i.value), r]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function _parseMinLengthMaxLengthPropertyValue(e, r) {
|
||||||
|
return _parseInteger(e, r);
|
||||||
|
}
|
||||||
|
function _parseMaxConsecutivePropertyValue(e, r) {
|
||||||
|
return _parseInteger(e, r);
|
||||||
|
}
|
||||||
|
function _parseInteger(e, r) {
|
||||||
|
if (!_isASCIIDigit(e[r])) return [null, r];
|
||||||
|
let t = e.length,
|
||||||
|
a = 0;
|
||||||
|
do {
|
||||||
|
((a = 10 * a + parseInt(e[r], 10)), ++r);
|
||||||
|
} while (r < t && e[r] !== PROPERTY_SEPARATOR && _isASCIIDigit(e[r]));
|
||||||
|
return r >= t || e[r] === PROPERTY_SEPARATOR ? [a, r] : [null, r];
|
||||||
|
}
|
||||||
|
function _parsePasswordRulesInternal(e) {
|
||||||
|
let r = [],
|
||||||
|
t = e.length;
|
||||||
|
for (var a = _indexOfNonWhitespaceCharacter(e); a < t; ) {
|
||||||
|
if (!_isIdentifierCharacter(e[a])) return r;
|
||||||
|
var [n, a] = _parsePasswordRule(e, a);
|
||||||
|
if (
|
||||||
|
(n && n.value && r.push(n),
|
||||||
|
(a = _indexOfNonWhitespaceCharacter(e, a)) >= t)
|
||||||
|
)
|
||||||
|
break;
|
||||||
|
if (e[a] !== PROPERTY_SEPARATOR) return null;
|
||||||
|
if ((a = _indexOfNonWhitespaceCharacter(e, a + 1)) >= t) return r;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
function parsePasswordRules(e, r) {
|
||||||
|
let t = _parsePasswordRulesInternal(e) || [],
|
||||||
|
a = r,
|
||||||
|
n = [],
|
||||||
|
i = [],
|
||||||
|
l = null,
|
||||||
|
s = 0,
|
||||||
|
u = null;
|
||||||
|
for (let e of t)
|
||||||
|
switch (e.name) {
|
||||||
|
case RuleName.MAX_CONSECUTIVE:
|
||||||
|
l = l ? Math.min(e.value, l) : e.value;
|
||||||
|
break;
|
||||||
|
case RuleName.MIN_LENGTH:
|
||||||
|
s = Math.max(e.value, s);
|
||||||
|
break;
|
||||||
|
case RuleName.MAX_LENGTH:
|
||||||
|
u = u ? Math.min(e.value, u) : e.value;
|
||||||
|
break;
|
||||||
|
case RuleName.REQUIRED:
|
||||||
|
((e.value = _canonicalizedPropertyValues(e.value, r)),
|
||||||
|
n.push(e),
|
||||||
|
a || (i = i.concat(e.value)));
|
||||||
|
break;
|
||||||
|
case RuleName.ALLOWED:
|
||||||
|
i = i.concat(e.value);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
(i = _canonicalizedPropertyValues(i, a)),
|
||||||
|
a ||
|
||||||
|
i.length ||
|
||||||
|
(i = [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]),
|
||||||
|
i.length && n.push(new Rule(RuleName.ALLOWED, i)),
|
||||||
|
null !== l && n.push(new Rule(RuleName.MAX_CONSECUTIVE, l)),
|
||||||
|
s > 0 && n.push(new Rule(RuleName.MIN_LENGTH, s)),
|
||||||
|
null !== u && n.push(new Rule(RuleName.MAX_LENGTH, u)),
|
||||||
|
n
|
||||||
|
);
|
||||||
|
}
|
||||||
|
console ||
|
||||||
|
(console = {
|
||||||
|
assert: function () {},
|
||||||
|
error: function () {},
|
||||||
|
warn: function () {},
|
||||||
|
});
|
||||||
|
const Identifier = {
|
||||||
|
ASCII_PRINTABLE: "ascii-printable",
|
||||||
|
DIGIT: "digit",
|
||||||
|
LOWER: "lower",
|
||||||
|
SPECIAL: "special",
|
||||||
|
UNICODE: "unicode",
|
||||||
|
UPPER: "upper",
|
||||||
|
},
|
||||||
|
RuleName = {
|
||||||
|
ALLOWED: "allowed",
|
||||||
|
MAX_CONSECUTIVE: "max-consecutive",
|
||||||
|
REQUIRED: "required",
|
||||||
|
MIN_LENGTH: "minlength",
|
||||||
|
MAX_LENGTH: "maxlength",
|
||||||
|
},
|
||||||
|
CHARACTER_CLASS_START_SENTINEL = "[",
|
||||||
|
CHARACTER_CLASS_END_SENTINEL = "]",
|
||||||
|
PROPERTY_VALUE_SEPARATOR = ",",
|
||||||
|
PROPERTY_SEPARATOR = ";",
|
||||||
|
PROPERTY_VALUE_START_SENTINEL = ":",
|
||||||
|
SPACE_CODE_POINT = " ".codePointAt(0),
|
||||||
|
SHOULD_NOT_BE_REACHED = "Should not be reached";
|
||||||
|
class Rule {
|
||||||
|
constructor(e, r) {
|
||||||
|
((this._name = e), (this.value = r));
|
||||||
|
}
|
||||||
|
get name() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class NamedCharacterClass {
|
||||||
|
constructor(e) {
|
||||||
|
this._name = e;
|
||||||
|
}
|
||||||
|
get name() {
|
||||||
|
return this._name.toLowerCase();
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
toHTMLString() {
|
||||||
|
return this._name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class CustomCharacterClass {
|
||||||
|
constructor(e) {
|
||||||
|
this._characters = e;
|
||||||
|
}
|
||||||
|
get characters() {
|
||||||
|
return this._characters;
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return `[${this._characters.join("")}]`;
|
||||||
|
}
|
||||||
|
toHTMLString() {
|
||||||
|
return `[${this._characters.join("").replace(/"/g, """)}]`;
|
||||||
|
}
|
||||||
|
}
|
||||||
71
26.2/js/layout/WebContentLayoutAnalyzer.js
Normal file
71
26.2/js/layout/WebContentLayoutAnalyzer.js
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
//# sourceURL=__InjectedScript_WebContentLayoutAnalyzer.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
// Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||||
|
function elementAppearsCentered(e, t) {
|
||||||
|
var n = window.innerWidth - t.right - t.left;
|
||||||
|
return Math.abs(n) <= 1;
|
||||||
|
}
|
||||||
|
function centeredElementIsNotAContainer(e, t) {
|
||||||
|
if (e === document.documentElement || e === document.body) return !0;
|
||||||
|
if (0 === t.left && t.width === window.innerWidth) return !0;
|
||||||
|
if (!t.height) return !0;
|
||||||
|
var n = e.innerText;
|
||||||
|
return !n || !n.trim();
|
||||||
|
}
|
||||||
|
var WebContentLayoutAnalyzer = function () {
|
||||||
|
((this.centeredContainerElement = null),
|
||||||
|
(this.rectOfCenteredContainerElementBeforeResize = null),
|
||||||
|
(this.rectOfCenteredContainerElementAfterResize = null));
|
||||||
|
};
|
||||||
|
WebContentLayoutAnalyzer.prototype = {
|
||||||
|
findCenteredContainerElement: function () {
|
||||||
|
for (
|
||||||
|
var e = null,
|
||||||
|
t = null,
|
||||||
|
n = document.getElementsByTagName("*"),
|
||||||
|
r = n.length,
|
||||||
|
i = 0;
|
||||||
|
i < r;
|
||||||
|
++i
|
||||||
|
) {
|
||||||
|
var o = n[i],
|
||||||
|
l = o.getBoundingClientRect();
|
||||||
|
elementAppearsCentered(o, l) &&
|
||||||
|
(centeredElementIsNotAContainer(o, l) ||
|
||||||
|
((!t || l.width > t.width) && ((e = o), (t = l))));
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
},
|
||||||
|
collectInformationBeforeResize: function () {
|
||||||
|
((this.centeredContainerElement = this.findCenteredContainerElement()),
|
||||||
|
this.centeredContainerElement &&
|
||||||
|
(this.rectOfCenteredContainerElementBeforeResize =
|
||||||
|
this.centeredContainerElement.getBoundingClientRect()));
|
||||||
|
},
|
||||||
|
collectInformationAfterResize: function () {
|
||||||
|
this.centeredContainerElement &&
|
||||||
|
document.contains(this.centeredContainerElement) &&
|
||||||
|
(this.rectOfCenteredContainerElementAfterResize =
|
||||||
|
this.centeredContainerElement.getBoundingClientRect());
|
||||||
|
},
|
||||||
|
layoutInformation: function () {
|
||||||
|
var e = !1,
|
||||||
|
t = null;
|
||||||
|
return (
|
||||||
|
this.rectOfCenteredContainerElementBeforeResize &&
|
||||||
|
this.rectOfCenteredContainerElementAfterResize &&
|
||||||
|
((e =
|
||||||
|
this.rectOfCenteredContainerElementBeforeResize.width ===
|
||||||
|
this.rectOfCenteredContainerElementAfterResize.width),
|
||||||
|
(t =
|
||||||
|
this.rectOfCenteredContainerElementBeforeResize.left -
|
||||||
|
this.rectOfCenteredContainerElementAfterResize.left)),
|
||||||
|
{
|
||||||
|
FoundCenteredContainer: !!this.centeredContainerElement,
|
||||||
|
CenteredContainerIsFixedWidth: e,
|
||||||
|
DistanceContainerMoved: t,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var WebContentLayoutAnalyzerJS = new WebContentLayoutAnalyzer();
|
||||||
104
26.2/js/metadata/MetadataExtractor.js
Normal file
104
26.2/js/metadata/MetadataExtractor.js
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
//# sourceURL=__InjectedScript_MetadataExtractor.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
function getIconType(e) {
|
||||||
|
var o = e.getAttribute("rel");
|
||||||
|
return "apple-touch-icon" === o
|
||||||
|
? IconTypeAppleTouchIcon
|
||||||
|
: "apple-touch-icon-precomposed" === o
|
||||||
|
? IconTypeAppleTouchIconPrecomposed
|
||||||
|
: IconTypeFavicon;
|
||||||
|
}
|
||||||
|
function compareIconsDescending(e, o) {
|
||||||
|
var c = getIconType(e),
|
||||||
|
t = getIconType(o);
|
||||||
|
if (c === IconTypeFavicon && t !== IconTypeFavicon) return 1;
|
||||||
|
if (t === IconTypeFavicon && c !== IconTypeFavicon) return -1;
|
||||||
|
var n = e.getAttribute("sizes"),
|
||||||
|
r = o.getAttribute("sizes"),
|
||||||
|
p = 0,
|
||||||
|
a = 0;
|
||||||
|
return (
|
||||||
|
n
|
||||||
|
? (p = parseInt(n))
|
||||||
|
: n ||
|
||||||
|
(c !== IconTypeAppleTouchIcon &&
|
||||||
|
c !== IconTypeAppleTouchIconPrecomposed) ||
|
||||||
|
(p = AppleTouchIconDefaultWidth),
|
||||||
|
r
|
||||||
|
? (a = parseInt(r))
|
||||||
|
: r ||
|
||||||
|
(t !== IconTypeAppleTouchIcon &&
|
||||||
|
t !== IconTypeAppleTouchIconPrecomposed) ||
|
||||||
|
(a = AppleTouchIconDefaultWidth),
|
||||||
|
a > p
|
||||||
|
? 1
|
||||||
|
: a < p
|
||||||
|
? -1
|
||||||
|
: c !== IconTypeAppleTouchIconPrecomposed &&
|
||||||
|
t === IconTypeAppleTouchIconPrecomposed
|
||||||
|
? 1
|
||||||
|
: t !== IconTypeAppleTouchIconPrecomposed &&
|
||||||
|
c === IconTypeAppleTouchIconPrecomposed
|
||||||
|
? -1
|
||||||
|
: 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function colorComponentsFromString(e) {
|
||||||
|
var o = document.createElement("canvas");
|
||||||
|
((o.width = 1), (o.height = 1));
|
||||||
|
var c = o.getContext("2d");
|
||||||
|
((c.fillStyle = e), c.fillRect(0, 0, 1, 1));
|
||||||
|
var t = c.getImageData(0, 0, 1, 1);
|
||||||
|
return [t.data[0], t.data[1], t.data[2]];
|
||||||
|
}
|
||||||
|
var MetadataExtractor = function () {};
|
||||||
|
const IconTypeFavicon = 0,
|
||||||
|
IconTypeAppleTouchIcon = 1,
|
||||||
|
IconTypeAppleTouchIconPrecomposed = 2,
|
||||||
|
AppleTouchIconDefaultWidth = 60;
|
||||||
|
MetadataExtractor.prototype = {
|
||||||
|
extractAndSortIconsWithSelector: function (e) {
|
||||||
|
var o = document.head.querySelectorAll(e);
|
||||||
|
return o.length
|
||||||
|
? Array.prototype.slice.call(o).sort(compareIconsDescending)
|
||||||
|
: [];
|
||||||
|
},
|
||||||
|
extractAppleTouchIconURLs: function () {
|
||||||
|
for (
|
||||||
|
var e = this.extractAndSortIconsWithSelector(
|
||||||
|
"link[rel=apple-touch-icon], link[rel=apple-touch-icon-precomposed]",
|
||||||
|
),
|
||||||
|
o = [],
|
||||||
|
c = 0;
|
||||||
|
c < e.length;
|
||||||
|
++c
|
||||||
|
) {
|
||||||
|
var t = e[c].href;
|
||||||
|
t && o.push(t);
|
||||||
|
}
|
||||||
|
return o;
|
||||||
|
},
|
||||||
|
extractFaviconURLs: function () {
|
||||||
|
for (
|
||||||
|
var e = this.extractAndSortIconsWithSelector(
|
||||||
|
"link[rel='shortcut icon'], link[rel=icon]",
|
||||||
|
),
|
||||||
|
o = [],
|
||||||
|
c = e.length,
|
||||||
|
t = 0;
|
||||||
|
t < c;
|
||||||
|
++t
|
||||||
|
)
|
||||||
|
o.push(e[t].href);
|
||||||
|
return o;
|
||||||
|
},
|
||||||
|
extractTemplateIconURLAndColor: function () {
|
||||||
|
var e = document.head.querySelector("link[rel=mask-icon]");
|
||||||
|
if (!e) return null;
|
||||||
|
var o = e.getAttribute("color");
|
||||||
|
return o && e.href
|
||||||
|
? { url: e.href, color: colorComponentsFromString(o) }
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var MetadataExtractorJS = new MetadataExtractor();
|
||||||
23
26.2/js/reader/Reader.js
Normal file
23
26.2/js/reader/Reader.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//# sourceURL=__InjectedScript_Reader.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Apple Inc. All rights reserved.
|
||||||
|
*/
|
||||||
|
function setScrollTop(e) {
|
||||||
|
document.documentElement.scrollTop = e;
|
||||||
|
}
|
||||||
|
function readerWillBecomeVisible() {
|
||||||
|
setReaderIsActive(!0);
|
||||||
|
}
|
||||||
|
function readerWillEnterBackground() {
|
||||||
|
setReaderIsActive(!1);
|
||||||
|
}
|
||||||
|
((ReaderJS._clickingOutsideOfPaperRectangleDismissesReader = !0),
|
||||||
|
(ReaderJS._isJavaScriptEnabled = function () {
|
||||||
|
return !!(ReaderJSController.initialConfiguration() || {})[
|
||||||
|
ReaderConfigurationJavaScriptEnabledKey
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
(ReaderAppearanceJS._tryApplyStaticConfiguration = function () {
|
||||||
|
return (document.body.classList.add("mac"), !1);
|
||||||
|
}));
|
||||||
5092
26.2/js/reader/ReaderArticleFinder.js
Normal file
5092
26.2/js/reader/ReaderArticleFinder.js
Normal file
File diff suppressed because it is too large
Load Diff
28
26.2/js/reader/ReaderShared.js
Normal file
28
26.2/js/reader/ReaderShared.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//# sourceURL=__InjectedScript_ReaderShared.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
// Copyright (c) 2025 Apple Inc. All rights reserved.
|
||||||
|
"use strict";
|
||||||
|
function normalizedElementTagName(e) {
|
||||||
|
return e.localName;
|
||||||
|
}
|
||||||
|
function plaintextVersionOfNodeAppendingNewlinesBetweenBlockElements(e) {
|
||||||
|
const n = (e.ownerDocument ?? document).createTreeWalker(
|
||||||
|
e,
|
||||||
|
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
let t = "";
|
||||||
|
for (n.currentNode = e; n.nextNode(); ) {
|
||||||
|
const e = n.currentNode;
|
||||||
|
if (e.nodeType === Node.TEXT_NODE) {
|
||||||
|
t += e.textContent;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let o = normalizedElementTagName(e);
|
||||||
|
("p" !== o && "div" !== o) || (t += "\n");
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
const READER_UNIQUE_ID_ATTRIBUTE_KEY = "data-reader-unique-id",
|
||||||
|
READER_UNIQUE_ID_TITLE = "titleElement",
|
||||||
|
READER_UNIQUE_ID_SUBHEAD = "subheadElement";
|
||||||
2678
26.2/js/reader/ReaderSharedUI.js
Normal file
2678
26.2/js/reader/ReaderSharedUI.js
Normal file
File diff suppressed because it is too large
Load Diff
37
26.2/js/reader/ReaderSharedUINormalWorld.js
Normal file
37
26.2/js/reader/ReaderSharedUINormalWorld.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
//# sourceURL=__InjectedScript_ReaderSharedUINormalWorld.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
function loadTwitterJavaScript() {
|
||||||
|
window.twttr ||
|
||||||
|
(window.twttr = (function (e, t, r) {
|
||||||
|
var i,
|
||||||
|
a,
|
||||||
|
d = e.getElementsByTagName(t)[0];
|
||||||
|
if (!e.getElementById(r))
|
||||||
|
return (
|
||||||
|
((a = e.createElement(t)).id = r),
|
||||||
|
(a.src = "https://platform.twitter.com/widgets.js"),
|
||||||
|
d.parentNode.insertBefore(a, d),
|
||||||
|
window.twttr ||
|
||||||
|
(i = {
|
||||||
|
_e: [],
|
||||||
|
ready: function (e) {
|
||||||
|
i._e.push(e);
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})(document, "script", "twitter-wjs"));
|
||||||
|
}
|
||||||
|
function richTweetWasCreatedFromSimpleTweet(e) {
|
||||||
|
e.parentNode.querySelector(".simple-tweet").classList.add("hidden");
|
||||||
|
}
|
||||||
|
function replaceSimpleTweetsWithRichTweets(e) {
|
||||||
|
let t = document.querySelectorAll("[data-reader-tweet-id]");
|
||||||
|
t.length &&
|
||||||
|
(loadTwitterJavaScript(),
|
||||||
|
twttr.ready(function (r) {
|
||||||
|
for (let i of t)
|
||||||
|
r.widgets
|
||||||
|
.createTweet(i.getAttribute("data-reader-tweet-id"), i, e)
|
||||||
|
.then(richTweetWasCreatedFromSimpleTweet);
|
||||||
|
}));
|
||||||
|
}
|
||||||
249
26.2/js/schema/SchemaDataExtractor.js
Normal file
249
26.2/js/schema/SchemaDataExtractor.js
Normal file
@@ -0,0 +1,249 @@
|
|||||||
|
//# sourceURL=__InjectedScript_SchemaDataExtractor.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
var SchemaDataExtractor = function () {};
|
||||||
|
((SchemaDataExtractor.validAddressProperties = {
|
||||||
|
addressCountry: 1,
|
||||||
|
addressLocality: 1,
|
||||||
|
addressRegion: 1,
|
||||||
|
postOfficeBoxNumber: 1,
|
||||||
|
postalCode: 1,
|
||||||
|
streetAddress: 1,
|
||||||
|
}),
|
||||||
|
(SchemaDataExtractor.validParentSchemaTypes = {
|
||||||
|
"http://schema.org/Person": 1,
|
||||||
|
"https://schema.org/Person": 1,
|
||||||
|
"http://schema.org/LocalBusiness": 1,
|
||||||
|
"https://schema.org/LocalBusiness": 1,
|
||||||
|
"http://schema.org/Organization": 1,
|
||||||
|
"https://schema.org/Organization": 1,
|
||||||
|
"http://schema.org/Restaurant": 1,
|
||||||
|
"https://schema.org/Restaurant": 1,
|
||||||
|
"http://schema.org/Corporation": 1,
|
||||||
|
"https://schema.org/Corporation": 1,
|
||||||
|
"http://schema.org/EducationalOrganization": 1,
|
||||||
|
"https://schema.org/EducationalOrganization": 1,
|
||||||
|
"http://schema.org/GovernmentOrganization": 1,
|
||||||
|
"https://schema.org/GovernmentOrganization": 1,
|
||||||
|
"http://schema.org/MedicalOrganization": 1,
|
||||||
|
"https://schema.org/MedicalOrganization": 1,
|
||||||
|
"http://schema.org/AnimalShelter": 1,
|
||||||
|
"https://schema.org/AnimalShelter": 1,
|
||||||
|
"http://schema.org/AutomotiveBusiness": 1,
|
||||||
|
"https://schema.org/AutomotiveBusiness": 1,
|
||||||
|
"http://schema.org/ChildCare": 1,
|
||||||
|
"https://schema.org/ChildCare": 1,
|
||||||
|
"http://schema.org/DryCleaningOrLaundry": 1,
|
||||||
|
"https://schema.org/DryCleaningOrLaundry": 1,
|
||||||
|
"http://schema.org/EmergencyService": 1,
|
||||||
|
"https://schema.org/EmergencyService": 1,
|
||||||
|
"http://schema.org/EmploymentAgency": 1,
|
||||||
|
"https://schema.org/EmploymentAgency": 1,
|
||||||
|
"http://schema.org/EntertainmentBusiness": 1,
|
||||||
|
"https://schema.org/EntertainmentBusiness": 1,
|
||||||
|
"http://schema.org/FinancialService": 1,
|
||||||
|
"https://schema.org/FinancialService": 1,
|
||||||
|
"http://schema.org/FoodEstablishment": 1,
|
||||||
|
"https://schema.org/FoodEstablishment": 1,
|
||||||
|
"http://schema.org/GovernmentOffice": 1,
|
||||||
|
"https://schema.org/GovernmentOffice": 1,
|
||||||
|
"http://schema.org/HealthAndBeautyBusiness": 1,
|
||||||
|
"https://schema.org/HealthAndBeautyBusiness": 1,
|
||||||
|
"http://schema.org/HomeAndConstructionBusiness": 1,
|
||||||
|
"https://schema.org/HomeAndConstructionBusiness": 1,
|
||||||
|
"http://schema.org/InternetCafe": 1,
|
||||||
|
"https://schema.org/InternetCafe": 1,
|
||||||
|
"http://schema.org/LegalService": 1,
|
||||||
|
"https://schema.org/LegalService": 1,
|
||||||
|
"http://schema.org/Library": 1,
|
||||||
|
"https://schema.org/Library": 1,
|
||||||
|
"http://schema.org/LodgingBusiness": 1,
|
||||||
|
"https://schema.org/LodgingBusiness": 1,
|
||||||
|
"http://schema.org/ProfessionalService": 1,
|
||||||
|
"https://schema.org/ProfessionalService": 1,
|
||||||
|
"http://schema.org/RadioStation": 1,
|
||||||
|
"https://schema.org/RadioStation": 1,
|
||||||
|
"http://schema.org/RealEstateAgent": 1,
|
||||||
|
"https://schema.org/RealEstateAgent": 1,
|
||||||
|
"http://schema.org/RecyclingCenter": 1,
|
||||||
|
"https://schema.org/RecyclingCenter": 1,
|
||||||
|
"http://schema.org/SelfStorage": 1,
|
||||||
|
"https://schema.org/SelfStorage": 1,
|
||||||
|
"http://schema.org/ShoppingCenter": 1,
|
||||||
|
"https://schema.org/ShoppingCenter": 1,
|
||||||
|
"http://schema.org/SportsActivityLocation": 1,
|
||||||
|
"https://schema.org/SportsActivityLocation": 1,
|
||||||
|
"http://schema.org/Store": 1,
|
||||||
|
"https://schema.org/Store": 1,
|
||||||
|
"http://schema.org/TelevisionStation": 1,
|
||||||
|
"https://schema.org/TelevisionStation": 1,
|
||||||
|
"http://schema.org/TouristInformationCenter": 1,
|
||||||
|
"https://schema.org/TouristInformationCenter": 1,
|
||||||
|
"http://schema.org/TravelAgency": 1,
|
||||||
|
"https://schema.org/TravelAgency": 1,
|
||||||
|
}),
|
||||||
|
(SchemaDataExtractor.validBaseSchemaTypes = {
|
||||||
|
"http://schema.org/PostalAddress": 1,
|
||||||
|
"https://schema.org/PostalAddress": 1,
|
||||||
|
}),
|
||||||
|
(SchemaDataExtractor.containsSchemaOrgKey = "containsSchemaOrg"),
|
||||||
|
(SchemaDataExtractor.containsMicrodataKey = "containsMicrodata"),
|
||||||
|
(SchemaDataExtractor.schemaOrgTypeDomain = "schema.org"),
|
||||||
|
(SchemaDataExtractor.prototype = {
|
||||||
|
isValidParentSchemaType: function (t) {
|
||||||
|
return SchemaDataExtractor.validParentSchemaTypes[t];
|
||||||
|
},
|
||||||
|
isValidBaseSchemaType: function (t) {
|
||||||
|
return SchemaDataExtractor.validBaseSchemaTypes[t];
|
||||||
|
},
|
||||||
|
extractFilteredSchemaValuesFromMicroData: function () {
|
||||||
|
const t = document.querySelectorAll("[itemscope]");
|
||||||
|
let e = [],
|
||||||
|
r = [],
|
||||||
|
a = !1;
|
||||||
|
for (let o of t) {
|
||||||
|
let t = o.getAttribute("itemType");
|
||||||
|
t &&
|
||||||
|
(this.isValidParentSchemaType(t) && e.push(o),
|
||||||
|
this.isValidBaseSchemaType(t) && r.push(o),
|
||||||
|
!a &&
|
||||||
|
t.includes(SchemaDataExtractor.schemaOrgTypeDomain) &&
|
||||||
|
(a = !0));
|
||||||
|
}
|
||||||
|
let o = {};
|
||||||
|
if (!a) return o;
|
||||||
|
if (((o[SchemaDataExtractor.containsSchemaOrgKey] = !0), 1 !== r.length))
|
||||||
|
return o;
|
||||||
|
const s = r[0],
|
||||||
|
c = s.getAttribute("itemtype");
|
||||||
|
if (!c || -1 === c.indexOf("PostalAddress")) return o;
|
||||||
|
const n = s.querySelectorAll("[itemprop]");
|
||||||
|
for (let t of n) {
|
||||||
|
let e = t.getAttribute("itemprop");
|
||||||
|
e &&
|
||||||
|
SchemaDataExtractor.validAddressProperties[e] &&
|
||||||
|
(o[e] = t.textContent ? t.textContent : t.getAttribute("content"));
|
||||||
|
}
|
||||||
|
let h = s.parentNode;
|
||||||
|
for (; null !== h && -1 === e.indexOf(h); ) h = h.parentNode;
|
||||||
|
const i = s.querySelectorAll("[itemprop='telephone']");
|
||||||
|
if (null !== h) {
|
||||||
|
let t = h.querySelectorAll("[itemprop='name']");
|
||||||
|
(t.length && (o.name = t[0].textContent),
|
||||||
|
0 === i.length && (i = h.querySelectorAll("[itemprop='telephone']")));
|
||||||
|
}
|
||||||
|
return (i.length && (o.telephone = i[0].textContent), o);
|
||||||
|
},
|
||||||
|
extractAllSchemaValuesFromMicroData: function () {
|
||||||
|
const t = document.querySelectorAll("[itemscope]");
|
||||||
|
let e = [],
|
||||||
|
r = !1;
|
||||||
|
for (let a of t) {
|
||||||
|
const t = a.getAttribute("itemType");
|
||||||
|
t &&
|
||||||
|
(e.push(a),
|
||||||
|
!r &&
|
||||||
|
t.includes(SchemaDataExtractor.schemaOrgTypeDomain) &&
|
||||||
|
(r = !0));
|
||||||
|
}
|
||||||
|
let a = {};
|
||||||
|
if (!r) return a;
|
||||||
|
if (((a[SchemaDataExtractor.containsSchemaOrgKey] = !0), 1 !== e.length))
|
||||||
|
return a;
|
||||||
|
const o = e[0],
|
||||||
|
s = (o.getAttribute("itemtype"), o.querySelectorAll("[itemprop]"));
|
||||||
|
for (let t of s) {
|
||||||
|
let e = t.getAttribute("itemprop");
|
||||||
|
e && (a[e] = t.textContent ? t.textContent : t.getAttribute("content"));
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
},
|
||||||
|
extractFilteredSchemaValuesFromJSONLD: function () {
|
||||||
|
let t = {};
|
||||||
|
const e = document.querySelector('script[type="application/ld+json"]');
|
||||||
|
if (!e) return t;
|
||||||
|
let r;
|
||||||
|
try {
|
||||||
|
r = JSON.parse(e.text);
|
||||||
|
} catch (e) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
let a = r["@context"];
|
||||||
|
if ("http://schema.org" !== a && "https://schema.org" !== a) return t;
|
||||||
|
t[SchemaDataExtractor.containsSchemaOrgKey] = !0;
|
||||||
|
let o = [];
|
||||||
|
for (o.unshift(r); o.length; ) {
|
||||||
|
let e = o.shift();
|
||||||
|
if (null != e) {
|
||||||
|
if (
|
||||||
|
(Object.prototype.hasOwnProperty.call(e, "telephone") &&
|
||||||
|
(t.telephone = e.telephone),
|
||||||
|
"PostalAddress" === e["@type"])
|
||||||
|
) {
|
||||||
|
for (let r in e)
|
||||||
|
SchemaDataExtractor.validAddressProperties[r] && (t[r] = e[r]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (let t in e) {
|
||||||
|
let r = e[t];
|
||||||
|
"object" == typeof r && o.push(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
},
|
||||||
|
extractAllSchemaValuesFromJSONLD: function () {
|
||||||
|
let t = {};
|
||||||
|
const e = document.querySelector('script[type="application/ld+json"]');
|
||||||
|
if (!e) return t;
|
||||||
|
let r, a;
|
||||||
|
try {
|
||||||
|
r = JSON.parse(e.text);
|
||||||
|
} catch (e) {
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
((a = Array.isArray(r) ? r[0]["@context"] : r["@context"]),
|
||||||
|
"http://schema.org" !== a && "https://schema.org" !== a)
|
||||||
|
)
|
||||||
|
return t;
|
||||||
|
t[SchemaDataExtractor.containsSchemaOrgKey] = !0;
|
||||||
|
let o = [];
|
||||||
|
o.unshift(r);
|
||||||
|
const s = o.shift();
|
||||||
|
for (let e in s) t[e] = s[e];
|
||||||
|
return t;
|
||||||
|
},
|
||||||
|
resultHasAddressOrTelephone: function (t) {
|
||||||
|
return (
|
||||||
|
null != t &&
|
||||||
|
(Object.prototype.hasOwnProperty.call(t, "streetAddress") ||
|
||||||
|
Object.prototype.hasOwnProperty.call(t, "telephone"))
|
||||||
|
);
|
||||||
|
},
|
||||||
|
resultHasSchemaOrgInfo: function (t) {
|
||||||
|
return (
|
||||||
|
null != t &&
|
||||||
|
Object.prototype.hasOwnProperty.call(
|
||||||
|
t,
|
||||||
|
SchemaDataExtractor.containsSchemaOrgKey,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
extractSchemaValuesFromSchemaOrg: function () {
|
||||||
|
let t = this.extractAllSchemaValuesFromMicroData(),
|
||||||
|
e = this.extractFilteredSchemaValuesFromMicroData();
|
||||||
|
return (
|
||||||
|
this.resultHasAddressOrTelephone(e) ||
|
||||||
|
(e = this.extractFilteredSchemaValuesFromJSONLD()),
|
||||||
|
this.resultHasAddressOrTelephone(t) ||
|
||||||
|
(t = this.extractAllSchemaValuesFromJSONLD()),
|
||||||
|
(this.resultHasAddressOrTelephone(e) ||
|
||||||
|
this.resultHasSchemaOrgInfo(e)) &&
|
||||||
|
(e.url = location.href),
|
||||||
|
[e, t]
|
||||||
|
);
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
"undefined" == typeof SchemaDataExtractorJS &&
|
||||||
|
(SchemaDataExtractorJS = new SchemaDataExtractor()),
|
||||||
|
SchemaDataExtractorJS.extractSchemaValuesFromSchemaOrg());
|
||||||
20
26.2/js/schema/SchemaOrgMarkupChecker.js
Normal file
20
26.2/js/schema/SchemaOrgMarkupChecker.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//# sourceURL=__InjectedScript_SchemaOrgMarkupChecker.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
(function () {
|
||||||
|
const e = "schema.org";
|
||||||
|
var t = document.querySelectorAll('script[type="application/ld+json"]');
|
||||||
|
for (let o of t) {
|
||||||
|
var r;
|
||||||
|
try {
|
||||||
|
r = JSON.parse(o.text);
|
||||||
|
} catch (e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (r["@context"].toLowerCase().includes(e)) return !0;
|
||||||
|
}
|
||||||
|
var o = document.querySelectorAll("[itemscope]");
|
||||||
|
for (let t of o) {
|
||||||
|
var c = t.getAttribute("itemType");
|
||||||
|
if (c && c.toLowerCase().includes(e)) return !0;
|
||||||
|
}
|
||||||
|
})();
|
||||||
22
26.2/js/search/OpenSearchURLFinder.js
Normal file
22
26.2/js/search/OpenSearchURLFinder.js
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//# sourceURL=__InjectedScript_OpenSearchURLFinder.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
var OpenSearchURLFinder = function () {};
|
||||||
|
OpenSearchURLFinder.prototype = {
|
||||||
|
firstOpenSearchURLString: function () {
|
||||||
|
if (!document.head) return null;
|
||||||
|
for (
|
||||||
|
var e = document.head.getElementsByTagName("link"), r = e.length, n = 0;
|
||||||
|
n < r;
|
||||||
|
++n
|
||||||
|
) {
|
||||||
|
var t = e[n];
|
||||||
|
if (
|
||||||
|
"search" === t.getAttribute("rel") &&
|
||||||
|
"application/opensearchdescription+xml" === t.getAttribute("type")
|
||||||
|
)
|
||||||
|
return t.href;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
var OpenSearchURLFinderJS = new OpenSearchURLFinder();
|
||||||
189
26.2/js/search/QuickWebsiteSearchURLDetector.js
Normal file
189
26.2/js/search/QuickWebsiteSearchURLDetector.js
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
//# sourceURL=__InjectedScript_QuickWebsiteSearchURLDetector.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
"use strict";
|
||||||
|
function urlEncode(e) {
|
||||||
|
return encodeURIComponent(e).replace(/%20/g, "+");
|
||||||
|
}
|
||||||
|
function regularExpressionForDomainMatching(e) {
|
||||||
|
return new RegExp("(^|.)" + e.replaceAll(".", "\\.") + "$");
|
||||||
|
}
|
||||||
|
function userIsOnDomain(e) {
|
||||||
|
return regularExpressionForDomainMatching(e).test(document.location.hostname);
|
||||||
|
}
|
||||||
|
function isTextField(e) {
|
||||||
|
if (e instanceof HTMLTextAreaElement) return !0;
|
||||||
|
if (!(e instanceof HTMLInputElement)) return !1;
|
||||||
|
const t = {
|
||||||
|
date: !0,
|
||||||
|
"datetime-local": !0,
|
||||||
|
email: !0,
|
||||||
|
isindex: !0,
|
||||||
|
month: !0,
|
||||||
|
number: !0,
|
||||||
|
password: !0,
|
||||||
|
search: !0,
|
||||||
|
tel: !0,
|
||||||
|
telephone: !0,
|
||||||
|
text: !0,
|
||||||
|
time: !0,
|
||||||
|
url: !0,
|
||||||
|
week: !0,
|
||||||
|
};
|
||||||
|
var n = e.type;
|
||||||
|
return !n || n in t;
|
||||||
|
}
|
||||||
|
function queryAllBySelector(e, t) {
|
||||||
|
try {
|
||||||
|
return window.collectMatchingElementsInFlatTree(e, t);
|
||||||
|
} catch (e) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function elementsInFormPiercingShadowDOM(e) {
|
||||||
|
e.elements;
|
||||||
|
return queryAllBySelector(
|
||||||
|
e,
|
||||||
|
"button, fieldset, input:not([type='image']), object, output, select, textarea",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function getLocalName(e) {
|
||||||
|
var t = e.localName;
|
||||||
|
return "string" == typeof t || "string" == typeof (t = e.nodeName)
|
||||||
|
? t
|
||||||
|
: void 0;
|
||||||
|
}
|
||||||
|
function isSelectInDefaultState(e) {
|
||||||
|
let t = e.options,
|
||||||
|
n = t.length;
|
||||||
|
for (var r = 0; r < n; ++r) {
|
||||||
|
let n = t[r];
|
||||||
|
if (n.selected !== n.defaultSelected) {
|
||||||
|
if (n.defaultSelected) return !1;
|
||||||
|
if (e.multiple || r) return !1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !0;
|
||||||
|
}
|
||||||
|
function isSubmitButton(e) {
|
||||||
|
return (
|
||||||
|
(e instanceof HTMLButtonElement || e instanceof HTMLInputElement) &&
|
||||||
|
e.type &&
|
||||||
|
"submit" === e.type
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function isSecureTextField(e) {
|
||||||
|
if (!(e instanceof HTMLInputElement)) return !1;
|
||||||
|
try {
|
||||||
|
if (e.matches(":-webkit-autofill-strong-password")) return !0;
|
||||||
|
} catch (e) {}
|
||||||
|
const t = getComputedStyle(e, null).getPropertyValue("-webkit-text-security"),
|
||||||
|
n = e.type;
|
||||||
|
if ("none" !== t || "password" === n) return !0;
|
||||||
|
if (n && "text" !== n) return !1;
|
||||||
|
if (userIsOnDomain("ninehours.co.jp")) {
|
||||||
|
let t = e.name;
|
||||||
|
if ("guestPassword" === t || "guestPasswordConfirm" === t) return !0;
|
||||||
|
}
|
||||||
|
return !1;
|
||||||
|
}
|
||||||
|
function isCheckboxOrRadioButtonInDefaultState(e) {
|
||||||
|
return e.checked === e.defaultChecked;
|
||||||
|
}
|
||||||
|
function textAreaElementLookLikeItIsPartOfASearchForm(e) {
|
||||||
|
return (
|
||||||
|
e instanceof HTMLTextAreaElement &&
|
||||||
|
("search" === e.getAttribute("type") ||
|
||||||
|
"search" === e.inputMode ||
|
||||||
|
"search" === e.getAttribute("enterkeyhint"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
function isInputAllowedInSearchForm(e) {
|
||||||
|
const t = getLocalName(e).toLowerCase();
|
||||||
|
if ("button" === t || "fieldset" === t) return !0;
|
||||||
|
if ("select" === t) return isSelectInDefaultState(e);
|
||||||
|
if ("input" !== t && !textAreaElementLookLikeItIsPartOfASearchForm(e))
|
||||||
|
return !1;
|
||||||
|
const n = e.type;
|
||||||
|
return "radio" === n || "checkbox" === n
|
||||||
|
? isCheckboxOrRadioButtonInDefaultState(e)
|
||||||
|
: "hidden" === n ||
|
||||||
|
"reset" === n ||
|
||||||
|
"submit" === n ||
|
||||||
|
"button" === n ||
|
||||||
|
"image" === n ||
|
||||||
|
(isTextField(e) && !isSecureTextField(e));
|
||||||
|
}
|
||||||
|
function isSearchForm(e) {
|
||||||
|
if ("get" !== e.method) return !1;
|
||||||
|
const t = elementsInFormPiercingShadowDOM(e),
|
||||||
|
n = t.length;
|
||||||
|
for (let e = 0; e < n; ++e) if (!isInputAllowedInSearchForm(t[e])) return !1;
|
||||||
|
return !0;
|
||||||
|
}
|
||||||
|
function visibleNonEmptyFormTextControlsInForm(e) {
|
||||||
|
let t = [],
|
||||||
|
n = elementsInFormPiercingShadowDOM(e),
|
||||||
|
r = n.length;
|
||||||
|
for (let e = 0; e < r; ++e) {
|
||||||
|
let r = n[e];
|
||||||
|
r.checkVisibility() &&
|
||||||
|
null != r.value &&
|
||||||
|
r.value.length &&
|
||||||
|
isTextField(r) &&
|
||||||
|
t.push(r);
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function shouldInputBeIncludedInSearchURLQuery(e) {
|
||||||
|
if (e.disabled) return !1;
|
||||||
|
if (!e.name.length) return !1;
|
||||||
|
if (!e.value.length) return !1;
|
||||||
|
if (e instanceof HTMLSelectElement) return !0;
|
||||||
|
var t = getLocalName(e).toLowerCase(),
|
||||||
|
n = e.type;
|
||||||
|
return "button" === t
|
||||||
|
? "submit" === n
|
||||||
|
: "input" === t &&
|
||||||
|
("submit" === n ||
|
||||||
|
("checkbox" === n || "radio" === n
|
||||||
|
? e.checked
|
||||||
|
: "hidden" === n || isTextField(e)));
|
||||||
|
}
|
||||||
|
function searchTextFieldFormSubmissionURLString(e) {
|
||||||
|
const t = e.form;
|
||||||
|
if (!t) return null;
|
||||||
|
let n = t.getAttribute("action");
|
||||||
|
if (!n || !n.length) return null;
|
||||||
|
if (!/^https?:/i.test(t.action)) return null;
|
||||||
|
let r = null,
|
||||||
|
i = "",
|
||||||
|
o = elementsInFormPiercingShadowDOM(t),
|
||||||
|
u = o.length;
|
||||||
|
for (let t = 0; t < u; ++t) {
|
||||||
|
let n = o[t];
|
||||||
|
if (
|
||||||
|
(n === e || shouldInputBeIncludedInSearchURLQuery(n)) &&
|
||||||
|
(!isSubmitButton(n) || (r || (r = n), n === r))
|
||||||
|
) {
|
||||||
|
i.length && (i += "&");
|
||||||
|
var l = n === e ? "{searchTerms}" : urlEncode(n.value);
|
||||||
|
i += urlEncode(n.name) + "=" + l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let s = document.createElement("a");
|
||||||
|
return ((s.href = t.action), (s.search = i), s.href);
|
||||||
|
}
|
||||||
|
function handleFormSubmission(e) {
|
||||||
|
const t = e.target;
|
||||||
|
if (!isSearchForm(t)) return;
|
||||||
|
const n = visibleNonEmptyFormTextControlsInForm(t);
|
||||||
|
if (n.length > 1) return;
|
||||||
|
const r = n[0];
|
||||||
|
if (!r) return;
|
||||||
|
const i = searchTextFieldFormSubmissionURLString(r);
|
||||||
|
i &&
|
||||||
|
window.webkit.messageHandlers.quickWebsiteSearchDetectedSearchURL.postMessage(
|
||||||
|
i,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
window.addEventListener("submit", handleFormSubmission);
|
||||||
5
26.2/js/translation/Translation.js
Normal file
5
26.2/js/translation/Translation.js
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
//# sourceURL=__InjectedScript_Translation.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
function updateLanguageAttributesForTranslation(n) {
|
||||||
|
document.documentElement.lang && (document.documentElement.lang = n);
|
||||||
|
}
|
||||||
749
26.2/js/utilities/NodePath.js
Normal file
749
26.2/js/utilities/NodePath.js
Normal file
@@ -0,0 +1,749 @@
|
|||||||
|
//# sourceURL=__InjectedScript_NodePath.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
// Copyright (C) 2023-2024 Apple Inc. All rights reserved.
|
||||||
|
"use strict";
|
||||||
|
(globalThis.WAS || (globalThis.WAS = {}),
|
||||||
|
(WAS.NodePath = class {
|
||||||
|
static {
|
||||||
|
function e(e, t) {
|
||||||
|
if (e === t) return 0;
|
||||||
|
for (
|
||||||
|
var n = e.length, o = t.length, a = new Array(n + 1), i = 0;
|
||||||
|
i < n + 1;
|
||||||
|
++i
|
||||||
|
)
|
||||||
|
((a[i] = new Array(o + 1)), (a[i][0] = i));
|
||||||
|
for (var s = 0; s < o + 1; ++s) a[0][s] = s;
|
||||||
|
for (s = 1; s < o + 1; ++s) {
|
||||||
|
let o = t[s - 1];
|
||||||
|
for (i = 1; i < n + 1; ++i)
|
||||||
|
if (e[i - 1] === o) a[i][s] = a[i - 1][s - 1];
|
||||||
|
else {
|
||||||
|
var d = a[i - 1][s] + 1,
|
||||||
|
r = a[i][s - 1] + 1,
|
||||||
|
h = a[i - 1][s - 1] + 1;
|
||||||
|
a[i][s] = Math.min(d, r, h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a[n][o];
|
||||||
|
}
|
||||||
|
((WAS.Assert =
|
||||||
|
WAS.Assert ||
|
||||||
|
class {
|
||||||
|
static isTrue(e, t, ...n) {}
|
||||||
|
static isType(e, ...t) {}
|
||||||
|
static optionalIsType(e, ...t) {}
|
||||||
|
static arrayContentIsType(e, ...t) {}
|
||||||
|
static optionalArrayContentIsType(e, ...t) {}
|
||||||
|
static isEnum(e, t) {}
|
||||||
|
static optionalIsEnum(e, t) {}
|
||||||
|
static isSubclass(e, t) {}
|
||||||
|
static notReached(e, ...t) {}
|
||||||
|
}),
|
||||||
|
Object.defineProperties(CharacterData, {
|
||||||
|
nodePath_isCharacterData: {
|
||||||
|
value(e) {
|
||||||
|
switch (Node.nodePath_nodeType(e)) {
|
||||||
|
case Node.TEXT_NODE:
|
||||||
|
case Node.CDATA_SECTION_NODE:
|
||||||
|
case Node.PROCESSING_INSTRUCTION_NODE:
|
||||||
|
case Node.COMMENT_NODE:
|
||||||
|
return !0;
|
||||||
|
default:
|
||||||
|
return !1;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nodePath_data: {
|
||||||
|
value: (e) =>
|
||||||
|
CharacterData.nodePath_isCharacterData(e)
|
||||||
|
? Object.nodePath_get(e, CharacterData, "data")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Document, {
|
||||||
|
nodePath_isDocument: {
|
||||||
|
value: (e) => Node.nodePath_nodeType(e) === Node.DOCUMENT_NODE,
|
||||||
|
},
|
||||||
|
nodePath_defaultView: {
|
||||||
|
value: (e) =>
|
||||||
|
Document.nodePath_isDocument(e)
|
||||||
|
? Object.nodePath_get(e, Document, "defaultView")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Element, {
|
||||||
|
nodePath_isElement: {
|
||||||
|
value: (e) => Node.nodePath_nodeType(e) === Node.ELEMENT_NODE,
|
||||||
|
},
|
||||||
|
nodePath_tagName: {
|
||||||
|
value: (e) =>
|
||||||
|
Element.nodePath_isElement(e)
|
||||||
|
? Object.nodePath_get(e, Element, "tagName")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
nodePath_id: {
|
||||||
|
value: (e) =>
|
||||||
|
Element.nodePath_isElement(e)
|
||||||
|
? Object.nodePath_get(e, Element, "id")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
nodePath_className: {
|
||||||
|
value: (e) =>
|
||||||
|
Element.nodePath_isElement(e)
|
||||||
|
? Object.nodePath_get(e, Element, "className")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
nodePath_shadowRoot: {
|
||||||
|
value: (e) =>
|
||||||
|
Element.nodePath_isElement(e)
|
||||||
|
? Object.nodePath_get(e, Element, "shadowRoot")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
nodePath_querySelectorAll: {
|
||||||
|
value: (e, t) =>
|
||||||
|
Element.nodePath_isElement(e)
|
||||||
|
? Element.prototype.querySelectorAll.call(e, t)
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(HTMLIFrameElement, {
|
||||||
|
nodePath_isHTMLIFrameElement: {
|
||||||
|
value: (e) =>
|
||||||
|
Node.nodePath_nodeType(e) === Node.ELEMENT_NODE &&
|
||||||
|
"HTMLIFrameElement" === Object.getPrototypeOf(e).constructor.name,
|
||||||
|
},
|
||||||
|
nodePath_contentWindowDocument: {
|
||||||
|
value(e) {
|
||||||
|
if (!HTMLIFrameElement.nodePath_isHTMLIFrameElement(e))
|
||||||
|
return null;
|
||||||
|
try {
|
||||||
|
return Object.nodePath_get(
|
||||||
|
e,
|
||||||
|
HTMLIFrameElement,
|
||||||
|
"contentWindow",
|
||||||
|
).document;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Node, {
|
||||||
|
nodePath_nodeType: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "nodeType")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_firstChild: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "firstChild")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_nextSibling: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "nextSibling")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_previousSibling: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "previousSibling")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_childNodes: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "childNodes")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_textContent: {
|
||||||
|
value: (e) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Object.nodePath_get(e, Node, "textContent")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_cloneNode: {
|
||||||
|
value: (e, { shouldIncludeSubtree: t }) => (
|
||||||
|
WAS.Assert.isType(e, Node),
|
||||||
|
Node.prototype.cloneNode.call(e, t)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_isEmptyTextNode: {
|
||||||
|
value: (e) =>
|
||||||
|
Text.nodePath_isText(e) &&
|
||||||
|
CharacterData.nodePath_data(e)
|
||||||
|
.nodePath_isEmptyExcludingWhitespace,
|
||||||
|
},
|
||||||
|
nodePath_siblingIndexOfNode: {
|
||||||
|
value(e) {
|
||||||
|
let t = 0;
|
||||||
|
for (
|
||||||
|
let n = Node.nodePath_previousSibling(e);
|
||||||
|
n;
|
||||||
|
n = Node.nodePath_previousSibling(n)
|
||||||
|
)
|
||||||
|
Node.nodePath_includeWhenComputingSiblingIndex(n) && ++t;
|
||||||
|
return t;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nodePath_includeWhenComputingSiblingIndex: {
|
||||||
|
value: (e) =>
|
||||||
|
!(
|
||||||
|
Node.nodePath_isEmptyTextNode(e) ||
|
||||||
|
(Element.nodePath_isElement(e) &&
|
||||||
|
"SCRIPT" === Element.nodePath_tagName(e).toUpperCase())
|
||||||
|
),
|
||||||
|
},
|
||||||
|
nodePath_immediateSourceMarkupOfNode: {
|
||||||
|
value: (e) =>
|
||||||
|
Node.nodePath_nodeType(e) === Node.DOCUMENT_FRAGMENT_NODE
|
||||||
|
? null
|
||||||
|
: Node.nodePath_cloneNode(e, { shouldIncludeSubtree: !1 })
|
||||||
|
.outerHTML,
|
||||||
|
},
|
||||||
|
nodePath_immediateInnerTextOfNode: {
|
||||||
|
value(e) {
|
||||||
|
if (!Node.prototype.hasChildNodes.call(e))
|
||||||
|
return Node.nodePath_textContent(e)?.trim();
|
||||||
|
let t = "";
|
||||||
|
for (let n of Node.nodePath_childNodes(e))
|
||||||
|
Text.nodePath_isText(n) &&
|
||||||
|
(t += CharacterData.nodePath_data(n));
|
||||||
|
return t.trim();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nodePath_getBoundingClientRect: {
|
||||||
|
value(e) {
|
||||||
|
if ((WAS.Assert.isType(e, Node, Range), e instanceof Range))
|
||||||
|
return e.getBoundingClientRect();
|
||||||
|
if (Text.nodePath_isText(e)) {
|
||||||
|
let t = new Range();
|
||||||
|
return (
|
||||||
|
t.setStart(e, 0),
|
||||||
|
t.setEnd(e, CharacterData.nodePath_data(e).length),
|
||||||
|
t.getBoundingClientRect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Element.nodePath_isElement(e)
|
||||||
|
? Element.prototype.getBoundingClientRect.call(e)
|
||||||
|
: null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Object, {
|
||||||
|
nodePath_get: {
|
||||||
|
value: (e, t, n) =>
|
||||||
|
Object.getOwnPropertyDescriptor(t.prototype, n)?.get?.call?.(e),
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Range, {
|
||||||
|
nodePath_fromNode: {
|
||||||
|
value(e) {
|
||||||
|
let t = new Range();
|
||||||
|
return (t.selectNode(e), t);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nodePath_isSingleElementRange: {
|
||||||
|
value: (e) =>
|
||||||
|
e.startContainer === e.endContainer &&
|
||||||
|
!Text.nodePath_isText(e.commonAncestorContainer) &&
|
||||||
|
1 === Math.abs(e.endOffset - e.startOffset),
|
||||||
|
},
|
||||||
|
nodePath_singleElementFromRange: {
|
||||||
|
value: (e) =>
|
||||||
|
Range.nodePath_isSingleElementRange(e)
|
||||||
|
? Node.nodePath_childNodes(e.commonAncestorContainer)[
|
||||||
|
e.startOffset
|
||||||
|
]
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
nodePath_startNodeFromRange: {
|
||||||
|
value: (e) =>
|
||||||
|
Text.nodePath_isText(e.startContainer)
|
||||||
|
? null
|
||||||
|
: Node.nodePath_childNodes(e.startContainer)[e.startOffset],
|
||||||
|
},
|
||||||
|
nodePath_endNodeFromRange: {
|
||||||
|
value: (e) =>
|
||||||
|
Text.nodePath_isText(e.endContainer)
|
||||||
|
? Node.nodePath_childNodes(e.endContainer)[e.endOffset - 1]
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Range.prototype, {
|
||||||
|
nodePath_equals: {
|
||||||
|
value(e) {
|
||||||
|
return (
|
||||||
|
this.commonAncestorContainer === e.commonAncestorContainer &&
|
||||||
|
0 === this.compareBoundaryPoints(Range.START_TO_START, e) &&
|
||||||
|
0 === this.compareBoundaryPoints(Range.END_TO_END, e)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(ShadowRoot, {
|
||||||
|
nodePath_isShadowRoot: {
|
||||||
|
value: (e) =>
|
||||||
|
Node.nodePath_nodeType(e) === Node.DOCUMENT_FRAGMENT_NODE &&
|
||||||
|
"ShadowRoot" === Object.getPrototypeOf(e).constructor.name,
|
||||||
|
},
|
||||||
|
nodePath_host: {
|
||||||
|
value: (e) =>
|
||||||
|
ShadowRoot.nodePath_isShadowRoot(e)
|
||||||
|
? Object.nodePath_get(e, ShadowRoot, "host")
|
||||||
|
: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(String, {
|
||||||
|
_nodePath_matchAnyNonWhitespaceRegex: { value: /\S/ },
|
||||||
|
}),
|
||||||
|
Object.defineProperties(String.prototype, {
|
||||||
|
nodePath_isEmptyExcludingWhitespace: {
|
||||||
|
get() {
|
||||||
|
return (
|
||||||
|
!this.length ||
|
||||||
|
!String._nodePath_matchAnyNonWhitespaceRegex.test(this)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
nodePath_similarityTo: {
|
||||||
|
value(t) {
|
||||||
|
if (!t) return this.length ? 0 : 1;
|
||||||
|
let n = Math.max(this.length, t.length);
|
||||||
|
return n ? (n - e(this, t)) / n : 0;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
Object.defineProperties(Text, {
|
||||||
|
nodePath_isText: {
|
||||||
|
value: (e) => Node.nodePath_nodeType(e) === Node.TEXT_NODE,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
static ObjectRepresentationCodableInfo = { classPath: "WAS.NodePath" };
|
||||||
|
static #e = class {
|
||||||
|
#t;
|
||||||
|
#n;
|
||||||
|
#o;
|
||||||
|
#a;
|
||||||
|
#i;
|
||||||
|
#s;
|
||||||
|
#d;
|
||||||
|
#r;
|
||||||
|
constructor(
|
||||||
|
e,
|
||||||
|
t,
|
||||||
|
{
|
||||||
|
tag: n,
|
||||||
|
id: o,
|
||||||
|
classes: a,
|
||||||
|
text: i,
|
||||||
|
sourceMarkup: s,
|
||||||
|
boundingClientRect: d,
|
||||||
|
} = {},
|
||||||
|
) {
|
||||||
|
(WAS.Assert.isType(e, Number),
|
||||||
|
WAS.Assert.isType(t, Number),
|
||||||
|
WAS.Assert.optionalIsType(n, String),
|
||||||
|
WAS.Assert.optionalIsType(o, String),
|
||||||
|
WAS.Assert.optionalIsType(a, String),
|
||||||
|
WAS.Assert.optionalIsType(i, String),
|
||||||
|
WAS.Assert.optionalIsType(s, String),
|
||||||
|
WAS.Assert.optionalIsType(d, Object),
|
||||||
|
(this.#t = e),
|
||||||
|
(this.#n = t),
|
||||||
|
(this.#d = s),
|
||||||
|
(this.#r = d),
|
||||||
|
e === Node.ELEMENT_NODE
|
||||||
|
? (WAS.Assert.isTrue(n, "Tag must be present for ELEMENT_NODEs"),
|
||||||
|
(this.#o = n),
|
||||||
|
(this.#a = o?.length ? o : void 0),
|
||||||
|
(this.#i = a?.length ? a : void 0),
|
||||||
|
(this.#s = i))
|
||||||
|
: e === Node.TEXT_NODE && (this.#s = i));
|
||||||
|
}
|
||||||
|
static fromNode(e) {
|
||||||
|
WAS.Assert.isType(e, Node);
|
||||||
|
let t = Node.nodePath_nodeType(e),
|
||||||
|
n = Node.nodePath_siblingIndexOfNode(e),
|
||||||
|
o = {};
|
||||||
|
if (Element.nodePath_isElement(e)) {
|
||||||
|
((o.tag = Element.nodePath_tagName(e)),
|
||||||
|
(o.id = Element.nodePath_id(e)),
|
||||||
|
(o.classes = Element.nodePath_className(e)));
|
||||||
|
let t = Node.nodePath_immediateInnerTextOfNode(e);
|
||||||
|
t.length && (o.text = t);
|
||||||
|
} else
|
||||||
|
Text.nodePath_isText(e) && (o.text = CharacterData.nodePath_data(e));
|
||||||
|
o.sourceMarkup = Node.nodePath_immediateSourceMarkupOfNode(e);
|
||||||
|
let a = Node.nodePath_getBoundingClientRect(e);
|
||||||
|
return (
|
||||||
|
a &&
|
||||||
|
(o.boundingClientRect = {
|
||||||
|
x: a.x,
|
||||||
|
y: a.y,
|
||||||
|
width: a.width,
|
||||||
|
height: a.height,
|
||||||
|
}),
|
||||||
|
new WAS.NodePath.#e(t, n, o)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
static fromObjectRepresentation(e) {
|
||||||
|
return (
|
||||||
|
WAS.Assert.isType(e, Object),
|
||||||
|
new WAS.NodePath.#e(e.type, e.index, e)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
get objectRepresentation() {
|
||||||
|
return {
|
||||||
|
type: this.#t,
|
||||||
|
index: this.#n,
|
||||||
|
tag: this.#o,
|
||||||
|
id: this.#a,
|
||||||
|
classes: this.#i,
|
||||||
|
text: this.#s,
|
||||||
|
sourceMarkup: this.#d,
|
||||||
|
boundingClientRect: this.#r,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
get type() {
|
||||||
|
return this.#t;
|
||||||
|
}
|
||||||
|
get index() {
|
||||||
|
return this.#n;
|
||||||
|
}
|
||||||
|
get tag() {
|
||||||
|
return this.#o;
|
||||||
|
}
|
||||||
|
get id() {
|
||||||
|
return this.#a;
|
||||||
|
}
|
||||||
|
get classes() {
|
||||||
|
return this.#i;
|
||||||
|
}
|
||||||
|
get text() {
|
||||||
|
return this.#s;
|
||||||
|
}
|
||||||
|
toElementCSSSelector() {
|
||||||
|
if (this.type !== Node.ELEMENT_NODE) return null;
|
||||||
|
let e = CSS.escape(this.tag);
|
||||||
|
this.id && (e += `#${CSS.escape(this.id)}`);
|
||||||
|
for (let t of this.classes?.split(" ") ?? [])
|
||||||
|
t.length && (e += `.${CSS.escape(t)}`);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this.objectRepresentation);
|
||||||
|
}
|
||||||
|
equals(e) {
|
||||||
|
return (
|
||||||
|
WAS.Assert.optionalIsType(e, WAS.NodePath.#e),
|
||||||
|
!!e &&
|
||||||
|
this.#t === e.#t &&
|
||||||
|
this.#n === e.#n &&
|
||||||
|
this.#o === e.#o &&
|
||||||
|
this.#a === e.#a &&
|
||||||
|
this.#i === e.#i &&
|
||||||
|
this.#s === e.#s
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static #h = 1e3;
|
||||||
|
static #l = 500;
|
||||||
|
static #c = 200;
|
||||||
|
static #m = 200;
|
||||||
|
static #N = 100;
|
||||||
|
static #p = 10;
|
||||||
|
#u;
|
||||||
|
#C;
|
||||||
|
#_;
|
||||||
|
#P;
|
||||||
|
#A;
|
||||||
|
#f;
|
||||||
|
constructor(
|
||||||
|
e,
|
||||||
|
{
|
||||||
|
startContainerAdditionalComponents: t,
|
||||||
|
startContainerOffset: n,
|
||||||
|
endContainerAdditionalComponents: o,
|
||||||
|
endContainerOffset: a,
|
||||||
|
} = {},
|
||||||
|
) {
|
||||||
|
(WAS.Assert.arrayContentIsType(e, WAS.NodePath.#e),
|
||||||
|
WAS.Assert.isTrue(
|
||||||
|
e[0]?.type == Node.DOCUMENT_NODE,
|
||||||
|
"First path component should always be a document node.",
|
||||||
|
),
|
||||||
|
(this.#u = e),
|
||||||
|
(this.#_ = t),
|
||||||
|
(this.#P = n),
|
||||||
|
(this.#A = o),
|
||||||
|
(this.#f = a));
|
||||||
|
}
|
||||||
|
static #g(e, t) {
|
||||||
|
WAS.Assert.isType(e, Node);
|
||||||
|
let n = [],
|
||||||
|
o = e,
|
||||||
|
a = 0;
|
||||||
|
for (; o && (++a, !(a > 512)); ) {
|
||||||
|
let e;
|
||||||
|
for (
|
||||||
|
;
|
||||||
|
o && (n.push(WAS.NodePath.#e.fromNode(o)), (e = o), o !== t);
|
||||||
|
o = o.parentNode
|
||||||
|
);
|
||||||
|
if (e === t) break;
|
||||||
|
let a = Document.nodePath_defaultView(e);
|
||||||
|
if (a) {
|
||||||
|
o = a.frameElement;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let i = ShadowRoot.nodePath_host(e);
|
||||||
|
i && (o = i);
|
||||||
|
}
|
||||||
|
return n.toReversed();
|
||||||
|
}
|
||||||
|
static from(e, t) {
|
||||||
|
return e instanceof Range
|
||||||
|
? WAS.NodePath.fromRange(e, t)
|
||||||
|
: WAS.NodePath.fromNode(e, t);
|
||||||
|
}
|
||||||
|
static fromNode(e, t) {
|
||||||
|
let n = new WAS.NodePath(WAS.NodePath.#g(e, t));
|
||||||
|
return ((n.#C = new WeakRef(Range.nodePath_fromNode(e))), n);
|
||||||
|
}
|
||||||
|
static fromRange(e, t) {
|
||||||
|
let n = Range.nodePath_singleElementFromRange(e);
|
||||||
|
if (n) return WAS.NodePath.fromNode(n, t);
|
||||||
|
let o,
|
||||||
|
a,
|
||||||
|
i,
|
||||||
|
s,
|
||||||
|
d = WAS.NodePath.#g(e.commonAncestorContainer, t),
|
||||||
|
r = Range.nodePath_startNodeFromRange(e);
|
||||||
|
r
|
||||||
|
? (o = WAS.NodePath.#g(r, e.commonAncestorContainer).toSpliced(0, 1))
|
||||||
|
: e.startContainer !== e.commonAncestorContainer
|
||||||
|
? ((o = WAS.NodePath.#g(
|
||||||
|
e.startContainer,
|
||||||
|
e.commonAncestorContainer,
|
||||||
|
).toSpliced(0, 1)),
|
||||||
|
(a = e.startOffset))
|
||||||
|
: (o = []);
|
||||||
|
let h = Range.nodePath_endNodeFromRange(e);
|
||||||
|
h
|
||||||
|
? (i = WAS.NodePath.#g(h, e.commonAncestorContainer).toSpliced(0, 1))
|
||||||
|
: e.endContainer !== e.commonAncestorContainer
|
||||||
|
? ((i = WAS.NodePath.#g(
|
||||||
|
e.endContainer,
|
||||||
|
e.commonAncestorContainer,
|
||||||
|
).toSpliced(0, 1)),
|
||||||
|
(s = e.endOffset))
|
||||||
|
: (i = []);
|
||||||
|
let l = new WAS.NodePath(d, {
|
||||||
|
startContainerAdditionalComponents: o,
|
||||||
|
startContainerOffset: a,
|
||||||
|
endContainerAdditionalComponents: i,
|
||||||
|
endContainerOffset: s,
|
||||||
|
});
|
||||||
|
return ((l.#C = new WeakRef(e)), l);
|
||||||
|
}
|
||||||
|
static fromObjectRepresentation(e) {
|
||||||
|
const t = (e) => (
|
||||||
|
WAS.Assert.isType(e, Array),
|
||||||
|
e.map((e) => WAS.NodePath.#e.fromObjectRepresentation(e))
|
||||||
|
);
|
||||||
|
return Array.isArray(e)
|
||||||
|
? new WAS.NodePath(t(e))
|
||||||
|
: (WAS.Assert.isType(e, Object),
|
||||||
|
new WAS.NodePath(t(e.pathComponents), {
|
||||||
|
startContainerAdditionalComponents:
|
||||||
|
e.startContainerAdditionalComponents
|
||||||
|
? t(e.startContainerAdditionalComponents)
|
||||||
|
: void 0,
|
||||||
|
startContainerOffset: e.startContainerOffset ?? void 0,
|
||||||
|
endContainerAdditionalComponents: e.endContainerAdditionalComponents
|
||||||
|
? t(e.endContainerAdditionalComponents)
|
||||||
|
: void 0,
|
||||||
|
endContainerOffset: e.endContainerOffset ?? void 0,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
get objectRepresentation() {
|
||||||
|
const e = (e) => (
|
||||||
|
WAS.Assert.isType(e, Array),
|
||||||
|
e.map((e) => e.objectRepresentation)
|
||||||
|
);
|
||||||
|
return {
|
||||||
|
pathComponents: e(this.#u),
|
||||||
|
startContainerAdditionalComponents: this.#_ ? e(this.#_) : void 0,
|
||||||
|
startContainerOffset: this.#P,
|
||||||
|
endContainerAdditionalComponents: this.#A ? e(this.#A) : void 0,
|
||||||
|
endContainerOffset: this.#f,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static nodePathIsKnownFormControlInputElement(e) {
|
||||||
|
let t = e?.pathComponents.at(-1)?.tag?.toUpperCase();
|
||||||
|
switch (t) {
|
||||||
|
case "INPUT":
|
||||||
|
case "SELECT":
|
||||||
|
case "TEXTAREA":
|
||||||
|
return !0;
|
||||||
|
default:
|
||||||
|
return !1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
get pathComponents() {
|
||||||
|
return this.#u;
|
||||||
|
}
|
||||||
|
get userFriendlySummary() {
|
||||||
|
let e = this.#u.at(-1);
|
||||||
|
return e.type === Node.TEXT_NODE
|
||||||
|
? e.text.trim()
|
||||||
|
: e.text
|
||||||
|
? `${e.tag.toLowerCase()}: "${e.text.trim()}"`
|
||||||
|
: e.tag.toLowerCase();
|
||||||
|
}
|
||||||
|
toString() {
|
||||||
|
return JSON.stringify(this.objectRepresentation);
|
||||||
|
}
|
||||||
|
equals(e) {
|
||||||
|
if ((WAS.Assert.optionalIsType(e, WAS.NodePath), !e)) return !1;
|
||||||
|
if (this.#u.length !== e.#u.length) return !1;
|
||||||
|
for (let t = 0; t < this.#u.length; ++t)
|
||||||
|
if (!this.#u[t].equals(e.#u[t])) return !1;
|
||||||
|
if (this.#_?.length !== e.#_?.length) return !1;
|
||||||
|
for (let t = 0; t < this.#_?.length; ++t)
|
||||||
|
if (!this.#_[t].equals(e.#_[t])) return !1;
|
||||||
|
if (this.#A?.length !== e.#A?.length) return !1;
|
||||||
|
for (let t = 0; t < this.#A?.length; ++t)
|
||||||
|
if (!this.#A[t].equals(e.#A[t])) return !1;
|
||||||
|
return this.#P === e.#P && this.#f === e.#f;
|
||||||
|
}
|
||||||
|
resolvedRangeInDocument(e) {
|
||||||
|
let t = this.#C?.deref();
|
||||||
|
if (t?.intersectsNode(e)) return t;
|
||||||
|
if (this.#_ && this.#A) {
|
||||||
|
let t = WAS.NodePath.#E(e, [...this.#u, ...this.#_]),
|
||||||
|
n = WAS.NodePath.#E(e, [...this.#u, ...this.#A]);
|
||||||
|
if (!t || !n) return null;
|
||||||
|
let o = new Range();
|
||||||
|
return (
|
||||||
|
this.#P ? o.setStart(t, this.#P) : o.setStartBefore(t),
|
||||||
|
this.#f ? o.setEnd(n, this.#f) : o.setEndAfter(n),
|
||||||
|
(this.#C = new WeakRef(o)),
|
||||||
|
o
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let n = WAS.NodePath.#E(e, this.#u);
|
||||||
|
if (!n) return null;
|
||||||
|
let o = Range.nodePath_fromNode(n);
|
||||||
|
return ((this.#C = new WeakRef(o)), o);
|
||||||
|
}
|
||||||
|
static #E(e, t) {
|
||||||
|
(WAS.Assert.isType(e, Node),
|
||||||
|
WAS.Assert.isTrue(
|
||||||
|
Document.nodePath_isDocument(e),
|
||||||
|
"Must provide root document node in which to resolve this NodePath.",
|
||||||
|
));
|
||||||
|
let n = e;
|
||||||
|
e: for (let e = 1; e < t.length && n; ++e) {
|
||||||
|
let o = t[e],
|
||||||
|
a = -1,
|
||||||
|
i = null;
|
||||||
|
const s = () => {
|
||||||
|
n = i;
|
||||||
|
let o = t.length > e ? t[e + 1] : null;
|
||||||
|
return n &&
|
||||||
|
HTMLIFrameElement.nodePath_isHTMLIFrameElement(n) &&
|
||||||
|
o?.type === Node.DOCUMENT_NODE
|
||||||
|
? (++e,
|
||||||
|
void (n = HTMLIFrameElement.nodePath_contentWindowDocument(n)))
|
||||||
|
: n && o?.type === Node.DOCUMENT_FRAGMENT_NODE
|
||||||
|
? (++e, void (n = Element.nodePath_shadowRoot(n)))
|
||||||
|
: void 0;
|
||||||
|
};
|
||||||
|
if (Element.nodePath_isElement(n)) {
|
||||||
|
let o = [],
|
||||||
|
a = e;
|
||||||
|
for (; a < t.length; ++a) {
|
||||||
|
let e = t[a];
|
||||||
|
if (e.type !== Node.ELEMENT_NODE) break;
|
||||||
|
o.push(e.toElementCSSSelector());
|
||||||
|
}
|
||||||
|
if (o.length) {
|
||||||
|
const t = (e) => o.slice(0, o.length - e).join(" > ");
|
||||||
|
let d = null;
|
||||||
|
for (let r = 0; r < o.length; ++r)
|
||||||
|
if (
|
||||||
|
((d = Element.nodePath_querySelectorAll(n, t(r))),
|
||||||
|
1 === d.length)
|
||||||
|
) {
|
||||||
|
((i = d.item(0)), (e = a - r - 1), s());
|
||||||
|
continue e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let d = 0;
|
||||||
|
for (
|
||||||
|
let e = Node.nodePath_firstChild(n);
|
||||||
|
e;
|
||||||
|
e = Node.nodePath_nextSibling(e)
|
||||||
|
) {
|
||||||
|
if (!Node.nodePath_includeWhenComputingSiblingIndex(e)) continue;
|
||||||
|
let t = Number.MIN_VALUE,
|
||||||
|
n = !0;
|
||||||
|
const s = (e, o) => {
|
||||||
|
e ? (t += o) : (n = !1);
|
||||||
|
},
|
||||||
|
r = (e, o) => {
|
||||||
|
(1 !== e && (n = !1), (t += e * o));
|
||||||
|
},
|
||||||
|
h = (e) => {
|
||||||
|
e && ((n = !1), (t -= e));
|
||||||
|
};
|
||||||
|
if (
|
||||||
|
(s(Node.nodePath_nodeType(e) === o.type, WAS.NodePath.#h),
|
||||||
|
Element.nodePath_isElement(e))
|
||||||
|
) {
|
||||||
|
(s(Element.nodePath_tagName(e) == o.tag, WAS.NodePath.#l),
|
||||||
|
s(Element.nodePath_id(e) == o.id, WAS.NodePath.#c));
|
||||||
|
let t = Element.nodePath_className(e)?.split(" ") ?? [],
|
||||||
|
n = t.length,
|
||||||
|
a = o.classes?.split(" ") ?? [],
|
||||||
|
i = a.length;
|
||||||
|
for (let e = 0; e < a.length; ++e) {
|
||||||
|
let n = a[e],
|
||||||
|
o = t.indexOf(n);
|
||||||
|
-1 !== o && (t.splice(o, 1), a.splice(e, 1), --e);
|
||||||
|
}
|
||||||
|
(r(
|
||||||
|
(n ? (n - t.length) / n : 1) * (i ? (i - a.length) / i : 1),
|
||||||
|
WAS.NodePath.#N,
|
||||||
|
),
|
||||||
|
r(
|
||||||
|
Node.nodePath_immediateInnerTextOfNode(e).nodePath_similarityTo(
|
||||||
|
o.text,
|
||||||
|
),
|
||||||
|
WAS.NodePath.#m,
|
||||||
|
));
|
||||||
|
} else if (Text.nodePath_isText(e)) {
|
||||||
|
let t = CharacterData.nodePath_data(e)?.nodePath_similarityTo(
|
||||||
|
o.text,
|
||||||
|
);
|
||||||
|
r(t, WAS.NodePath.#m);
|
||||||
|
}
|
||||||
|
if ((h(Math.abs(d - o.index) * WAS.NodePath.#p), n)) {
|
||||||
|
((a = Number.NaN), (i = e));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(t > a && ((a = t), (i = e)), ++d);
|
||||||
|
}
|
||||||
|
s();
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}));
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
//# sourceURL=__InjectedScript_SavePageInliningOrDiscardingExternalResources.js
|
||||||
|
/* Copyright (c) 2025 Apple Inc. All rights reserved. */
|
||||||
|
function copyPage() {
|
||||||
|
function e(e) {
|
||||||
|
function t(e) {
|
||||||
|
var t = document.createElement("a");
|
||||||
|
return ((t.href = e), t);
|
||||||
|
}
|
||||||
|
function r(e) {
|
||||||
|
var t = e.pathname.substring(1).split("/");
|
||||||
|
return (t[t.length - 1] || t.pop(), t);
|
||||||
|
}
|
||||||
|
function n(e) {
|
||||||
|
var t = r(e);
|
||||||
|
return t.length ? t[t.length - 1] : null;
|
||||||
|
}
|
||||||
|
return n(t(e));
|
||||||
|
}
|
||||||
|
function t(t) {
|
||||||
|
const r = /url\((.*?\/.*?)\)/gi;
|
||||||
|
for (;;) {
|
||||||
|
var n = r.exec(t);
|
||||||
|
if (!n) break;
|
||||||
|
t = t.replace(n[0], "url(" + e(n[1]) + ")");
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
function r(e) {
|
||||||
|
function r(e, n) {
|
||||||
|
if (e) {
|
||||||
|
var i, o;
|
||||||
|
try {
|
||||||
|
i = e.rules;
|
||||||
|
} catch (e) {
|
||||||
|
i = null;
|
||||||
|
}
|
||||||
|
if (!i) {
|
||||||
|
var u = e.ownerNode;
|
||||||
|
if (!u) return;
|
||||||
|
var c = u.parentNode;
|
||||||
|
if (!c) return;
|
||||||
|
var l = u.nextSibling;
|
||||||
|
return (c.removeChild(u), r(e, n), void c.insertBefore(u, l));
|
||||||
|
}
|
||||||
|
for (var d = i.length, s = 0; s < d; ++s) {
|
||||||
|
var m = i[s];
|
||||||
|
m.type !== CSSRule.IMPORT_RULE
|
||||||
|
? (o ||
|
||||||
|
((o = document.createElement("style")),
|
||||||
|
e.media &&
|
||||||
|
e.media.length > 0 &&
|
||||||
|
o.setAttribute("media", e.media.mediaText),
|
||||||
|
n && n.media && o.setAttribute("media", n.media.mediaText),
|
||||||
|
a.push(o)),
|
||||||
|
o.appendChild(document.createTextNode(t(m.cssText) + "\n")))
|
||||||
|
: r(m.styleSheet, m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var n = e.styleSheets, a = [], i = n.length, o = 0; o < i; ++o)
|
||||||
|
r(n[o]);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
function n(e, r) {
|
||||||
|
for (var n = e.attributes, a = n.length, i = 0; i < a; ++i) {
|
||||||
|
var o = n[i],
|
||||||
|
u = o.name.toLowerCase();
|
||||||
|
if ("on" !== u.substr(0, 2)) {
|
||||||
|
var c = o.value;
|
||||||
|
"style" === u && (c = t(c));
|
||||||
|
try {
|
||||||
|
r.setAttribute(o.name, c);
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function a(e, t) {
|
||||||
|
for (var r = e.childNodes, n = r.length, a = 0; a < n; ++a) {
|
||||||
|
var o = i(r[a]);
|
||||||
|
o && t.appendChild(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function i(t) {
|
||||||
|
if (!t) return t;
|
||||||
|
if (t.nodeType === Node.TEXT_NODE) return document.createTextNode(t.data);
|
||||||
|
if (t.nodeType !== Node.ELEMENT_NODE) return null;
|
||||||
|
const c = new Set(["AUDIO", "OBJECT", "SCRIPT", "STYLE", "VIDEO"]);
|
||||||
|
var l = t.tagName.toUpperCase();
|
||||||
|
if (c.has(l)) return null;
|
||||||
|
if ("LINK" === l && "STYLESHEET" === t.rel.toUpperCase()) return null;
|
||||||
|
if ("META" === l && "CONTENT-TYPE" === t.httpEquiv.toUpperCase())
|
||||||
|
return null;
|
||||||
|
var d = document.createElement(t.tagName);
|
||||||
|
if (
|
||||||
|
(n(t, d),
|
||||||
|
a(t, d),
|
||||||
|
"IMG" === l || ("INPUT" === l && "IMAGE" === t.type.toUpperCase()))
|
||||||
|
)
|
||||||
|
return (
|
||||||
|
(d.src = e(t.src)),
|
||||||
|
d.setAttribute("width", t.width),
|
||||||
|
d.setAttribute("height", t.height),
|
||||||
|
d
|
||||||
|
);
|
||||||
|
if ("IFRAME" === l) {
|
||||||
|
try {
|
||||||
|
var s = i(t.contentDocument.documentElement);
|
||||||
|
if (s) {
|
||||||
|
var m = "iframe_" + u + ".html";
|
||||||
|
((d.src = m),
|
||||||
|
(s.dataset.originalSource = t.src),
|
||||||
|
(o[m] = s.outerHTML),
|
||||||
|
u++);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
((d.src = ""),
|
||||||
|
d.appendChild(
|
||||||
|
document.createTextNode(
|
||||||
|
"Failed to copy <iframe>: " + e + ": " + e.stack,
|
||||||
|
),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
if ("INPUT" === l) d.setAttribute("value", t.value);
|
||||||
|
else if ("HEAD" === l) {
|
||||||
|
for (var f = r(t.ownerDocument), h = f.length, p = 0; p < h; ++p)
|
||||||
|
(d.appendChild(document.createTextNode("\n")), d.appendChild(f[p]));
|
||||||
|
var v = document.createElement("meta");
|
||||||
|
((v.httpEquiv = "Content-Type"),
|
||||||
|
(v.content = "text/html; charset=UTF-8"),
|
||||||
|
d.insertBefore(v, d.firstChild));
|
||||||
|
}
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
var o = {},
|
||||||
|
u = 0,
|
||||||
|
c = i(document.documentElement);
|
||||||
|
return (
|
||||||
|
(c.dataset.originSource = window.location),
|
||||||
|
(o["main.html"] = c.outerHTML),
|
||||||
|
o
|
||||||
|
);
|
||||||
|
}
|
||||||
|
copyPage();
|
||||||
45
DEV.md
45
DEV.md
@@ -29,6 +29,36 @@ Intelligently classifies form fields to enable autofill:
|
|||||||
- **Date field parsing**: understands various date formats and splits (day/month/year)
|
- **Date field parsing**: understands various date formats and splits (day/month/year)
|
||||||
- **Smart matching**: uses pattern recognition to classify fields even without explicit HTML hints
|
- **Smart matching**: uses pattern recognition to classify fields even without explicit HTML hints
|
||||||
|
|
||||||
|
### **[FormMetadataContactsAutoFillMappings.js](26.2/js/forms/FormMetadataContactsAutoFillMappings.js)** *(New in 26.2)*
|
||||||
|
Mappings between form fields and Contacts data:
|
||||||
|
- Defines relationships between HTML form fields and Contact card properties
|
||||||
|
- Maps autofill field types to vCard/Contacts attributes
|
||||||
|
- Handles address components (street, city, state, postal code)
|
||||||
|
- Contact information mapping (name, email, phone, organization)
|
||||||
|
- Enables seamless autofill from Contacts app
|
||||||
|
|
||||||
|
### **[FormMetadataJSController.js](26.2/js/forms/FormMetadataJSController.js)** *(New in 26.2)*
|
||||||
|
JavaScript bridge for form metadata operations:
|
||||||
|
- Provides communication layer between native code and web content
|
||||||
|
- Manages form field metadata collection and updates
|
||||||
|
- Coordinates autofill operations across different contexts
|
||||||
|
- Handles form submission and validation events
|
||||||
|
|
||||||
|
### **[FormMetadataUtilities.js](26.2/js/forms/FormMetadataUtilities.js)** *(New in 26.2)*
|
||||||
|
Utility functions for form processing:
|
||||||
|
- Helper functions for form element analysis
|
||||||
|
- Field value normalization and validation
|
||||||
|
- Common patterns for field identification
|
||||||
|
- Shared utilities used across form metadata modules
|
||||||
|
|
||||||
|
### **[PasswordRulesParserJS.js](26.2/js/forms/PasswordRulesParserJS.js)** *(New in 26.2)*
|
||||||
|
Parses password requirement rules:
|
||||||
|
- Implements password rules format parsing (as per WHATWG spec)
|
||||||
|
- Interprets password requirements from websites
|
||||||
|
- Generates strong passwords that meet specific site requirements
|
||||||
|
- Handles character classes (uppercase, lowercase, digits, special)
|
||||||
|
- Validates password constraints (min/max length, required/allowed characters)
|
||||||
|
|
||||||
### **[NodePath.js](js/utilities/NodePath.js)**
|
### **[NodePath.js](js/utilities/NodePath.js)**
|
||||||
Creates stable references to DOM elements:
|
Creates stable references to DOM elements:
|
||||||
- **Path-based element identification**: creates a "fingerprint" for DOM nodes that works even when the DOM changes
|
- **Path-based element identification**: creates a "fingerprint" for DOM nodes that works even when the DOM changes
|
||||||
@@ -84,6 +114,13 @@ Safari's article detection and cleaning algorithm (similar to Mozilla's Readabil
|
|||||||
- Handles multi-column layouts
|
- Handles multi-column layouts
|
||||||
- Detects CJK (Chinese, Japanese, Korean) text using Unicode ranges
|
- Detects CJK (Chinese, Japanese, Korean) text using Unicode ranges
|
||||||
|
|
||||||
|
### **[ReaderShared.js](26.2/js/reader/ReaderShared.js)** *(New in 26.2)*
|
||||||
|
Shared utilities for Reader Mode:
|
||||||
|
- Common functions used across Reader Mode components
|
||||||
|
- Text processing and article content utilities
|
||||||
|
- DOM manipulation helpers specific to Reader Mode
|
||||||
|
- Coordinate Reader behavior between different modules
|
||||||
|
|
||||||
### **[ReaderSharedUI.js](js/reader/ReaderSharedUI.js)**
|
### **[ReaderSharedUI.js](js/reader/ReaderSharedUI.js)**
|
||||||
Powers the actual Reader Mode interface:
|
Powers the actual Reader Mode interface:
|
||||||
|
|
||||||
@@ -151,6 +188,14 @@ Enables custom search engine discovery:
|
|||||||
- Powers Safari's search engine discovery feature
|
- Powers Safari's search engine discovery feature
|
||||||
- Allows users to add custom search engines from websites
|
- Allows users to add custom search engines from websites
|
||||||
|
|
||||||
|
### **[QuickWebsiteSearchURLDetector.js](26.2/js/search/QuickWebsiteSearchURLDetector.js)** *(New in 26.2)*
|
||||||
|
Detects website search capabilities:
|
||||||
|
- Analyzes web pages for search functionality
|
||||||
|
- Identifies search forms and input fields
|
||||||
|
- Extracts search URL patterns from website structure
|
||||||
|
- Enables Safari's Quick Website Search feature
|
||||||
|
- Automatically discovers site-specific search without OpenSearch tags
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Localization & Translation
|
## Localization & Translation
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -1,8 +1,18 @@
|
|||||||
# Safari Internal JavaScript Services
|
# Safari Internal JavaScript Services
|
||||||
|
|
||||||
- Safari Version: 15.7
|
This repository contains two dumps of Safari's internal JavaScript files:
|
||||||
- Extraction Method: dyld_shared_cache
|
|
||||||
|
## Available Versions
|
||||||
|
|
||||||
|
### Safari 15.7
|
||||||
|
- Location: [`15.7/`](15.7/)
|
||||||
- Extraction Date: 16/01/2026
|
- Extraction Date: 16/01/2026
|
||||||
|
- Extraction Method: dyld_shared_cache
|
||||||
|
|
||||||
|
### Safari 26.2 (Latest)
|
||||||
|
- Location: [`26.2/`](26.2/)
|
||||||
|
- Extraction Date: 17/01/2026
|
||||||
|
- Extraction Method: dyld_shared_cache
|
||||||
|
|
||||||
**Credit:** Inspired by [safari-readability](https://github.com/dm-zharov/safari-readability) by [dm-zharov](https://github.com/dm-zharov)
|
**Credit:** Inspired by [safari-readability](https://github.com/dm-zharov/safari-readability) by [dm-zharov](https://github.com/dm-zharov)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user