opensteer 0.9.4 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-HQCMXRBE.js → chunk-7D45QUZ3.js} +3 -6
- package/dist/chunk-7D45QUZ3.js.map +1 -0
- package/dist/{chunk-GEUHKPC2.js → chunk-7LQL5YUR.js} +539 -215
- package/dist/chunk-7LQL5YUR.js.map +1 -0
- package/dist/cli/bin.cjs +549 -208
- package/dist/cli/bin.cjs.map +1 -1
- package/dist/cli/bin.js +16 -30
- package/dist/cli/bin.js.map +1 -1
- package/dist/index.cjs +533 -353
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -458
- package/dist/index.d.ts +6 -458
- package/dist/index.js +2 -3
- package/dist/opensteer-T2JENADR.js +6 -0
- package/dist/{opensteer-PJI7VUIT.js.map → opensteer-T2JENADR.js.map} +1 -1
- package/package.json +5 -5
- package/skills/opensteer/SKILL.md +134 -94
- package/dist/chunk-GEUHKPC2.js.map +0 -1
- package/dist/chunk-HQCMXRBE.js.map +0 -1
- package/dist/chunk-KCINASQC.js +0 -3
- package/dist/chunk-KCINASQC.js.map +0 -1
- package/dist/opensteer-PJI7VUIT.js +0 -6
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, assertSupportedEngineOptions,
|
|
2
|
-
import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord,
|
|
1
|
+
import { resolveFilesystemWorkspacePath, createFilesystemOpensteerWorkspace, DEFAULT_OPENSTEER_ENGINE, assertSupportedEngineOptions, normalizeObservabilityConfig, manifestToExternalBinaryLocation, normalizeObservationContext, OpensteerBrowserManager } from './chunk-GSCQQKZZ.js';
|
|
2
|
+
import { canonicalJsonString, toCanonicalJsonValue, readPersistedCloudSessionRecord, writePersistedSessionRecord, clearPersistedSessionRecord, resolveBrandUserDataDir, sha256Hex, getBrowserBrand, detectInstalledBrowserBrands, __require } from './chunk-T5P2QGZ3.js';
|
|
3
3
|
import { selectAll } from 'css-select';
|
|
4
4
|
import { createHash, randomUUID, pbkdf2Sync, createDecipheriv } from 'crypto';
|
|
5
5
|
import { existsSync, readFileSync } from 'fs';
|
|
@@ -7,7 +7,7 @@ import path2, { join } from 'path';
|
|
|
7
7
|
import { promisify } from 'util';
|
|
8
8
|
import { gzip as gzip$1 } from 'zlib';
|
|
9
9
|
import { execFile as execFile$1, spawn } from 'child_process';
|
|
10
|
-
import { rm, mkdtemp, writeFile, readFile
|
|
10
|
+
import { rm, mkdtemp, copyFile, writeFile, readFile } from 'fs/promises';
|
|
11
11
|
import { tmpdir } from 'os';
|
|
12
12
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
13
13
|
import sharp from 'sharp';
|
|
@@ -307,6 +307,7 @@ var defaultNavigationSettleObserver = {
|
|
|
307
307
|
return false;
|
|
308
308
|
}
|
|
309
309
|
try {
|
|
310
|
+
const startedAt = Date.now();
|
|
310
311
|
await input.engine.waitForPostLoadQuiet({
|
|
311
312
|
pageRef: input.pageRef,
|
|
312
313
|
timeoutMs: effectiveTimeout,
|
|
@@ -314,9 +315,13 @@ var defaultNavigationSettleObserver = {
|
|
|
314
315
|
captureWindowMs: Math.min(NAVIGATION_POST_LOAD_CAPTURE_WINDOW_MS, effectiveTimeout),
|
|
315
316
|
signal: input.signal
|
|
316
317
|
});
|
|
318
|
+
const visualTimeout = Math.max(0, effectiveTimeout - (Date.now() - startedAt));
|
|
319
|
+
if (visualTimeout <= 0) {
|
|
320
|
+
return true;
|
|
321
|
+
}
|
|
317
322
|
await input.engine.waitForVisualStability({
|
|
318
323
|
pageRef: input.pageRef,
|
|
319
|
-
timeoutMs:
|
|
324
|
+
timeoutMs: visualTimeout,
|
|
320
325
|
settleMs: profile.settleMs,
|
|
321
326
|
scope: profile.scope
|
|
322
327
|
});
|
|
@@ -4149,10 +4154,10 @@ var opensteerDomScrollInputSchema = objectSchema(
|
|
|
4149
4154
|
required: ["target", "direction", "amount"]
|
|
4150
4155
|
}
|
|
4151
4156
|
);
|
|
4152
|
-
var
|
|
4157
|
+
var opensteerExtractTemplateSchema = objectSchema(
|
|
4153
4158
|
{},
|
|
4154
4159
|
{
|
|
4155
|
-
title: "
|
|
4160
|
+
title: "OpensteerExtractTemplate",
|
|
4156
4161
|
additionalProperties: true
|
|
4157
4162
|
}
|
|
4158
4163
|
);
|
|
@@ -4160,13 +4165,13 @@ var opensteerDomExtractInputSchema = defineSchema({
|
|
|
4160
4165
|
...objectSchema(
|
|
4161
4166
|
{
|
|
4162
4167
|
persist: stringSchema(),
|
|
4163
|
-
|
|
4168
|
+
template: opensteerExtractTemplateSchema
|
|
4164
4169
|
},
|
|
4165
4170
|
{
|
|
4166
4171
|
title: "OpensteerDomExtractInput"
|
|
4167
4172
|
}
|
|
4168
4173
|
),
|
|
4169
|
-
anyOf: [defineSchema({ required: ["persist"] }), defineSchema({ required: ["
|
|
4174
|
+
anyOf: [defineSchema({ required: ["persist"] }), defineSchema({ required: ["template"] })]
|
|
4170
4175
|
});
|
|
4171
4176
|
var jsonValueSchema2 = recordSchema({}, { title: "JsonValueRecord" });
|
|
4172
4177
|
var opensteerDomExtractOutputSchema = objectSchema(
|
|
@@ -8917,9 +8922,9 @@ function isPersistedObjectNode(node) {
|
|
|
8917
8922
|
}
|
|
8918
8923
|
|
|
8919
8924
|
// ../runtime-core/src/sdk/extraction.ts
|
|
8920
|
-
function
|
|
8921
|
-
if (!
|
|
8922
|
-
throw new Error("Invalid extraction
|
|
8925
|
+
function assertValidOpensteerExtractionTemplateRoot(template) {
|
|
8926
|
+
if (!template || typeof template !== "object" || Array.isArray(template)) {
|
|
8927
|
+
throw new Error("Invalid extraction template: expected a JSON object at the top level.");
|
|
8923
8928
|
}
|
|
8924
8929
|
}
|
|
8925
8930
|
function isPersistedOpensteerExtractionValueNode2(value) {
|
|
@@ -8941,12 +8946,12 @@ function isPersistedOpensteerExtractionArrayNode2(value) {
|
|
|
8941
8946
|
return "$array" in value;
|
|
8942
8947
|
}
|
|
8943
8948
|
async function compileOpensteerExtractionFieldTargets(options) {
|
|
8944
|
-
|
|
8949
|
+
assertValidOpensteerExtractionTemplateRoot(options.template);
|
|
8945
8950
|
const fields = [];
|
|
8946
|
-
await
|
|
8951
|
+
await collectFieldTargetsFromTemplateObject({
|
|
8947
8952
|
dom: options.dom,
|
|
8948
8953
|
pageRef: options.pageRef,
|
|
8949
|
-
value: options.
|
|
8954
|
+
value: options.template,
|
|
8950
8955
|
path: "",
|
|
8951
8956
|
fields,
|
|
8952
8957
|
insideArray: false
|
|
@@ -8998,13 +9003,13 @@ function createOpensteerExtractionDescriptorStore(options) {
|
|
|
8998
9003
|
}
|
|
8999
9004
|
return new MemoryOpensteerExtractionDescriptorStore(namespace);
|
|
9000
9005
|
}
|
|
9001
|
-
async function
|
|
9006
|
+
async function collectFieldTargetsFromTemplateObject(options) {
|
|
9002
9007
|
for (const [key, childValue] of Object.entries(options.value)) {
|
|
9003
9008
|
const normalizedKey = normalizeKey(key);
|
|
9004
9009
|
if (!normalizedKey) {
|
|
9005
9010
|
continue;
|
|
9006
9011
|
}
|
|
9007
|
-
await
|
|
9012
|
+
await collectFieldTargetsFromTemplateValue({
|
|
9008
9013
|
dom: options.dom,
|
|
9009
9014
|
pageRef: options.pageRef,
|
|
9010
9015
|
value: childValue,
|
|
@@ -9014,8 +9019,8 @@ async function collectFieldTargetsFromSchemaObject(options) {
|
|
|
9014
9019
|
});
|
|
9015
9020
|
}
|
|
9016
9021
|
}
|
|
9017
|
-
async function
|
|
9018
|
-
const normalizedField =
|
|
9022
|
+
async function collectFieldTargetsFromTemplateValue(options) {
|
|
9023
|
+
const normalizedField = normalizeTemplateField(options.value);
|
|
9019
9024
|
if (normalizedField !== null) {
|
|
9020
9025
|
options.fields.push(
|
|
9021
9026
|
await compileFieldTarget({
|
|
@@ -9030,12 +9035,12 @@ async function collectFieldTargetsFromSchemaValue(options) {
|
|
|
9030
9035
|
if (Array.isArray(options.value)) {
|
|
9031
9036
|
if (options.insideArray) {
|
|
9032
9037
|
throw new Error(
|
|
9033
|
-
`Nested arrays are not supported in extraction
|
|
9038
|
+
`Nested arrays are not supported in extraction template at "${labelForPath(options.path)}".`
|
|
9034
9039
|
);
|
|
9035
9040
|
}
|
|
9036
9041
|
if (options.value.length === 0) {
|
|
9037
9042
|
throw new Error(
|
|
9038
|
-
`Extraction array "${labelForPath(options.path)}" must include at least one representative item.`
|
|
9043
|
+
`Extraction array "${labelForPath(options.path)}" must include at least one representative template item.`
|
|
9039
9044
|
);
|
|
9040
9045
|
}
|
|
9041
9046
|
for (let index = 0; index < options.value.length; index += 1) {
|
|
@@ -9046,7 +9051,7 @@ async function collectFieldTargetsFromSchemaValue(options) {
|
|
|
9046
9051
|
);
|
|
9047
9052
|
}
|
|
9048
9053
|
const fieldCountBeforeItem = options.fields.length;
|
|
9049
|
-
await
|
|
9054
|
+
await collectFieldTargetsFromTemplateObject({
|
|
9050
9055
|
dom: options.dom,
|
|
9051
9056
|
pageRef: options.pageRef,
|
|
9052
9057
|
value: itemValue,
|
|
@@ -9057,7 +9062,7 @@ async function collectFieldTargetsFromSchemaValue(options) {
|
|
|
9057
9062
|
const itemFields = options.fields.slice(fieldCountBeforeItem);
|
|
9058
9063
|
if (!itemFields.some((field) => !("source" in field))) {
|
|
9059
9064
|
throw new Error(
|
|
9060
|
-
`Extraction array "${labelForPath(options.path)}" item ${String(index)} must include at least one element
|
|
9065
|
+
`Extraction array "${labelForPath(options.path)}" item ${String(index)} must include at least one element number or selector field.`
|
|
9061
9066
|
);
|
|
9062
9067
|
}
|
|
9063
9068
|
}
|
|
@@ -9065,10 +9070,10 @@ async function collectFieldTargetsFromSchemaValue(options) {
|
|
|
9065
9070
|
}
|
|
9066
9071
|
if (!options.value || typeof options.value !== "object") {
|
|
9067
9072
|
throw new Error(
|
|
9068
|
-
`Invalid extraction
|
|
9073
|
+
`Invalid extraction template value at "${labelForPath(options.path)}": expected an object, array, or field descriptor.`
|
|
9069
9074
|
);
|
|
9070
9075
|
}
|
|
9071
|
-
await
|
|
9076
|
+
await collectFieldTargetsFromTemplateObject({
|
|
9072
9077
|
dom: options.dom,
|
|
9073
9078
|
pageRef: options.pageRef,
|
|
9074
9079
|
value: options.value,
|
|
@@ -9100,7 +9105,7 @@ async function compileFieldTarget(options) {
|
|
|
9100
9105
|
path: await resolveSelectorFieldPath({
|
|
9101
9106
|
dom: options.dom,
|
|
9102
9107
|
pageRef: options.pageRef,
|
|
9103
|
-
selector: `[c="${String(options.field.
|
|
9108
|
+
selector: `[c="${String(options.field.c)}"]`
|
|
9104
9109
|
}),
|
|
9105
9110
|
...options.field.attribute === void 0 ? {} : { attribute: options.field.attribute }
|
|
9106
9111
|
};
|
|
@@ -9401,24 +9406,29 @@ function countNonNullLeaves(value) {
|
|
|
9401
9406
|
}
|
|
9402
9407
|
return Object.values(value).reduce((sum, item) => sum + countNonNullLeaves(item), 0);
|
|
9403
9408
|
}
|
|
9404
|
-
function
|
|
9409
|
+
function normalizeTemplateField(value) {
|
|
9410
|
+
if (typeof value === "number") {
|
|
9411
|
+
return {
|
|
9412
|
+
c: normalizeExtractionCounter(value)
|
|
9413
|
+
};
|
|
9414
|
+
}
|
|
9405
9415
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
9406
9416
|
return null;
|
|
9407
9417
|
}
|
|
9408
9418
|
const raw = value;
|
|
9409
|
-
const
|
|
9419
|
+
const hasCounter = raw.c !== void 0 || raw.element !== void 0;
|
|
9410
9420
|
const hasSelector = raw.selector !== void 0;
|
|
9411
9421
|
const hasSource = raw.source !== void 0;
|
|
9412
|
-
const targetCount = Number(
|
|
9422
|
+
const targetCount = Number(hasCounter) + Number(hasSelector) + Number(hasSource);
|
|
9413
9423
|
if (targetCount === 0) {
|
|
9414
9424
|
return null;
|
|
9415
9425
|
}
|
|
9416
9426
|
if (targetCount !== 1) {
|
|
9417
9427
|
throw new Error(
|
|
9418
|
-
"Extraction field descriptors must specify exactly one of element, selector, or source."
|
|
9428
|
+
"Extraction field descriptors must specify exactly one of c/element, selector, or source."
|
|
9419
9429
|
);
|
|
9420
9430
|
}
|
|
9421
|
-
const attribute = raw.attribute === void 0 ? void 0 : normalizeNonEmptyString("attribute", raw.attribute);
|
|
9431
|
+
const attribute = raw.attr !== void 0 ? normalizeNonEmptyString("attr", raw.attr) : raw.attribute === void 0 ? void 0 : normalizeNonEmptyString("attribute", raw.attribute);
|
|
9422
9432
|
if (hasSource) {
|
|
9423
9433
|
if (raw.source !== "current_url") {
|
|
9424
9434
|
throw new Error(`Unsupported extraction source "${String(raw.source)}".`);
|
|
@@ -9433,17 +9443,20 @@ function normalizeSchemaField(value) {
|
|
|
9433
9443
|
...attribute === void 0 ? {} : { attribute }
|
|
9434
9444
|
};
|
|
9435
9445
|
}
|
|
9436
|
-
const element = Number(raw.element);
|
|
9437
|
-
if (!Number.isInteger(element) || element < 1) {
|
|
9438
|
-
throw new Error(
|
|
9439
|
-
`Extraction field element must be a positive integer, received ${String(raw.element)}.`
|
|
9440
|
-
);
|
|
9441
|
-
}
|
|
9442
9446
|
return {
|
|
9443
|
-
element,
|
|
9447
|
+
c: normalizeExtractionCounter(raw.c ?? raw.element),
|
|
9444
9448
|
...attribute === void 0 ? {} : { attribute }
|
|
9445
9449
|
};
|
|
9446
9450
|
}
|
|
9451
|
+
function normalizeExtractionCounter(value) {
|
|
9452
|
+
const counter = Number(value);
|
|
9453
|
+
if (!Number.isInteger(counter) || counter < 1) {
|
|
9454
|
+
throw new Error(
|
|
9455
|
+
`Extraction element number must be a positive integer, received ${String(value)}.`
|
|
9456
|
+
);
|
|
9457
|
+
}
|
|
9458
|
+
return counter;
|
|
9459
|
+
}
|
|
9447
9460
|
function normalizeNamespace(namespace) {
|
|
9448
9461
|
const normalized = String(namespace ?? "default").trim();
|
|
9449
9462
|
return normalized.length === 0 ? "default" : normalized;
|
|
@@ -9474,7 +9487,7 @@ function parseExtractionDescriptorRecord(record) {
|
|
|
9474
9487
|
kind: "dom-extraction",
|
|
9475
9488
|
persist: raw.persist,
|
|
9476
9489
|
root,
|
|
9477
|
-
...typeof raw.schemaHash === "string" ? {
|
|
9490
|
+
...typeof raw.templateHash === "string" ? { templateHash: raw.templateHash } : typeof raw.schemaHash === "string" ? { templateHash: raw.schemaHash } : {},
|
|
9478
9491
|
...typeof raw.sourceUrl === "string" ? { sourceUrl: raw.sourceUrl } : {}
|
|
9479
9492
|
}
|
|
9480
9493
|
};
|
|
@@ -9560,7 +9573,7 @@ var FilesystemOpensteerExtractionDescriptorStore = class {
|
|
|
9560
9573
|
kind: "dom-extraction",
|
|
9561
9574
|
persist: input.persist,
|
|
9562
9575
|
root: input.root,
|
|
9563
|
-
...input.
|
|
9576
|
+
...input.templateHash === void 0 ? {} : { templateHash: input.templateHash },
|
|
9564
9577
|
...input.sourceUrl === void 0 ? {} : { sourceUrl: input.sourceUrl }
|
|
9565
9578
|
};
|
|
9566
9579
|
const key = persistKey(this.namespace, input.persist);
|
|
@@ -9609,7 +9622,7 @@ var MemoryOpensteerExtractionDescriptorStore = class {
|
|
|
9609
9622
|
kind: "dom-extraction",
|
|
9610
9623
|
persist: input.persist,
|
|
9611
9624
|
root: input.root,
|
|
9612
|
-
...input.
|
|
9625
|
+
...input.templateHash === void 0 ? {} : { templateHash: input.templateHash },
|
|
9613
9626
|
...input.sourceUrl === void 0 ? {} : { sourceUrl: input.sourceUrl }
|
|
9614
9627
|
};
|
|
9615
9628
|
const key = persistKey(this.namespace, input.persist);
|
|
@@ -10608,7 +10621,7 @@ async function dispatchSemanticOperation(runtime, operation, input, options = {}
|
|
|
10608
10621
|
|
|
10609
10622
|
// ../runtime-core/package.json
|
|
10610
10623
|
var package_default = {
|
|
10611
|
-
version: "0.2.
|
|
10624
|
+
version: "0.2.4"};
|
|
10612
10625
|
|
|
10613
10626
|
// ../runtime-core/src/version.ts
|
|
10614
10627
|
var OPENSTEER_RUNTIME_CORE_VERSION = package_default.version;
|
|
@@ -11654,10 +11667,19 @@ var VOID_TAGS = /* @__PURE__ */ new Set([
|
|
|
11654
11667
|
// ../runtime-core/src/sdk/snapshot/cleaner.ts
|
|
11655
11668
|
var STRIP_TAGS = /* @__PURE__ */ new Set(["script", "style", "noscript", "meta", "link", "template"]);
|
|
11656
11669
|
var TEXT_ATTR_MAX = 150;
|
|
11657
|
-
var
|
|
11658
|
-
var
|
|
11670
|
+
var SRCSET_ATTR_MAX = 160;
|
|
11671
|
+
var MIDDLE_TRUNCATED_URL_ATTRS = /* @__PURE__ */ new Set(["href", "src"]);
|
|
11659
11672
|
var TEXT_ATTRS = /* @__PURE__ */ new Set(["alt", "title", "aria-label", "placeholder", "value"]);
|
|
11660
|
-
var TRUNCATION_SUFFIX = "
|
|
11673
|
+
var TRUNCATION_SUFFIX = "...";
|
|
11674
|
+
var MIDDLE_TRUNCATION_MARKER = "...";
|
|
11675
|
+
var MIDDLE_TRUNCATION_HEAD_MAX = 40;
|
|
11676
|
+
var MIDDLE_TRUNCATION_TAIL_MAX = 20;
|
|
11677
|
+
var SRCSET_CANDIDATE_HEAD_MAX = 36;
|
|
11678
|
+
var SRCSET_CANDIDATE_TAIL_MAX = 12;
|
|
11679
|
+
var SRCSET_COMPACT_CANDIDATE_HEAD_MAX = 20;
|
|
11680
|
+
var SRCSET_COMPACT_CANDIDATE_TAIL_MAX = 8;
|
|
11681
|
+
var SRCSET_FALLBACK_HEAD_MAX = 56;
|
|
11682
|
+
var SRCSET_FALLBACK_TAIL_MAX = 20;
|
|
11661
11683
|
var NOISE_SELECTORS = [
|
|
11662
11684
|
`[${OPENSTEER_HIDDEN_ATTR}]`,
|
|
11663
11685
|
"[hidden]",
|
|
@@ -11720,19 +11742,260 @@ function truncateValue(value, max) {
|
|
|
11720
11742
|
}
|
|
11721
11743
|
return `${head}${TRUNCATION_SUFFIX}`;
|
|
11722
11744
|
}
|
|
11745
|
+
function takeValueWithinSerializedLengthFromEnd(value, max) {
|
|
11746
|
+
let serializedLength = 0;
|
|
11747
|
+
const chars = [];
|
|
11748
|
+
for (let index = value.length - 1; index >= 0; index -= 1) {
|
|
11749
|
+
const char = value[index];
|
|
11750
|
+
let nextLength = 1;
|
|
11751
|
+
if (char === "&") {
|
|
11752
|
+
nextLength = 5;
|
|
11753
|
+
} else if (char === "<" || char === ">") {
|
|
11754
|
+
nextLength = 4;
|
|
11755
|
+
} else if (char === '"') {
|
|
11756
|
+
nextLength = 6;
|
|
11757
|
+
}
|
|
11758
|
+
if (serializedLength + nextLength > max) {
|
|
11759
|
+
break;
|
|
11760
|
+
}
|
|
11761
|
+
chars.push(char);
|
|
11762
|
+
serializedLength += nextLength;
|
|
11763
|
+
}
|
|
11764
|
+
return chars.reverse().join("");
|
|
11765
|
+
}
|
|
11766
|
+
function truncateValueInMiddle(value, headMax, tailMax, marker = MIDDLE_TRUNCATION_MARKER) {
|
|
11767
|
+
const markerLength = getSerializedLength(marker);
|
|
11768
|
+
const max = headMax + markerLength + tailMax;
|
|
11769
|
+
if (getSerializedLength(value) <= max) {
|
|
11770
|
+
return value;
|
|
11771
|
+
}
|
|
11772
|
+
const head = takeValueWithinSerializedLength(value, headMax).replace(/\s+$/u, "");
|
|
11773
|
+
const tail = takeValueWithinSerializedLengthFromEnd(value, tailMax).replace(/^\s+/u, "");
|
|
11774
|
+
if (head.length === 0) {
|
|
11775
|
+
return tail.length === 0 ? marker : `${marker}${tail}`;
|
|
11776
|
+
}
|
|
11777
|
+
if (tail.length === 0) {
|
|
11778
|
+
return `${head}${marker}`;
|
|
11779
|
+
}
|
|
11780
|
+
return `${head}${marker}${tail}`;
|
|
11781
|
+
}
|
|
11723
11782
|
function getAttrLimit(attr) {
|
|
11724
|
-
if (
|
|
11725
|
-
return
|
|
11783
|
+
if (attr === "srcset") {
|
|
11784
|
+
return SRCSET_ATTR_MAX;
|
|
11726
11785
|
}
|
|
11727
11786
|
if (TEXT_ATTRS.has(attr)) {
|
|
11728
11787
|
return TEXT_ATTR_MAX;
|
|
11729
11788
|
}
|
|
11730
11789
|
return void 0;
|
|
11731
11790
|
}
|
|
11791
|
+
function shouldBoundAttr(attr) {
|
|
11792
|
+
return MIDDLE_TRUNCATED_URL_ATTRS.has(attr) || getAttrLimit(attr) !== void 0;
|
|
11793
|
+
}
|
|
11732
11794
|
function setBoundedAttr(el, attr, value) {
|
|
11795
|
+
if (MIDDLE_TRUNCATED_URL_ATTRS.has(attr)) {
|
|
11796
|
+
el.attr(
|
|
11797
|
+
attr,
|
|
11798
|
+
truncateValueInMiddle(value, MIDDLE_TRUNCATION_HEAD_MAX, MIDDLE_TRUNCATION_TAIL_MAX)
|
|
11799
|
+
);
|
|
11800
|
+
return;
|
|
11801
|
+
}
|
|
11733
11802
|
const limit = getAttrLimit(attr);
|
|
11803
|
+
if (attr === "srcset" && limit !== void 0) {
|
|
11804
|
+
el.attr(attr, truncateSrcsetValue(value, limit));
|
|
11805
|
+
return;
|
|
11806
|
+
}
|
|
11734
11807
|
el.attr(attr, limit === void 0 ? value : truncateValue(value, limit));
|
|
11735
11808
|
}
|
|
11809
|
+
function truncateSrcsetValue(value, max) {
|
|
11810
|
+
if (getSerializedLength(value) <= max) {
|
|
11811
|
+
return value;
|
|
11812
|
+
}
|
|
11813
|
+
const candidates = parseSrcsetCandidates2(value);
|
|
11814
|
+
if (candidates.length === 0) {
|
|
11815
|
+
return truncateValueInMiddle(value, SRCSET_FALLBACK_HEAD_MAX, SRCSET_FALLBACK_TAIL_MAX);
|
|
11816
|
+
}
|
|
11817
|
+
for (const [headMax, tailMax, includeBest] of [
|
|
11818
|
+
[SRCSET_CANDIDATE_HEAD_MAX, SRCSET_CANDIDATE_TAIL_MAX, true],
|
|
11819
|
+
[SRCSET_COMPACT_CANDIDATE_HEAD_MAX, SRCSET_COMPACT_CANDIDATE_TAIL_MAX, true],
|
|
11820
|
+
[SRCSET_COMPACT_CANDIDATE_HEAD_MAX, SRCSET_COMPACT_CANDIDATE_TAIL_MAX, false]
|
|
11821
|
+
]) {
|
|
11822
|
+
const compact = buildTruncatedSrcsetValue(candidates, headMax, tailMax, includeBest);
|
|
11823
|
+
if (getSerializedLength(compact) <= max) {
|
|
11824
|
+
return compact;
|
|
11825
|
+
}
|
|
11826
|
+
}
|
|
11827
|
+
return truncateValueInMiddle(value, SRCSET_FALLBACK_HEAD_MAX, SRCSET_FALLBACK_TAIL_MAX);
|
|
11828
|
+
}
|
|
11829
|
+
function buildTruncatedSrcsetValue(candidates, headMax, tailMax, includeBest) {
|
|
11830
|
+
const kept = getPreferredSrcsetCandidateIndices(candidates, includeBest);
|
|
11831
|
+
const parts = [];
|
|
11832
|
+
let previousIndex;
|
|
11833
|
+
for (const candidateIndex of kept) {
|
|
11834
|
+
if (previousIndex !== void 0 && candidateIndex - previousIndex > 1) {
|
|
11835
|
+
parts.push(MIDDLE_TRUNCATION_MARKER);
|
|
11836
|
+
}
|
|
11837
|
+
parts.push(formatSrcsetCandidate(candidates[candidateIndex], headMax, tailMax));
|
|
11838
|
+
previousIndex = candidateIndex;
|
|
11839
|
+
}
|
|
11840
|
+
return parts.join(", ");
|
|
11841
|
+
}
|
|
11842
|
+
function getPreferredSrcsetCandidateIndices(candidates, includeBest) {
|
|
11843
|
+
if (candidates.length === 0) {
|
|
11844
|
+
return [];
|
|
11845
|
+
}
|
|
11846
|
+
const kept = /* @__PURE__ */ new Set([0, candidates.length - 1]);
|
|
11847
|
+
if (includeBest) {
|
|
11848
|
+
kept.add(pickBestSrcsetCandidateIndex(candidates));
|
|
11849
|
+
}
|
|
11850
|
+
return [...kept].filter((index) => index >= 0 && index < candidates.length).sort((a, b) => a - b);
|
|
11851
|
+
}
|
|
11852
|
+
function pickBestSrcsetCandidateIndex(candidates) {
|
|
11853
|
+
let bestWidthIndex = -1;
|
|
11854
|
+
let bestWidth = -1;
|
|
11855
|
+
let bestDensityIndex = -1;
|
|
11856
|
+
let bestDensity = -1;
|
|
11857
|
+
for (let index = 0; index < candidates.length; index += 1) {
|
|
11858
|
+
const candidate = candidates[index];
|
|
11859
|
+
if (typeof candidate.width === "number" && Number.isFinite(candidate.width) && candidate.width > bestWidth) {
|
|
11860
|
+
bestWidth = candidate.width;
|
|
11861
|
+
bestWidthIndex = index;
|
|
11862
|
+
}
|
|
11863
|
+
if (typeof candidate.density === "number" && Number.isFinite(candidate.density) && candidate.density > bestDensity) {
|
|
11864
|
+
bestDensity = candidate.density;
|
|
11865
|
+
bestDensityIndex = index;
|
|
11866
|
+
}
|
|
11867
|
+
}
|
|
11868
|
+
if (bestWidthIndex >= 0) {
|
|
11869
|
+
return bestWidthIndex;
|
|
11870
|
+
}
|
|
11871
|
+
if (bestDensityIndex >= 0) {
|
|
11872
|
+
return bestDensityIndex;
|
|
11873
|
+
}
|
|
11874
|
+
return candidates.length - 1;
|
|
11875
|
+
}
|
|
11876
|
+
function formatSrcsetCandidate(candidate, headMax, tailMax) {
|
|
11877
|
+
const url = truncateValueInMiddle(candidate.url, headMax, tailMax);
|
|
11878
|
+
return candidate.descriptorText ? `${url} ${candidate.descriptorText}` : url;
|
|
11879
|
+
}
|
|
11880
|
+
function parseSrcsetCandidates2(raw) {
|
|
11881
|
+
const text = raw.trim();
|
|
11882
|
+
if (!text) {
|
|
11883
|
+
return [];
|
|
11884
|
+
}
|
|
11885
|
+
const out = [];
|
|
11886
|
+
let index = 0;
|
|
11887
|
+
while (index < text.length) {
|
|
11888
|
+
index = skipSrcsetSeparators(text, index);
|
|
11889
|
+
if (index >= text.length) {
|
|
11890
|
+
break;
|
|
11891
|
+
}
|
|
11892
|
+
const urlToken = readSrcsetUrlToken(text, index);
|
|
11893
|
+
index = urlToken.nextIndex;
|
|
11894
|
+
const url = urlToken.value.trim();
|
|
11895
|
+
if (!url) {
|
|
11896
|
+
continue;
|
|
11897
|
+
}
|
|
11898
|
+
index = skipSrcsetWhitespace(text, index);
|
|
11899
|
+
const descriptors = [];
|
|
11900
|
+
while (index < text.length && text[index] !== ",") {
|
|
11901
|
+
const descriptorToken = readSrcsetDescriptorToken(text, index);
|
|
11902
|
+
if (!descriptorToken.value) {
|
|
11903
|
+
index = descriptorToken.nextIndex;
|
|
11904
|
+
continue;
|
|
11905
|
+
}
|
|
11906
|
+
descriptors.push(descriptorToken.value);
|
|
11907
|
+
index = descriptorToken.nextIndex;
|
|
11908
|
+
index = skipSrcsetWhitespace(text, index);
|
|
11909
|
+
}
|
|
11910
|
+
if (index < text.length && text[index] === ",") {
|
|
11911
|
+
index += 1;
|
|
11912
|
+
}
|
|
11913
|
+
let width = null;
|
|
11914
|
+
let density = null;
|
|
11915
|
+
for (const descriptor of descriptors) {
|
|
11916
|
+
const token = descriptor.trim().toLowerCase();
|
|
11917
|
+
if (!token) {
|
|
11918
|
+
continue;
|
|
11919
|
+
}
|
|
11920
|
+
const widthMatch = token.match(/^(\d+)w$/);
|
|
11921
|
+
if (widthMatch) {
|
|
11922
|
+
const parsed = Number.parseInt(widthMatch[1], 10);
|
|
11923
|
+
if (Number.isFinite(parsed)) {
|
|
11924
|
+
width = parsed;
|
|
11925
|
+
}
|
|
11926
|
+
continue;
|
|
11927
|
+
}
|
|
11928
|
+
const densityMatch = token.match(/^(\d*\.?\d+)x$/);
|
|
11929
|
+
if (densityMatch) {
|
|
11930
|
+
const parsed = Number.parseFloat(densityMatch[1]);
|
|
11931
|
+
if (Number.isFinite(parsed)) {
|
|
11932
|
+
density = parsed;
|
|
11933
|
+
}
|
|
11934
|
+
}
|
|
11935
|
+
}
|
|
11936
|
+
out.push({
|
|
11937
|
+
url,
|
|
11938
|
+
descriptorText: descriptors.join(" "),
|
|
11939
|
+
width,
|
|
11940
|
+
density
|
|
11941
|
+
});
|
|
11942
|
+
}
|
|
11943
|
+
return out;
|
|
11944
|
+
}
|
|
11945
|
+
function skipSrcsetWhitespace(value, index) {
|
|
11946
|
+
let cursor = index;
|
|
11947
|
+
while (cursor < value.length && /\s/u.test(value[cursor])) {
|
|
11948
|
+
cursor += 1;
|
|
11949
|
+
}
|
|
11950
|
+
return cursor;
|
|
11951
|
+
}
|
|
11952
|
+
function skipSrcsetSeparators(value, index) {
|
|
11953
|
+
let cursor = skipSrcsetWhitespace(value, index);
|
|
11954
|
+
while (cursor < value.length && value[cursor] === ",") {
|
|
11955
|
+
cursor += 1;
|
|
11956
|
+
cursor = skipSrcsetWhitespace(value, cursor);
|
|
11957
|
+
}
|
|
11958
|
+
return cursor;
|
|
11959
|
+
}
|
|
11960
|
+
function readSrcsetUrlToken(value, index) {
|
|
11961
|
+
let cursor = index;
|
|
11962
|
+
let out = "";
|
|
11963
|
+
const isDataUrl = value.slice(index, index + 5).toLowerCase().startsWith("data:");
|
|
11964
|
+
while (cursor < value.length) {
|
|
11965
|
+
const char = value[cursor];
|
|
11966
|
+
if (/\s/u.test(char)) {
|
|
11967
|
+
break;
|
|
11968
|
+
}
|
|
11969
|
+
if (char === "," && !isDataUrl) {
|
|
11970
|
+
break;
|
|
11971
|
+
}
|
|
11972
|
+
out += char;
|
|
11973
|
+
cursor += 1;
|
|
11974
|
+
}
|
|
11975
|
+
if (isDataUrl && out.endsWith(",") && cursor < value.length) {
|
|
11976
|
+
out = out.slice(0, -1);
|
|
11977
|
+
}
|
|
11978
|
+
return {
|
|
11979
|
+
value: out,
|
|
11980
|
+
nextIndex: cursor
|
|
11981
|
+
};
|
|
11982
|
+
}
|
|
11983
|
+
function readSrcsetDescriptorToken(value, index) {
|
|
11984
|
+
let cursor = skipSrcsetWhitespace(value, index);
|
|
11985
|
+
let out = "";
|
|
11986
|
+
while (cursor < value.length) {
|
|
11987
|
+
const char = value[cursor];
|
|
11988
|
+
if (char === "," || /\s/u.test(char)) {
|
|
11989
|
+
break;
|
|
11990
|
+
}
|
|
11991
|
+
out += char;
|
|
11992
|
+
cursor += 1;
|
|
11993
|
+
}
|
|
11994
|
+
return {
|
|
11995
|
+
value: out.trim(),
|
|
11996
|
+
nextIndex: cursor
|
|
11997
|
+
};
|
|
11998
|
+
}
|
|
11736
11999
|
function removeNoise($) {
|
|
11737
12000
|
for (const tag of STRIP_TAGS) {
|
|
11738
12001
|
$(tag).remove();
|
|
@@ -11757,38 +12020,68 @@ function markInlineSelfHiddenFallback($) {
|
|
|
11757
12020
|
});
|
|
11758
12021
|
}
|
|
11759
12022
|
function pruneSelfHiddenNodes($) {
|
|
11760
|
-
const
|
|
11761
|
-
|
|
11762
|
-
nodes.push($(this));
|
|
11763
|
-
});
|
|
11764
|
-
nodes.sort((left, right) => right.parents().length - left.parents().length);
|
|
11765
|
-
for (const el of nodes) {
|
|
11766
|
-
if (!el[0]) {
|
|
12023
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
12024
|
+
if (node.attribs?.[OPENSTEER_SELF_HIDDEN_ATTR] === void 0) {
|
|
11767
12025
|
continue;
|
|
11768
12026
|
}
|
|
12027
|
+
const el = $(node);
|
|
11769
12028
|
el.contents().each(function removeSelfHiddenText() {
|
|
11770
12029
|
if (this.type === "text") {
|
|
11771
12030
|
$(this).remove();
|
|
11772
12031
|
}
|
|
11773
12032
|
});
|
|
11774
|
-
if (
|
|
12033
|
+
if (!hasElementChildren(node)) {
|
|
11775
12034
|
el.remove();
|
|
11776
12035
|
}
|
|
11777
12036
|
}
|
|
11778
12037
|
}
|
|
11779
|
-
function
|
|
11780
|
-
return
|
|
11781
|
-
return this.type === "text" && $(this).text().trim() !== "";
|
|
11782
|
-
}).length > 0;
|
|
12038
|
+
function getChildNodes(node) {
|
|
12039
|
+
return node?.children ?? [];
|
|
11783
12040
|
}
|
|
11784
|
-
function
|
|
11785
|
-
return
|
|
12041
|
+
function isElementLikeNode(node) {
|
|
12042
|
+
return node?.type === "tag" || node?.type === "script" || node?.type === "style";
|
|
12043
|
+
}
|
|
12044
|
+
function hasDirectText(node) {
|
|
12045
|
+
if (!node) {
|
|
12046
|
+
return false;
|
|
12047
|
+
}
|
|
12048
|
+
for (const child of getChildNodes(node)) {
|
|
12049
|
+
if (child.type === "text" && (child.data || "").trim() !== "") {
|
|
12050
|
+
return true;
|
|
12051
|
+
}
|
|
12052
|
+
}
|
|
12053
|
+
return false;
|
|
12054
|
+
}
|
|
12055
|
+
function hasElementChildren(node) {
|
|
12056
|
+
if (!node) {
|
|
12057
|
+
return false;
|
|
12058
|
+
}
|
|
12059
|
+
for (const child of getChildNodes(node)) {
|
|
12060
|
+
if (isElementLikeNode(child)) {
|
|
12061
|
+
return true;
|
|
12062
|
+
}
|
|
12063
|
+
}
|
|
12064
|
+
return false;
|
|
12065
|
+
}
|
|
12066
|
+
function hasTextDeepNode(node) {
|
|
12067
|
+
if (!node) {
|
|
12068
|
+
return false;
|
|
12069
|
+
}
|
|
12070
|
+
if (node.type === "text") {
|
|
12071
|
+
return (node.data || "").trim() !== "";
|
|
12072
|
+
}
|
|
12073
|
+
for (const child of getChildNodes(node)) {
|
|
12074
|
+
if (hasTextDeepNode(child)) {
|
|
12075
|
+
return true;
|
|
12076
|
+
}
|
|
12077
|
+
}
|
|
12078
|
+
return false;
|
|
11786
12079
|
}
|
|
11787
12080
|
function hasActionLabel(attrs) {
|
|
11788
12081
|
return typeof attrs["aria-label"] === "string" && attrs["aria-label"].trim() !== "" || typeof attrs["aria-labelledby"] === "string" && attrs["aria-labelledby"].trim() !== "" || typeof attrs["aria-describedby"] === "string" && attrs["aria-describedby"].trim() !== "" || typeof attrs.title === "string" && attrs.title.trim() !== "" || typeof attrs.placeholder === "string" && attrs.placeholder.trim() !== "" || typeof attrs.value === "string" && attrs.value.trim() !== "";
|
|
11789
12082
|
}
|
|
11790
12083
|
function unwrapActionNode($, el) {
|
|
11791
|
-
if (
|
|
12084
|
+
if (hasTextDeepNode(el[0])) {
|
|
11792
12085
|
if (el.prev().length > 0) {
|
|
11793
12086
|
el.before(" ");
|
|
11794
12087
|
}
|
|
@@ -11809,7 +12102,7 @@ function stripToAttrs(el, keep) {
|
|
|
11809
12102
|
if (typeof value !== "string") {
|
|
11810
12103
|
continue;
|
|
11811
12104
|
}
|
|
11812
|
-
if (
|
|
12105
|
+
if (shouldBoundAttr(attr)) {
|
|
11813
12106
|
setBoundedAttr(el, attr, value);
|
|
11814
12107
|
}
|
|
11815
12108
|
}
|
|
@@ -11827,6 +12120,9 @@ function restoreBoundedAttr(el, attr, value) {
|
|
|
11827
12120
|
function deduplicateImages(html) {
|
|
11828
12121
|
const seen = /* @__PURE__ */ new Set();
|
|
11829
12122
|
return html.replace(/<img\b([^>]*)>/gi, (full, attrContent) => {
|
|
12123
|
+
if (/\bc\s*=/.test(attrContent)) {
|
|
12124
|
+
return full;
|
|
12125
|
+
}
|
|
11830
12126
|
const srcMatch = attrContent.match(/\bsrc\s*=\s*(["']?)(.*?)\1/);
|
|
11831
12127
|
const srcsetMatch = attrContent.match(/\bsrcset\s*=\s*(["'])(.*?)\1/);
|
|
11832
12128
|
let src = null;
|
|
@@ -11845,59 +12141,155 @@ function deduplicateImages(html) {
|
|
|
11845
12141
|
return full;
|
|
11846
12142
|
});
|
|
11847
12143
|
}
|
|
11848
|
-
function
|
|
11849
|
-
|
|
12144
|
+
function hasAttribute2(node, attr) {
|
|
12145
|
+
return node?.attribs?.[attr] !== void 0;
|
|
12146
|
+
}
|
|
12147
|
+
function hasPictureAncestor(node) {
|
|
12148
|
+
let current = node?.parent;
|
|
12149
|
+
while (current) {
|
|
12150
|
+
if (isElementLikeNode(current) && (current.tagName || "").toLowerCase() === "picture") {
|
|
12151
|
+
return true;
|
|
12152
|
+
}
|
|
12153
|
+
current = current.parent;
|
|
12154
|
+
}
|
|
12155
|
+
return false;
|
|
12156
|
+
}
|
|
12157
|
+
function pictureHasPreservedDescendant(node) {
|
|
12158
|
+
if (!node) {
|
|
12159
|
+
return false;
|
|
12160
|
+
}
|
|
12161
|
+
for (const child of getChildNodes(node)) {
|
|
12162
|
+
if (!isElementLikeNode(child)) {
|
|
12163
|
+
continue;
|
|
12164
|
+
}
|
|
12165
|
+
const tag = (child.tagName || "").toLowerCase();
|
|
12166
|
+
if (tag === "img") {
|
|
12167
|
+
return true;
|
|
12168
|
+
}
|
|
12169
|
+
if (tag === "source" && typeof child.attribs?.src === "string" && child.attribs.src.trim() !== "") {
|
|
12170
|
+
return true;
|
|
12171
|
+
}
|
|
12172
|
+
if (tag === "source" && typeof child.attribs?.srcset === "string" && child.attribs.srcset.trim() !== "") {
|
|
12173
|
+
return true;
|
|
12174
|
+
}
|
|
12175
|
+
if (pictureHasPreservedDescendant(child)) {
|
|
12176
|
+
return true;
|
|
12177
|
+
}
|
|
12178
|
+
}
|
|
12179
|
+
return false;
|
|
12180
|
+
}
|
|
12181
|
+
function isPreservedImageElement(node) {
|
|
12182
|
+
const tag = (node?.tagName || "").toLowerCase();
|
|
11850
12183
|
if (tag === "img") {
|
|
11851
12184
|
return true;
|
|
11852
12185
|
}
|
|
11853
12186
|
if (tag === "picture") {
|
|
11854
|
-
|
|
11855
|
-
const hasSource = el.find("source[src], source[srcset]").length > 0;
|
|
11856
|
-
return hasImg || hasSource;
|
|
12187
|
+
return pictureHasPreservedDescendant(node);
|
|
11857
12188
|
}
|
|
11858
12189
|
if (tag === "source") {
|
|
11859
|
-
const inPicture =
|
|
11860
|
-
const hasSrc =
|
|
12190
|
+
const inPicture = hasPictureAncestor(node);
|
|
12191
|
+
const hasSrc = typeof node?.attribs?.src === "string" && node.attribs.src.trim() !== "" || typeof node?.attribs?.srcset === "string" && node.attribs.srcset.trim() !== "";
|
|
11861
12192
|
return inPicture && hasSrc;
|
|
11862
12193
|
}
|
|
11863
12194
|
return false;
|
|
11864
12195
|
}
|
|
12196
|
+
function getElementsInReverseDocumentOrder($) {
|
|
12197
|
+
return $.root().find("*").toArray().reverse().filter((node) => node.type === "tag");
|
|
12198
|
+
}
|
|
12199
|
+
function getNodeDepth(node) {
|
|
12200
|
+
let depth = 0;
|
|
12201
|
+
let current = node.parent;
|
|
12202
|
+
while (current) {
|
|
12203
|
+
depth++;
|
|
12204
|
+
current = current.parent;
|
|
12205
|
+
}
|
|
12206
|
+
return depth;
|
|
12207
|
+
}
|
|
12208
|
+
function getElementsByDepthDescending($) {
|
|
12209
|
+
const elements = $.root().find("*").toArray().filter((node) => node.type === "tag");
|
|
12210
|
+
const depths = /* @__PURE__ */ new Map();
|
|
12211
|
+
for (const el of elements) {
|
|
12212
|
+
depths.set(el, getNodeDepth(el));
|
|
12213
|
+
}
|
|
12214
|
+
return elements.sort((a, b) => (depths.get(b) ?? 0) - (depths.get(a) ?? 0));
|
|
12215
|
+
}
|
|
11865
12216
|
function flattenExtractionTree($) {
|
|
11866
|
-
const
|
|
11867
|
-
|
|
11868
|
-
|
|
11869
|
-
|
|
11870
|
-
|
|
11871
|
-
|
|
11872
|
-
|
|
11873
|
-
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
11884
|
-
|
|
11885
|
-
|
|
11886
|
-
|
|
11887
|
-
|
|
11888
|
-
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
12217
|
+
for (const node of getElementsInReverseDocumentOrder($)) {
|
|
12218
|
+
const el = $(node);
|
|
12219
|
+
const tag = (node.tagName || "").toLowerCase();
|
|
12220
|
+
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag) || isPreservedImageElement(node)) {
|
|
12221
|
+
continue;
|
|
12222
|
+
}
|
|
12223
|
+
if (tag === "a" || hasDirectText(node)) {
|
|
12224
|
+
continue;
|
|
12225
|
+
}
|
|
12226
|
+
if (!hasElementChildren(node)) {
|
|
12227
|
+
el.remove();
|
|
12228
|
+
continue;
|
|
12229
|
+
}
|
|
12230
|
+
el.replaceWith(el.contents());
|
|
12231
|
+
}
|
|
12232
|
+
}
|
|
12233
|
+
function hasMarkedAncestor(el, attr) {
|
|
12234
|
+
let current = el[0]?.parent;
|
|
12235
|
+
while (current) {
|
|
12236
|
+
if (!isElementLikeNode(current)) {
|
|
12237
|
+
return false;
|
|
12238
|
+
}
|
|
12239
|
+
if (current.attribs?.[attr] !== void 0) {
|
|
12240
|
+
return true;
|
|
12241
|
+
}
|
|
12242
|
+
current = current.parent;
|
|
12243
|
+
}
|
|
12244
|
+
return false;
|
|
12245
|
+
}
|
|
12246
|
+
function isIndicatorImage(node) {
|
|
12247
|
+
return (node?.tagName || "").toLowerCase() === "img" && (hasAttribute2(node, "alt") || hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
12248
|
+
}
|
|
12249
|
+
function isIndicatorPictureSource(node) {
|
|
12250
|
+
return (node?.tagName || "").toLowerCase() === "source" && hasPictureAncestor(node) && (hasAttribute2(node, "src") || hasAttribute2(node, "srcset"));
|
|
12251
|
+
}
|
|
12252
|
+
function isSemanticIndicator(node) {
|
|
12253
|
+
const tag = (node?.tagName || "").toLowerCase();
|
|
12254
|
+
if (tag === "svg") {
|
|
12255
|
+
return true;
|
|
12256
|
+
}
|
|
12257
|
+
return hasAttribute2(node, "aria-label") || hasAttribute2(node, "title") || hasAttribute2(node, "data-icon") || node?.attribs?.role === "img";
|
|
12258
|
+
}
|
|
12259
|
+
function findIndicatorDescendant(root) {
|
|
12260
|
+
if (!root) {
|
|
12261
|
+
return void 0;
|
|
12262
|
+
}
|
|
12263
|
+
let firstImage;
|
|
12264
|
+
let firstSource;
|
|
12265
|
+
let firstSemantic;
|
|
12266
|
+
const visit = (node) => {
|
|
12267
|
+
if (!isElementLikeNode(node)) {
|
|
12268
|
+
return false;
|
|
12269
|
+
}
|
|
12270
|
+
if (isIndicatorImage(node)) {
|
|
12271
|
+
firstImage = node;
|
|
12272
|
+
return true;
|
|
12273
|
+
}
|
|
12274
|
+
if (firstSource === void 0 && isIndicatorPictureSource(node)) {
|
|
12275
|
+
firstSource = node;
|
|
12276
|
+
}
|
|
12277
|
+
if (firstSemantic === void 0 && isSemanticIndicator(node)) {
|
|
12278
|
+
firstSemantic = node;
|
|
12279
|
+
}
|
|
12280
|
+
for (const child of getChildNodes(node)) {
|
|
12281
|
+
if (visit(child)) {
|
|
12282
|
+
return true;
|
|
11893
12283
|
}
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
});
|
|
11897
|
-
el.replaceWith(el.contents());
|
|
11898
|
-
});
|
|
12284
|
+
}
|
|
12285
|
+
return false;
|
|
11899
12286
|
};
|
|
11900
|
-
|
|
12287
|
+
for (const child of getChildNodes(root)) {
|
|
12288
|
+
if (visit(child)) {
|
|
12289
|
+
return firstImage;
|
|
12290
|
+
}
|
|
12291
|
+
}
|
|
12292
|
+
return firstImage ?? firstSource ?? firstSemantic;
|
|
11901
12293
|
}
|
|
11902
12294
|
function serializeForExtraction($, root) {
|
|
11903
12295
|
const lines = [];
|
|
@@ -11966,7 +12358,7 @@ function serializeForExtraction($, root) {
|
|
|
11966
12358
|
lines.push(`${" ".repeat(depth)}</${tagName}>`);
|
|
11967
12359
|
}
|
|
11968
12360
|
traverse(root, 0);
|
|
11969
|
-
return lines.join("
|
|
12361
|
+
return lines.map((l) => l.trim()).filter((l) => l.length > 0).join("");
|
|
11970
12362
|
}
|
|
11971
12363
|
function isClickable($, el, context) {
|
|
11972
12364
|
if (context.hasPreMarked) {
|
|
@@ -12058,7 +12450,11 @@ function cleanForExtraction(html) {
|
|
|
12058
12450
|
}
|
|
12059
12451
|
});
|
|
12060
12452
|
flattenExtractionTree($clean);
|
|
12061
|
-
|
|
12453
|
+
const root = $clean.root()[0];
|
|
12454
|
+
if (root === void 0) {
|
|
12455
|
+
return "";
|
|
12456
|
+
}
|
|
12457
|
+
return deduplicateImages(serializeForExtraction($clean, root));
|
|
12062
12458
|
}
|
|
12063
12459
|
function cleanForAction(html) {
|
|
12064
12460
|
if (!html.trim()) {
|
|
@@ -12084,22 +12480,12 @@ function cleanForAction(html) {
|
|
|
12084
12480
|
$(`[${clickableMark}]`).each(function markIndicators() {
|
|
12085
12481
|
const el = $(this);
|
|
12086
12482
|
const wrapperAttrs = el.attr() || {};
|
|
12087
|
-
if (
|
|
12483
|
+
if (hasTextDeepNode(el[0]) || hasActionLabel(wrapperAttrs)) {
|
|
12088
12484
|
return;
|
|
12089
12485
|
}
|
|
12090
|
-
const
|
|
12091
|
-
if (
|
|
12092
|
-
|
|
12093
|
-
return;
|
|
12094
|
-
}
|
|
12095
|
-
const pictureSourceIndicator = el.find("picture source[src], picture source[srcset]").first();
|
|
12096
|
-
if (pictureSourceIndicator.length) {
|
|
12097
|
-
pictureSourceIndicator.attr(indicatorMark, "1");
|
|
12098
|
-
return;
|
|
12099
|
-
}
|
|
12100
|
-
const semanticIndicator = el.find('[aria-label], [title], [data-icon], [role="img"], svg').first();
|
|
12101
|
-
if (semanticIndicator.length) {
|
|
12102
|
-
semanticIndicator.attr(indicatorMark, "1");
|
|
12486
|
+
const indicatorNode = findIndicatorDescendant(el[0]);
|
|
12487
|
+
if (indicatorNode !== void 0) {
|
|
12488
|
+
$(indicatorNode).attr(indicatorMark, "1");
|
|
12103
12489
|
}
|
|
12104
12490
|
});
|
|
12105
12491
|
$(`[${clickableMark}]`).each(function removeEmptyClickable() {
|
|
@@ -12109,7 +12495,7 @@ function cleanForAction(html) {
|
|
|
12109
12495
|
if (NATIVE_INTERACTIVE_TAGS.has(tag) || tag === "a") {
|
|
12110
12496
|
return;
|
|
12111
12497
|
}
|
|
12112
|
-
if (
|
|
12498
|
+
if (hasElementChildren(node) || hasDirectText(node)) {
|
|
12113
12499
|
return;
|
|
12114
12500
|
}
|
|
12115
12501
|
const wrapperAttrs = el.attr() || {};
|
|
@@ -12135,46 +12521,31 @@ function cleanForAction(html) {
|
|
|
12135
12521
|
current = ancestor.parent();
|
|
12136
12522
|
}
|
|
12137
12523
|
});
|
|
12138
|
-
|
|
12139
|
-
|
|
12140
|
-
|
|
12141
|
-
|
|
12142
|
-
|
|
12143
|
-
|
|
12144
|
-
|
|
12145
|
-
|
|
12146
|
-
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
const tag = (node.tagName || "").toLowerCase();
|
|
12152
|
-
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
12153
|
-
continue;
|
|
12154
|
-
}
|
|
12155
|
-
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
12156
|
-
continue;
|
|
12157
|
-
}
|
|
12158
|
-
const insideClickable = el.parents(`[${clickableMark}]`).length > 0;
|
|
12159
|
-
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
12160
|
-
const hasContent = el.children().length > 0 || hasDirectText($, el);
|
|
12161
|
-
if (insideClickable || preserveBranch) {
|
|
12162
|
-
if (!hasContent) {
|
|
12163
|
-
el.remove();
|
|
12164
|
-
} else {
|
|
12165
|
-
unwrapActionNode($, el);
|
|
12166
|
-
}
|
|
12167
|
-
changed = true;
|
|
12168
|
-
continue;
|
|
12169
|
-
}
|
|
12524
|
+
for (const node of getElementsByDepthDescending($)) {
|
|
12525
|
+
const el = $(node);
|
|
12526
|
+
const tag = (node.tagName || "").toLowerCase();
|
|
12527
|
+
if (ROOT_TAGS.has(tag) || isBoundaryTag(tag)) {
|
|
12528
|
+
continue;
|
|
12529
|
+
}
|
|
12530
|
+
if (el.attr(clickableMark) !== void 0 || el.attr(indicatorMark) !== void 0) {
|
|
12531
|
+
continue;
|
|
12532
|
+
}
|
|
12533
|
+
const insideClickable = hasMarkedAncestor(el, clickableMark);
|
|
12534
|
+
const preserveBranch = el.attr(branchMark) !== void 0;
|
|
12535
|
+
const hasContent = hasElementChildren(node) || hasDirectText(node);
|
|
12536
|
+
if (insideClickable || preserveBranch) {
|
|
12170
12537
|
if (!hasContent) {
|
|
12171
12538
|
el.remove();
|
|
12172
|
-
|
|
12173
|
-
|
|
12539
|
+
} else {
|
|
12540
|
+
unwrapActionNode($, el);
|
|
12174
12541
|
}
|
|
12175
|
-
|
|
12176
|
-
changed = true;
|
|
12542
|
+
continue;
|
|
12177
12543
|
}
|
|
12544
|
+
if (!hasContent) {
|
|
12545
|
+
el.remove();
|
|
12546
|
+
continue;
|
|
12547
|
+
}
|
|
12548
|
+
unwrapActionNode($, el);
|
|
12178
12549
|
}
|
|
12179
12550
|
$.root().find("*").contents().each(function normalizeActionTextNodes() {
|
|
12180
12551
|
if (this.type !== "text") {
|
|
@@ -12254,21 +12625,7 @@ function cleanForAction(html) {
|
|
|
12254
12625
|
OPENSTEER_SPARSE_COUNTER_ATTR
|
|
12255
12626
|
]);
|
|
12256
12627
|
if (clickable) {
|
|
12257
|
-
for (const attr of [
|
|
12258
|
-
"href",
|
|
12259
|
-
"role",
|
|
12260
|
-
"type",
|
|
12261
|
-
"title",
|
|
12262
|
-
"placeholder",
|
|
12263
|
-
"value",
|
|
12264
|
-
"aria-label",
|
|
12265
|
-
"aria-labelledby",
|
|
12266
|
-
"aria-describedby",
|
|
12267
|
-
"aria-expanded",
|
|
12268
|
-
"aria-pressed",
|
|
12269
|
-
"aria-selected",
|
|
12270
|
-
"aria-haspopup"
|
|
12271
|
-
]) {
|
|
12628
|
+
for (const attr of ["href", "role", "type", "title", "placeholder", "value", "aria-label"]) {
|
|
12272
12629
|
keep.add(attr);
|
|
12273
12630
|
}
|
|
12274
12631
|
}
|
|
@@ -12888,9 +13245,9 @@ function renderNode(snapshot, node, nodesById, snapshotsByDocumentRef, snapshotI
|
|
|
12888
13245
|
const snapshotAttributes = normalizeNodeAttributes(node.attributes);
|
|
12889
13246
|
const authoredAttributes = stripInternalSnapshotAttributes(snapshotAttributes);
|
|
12890
13247
|
const attributes = [...authoredAttributes];
|
|
12891
|
-
const subtreeHidden =
|
|
12892
|
-
const selfHidden = !subtreeHidden && (
|
|
12893
|
-
const interactive = !subtreeHidden && !selfHidden && (
|
|
13248
|
+
const subtreeHidden = hasAttribute3(snapshotAttributes, OPENSTEER_HIDDEN_ATTR) || isLikelySubtreeHidden(node);
|
|
13249
|
+
const selfHidden = !subtreeHidden && (hasAttribute3(snapshotAttributes, OPENSTEER_SELF_HIDDEN_ATTR) || isLikelySelfHidden(node, nodesById));
|
|
13250
|
+
const interactive = !subtreeHidden && !selfHidden && (hasAttribute3(snapshotAttributes, OPENSTEER_INTERACTIVE_ATTR) || isLikelyInteractive(tagName, node, authoredAttributes));
|
|
12894
13251
|
if (interactive) {
|
|
12895
13252
|
attributes.push({ name: OPENSTEER_INTERACTIVE_ATTR, value: "1" });
|
|
12896
13253
|
}
|
|
@@ -13208,7 +13565,7 @@ function parseOpacity(value) {
|
|
|
13208
13565
|
const parsed = Number.parseFloat(value);
|
|
13209
13566
|
return Number.isFinite(parsed) ? parsed : Number.NaN;
|
|
13210
13567
|
}
|
|
13211
|
-
function
|
|
13568
|
+
function hasAttribute3(attributes, name) {
|
|
13212
13569
|
const normalizedName = name.toLowerCase();
|
|
13213
13570
|
return attributes.some((attribute) => attribute.name.toLowerCase() === normalizedName);
|
|
13214
13571
|
}
|
|
@@ -15169,12 +15526,12 @@ var OpensteerSessionRuntime = class {
|
|
|
15169
15526
|
async (timeout) => {
|
|
15170
15527
|
let descriptor2;
|
|
15171
15528
|
let data;
|
|
15172
|
-
if (input.
|
|
15173
|
-
|
|
15529
|
+
if (input.template !== void 0) {
|
|
15530
|
+
assertValidOpensteerExtractionTemplateRoot(input.template);
|
|
15174
15531
|
const fieldTargets = await timeout.runStep(
|
|
15175
15532
|
() => compileOpensteerExtractionFieldTargets({
|
|
15176
15533
|
pageRef,
|
|
15177
|
-
|
|
15534
|
+
template: input.template,
|
|
15178
15535
|
dom: this.requireDom()
|
|
15179
15536
|
})
|
|
15180
15537
|
);
|
|
@@ -15206,7 +15563,7 @@ var OpensteerSessionRuntime = class {
|
|
|
15206
15563
|
() => descriptors.write({
|
|
15207
15564
|
persist,
|
|
15208
15565
|
root: payload,
|
|
15209
|
-
|
|
15566
|
+
templateHash: canonicalJsonString(input.template),
|
|
15210
15567
|
sourceUrl: pageInfo.url
|
|
15211
15568
|
})
|
|
15212
15569
|
);
|
|
@@ -15266,7 +15623,7 @@ var OpensteerSessionRuntime = class {
|
|
|
15266
15623
|
artifacts,
|
|
15267
15624
|
data: {
|
|
15268
15625
|
...input.persist === void 0 ? {} : { persist: input.persist },
|
|
15269
|
-
...descriptor?.payload.
|
|
15626
|
+
...descriptor?.payload.templateHash === void 0 ? {} : { templateHash: descriptor.payload.templateHash },
|
|
15270
15627
|
data: output.data
|
|
15271
15628
|
},
|
|
15272
15629
|
context: buildRuntimeTraceContext({
|
|
@@ -22343,39 +22700,6 @@ var OpensteerRuntime = class extends OpensteerSessionRuntime {
|
|
|
22343
22700
|
);
|
|
22344
22701
|
}
|
|
22345
22702
|
};
|
|
22346
|
-
var OpensteerSessionRuntime2 = class extends OpensteerSessionRuntime {
|
|
22347
|
-
constructor(options) {
|
|
22348
|
-
const rootPath = options.rootPath ?? path2.resolve(options.rootDir ?? process.cwd());
|
|
22349
|
-
const cleanupRootOnClose = options.cleanupRootOnClose ?? false;
|
|
22350
|
-
const engineName = options.engineName ?? DEFAULT_OPENSTEER_ENGINE;
|
|
22351
|
-
assertSupportedEngineOptions({
|
|
22352
|
-
engineName,
|
|
22353
|
-
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
22354
|
-
...options.context === void 0 ? {} : { context: options.context }
|
|
22355
|
-
});
|
|
22356
|
-
super(
|
|
22357
|
-
buildSharedRuntimeOptions({
|
|
22358
|
-
name: options.name,
|
|
22359
|
-
...options.rootDir === void 0 ? {} : { rootDir: options.rootDir },
|
|
22360
|
-
rootPath,
|
|
22361
|
-
...options.environment === void 0 ? {} : { environment: options.environment },
|
|
22362
|
-
...options.browser === void 0 ? {} : { browser: options.browser },
|
|
22363
|
-
...options.launch === void 0 ? {} : { launch: options.launch },
|
|
22364
|
-
...options.context === void 0 ? {} : { context: options.context },
|
|
22365
|
-
engineName,
|
|
22366
|
-
...options.engine === void 0 ? {} : { engine: options.engine },
|
|
22367
|
-
...options.engineFactory === void 0 ? {} : { engineFactory: options.engineFactory },
|
|
22368
|
-
...options.policy === void 0 ? {} : { policy: options.policy },
|
|
22369
|
-
...options.descriptorStore === void 0 ? {} : { descriptorStore: options.descriptorStore },
|
|
22370
|
-
...options.extractionDescriptorStore === void 0 ? {} : { extractionDescriptorStore: options.extractionDescriptorStore },
|
|
22371
|
-
cleanupRootOnClose,
|
|
22372
|
-
...options.observability === void 0 ? {} : { observability: options.observability },
|
|
22373
|
-
...options.observationSessionId === void 0 ? {} : { observationSessionId: options.observationSessionId },
|
|
22374
|
-
...options.observationSink === void 0 ? {} : { observationSink: options.observationSink }
|
|
22375
|
-
})
|
|
22376
|
-
);
|
|
22377
|
-
}
|
|
22378
|
-
};
|
|
22379
22703
|
function buildSharedRuntimeOptions(input) {
|
|
22380
22704
|
const ownership = resolveOwnership(input.browser);
|
|
22381
22705
|
const engineFactory = input.engineFactory ?? ((factoryOptions) => new OpensteerBrowserManager({
|
|
@@ -22467,6 +22791,6 @@ function createOpensteerSemanticRuntime(input = {}) {
|
|
|
22467
22791
|
});
|
|
22468
22792
|
}
|
|
22469
22793
|
|
|
22470
|
-
export { CloudSessionProxy, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, FlowRecorderCollector, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OpensteerCloudClient,
|
|
22471
|
-
//# sourceMappingURL=chunk-
|
|
22472
|
-
//# sourceMappingURL=chunk-
|
|
22794
|
+
export { CloudSessionProxy, DEFERRED_MATCH_ATTR_KEYS, ElementPathError, FlowRecorderCollector, MATCH_ATTRIBUTE_PRIORITY, OPENSTEER_DOM_ACTION_BRIDGE_SYMBOL, OpensteerCloudClient, STABLE_PRIMARY_ATTR_KEYS, assertProviderSupportsEngine, buildArrayFieldPathCandidates, buildDomDescriptorKey, buildDomDescriptorPayload, buildDomDescriptorVersion, buildPathCandidates, buildPathSelectorHint, buildSegmentSelector, cloneElementPath, cloneReplayElementPath, cloneStructuralElementAnchor, createDomDescriptorStore, createDomRuntime, createOpensteerExtractionDescriptorStore, createOpensteerSemanticRuntime, defaultFallbackPolicy, defaultPolicy, defaultRetryPolicy, defaultSettlePolicy, defaultTimeoutPolicy, delayWithSignal, dispatchSemanticOperation, generateReplayScript, hashDomDescriptorPersist, isCurrentUrlField, isValidCssAttributeKey, loadEnvironment, normalizeExtractedValue, normalizeOpensteerProviderMode, parseDomDescriptorRecord, parseExtractionDescriptorRecord, requireCloudAppBaseUrl, resolveCloudConfig, resolveDomActionBridge, resolveExtractedValueInContext, resolveOpensteerEnvironment, resolveOpensteerProvider, resolveOpensteerRuntimeConfig, runWithPolicyTimeout, sanitizeElementPath, sanitizeReplayElementPath, sanitizeStructuralElementAnchor, settleWithPolicy, shouldKeepAttributeForPath };
|
|
22795
|
+
//# sourceMappingURL=chunk-7LQL5YUR.js.map
|
|
22796
|
+
//# sourceMappingURL=chunk-7LQL5YUR.js.map
|