tabwright 1.0.0
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/LICENSE +21 -0
- package/bin.js +4 -0
- package/dist/a11y-client.js +204 -0
- package/dist/agent-skills/tabwright/SKILL.md +119 -0
- package/dist/aria-snapshot.d.ts +262 -0
- package/dist/aria-snapshot.d.ts.map +1 -0
- package/dist/aria-snapshot.js +1256 -0
- package/dist/aria-snapshot.js.map +1 -0
- package/dist/aria-snapshot.test.d.ts +2 -0
- package/dist/aria-snapshot.test.d.ts.map +1 -0
- package/dist/aria-snapshot.test.js +270 -0
- package/dist/aria-snapshot.test.js.map +1 -0
- package/dist/aria-snapshot.unit.test.d.ts +2 -0
- package/dist/aria-snapshot.unit.test.d.ts.map +1 -0
- package/dist/aria-snapshot.unit.test.js +542 -0
- package/dist/aria-snapshot.unit.test.js.map +1 -0
- package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts +5 -0
- package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.d.ts.map +1 -0
- package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js +5 -0
- package/dist/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.js.map +1 -0
- package/dist/bippy.js +894 -0
- package/dist/browser-config.d.ts +13 -0
- package/dist/browser-config.d.ts.map +1 -0
- package/dist/browser-config.js +126 -0
- package/dist/browser-config.js.map +1 -0
- package/dist/browser-install.d.ts +16 -0
- package/dist/browser-install.d.ts.map +1 -0
- package/dist/browser-install.js +238 -0
- package/dist/browser-install.js.map +1 -0
- package/dist/browser-launch.d.ts +17 -0
- package/dist/browser-launch.d.ts.map +1 -0
- package/dist/browser-launch.js +44 -0
- package/dist/browser-launch.js.map +1 -0
- package/dist/builtin-capabilities.d.ts +28 -0
- package/dist/builtin-capabilities.d.ts.map +1 -0
- package/dist/builtin-capabilities.js +2673 -0
- package/dist/builtin-capabilities.js.map +1 -0
- package/dist/capability-agent-skill.d.ts +60 -0
- package/dist/capability-agent-skill.d.ts.map +1 -0
- package/dist/capability-agent-skill.js +225 -0
- package/dist/capability-agent-skill.js.map +1 -0
- package/dist/capability-auth-state.d.ts +34 -0
- package/dist/capability-auth-state.d.ts.map +1 -0
- package/dist/capability-auth-state.js +157 -0
- package/dist/capability-auth-state.js.map +1 -0
- package/dist/capability-auth.d.ts +36 -0
- package/dist/capability-auth.d.ts.map +1 -0
- package/dist/capability-auth.js +198 -0
- package/dist/capability-auth.js.map +1 -0
- package/dist/capability-cli-confirmation.test.d.ts +2 -0
- package/dist/capability-cli-confirmation.test.d.ts.map +1 -0
- package/dist/capability-cli-confirmation.test.js +79 -0
- package/dist/capability-cli-confirmation.test.js.map +1 -0
- package/dist/capability-options.d.ts +20 -0
- package/dist/capability-options.d.ts.map +1 -0
- package/dist/capability-options.js +31 -0
- package/dist/capability-options.js.map +1 -0
- package/dist/capability-options.test.d.ts +2 -0
- package/dist/capability-options.test.d.ts.map +1 -0
- package/dist/capability-options.test.js +81 -0
- package/dist/capability-options.test.js.map +1 -0
- package/dist/capability-package.d.ts +27 -0
- package/dist/capability-package.d.ts.map +1 -0
- package/dist/capability-package.js +444 -0
- package/dist/capability-package.js.map +1 -0
- package/dist/capability-package.test.d.ts +2 -0
- package/dist/capability-package.test.d.ts.map +1 -0
- package/dist/capability-package.test.js +179 -0
- package/dist/capability-package.test.js.map +1 -0
- package/dist/capability-registry.d.ts +262 -0
- package/dist/capability-registry.d.ts.map +1 -0
- package/dist/capability-registry.js +931 -0
- package/dist/capability-registry.js.map +1 -0
- package/dist/capability-registry.test.d.ts +2 -0
- package/dist/capability-registry.test.d.ts.map +1 -0
- package/dist/capability-registry.test.js +1683 -0
- package/dist/capability-registry.test.js.map +1 -0
- package/dist/capability-runner.d.ts +99 -0
- package/dist/capability-runner.d.ts.map +1 -0
- package/dist/capability-runner.js +608 -0
- package/dist/capability-runner.js.map +1 -0
- package/dist/capability-search-relevance.test.d.ts +2 -0
- package/dist/capability-search-relevance.test.d.ts.map +1 -0
- package/dist/capability-search-relevance.test.js +67 -0
- package/dist/capability-search-relevance.test.js.map +1 -0
- package/dist/capability-studio.d.ts +11 -0
- package/dist/capability-studio.d.ts.map +1 -0
- package/dist/capability-studio.js +593 -0
- package/dist/capability-studio.js.map +1 -0
- package/dist/capability-studio.test.d.ts +2 -0
- package/dist/capability-studio.test.d.ts.map +1 -0
- package/dist/capability-studio.test.js +41 -0
- package/dist/capability-studio.test.js.map +1 -0
- package/dist/cdp-log.d.ts +19 -0
- package/dist/cdp-log.d.ts.map +1 -0
- package/dist/cdp-log.js +83 -0
- package/dist/cdp-log.js.map +1 -0
- package/dist/cdp-log.test.d.ts +2 -0
- package/dist/cdp-log.test.d.ts.map +1 -0
- package/dist/cdp-log.test.js +109 -0
- package/dist/cdp-log.test.js.map +1 -0
- package/dist/cdp-relay.d.ts +19 -0
- package/dist/cdp-relay.d.ts.map +1 -0
- package/dist/cdp-relay.js +2375 -0
- package/dist/cdp-relay.js.map +1 -0
- package/dist/cdp-session.d.ts +37 -0
- package/dist/cdp-session.d.ts.map +1 -0
- package/dist/cdp-session.js +36 -0
- package/dist/cdp-session.js.map +1 -0
- package/dist/cdp-types.d.ts +65 -0
- package/dist/cdp-types.d.ts.map +1 -0
- package/dist/cdp-types.js +91 -0
- package/dist/cdp-types.js.map +1 -0
- package/dist/channel-owner-inspect.test.d.ts +2 -0
- package/dist/channel-owner-inspect.test.d.ts.map +1 -0
- package/dist/channel-owner-inspect.test.js +75 -0
- package/dist/channel-owner-inspect.test.js.map +1 -0
- package/dist/chrome-discovery.d.ts +65 -0
- package/dist/chrome-discovery.d.ts.map +1 -0
- package/dist/chrome-discovery.js +173 -0
- package/dist/chrome-discovery.js.map +1 -0
- package/dist/chrome-discovery.test.d.ts +2 -0
- package/dist/chrome-discovery.test.d.ts.map +1 -0
- package/dist/chrome-discovery.test.js +41 -0
- package/dist/chrome-discovery.test.js.map +1 -0
- package/dist/clean-html.d.ts +11 -0
- package/dist/clean-html.d.ts.map +1 -0
- package/dist/clean-html.js +106 -0
- package/dist/clean-html.js.map +1 -0
- package/dist/cli-help.test.d.ts +2 -0
- package/dist/cli-help.test.d.ts.map +1 -0
- package/dist/cli-help.test.js +98 -0
- package/dist/cli-help.test.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2709 -0
- package/dist/cli.js.map +1 -0
- package/dist/cloud-client.d.ts +56 -0
- package/dist/cloud-client.d.ts.map +1 -0
- package/dist/cloud-client.js +127 -0
- package/dist/cloud-client.js.map +1 -0
- package/dist/create-logger.d.ts +9 -0
- package/dist/create-logger.d.ts.map +1 -0
- package/dist/create-logger.js +27 -0
- package/dist/create-logger.js.map +1 -0
- package/dist/debugger-api.md +458 -0
- package/dist/debugger-examples-types.d.ts +24 -0
- package/dist/debugger-examples-types.d.ts.map +1 -0
- package/dist/debugger-examples-types.js +2 -0
- package/dist/debugger-examples-types.js.map +1 -0
- package/dist/debugger-examples.d.ts +6 -0
- package/dist/debugger-examples.d.ts.map +1 -0
- package/dist/debugger-examples.js +53 -0
- package/dist/debugger-examples.js.map +1 -0
- package/dist/debugger.d.ts +381 -0
- package/dist/debugger.d.ts.map +1 -0
- package/dist/debugger.js +630 -0
- package/dist/debugger.js.map +1 -0
- package/dist/diff-utils.d.ts +20 -0
- package/dist/diff-utils.d.ts.map +1 -0
- package/dist/diff-utils.js +50 -0
- package/dist/diff-utils.js.map +1 -0
- package/dist/diff-utils.test.d.ts +2 -0
- package/dist/diff-utils.test.d.ts.map +1 -0
- package/dist/diff-utils.test.js +137 -0
- package/dist/diff-utils.test.js.map +1 -0
- package/dist/doctor.d.ts +44 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +246 -0
- package/dist/doctor.js.map +1 -0
- package/dist/doctor.test.d.ts +2 -0
- package/dist/doctor.test.d.ts.map +1 -0
- package/dist/doctor.test.js +208 -0
- package/dist/doctor.test.js.map +1 -0
- package/dist/editor-api.md +374 -0
- package/dist/editor-examples.d.ts +11 -0
- package/dist/editor-examples.d.ts.map +1 -0
- package/dist/editor-examples.js +124 -0
- package/dist/editor-examples.js.map +1 -0
- package/dist/editor.d.ts +203 -0
- package/dist/editor.d.ts.map +1 -0
- package/dist/editor.js +363 -0
- package/dist/editor.js.map +1 -0
- package/dist/env-compat.d.ts +2 -0
- package/dist/env-compat.d.ts.map +1 -0
- package/dist/env-compat.js +27 -0
- package/dist/env-compat.js.map +1 -0
- package/dist/executor.d.ts +229 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +1465 -0
- package/dist/executor.js.map +1 -0
- package/dist/executor.unit.test.d.ts +2 -0
- package/dist/executor.unit.test.d.ts.map +1 -0
- package/dist/executor.unit.test.js +143 -0
- package/dist/executor.unit.test.js.map +1 -0
- package/dist/extension/_locales/en/messages.json +278 -0
- package/dist/extension/_locales/zh_CN/messages.json +256 -0
- package/dist/extension/assets/options-CYH96Lcx.css +1349 -0
- package/dist/extension/background.js +3994 -0
- package/dist/extension/icons/SolarCursorSquareBold.png +0 -0
- package/dist/extension/icons/icon-black-128.png +0 -0
- package/dist/extension/icons/icon-black-16.png +0 -0
- package/dist/extension/icons/icon-black-32.png +0 -0
- package/dist/extension/icons/icon-black-48.png +0 -0
- package/dist/extension/icons/icon-gray-128.png +0 -0
- package/dist/extension/icons/icon-gray-16.png +0 -0
- package/dist/extension/icons/icon-gray-32.png +0 -0
- package/dist/extension/icons/icon-gray-48.png +0 -0
- package/dist/extension/icons/icon-green-128.png +0 -0
- package/dist/extension/icons/icon-green-16.png +0 -0
- package/dist/extension/icons/icon-green-32.png +0 -0
- package/dist/extension/icons/icon-green-48.png +0 -0
- package/dist/extension/icons/tabwright-icon-black.png +0 -0
- package/dist/extension/icons/tabwright-icon-gray-disabled.png +0 -0
- package/dist/extension/icons/tabwright-icon-gray-disabled.svg +1 -0
- package/dist/extension/manifest.json +54 -0
- package/dist/extension/options.js +16145 -0
- package/dist/extension/rrweb-recorder.js +12952 -0
- package/dist/extension/src/options.html +165 -0
- package/dist/extension/src/prism-bash.min.js +1 -0
- package/dist/extension/src/prism.min.js +1 -0
- package/dist/extension/src/welcome.html +396 -0
- package/dist/extension-connection.test.d.ts +2 -0
- package/dist/extension-connection.test.d.ts.map +1 -0
- package/dist/extension-connection.test.js +708 -0
- package/dist/extension-connection.test.js.map +1 -0
- package/dist/extension-icon-warning.test.d.ts +2 -0
- package/dist/extension-icon-warning.test.d.ts.map +1 -0
- package/dist/extension-icon-warning.test.js +33 -0
- package/dist/extension-icon-warning.test.js.map +1 -0
- package/dist/ghost-browser.d.ts +62 -0
- package/dist/ghost-browser.d.ts.map +1 -0
- package/dist/ghost-browser.js +107 -0
- package/dist/ghost-browser.js.map +1 -0
- package/dist/ghost-cursor-client.js +374 -0
- package/dist/ghost-cursor-controller.d.ts +46 -0
- package/dist/ghost-cursor-controller.d.ts.map +1 -0
- package/dist/ghost-cursor-controller.js +98 -0
- package/dist/ghost-cursor-controller.js.map +1 -0
- package/dist/ghost-cursor.d.ts +27 -0
- package/dist/ghost-cursor.d.ts.map +1 -0
- package/dist/ghost-cursor.js +79 -0
- package/dist/ghost-cursor.js.map +1 -0
- package/dist/htmlrewrite.d.ts +8 -0
- package/dist/htmlrewrite.d.ts.map +1 -0
- package/dist/htmlrewrite.js +339 -0
- package/dist/htmlrewrite.js.map +1 -0
- package/dist/htmlrewrite.test.d.ts +2 -0
- package/dist/htmlrewrite.test.d.ts.map +1 -0
- package/dist/htmlrewrite.test.js +7975 -0
- package/dist/htmlrewrite.test.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/kill-port.d.ts +29 -0
- package/dist/kill-port.d.ts.map +1 -0
- package/dist/kill-port.js +190 -0
- package/dist/kill-port.js.map +1 -0
- package/dist/kitty-graphics.d.ts +22 -0
- package/dist/kitty-graphics.d.ts.map +1 -0
- package/dist/kitty-graphics.js +71 -0
- package/dist/kitty-graphics.js.map +1 -0
- package/dist/kitty-graphics.test.d.ts +2 -0
- package/dist/kitty-graphics.test.d.ts.map +1 -0
- package/dist/kitty-graphics.test.js +125 -0
- package/dist/kitty-graphics.test.js.map +1 -0
- package/dist/locator-selector.test.d.ts +2 -0
- package/dist/locator-selector.test.d.ts.map +1 -0
- package/dist/locator-selector.test.js +98 -0
- package/dist/locator-selector.test.js.map +1 -0
- package/dist/mcp-client.d.ts +20 -0
- package/dist/mcp-client.d.ts.map +1 -0
- package/dist/mcp-client.js +56 -0
- package/dist/mcp-client.js.map +1 -0
- package/dist/mcp.d.ts +6 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +511 -0
- package/dist/mcp.js.map +1 -0
- package/dist/on-mouse-action.test.d.ts +2 -0
- package/dist/on-mouse-action.test.d.ts.map +1 -0
- package/dist/on-mouse-action.test.js +180 -0
- package/dist/on-mouse-action.test.js.map +1 -0
- package/dist/options-page.test.d.ts +2 -0
- package/dist/options-page.test.d.ts.map +1 -0
- package/dist/options-page.test.js +773 -0
- package/dist/options-page.test.js.map +1 -0
- package/dist/package-paths.d.ts +4 -0
- package/dist/package-paths.d.ts.map +1 -0
- package/dist/package-paths.js +30 -0
- package/dist/package-paths.js.map +1 -0
- package/dist/page-markdown.d.ts +40 -0
- package/dist/page-markdown.d.ts.map +1 -0
- package/dist/page-markdown.js +181 -0
- package/dist/page-markdown.js.map +1 -0
- package/dist/performance-examples.d.ts +5 -0
- package/dist/performance-examples.d.ts.map +1 -0
- package/dist/performance-examples.js +112 -0
- package/dist/performance-examples.js.map +1 -0
- package/dist/performance-profiling.md +417 -0
- package/dist/playwright-import.d.ts +19 -0
- package/dist/playwright-import.d.ts.map +1 -0
- package/dist/playwright-import.js +40 -0
- package/dist/playwright-import.js.map +1 -0
- package/dist/popup-relocation.test.d.ts +7 -0
- package/dist/popup-relocation.test.d.ts.map +1 -0
- package/dist/popup-relocation.test.js +139 -0
- package/dist/popup-relocation.test.js.map +1 -0
- package/dist/product-paths.d.ts +9 -0
- package/dist/product-paths.d.ts.map +1 -0
- package/dist/product-paths.js +24 -0
- package/dist/product-paths.js.map +1 -0
- package/dist/product-paths.test.d.ts +2 -0
- package/dist/product-paths.test.d.ts.map +1 -0
- package/dist/product-paths.test.js +39 -0
- package/dist/product-paths.test.js.map +1 -0
- package/dist/prompt.md +1004 -0
- package/dist/protocol.d.ts +248 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +59 -0
- package/dist/protocol.js.map +1 -0
- package/dist/protocol.test.d.ts +2 -0
- package/dist/protocol.test.d.ts.map +1 -0
- package/dist/protocol.test.js +31 -0
- package/dist/protocol.test.js.map +1 -0
- package/dist/react-source.d.ts +57 -0
- package/dist/react-source.d.ts.map +1 -0
- package/dist/react-source.js +254 -0
- package/dist/react-source.js.map +1 -0
- package/dist/readability.js +1674 -0
- package/dist/relay-client.d.ts +104 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +426 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-client.test.d.ts +2 -0
- package/dist/relay-client.test.d.ts.map +1 -0
- package/dist/relay-client.test.js +305 -0
- package/dist/relay-client.test.js.map +1 -0
- package/dist/relay-core.test.d.ts +2 -0
- package/dist/relay-core.test.d.ts.map +1 -0
- package/dist/relay-core.test.js +1427 -0
- package/dist/relay-core.test.js.map +1 -0
- package/dist/relay-navigation.test.d.ts +2 -0
- package/dist/relay-navigation.test.d.ts.map +1 -0
- package/dist/relay-navigation.test.js +661 -0
- package/dist/relay-navigation.test.js.map +1 -0
- package/dist/relay-session.test.d.ts +2 -0
- package/dist/relay-session.test.d.ts.map +1 -0
- package/dist/relay-session.test.js +1121 -0
- package/dist/relay-session.test.js.map +1 -0
- package/dist/relay-state.d.ts +178 -0
- package/dist/relay-state.d.ts.map +1 -0
- package/dist/relay-state.js +346 -0
- package/dist/relay-state.js.map +1 -0
- package/dist/relay-state.test.d.ts +2 -0
- package/dist/relay-state.test.d.ts.map +1 -0
- package/dist/relay-state.test.js +594 -0
- package/dist/relay-state.test.js.map +1 -0
- package/dist/replay-ai-index.d.ts +99 -0
- package/dist/replay-ai-index.d.ts.map +1 -0
- package/dist/replay-ai-index.js +677 -0
- package/dist/replay-ai-index.js.map +1 -0
- package/dist/replay-ai-index.test.d.ts +2 -0
- package/dist/replay-ai-index.test.d.ts.map +1 -0
- package/dist/replay-ai-index.test.js +255 -0
- package/dist/replay-ai-index.test.js.map +1 -0
- package/dist/replay-cli.test.d.ts +2 -0
- package/dist/replay-cli.test.d.ts.map +1 -0
- package/dist/replay-cli.test.js +275 -0
- package/dist/replay-cli.test.js.map +1 -0
- package/dist/replay-eval.d.ts +44 -0
- package/dist/replay-eval.d.ts.map +1 -0
- package/dist/replay-eval.js +902 -0
- package/dist/replay-eval.js.map +1 -0
- package/dist/replay-handoff.d.ts +29 -0
- package/dist/replay-handoff.d.ts.map +1 -0
- package/dist/replay-handoff.js +83 -0
- package/dist/replay-handoff.js.map +1 -0
- package/dist/replay-handoff.test.d.ts +2 -0
- package/dist/replay-handoff.test.d.ts.map +1 -0
- package/dist/replay-handoff.test.js +123 -0
- package/dist/replay-handoff.test.js.map +1 -0
- package/dist/replay-workflow-compiler.d.ts +44 -0
- package/dist/replay-workflow-compiler.d.ts.map +1 -0
- package/dist/replay-workflow-compiler.js +601 -0
- package/dist/replay-workflow-compiler.js.map +1 -0
- package/dist/replay-workflow-compiler.test.d.ts +2 -0
- package/dist/replay-workflow-compiler.test.d.ts.map +1 -0
- package/dist/replay-workflow-compiler.test.js +223 -0
- package/dist/replay-workflow-compiler.test.js.map +1 -0
- package/dist/rrweb-recording-relay.d.ts +56 -0
- package/dist/rrweb-recording-relay.d.ts.map +1 -0
- package/dist/rrweb-recording-relay.js +299 -0
- package/dist/rrweb-recording-relay.js.map +1 -0
- package/dist/rrweb-recording-relay.test.d.ts +2 -0
- package/dist/rrweb-recording-relay.test.d.ts.map +1 -0
- package/dist/rrweb-recording-relay.test.js +85 -0
- package/dist/rrweb-recording-relay.test.js.map +1 -0
- package/dist/rrweb-recording.d.ts +104 -0
- package/dist/rrweb-recording.d.ts.map +1 -0
- package/dist/rrweb-recording.js +180 -0
- package/dist/rrweb-recording.js.map +1 -0
- package/dist/scoped-fs.d.ts +95 -0
- package/dist/scoped-fs.d.ts.map +1 -0
- package/dist/scoped-fs.js +358 -0
- package/dist/scoped-fs.js.map +1 -0
- package/dist/scoped-fs.test.d.ts +5 -0
- package/dist/scoped-fs.test.d.ts.map +1 -0
- package/dist/scoped-fs.test.js +73 -0
- package/dist/scoped-fs.test.js.map +1 -0
- package/dist/selector-generator.js +7378 -0
- package/dist/skill-stub.test.d.ts +2 -0
- package/dist/skill-stub.test.d.ts.map +1 -0
- package/dist/skill-stub.test.js +22 -0
- package/dist/skill-stub.test.js.map +1 -0
- package/dist/snapshot-tools.test.d.ts +2 -0
- package/dist/snapshot-tools.test.d.ts.map +1 -0
- package/dist/snapshot-tools.test.js +856 -0
- package/dist/snapshot-tools.test.js.map +1 -0
- package/dist/start-relay-server.d.ts +6 -0
- package/dist/start-relay-server.d.ts.map +1 -0
- package/dist/start-relay-server.js +57 -0
- package/dist/start-relay-server.js.map +1 -0
- package/dist/styles-api.md +124 -0
- package/dist/styles-examples.d.ts +8 -0
- package/dist/styles-examples.d.ts.map +1 -0
- package/dist/styles-examples.js +64 -0
- package/dist/styles-examples.js.map +1 -0
- package/dist/styles.d.ts +27 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +231 -0
- package/dist/styles.js.map +1 -0
- package/dist/tabwright-agent-skill.d.ts +30 -0
- package/dist/tabwright-agent-skill.d.ts.map +1 -0
- package/dist/tabwright-agent-skill.js +74 -0
- package/dist/tabwright-agent-skill.js.map +1 -0
- package/dist/tabwright-agent-skill.test.d.ts +2 -0
- package/dist/tabwright-agent-skill.test.d.ts.map +1 -0
- package/dist/tabwright-agent-skill.test.js +51 -0
- package/dist/tabwright-agent-skill.test.js.map +1 -0
- package/dist/test-declarations.d.ts +13 -0
- package/dist/test-declarations.d.ts.map +1 -0
- package/dist/test-declarations.js +2 -0
- package/dist/test-declarations.js.map +1 -0
- package/dist/test-utils.d.ts +69 -0
- package/dist/test-utils.d.ts.map +1 -0
- package/dist/test-utils.js +448 -0
- package/dist/test-utils.js.map +1 -0
- package/dist/test-utils.test.d.ts +2 -0
- package/dist/test-utils.test.d.ts.map +1 -0
- package/dist/test-utils.test.js +55 -0
- package/dist/test-utils.test.js.map +1 -0
- package/dist/utils.d.ts +26 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +60 -0
- package/dist/utils.js.map +1 -0
- package/dist/wait-for-page-load.d.ts +16 -0
- package/dist/wait-for-page-load.d.ts.map +1 -0
- package/dist/wait-for-page-load.js +146 -0
- package/dist/wait-for-page-load.js.map +1 -0
- package/dist/workflow-capability.d.ts +72 -0
- package/dist/workflow-capability.d.ts.map +1 -0
- package/dist/workflow-capability.js +316 -0
- package/dist/workflow-capability.js.map +1 -0
- package/dist/workflow-script-flow.test.d.ts +2 -0
- package/dist/workflow-script-flow.test.d.ts.map +1 -0
- package/dist/workflow-script-flow.test.js +285 -0
- package/dist/workflow-script-flow.test.js.map +1 -0
- package/package.json +80 -0
- package/src/__snapshots__/x.com.processed.html +1003 -0
- package/src/__snapshots__/x.com.processed.withStyles.html +2720 -0
- package/src/a11y-client.ts +241 -0
- package/src/agent-skills/conan-config/SKILL.md +141 -0
- package/src/agent-skills/conan-config/agents/openai.yaml +4 -0
- package/src/aria-snapshot.test.ts +311 -0
- package/src/aria-snapshot.ts +1681 -0
- package/src/aria-snapshot.unit.test.ts +615 -0
- package/src/aria-snapshots/github-interactive.txt +193 -0
- package/src/aria-snapshots/github-raw.txt +309 -0
- package/src/aria-snapshots/hackernews-interactive.txt +477 -0
- package/src/aria-snapshots/hackernews-raw.txt +428 -0
- package/src/aria-snapshots/prosemirror-interactive.txt +66 -0
- package/src/aria-snapshots/prosemirror-raw.txt +145 -0
- package/src/assets/aria-labels-hacker-news.png +0 -0
- package/src/assets/aria-labels-old-reddit.png +0 -0
- package/src/assets/cursors/screen-studio/pointer-macos-tahoe-data-url.ts +5 -0
- package/src/assets/cursors/screen-studio/pointer-macos-tahoe.svg +18 -0
- package/src/assets/x.com.html +32946 -0
- package/src/browser-config.ts +179 -0
- package/src/browser-install.ts +284 -0
- package/src/browser-launch.ts +75 -0
- package/src/builtin-capabilities.ts +2765 -0
- package/src/capability-agent-skill.ts +305 -0
- package/src/capability-auth-state.ts +197 -0
- package/src/capability-auth.ts +249 -0
- package/src/capability-cli-confirmation.test.ts +90 -0
- package/src/capability-options.test.ts +89 -0
- package/src/capability-options.ts +57 -0
- package/src/capability-package.test.ts +204 -0
- package/src/capability-package.ts +555 -0
- package/src/capability-registry.test.ts +1905 -0
- package/src/capability-registry.ts +1234 -0
- package/src/capability-runner.ts +801 -0
- package/src/capability-search-relevance.test.ts +73 -0
- package/src/capability-studio.test.ts +45 -0
- package/src/capability-studio.ts +641 -0
- package/src/cdp-log.test.ts +131 -0
- package/src/cdp-log.ts +112 -0
- package/src/cdp-relay.ts +2944 -0
- package/src/cdp-session.ts +77 -0
- package/src/cdp-types.ts +158 -0
- package/src/channel-owner-inspect.test.ts +94 -0
- package/src/chrome-discovery.test.ts +50 -0
- package/src/chrome-discovery.ts +220 -0
- package/src/clean-html.ts +141 -0
- package/src/cli-help.test.ts +123 -0
- package/src/cli.ts +3181 -0
- package/src/cloud-client.ts +179 -0
- package/src/create-logger.ts +38 -0
- package/src/debugger-examples-types.ts +16 -0
- package/src/debugger-examples.ts +66 -0
- package/src/debugger.ts +708 -0
- package/src/diff-utils.test.ts +152 -0
- package/src/diff-utils.ts +70 -0
- package/src/doctor.test.ts +244 -0
- package/src/doctor.ts +321 -0
- package/src/editor-examples.ts +158 -0
- package/src/editor.ts +426 -0
- package/src/env-compat.ts +28 -0
- package/src/executor.ts +1824 -0
- package/src/executor.unit.test.ts +168 -0
- package/src/extension-connection.test.ts +855 -0
- package/src/extension-icon-warning.test.ts +45 -0
- package/src/ghost-browser.ts +149 -0
- package/src/ghost-cursor-client.ts +494 -0
- package/src/ghost-cursor-controller.ts +129 -0
- package/src/ghost-cursor.ts +123 -0
- package/src/htmlrewrite.test.ts +8008 -0
- package/src/htmlrewrite.ts +390 -0
- package/src/index.ts +53 -0
- package/src/kill-port.ts +219 -0
- package/src/kitty-graphics.test.ts +139 -0
- package/src/kitty-graphics.ts +79 -0
- package/src/locator-selector.test.ts +119 -0
- package/src/mcp-client.ts +78 -0
- package/src/mcp.ts +629 -0
- package/src/on-mouse-action.test.ts +226 -0
- package/src/options-page.test.ts +839 -0
- package/src/package-paths.ts +38 -0
- package/src/page-markdown.ts +240 -0
- package/src/performance-examples.ts +186 -0
- package/src/playwright-import.ts +59 -0
- package/src/popup-relocation.test.ts +163 -0
- package/src/product-paths.test.ts +47 -0
- package/src/product-paths.ts +28 -0
- package/src/protocol.test.ts +52 -0
- package/src/protocol.ts +351 -0
- package/src/react-source.ts +379 -0
- package/src/relay-client.test.ts +375 -0
- package/src/relay-client.ts +572 -0
- package/src/relay-core.test.ts +1603 -0
- package/src/relay-navigation.test.ts +790 -0
- package/src/relay-session.test.ts +1375 -0
- package/src/relay-state.test.ts +729 -0
- package/src/relay-state.ts +561 -0
- package/src/replay-ai-index.test.ts +278 -0
- package/src/replay-ai-index.ts +872 -0
- package/src/replay-cli.test.ts +325 -0
- package/src/replay-eval.ts +1039 -0
- package/src/replay-handoff.test.ts +163 -0
- package/src/replay-handoff.ts +109 -0
- package/src/replay-workflow-compiler.test.ts +250 -0
- package/src/replay-workflow-compiler.ts +700 -0
- package/src/resource.md +409 -0
- package/src/rrweb-recording-relay.test.ts +99 -0
- package/src/rrweb-recording-relay.ts +400 -0
- package/src/rrweb-recording.ts +322 -0
- package/src/scoped-fs.test.ts +80 -0
- package/src/scoped-fs.ts +420 -0
- package/src/skill-stub.test.ts +24 -0
- package/src/skill.md +1413 -0
- package/src/snapshot-tools.test.ts +1017 -0
- package/src/snapshots/hacker-news-accessibility-full.md +81 -0
- package/src/snapshots/hacker-news-accessibility-interactive.md +43 -0
- package/src/snapshots/page-markdown-output.txt +16 -0
- package/src/snapshots/shadcn-ui-accessibility-full.md +201 -0
- package/src/snapshots/shadcn-ui-accessibility-interactive.md +109 -0
- package/src/start-relay-server.ts +69 -0
- package/src/styles-examples.ts +84 -0
- package/src/styles.ts +343 -0
- package/src/tabwright-agent-skill.test.ts +61 -0
- package/src/tabwright-agent-skill.ts +105 -0
- package/src/test-declarations.ts +13 -0
- package/src/test-utils.test.ts +70 -0
- package/src/test-utils.ts +566 -0
- package/src/utils.ts +78 -0
- package/src/wait-for-page-load.ts +198 -0
- package/src/workflow-capability.ts +417 -0
- package/src/workflow-script-flow.test.ts +388 -0
|
@@ -0,0 +1,1674 @@
|
|
|
1
|
+
(() => {
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
12
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
30
|
+
return to;
|
|
31
|
+
};
|
|
32
|
+
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
33
|
+
|
|
34
|
+
// ../node_modules/.pnpm/@mozilla+readability@0.6.0/node_modules/@mozilla/readability/Readability.js
|
|
35
|
+
var require_Readability = __commonJS((exports, module) => {
|
|
36
|
+
function Readability(doc, options) {
|
|
37
|
+
if (options && options.documentElement) {
|
|
38
|
+
doc = options;
|
|
39
|
+
options = arguments[2];
|
|
40
|
+
} else if (!doc || !doc.documentElement) {
|
|
41
|
+
throw new Error("First argument to Readability constructor should be a document object.");
|
|
42
|
+
}
|
|
43
|
+
options = options || {};
|
|
44
|
+
this._doc = doc;
|
|
45
|
+
this._docJSDOMParser = this._doc.firstChild.__JSDOMParser__;
|
|
46
|
+
this._articleTitle = null;
|
|
47
|
+
this._articleByline = null;
|
|
48
|
+
this._articleDir = null;
|
|
49
|
+
this._articleSiteName = null;
|
|
50
|
+
this._attempts = [];
|
|
51
|
+
this._metadata = {};
|
|
52
|
+
this._debug = !!options.debug;
|
|
53
|
+
this._maxElemsToParse = options.maxElemsToParse || this.DEFAULT_MAX_ELEMS_TO_PARSE;
|
|
54
|
+
this._nbTopCandidates = options.nbTopCandidates || this.DEFAULT_N_TOP_CANDIDATES;
|
|
55
|
+
this._charThreshold = options.charThreshold || this.DEFAULT_CHAR_THRESHOLD;
|
|
56
|
+
this._classesToPreserve = this.CLASSES_TO_PRESERVE.concat(options.classesToPreserve || []);
|
|
57
|
+
this._keepClasses = !!options.keepClasses;
|
|
58
|
+
this._serializer = options.serializer || function(el) {
|
|
59
|
+
return el.innerHTML;
|
|
60
|
+
};
|
|
61
|
+
this._disableJSONLD = !!options.disableJSONLD;
|
|
62
|
+
this._allowedVideoRegex = options.allowedVideoRegex || this.REGEXPS.videos;
|
|
63
|
+
this._linkDensityModifier = options.linkDensityModifier || 0;
|
|
64
|
+
this._flags = this.FLAG_STRIP_UNLIKELYS | this.FLAG_WEIGHT_CLASSES | this.FLAG_CLEAN_CONDITIONALLY;
|
|
65
|
+
if (this._debug) {
|
|
66
|
+
let logNode = function(node) {
|
|
67
|
+
if (node.nodeType == node.TEXT_NODE) {
|
|
68
|
+
return `${node.nodeName} ("${node.textContent}")`;
|
|
69
|
+
}
|
|
70
|
+
let attrPairs = Array.from(node.attributes || [], function(attr) {
|
|
71
|
+
return `${attr.name}="${attr.value}"`;
|
|
72
|
+
}).join(" ");
|
|
73
|
+
return `<${node.localName} ${attrPairs}>`;
|
|
74
|
+
};
|
|
75
|
+
this.log = function() {
|
|
76
|
+
if (typeof console !== "undefined") {
|
|
77
|
+
let args = Array.from(arguments, (arg) => {
|
|
78
|
+
if (arg && arg.nodeType == this.ELEMENT_NODE) {
|
|
79
|
+
return logNode(arg);
|
|
80
|
+
}
|
|
81
|
+
return arg;
|
|
82
|
+
});
|
|
83
|
+
args.unshift("Reader: (Readability)");
|
|
84
|
+
console.log(...args);
|
|
85
|
+
} else if (typeof dump !== "undefined") {
|
|
86
|
+
var msg = Array.prototype.map.call(arguments, function(x) {
|
|
87
|
+
return x && x.nodeName ? logNode(x) : x;
|
|
88
|
+
}).join(" ");
|
|
89
|
+
dump("Reader: (Readability) " + msg + `
|
|
90
|
+
`);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
} else {
|
|
94
|
+
this.log = function() {};
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
Readability.prototype = {
|
|
98
|
+
FLAG_STRIP_UNLIKELYS: 1,
|
|
99
|
+
FLAG_WEIGHT_CLASSES: 2,
|
|
100
|
+
FLAG_CLEAN_CONDITIONALLY: 4,
|
|
101
|
+
ELEMENT_NODE: 1,
|
|
102
|
+
TEXT_NODE: 3,
|
|
103
|
+
DEFAULT_MAX_ELEMS_TO_PARSE: 0,
|
|
104
|
+
DEFAULT_N_TOP_CANDIDATES: 5,
|
|
105
|
+
DEFAULT_TAGS_TO_SCORE: "section,h2,h3,h4,h5,h6,p,td,pre".toUpperCase().split(","),
|
|
106
|
+
DEFAULT_CHAR_THRESHOLD: 500,
|
|
107
|
+
REGEXPS: {
|
|
108
|
+
unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
|
|
109
|
+
okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i,
|
|
110
|
+
positive: /article|body|content|entry|hentry|h-entry|main|page|pagination|post|text|blog|story/i,
|
|
111
|
+
negative: /-ad-|hidden|^hid$| hid$| hid |^hid |banner|combx|comment|com-|contact|footer|gdpr|masthead|media|meta|outbrain|promo|related|scroll|share|shoutbox|sidebar|skyscraper|sponsor|shopping|tags|widget/i,
|
|
112
|
+
extraneous: /print|archive|comment|discuss|e[\-]?mail|share|reply|all|login|sign|single|utility/i,
|
|
113
|
+
byline: /byline|author|dateline|writtenby|p-author/i,
|
|
114
|
+
replaceFonts: /<(\/?)font[^>]*>/gi,
|
|
115
|
+
normalize: /\s{2,}/g,
|
|
116
|
+
videos: /\/\/(www\.)?((dailymotion|youtube|youtube-nocookie|player\.vimeo|v\.qq)\.com|(archive|upload\.wikimedia)\.org|player\.twitch\.tv)/i,
|
|
117
|
+
shareElements: /(\b|_)(share|sharedaddy)(\b|_)/i,
|
|
118
|
+
nextLink: /(next|weiter|continue|>([^\|]|$)|»([^\|]|$))/i,
|
|
119
|
+
prevLink: /(prev|earl|old|new|<|«)/i,
|
|
120
|
+
tokenize: /\W+/g,
|
|
121
|
+
whitespace: /^\s*$/,
|
|
122
|
+
hasContent: /\S$/,
|
|
123
|
+
hashUrl: /^#.+/,
|
|
124
|
+
srcsetUrl: /(\S+)(\s+[\d.]+[xw])?(\s*(?:,|$))/g,
|
|
125
|
+
b64DataUrl: /^data:\s*([^\s;,]+)\s*;\s*base64\s*,/i,
|
|
126
|
+
commas: /\u002C|\u060C|\uFE50|\uFE10|\uFE11|\u2E41|\u2E34|\u2E32|\uFF0C/g,
|
|
127
|
+
jsonLdArticleTypes: /^Article|AdvertiserContentArticle|NewsArticle|AnalysisNewsArticle|AskPublicNewsArticle|BackgroundNewsArticle|OpinionNewsArticle|ReportageNewsArticle|ReviewNewsArticle|Report|SatiricalArticle|ScholarlyArticle|MedicalScholarlyArticle|SocialMediaPosting|BlogPosting|LiveBlogPosting|DiscussionForumPosting|TechArticle|APIReference$/,
|
|
128
|
+
adWords: /^(ad(vertising|vertisement)?|pub(licité)?|werb(ung)?|广告|Реклама|Anuncio)$/iu,
|
|
129
|
+
loadingWords: /^((loading|正在加载|Загрузка|chargement|cargando)(…|\.\.\.)?)$/iu
|
|
130
|
+
},
|
|
131
|
+
UNLIKELY_ROLES: [
|
|
132
|
+
"menu",
|
|
133
|
+
"menubar",
|
|
134
|
+
"complementary",
|
|
135
|
+
"navigation",
|
|
136
|
+
"alert",
|
|
137
|
+
"alertdialog",
|
|
138
|
+
"dialog"
|
|
139
|
+
],
|
|
140
|
+
DIV_TO_P_ELEMS: new Set([
|
|
141
|
+
"BLOCKQUOTE",
|
|
142
|
+
"DL",
|
|
143
|
+
"DIV",
|
|
144
|
+
"IMG",
|
|
145
|
+
"OL",
|
|
146
|
+
"P",
|
|
147
|
+
"PRE",
|
|
148
|
+
"TABLE",
|
|
149
|
+
"UL"
|
|
150
|
+
]),
|
|
151
|
+
ALTER_TO_DIV_EXCEPTIONS: ["DIV", "ARTICLE", "SECTION", "P", "OL", "UL"],
|
|
152
|
+
PRESENTATIONAL_ATTRIBUTES: [
|
|
153
|
+
"align",
|
|
154
|
+
"background",
|
|
155
|
+
"bgcolor",
|
|
156
|
+
"border",
|
|
157
|
+
"cellpadding",
|
|
158
|
+
"cellspacing",
|
|
159
|
+
"frame",
|
|
160
|
+
"hspace",
|
|
161
|
+
"rules",
|
|
162
|
+
"style",
|
|
163
|
+
"valign",
|
|
164
|
+
"vspace"
|
|
165
|
+
],
|
|
166
|
+
DEPRECATED_SIZE_ATTRIBUTE_ELEMS: ["TABLE", "TH", "TD", "HR", "PRE"],
|
|
167
|
+
PHRASING_ELEMS: [
|
|
168
|
+
"ABBR",
|
|
169
|
+
"AUDIO",
|
|
170
|
+
"B",
|
|
171
|
+
"BDO",
|
|
172
|
+
"BR",
|
|
173
|
+
"BUTTON",
|
|
174
|
+
"CITE",
|
|
175
|
+
"CODE",
|
|
176
|
+
"DATA",
|
|
177
|
+
"DATALIST",
|
|
178
|
+
"DFN",
|
|
179
|
+
"EM",
|
|
180
|
+
"EMBED",
|
|
181
|
+
"I",
|
|
182
|
+
"IMG",
|
|
183
|
+
"INPUT",
|
|
184
|
+
"KBD",
|
|
185
|
+
"LABEL",
|
|
186
|
+
"MARK",
|
|
187
|
+
"MATH",
|
|
188
|
+
"METER",
|
|
189
|
+
"NOSCRIPT",
|
|
190
|
+
"OBJECT",
|
|
191
|
+
"OUTPUT",
|
|
192
|
+
"PROGRESS",
|
|
193
|
+
"Q",
|
|
194
|
+
"RUBY",
|
|
195
|
+
"SAMP",
|
|
196
|
+
"SCRIPT",
|
|
197
|
+
"SELECT",
|
|
198
|
+
"SMALL",
|
|
199
|
+
"SPAN",
|
|
200
|
+
"STRONG",
|
|
201
|
+
"SUB",
|
|
202
|
+
"SUP",
|
|
203
|
+
"TEXTAREA",
|
|
204
|
+
"TIME",
|
|
205
|
+
"VAR",
|
|
206
|
+
"WBR"
|
|
207
|
+
],
|
|
208
|
+
CLASSES_TO_PRESERVE: ["page"],
|
|
209
|
+
HTML_ESCAPE_MAP: {
|
|
210
|
+
lt: "<",
|
|
211
|
+
gt: ">",
|
|
212
|
+
amp: "&",
|
|
213
|
+
quot: '"',
|
|
214
|
+
apos: "'"
|
|
215
|
+
},
|
|
216
|
+
_postProcessContent(articleContent) {
|
|
217
|
+
this._fixRelativeUris(articleContent);
|
|
218
|
+
this._simplifyNestedElements(articleContent);
|
|
219
|
+
if (!this._keepClasses) {
|
|
220
|
+
this._cleanClasses(articleContent);
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
_removeNodes(nodeList, filterFn) {
|
|
224
|
+
if (this._docJSDOMParser && nodeList._isLiveNodeList) {
|
|
225
|
+
throw new Error("Do not pass live node lists to _removeNodes");
|
|
226
|
+
}
|
|
227
|
+
for (var i = nodeList.length - 1;i >= 0; i--) {
|
|
228
|
+
var node = nodeList[i];
|
|
229
|
+
var parentNode = node.parentNode;
|
|
230
|
+
if (parentNode) {
|
|
231
|
+
if (!filterFn || filterFn.call(this, node, i, nodeList)) {
|
|
232
|
+
parentNode.removeChild(node);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
_replaceNodeTags(nodeList, newTagName) {
|
|
238
|
+
if (this._docJSDOMParser && nodeList._isLiveNodeList) {
|
|
239
|
+
throw new Error("Do not pass live node lists to _replaceNodeTags");
|
|
240
|
+
}
|
|
241
|
+
for (const node of nodeList) {
|
|
242
|
+
this._setNodeTag(node, newTagName);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
_forEachNode(nodeList, fn) {
|
|
246
|
+
Array.prototype.forEach.call(nodeList, fn, this);
|
|
247
|
+
},
|
|
248
|
+
_findNode(nodeList, fn) {
|
|
249
|
+
return Array.prototype.find.call(nodeList, fn, this);
|
|
250
|
+
},
|
|
251
|
+
_someNode(nodeList, fn) {
|
|
252
|
+
return Array.prototype.some.call(nodeList, fn, this);
|
|
253
|
+
},
|
|
254
|
+
_everyNode(nodeList, fn) {
|
|
255
|
+
return Array.prototype.every.call(nodeList, fn, this);
|
|
256
|
+
},
|
|
257
|
+
_getAllNodesWithTag(node, tagNames) {
|
|
258
|
+
if (node.querySelectorAll) {
|
|
259
|
+
return node.querySelectorAll(tagNames.join(","));
|
|
260
|
+
}
|
|
261
|
+
return [].concat.apply([], tagNames.map(function(tag) {
|
|
262
|
+
var collection = node.getElementsByTagName(tag);
|
|
263
|
+
return Array.isArray(collection) ? collection : Array.from(collection);
|
|
264
|
+
}));
|
|
265
|
+
},
|
|
266
|
+
_cleanClasses(node) {
|
|
267
|
+
var classesToPreserve = this._classesToPreserve;
|
|
268
|
+
var className = (node.getAttribute("class") || "").split(/\s+/).filter((cls) => classesToPreserve.includes(cls)).join(" ");
|
|
269
|
+
if (className) {
|
|
270
|
+
node.setAttribute("class", className);
|
|
271
|
+
} else {
|
|
272
|
+
node.removeAttribute("class");
|
|
273
|
+
}
|
|
274
|
+
for (node = node.firstElementChild;node; node = node.nextElementSibling) {
|
|
275
|
+
this._cleanClasses(node);
|
|
276
|
+
}
|
|
277
|
+
},
|
|
278
|
+
_isUrl(str) {
|
|
279
|
+
try {
|
|
280
|
+
new URL(str);
|
|
281
|
+
return true;
|
|
282
|
+
} catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
_fixRelativeUris(articleContent) {
|
|
287
|
+
var baseURI = this._doc.baseURI;
|
|
288
|
+
var documentURI = this._doc.documentURI;
|
|
289
|
+
function toAbsoluteURI(uri) {
|
|
290
|
+
if (baseURI == documentURI && uri.charAt(0) == "#") {
|
|
291
|
+
return uri;
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
return new URL(uri, baseURI).href;
|
|
295
|
+
} catch (ex) {}
|
|
296
|
+
return uri;
|
|
297
|
+
}
|
|
298
|
+
var links = this._getAllNodesWithTag(articleContent, ["a"]);
|
|
299
|
+
this._forEachNode(links, function(link) {
|
|
300
|
+
var href = link.getAttribute("href");
|
|
301
|
+
if (href) {
|
|
302
|
+
if (href.indexOf("javascript:") === 0) {
|
|
303
|
+
if (link.childNodes.length === 1 && link.childNodes[0].nodeType === this.TEXT_NODE) {
|
|
304
|
+
var text = this._doc.createTextNode(link.textContent);
|
|
305
|
+
link.parentNode.replaceChild(text, link);
|
|
306
|
+
} else {
|
|
307
|
+
var container = this._doc.createElement("span");
|
|
308
|
+
while (link.firstChild) {
|
|
309
|
+
container.appendChild(link.firstChild);
|
|
310
|
+
}
|
|
311
|
+
link.parentNode.replaceChild(container, link);
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
link.setAttribute("href", toAbsoluteURI(href));
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
var medias = this._getAllNodesWithTag(articleContent, [
|
|
319
|
+
"img",
|
|
320
|
+
"picture",
|
|
321
|
+
"figure",
|
|
322
|
+
"video",
|
|
323
|
+
"audio",
|
|
324
|
+
"source"
|
|
325
|
+
]);
|
|
326
|
+
this._forEachNode(medias, function(media) {
|
|
327
|
+
var src = media.getAttribute("src");
|
|
328
|
+
var poster = media.getAttribute("poster");
|
|
329
|
+
var srcset = media.getAttribute("srcset");
|
|
330
|
+
if (src) {
|
|
331
|
+
media.setAttribute("src", toAbsoluteURI(src));
|
|
332
|
+
}
|
|
333
|
+
if (poster) {
|
|
334
|
+
media.setAttribute("poster", toAbsoluteURI(poster));
|
|
335
|
+
}
|
|
336
|
+
if (srcset) {
|
|
337
|
+
var newSrcset = srcset.replace(this.REGEXPS.srcsetUrl, function(_, p1, p2, p3) {
|
|
338
|
+
return toAbsoluteURI(p1) + (p2 || "") + p3;
|
|
339
|
+
});
|
|
340
|
+
media.setAttribute("srcset", newSrcset);
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
_simplifyNestedElements(articleContent) {
|
|
345
|
+
var node = articleContent;
|
|
346
|
+
while (node) {
|
|
347
|
+
if (node.parentNode && ["DIV", "SECTION"].includes(node.tagName) && !(node.id && node.id.startsWith("readability"))) {
|
|
348
|
+
if (this._isElementWithoutContent(node)) {
|
|
349
|
+
node = this._removeAndGetNext(node);
|
|
350
|
+
continue;
|
|
351
|
+
} else if (this._hasSingleTagInsideElement(node, "DIV") || this._hasSingleTagInsideElement(node, "SECTION")) {
|
|
352
|
+
var child = node.children[0];
|
|
353
|
+
for (var i = 0;i < node.attributes.length; i++) {
|
|
354
|
+
child.setAttributeNode(node.attributes[i].cloneNode());
|
|
355
|
+
}
|
|
356
|
+
node.parentNode.replaceChild(child, node);
|
|
357
|
+
node = child;
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
node = this._getNextNode(node);
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
_getArticleTitle() {
|
|
365
|
+
var doc = this._doc;
|
|
366
|
+
var curTitle = "";
|
|
367
|
+
var origTitle = "";
|
|
368
|
+
try {
|
|
369
|
+
curTitle = origTitle = doc.title.trim();
|
|
370
|
+
if (typeof curTitle !== "string") {
|
|
371
|
+
curTitle = origTitle = this._getInnerText(doc.getElementsByTagName("title")[0]);
|
|
372
|
+
}
|
|
373
|
+
} catch (e) {}
|
|
374
|
+
var titleHadHierarchicalSeparators = false;
|
|
375
|
+
function wordCount(str) {
|
|
376
|
+
return str.split(/\s+/).length;
|
|
377
|
+
}
|
|
378
|
+
if (/ [\|\-\\\/>»] /.test(curTitle)) {
|
|
379
|
+
titleHadHierarchicalSeparators = / [\\\/>»] /.test(curTitle);
|
|
380
|
+
let allSeparators = Array.from(origTitle.matchAll(/ [\|\-\\\/>»] /gi));
|
|
381
|
+
curTitle = origTitle.substring(0, allSeparators.pop().index);
|
|
382
|
+
if (wordCount(curTitle) < 3) {
|
|
383
|
+
curTitle = origTitle.replace(/^[^\|\-\\\/>»]*[\|\-\\\/>»]/gi, "");
|
|
384
|
+
}
|
|
385
|
+
} else if (curTitle.includes(": ")) {
|
|
386
|
+
var headings = this._getAllNodesWithTag(doc, ["h1", "h2"]);
|
|
387
|
+
var trimmedTitle = curTitle.trim();
|
|
388
|
+
var match = this._someNode(headings, function(heading) {
|
|
389
|
+
return heading.textContent.trim() === trimmedTitle;
|
|
390
|
+
});
|
|
391
|
+
if (!match) {
|
|
392
|
+
curTitle = origTitle.substring(origTitle.lastIndexOf(":") + 1);
|
|
393
|
+
if (wordCount(curTitle) < 3) {
|
|
394
|
+
curTitle = origTitle.substring(origTitle.indexOf(":") + 1);
|
|
395
|
+
} else if (wordCount(origTitle.substr(0, origTitle.indexOf(":"))) > 5) {
|
|
396
|
+
curTitle = origTitle;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
} else if (curTitle.length > 150 || curTitle.length < 15) {
|
|
400
|
+
var hOnes = doc.getElementsByTagName("h1");
|
|
401
|
+
if (hOnes.length === 1) {
|
|
402
|
+
curTitle = this._getInnerText(hOnes[0]);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
curTitle = curTitle.trim().replace(this.REGEXPS.normalize, " ");
|
|
406
|
+
var curTitleWordCount = wordCount(curTitle);
|
|
407
|
+
if (curTitleWordCount <= 4 && (!titleHadHierarchicalSeparators || curTitleWordCount != wordCount(origTitle.replace(/[\|\-\\\/>»]+/g, "")) - 1)) {
|
|
408
|
+
curTitle = origTitle;
|
|
409
|
+
}
|
|
410
|
+
return curTitle;
|
|
411
|
+
},
|
|
412
|
+
_prepDocument() {
|
|
413
|
+
var doc = this._doc;
|
|
414
|
+
this._removeNodes(this._getAllNodesWithTag(doc, ["style"]));
|
|
415
|
+
if (doc.body) {
|
|
416
|
+
this._replaceBrs(doc.body);
|
|
417
|
+
}
|
|
418
|
+
this._replaceNodeTags(this._getAllNodesWithTag(doc, ["font"]), "SPAN");
|
|
419
|
+
},
|
|
420
|
+
_nextNode(node) {
|
|
421
|
+
var next = node;
|
|
422
|
+
while (next && next.nodeType != this.ELEMENT_NODE && this.REGEXPS.whitespace.test(next.textContent)) {
|
|
423
|
+
next = next.nextSibling;
|
|
424
|
+
}
|
|
425
|
+
return next;
|
|
426
|
+
},
|
|
427
|
+
_replaceBrs(elem) {
|
|
428
|
+
this._forEachNode(this._getAllNodesWithTag(elem, ["br"]), function(br) {
|
|
429
|
+
var next = br.nextSibling;
|
|
430
|
+
var replaced = false;
|
|
431
|
+
while ((next = this._nextNode(next)) && next.tagName == "BR") {
|
|
432
|
+
replaced = true;
|
|
433
|
+
var brSibling = next.nextSibling;
|
|
434
|
+
next.remove();
|
|
435
|
+
next = brSibling;
|
|
436
|
+
}
|
|
437
|
+
if (replaced) {
|
|
438
|
+
var p = this._doc.createElement("p");
|
|
439
|
+
br.parentNode.replaceChild(p, br);
|
|
440
|
+
next = p.nextSibling;
|
|
441
|
+
while (next) {
|
|
442
|
+
if (next.tagName == "BR") {
|
|
443
|
+
var nextElem = this._nextNode(next.nextSibling);
|
|
444
|
+
if (nextElem && nextElem.tagName == "BR") {
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
if (!this._isPhrasingContent(next)) {
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
var sibling = next.nextSibling;
|
|
452
|
+
p.appendChild(next);
|
|
453
|
+
next = sibling;
|
|
454
|
+
}
|
|
455
|
+
while (p.lastChild && this._isWhitespace(p.lastChild)) {
|
|
456
|
+
p.lastChild.remove();
|
|
457
|
+
}
|
|
458
|
+
if (p.parentNode.tagName === "P") {
|
|
459
|
+
this._setNodeTag(p.parentNode, "DIV");
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
});
|
|
463
|
+
},
|
|
464
|
+
_setNodeTag(node, tag) {
|
|
465
|
+
this.log("_setNodeTag", node, tag);
|
|
466
|
+
if (this._docJSDOMParser) {
|
|
467
|
+
node.localName = tag.toLowerCase();
|
|
468
|
+
node.tagName = tag.toUpperCase();
|
|
469
|
+
return node;
|
|
470
|
+
}
|
|
471
|
+
var replacement = node.ownerDocument.createElement(tag);
|
|
472
|
+
while (node.firstChild) {
|
|
473
|
+
replacement.appendChild(node.firstChild);
|
|
474
|
+
}
|
|
475
|
+
node.parentNode.replaceChild(replacement, node);
|
|
476
|
+
if (node.readability) {
|
|
477
|
+
replacement.readability = node.readability;
|
|
478
|
+
}
|
|
479
|
+
for (var i = 0;i < node.attributes.length; i++) {
|
|
480
|
+
replacement.setAttributeNode(node.attributes[i].cloneNode());
|
|
481
|
+
}
|
|
482
|
+
return replacement;
|
|
483
|
+
},
|
|
484
|
+
_prepArticle(articleContent) {
|
|
485
|
+
this._cleanStyles(articleContent);
|
|
486
|
+
this._markDataTables(articleContent);
|
|
487
|
+
this._fixLazyImages(articleContent);
|
|
488
|
+
this._cleanConditionally(articleContent, "form");
|
|
489
|
+
this._cleanConditionally(articleContent, "fieldset");
|
|
490
|
+
this._clean(articleContent, "object");
|
|
491
|
+
this._clean(articleContent, "embed");
|
|
492
|
+
this._clean(articleContent, "footer");
|
|
493
|
+
this._clean(articleContent, "link");
|
|
494
|
+
this._clean(articleContent, "aside");
|
|
495
|
+
var shareElementThreshold = this.DEFAULT_CHAR_THRESHOLD;
|
|
496
|
+
this._forEachNode(articleContent.children, function(topCandidate) {
|
|
497
|
+
this._cleanMatchedNodes(topCandidate, function(node, matchString) {
|
|
498
|
+
return this.REGEXPS.shareElements.test(matchString) && node.textContent.length < shareElementThreshold;
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
this._clean(articleContent, "iframe");
|
|
502
|
+
this._clean(articleContent, "input");
|
|
503
|
+
this._clean(articleContent, "textarea");
|
|
504
|
+
this._clean(articleContent, "select");
|
|
505
|
+
this._clean(articleContent, "button");
|
|
506
|
+
this._cleanHeaders(articleContent);
|
|
507
|
+
this._cleanConditionally(articleContent, "table");
|
|
508
|
+
this._cleanConditionally(articleContent, "ul");
|
|
509
|
+
this._cleanConditionally(articleContent, "div");
|
|
510
|
+
this._replaceNodeTags(this._getAllNodesWithTag(articleContent, ["h1"]), "h2");
|
|
511
|
+
this._removeNodes(this._getAllNodesWithTag(articleContent, ["p"]), function(paragraph) {
|
|
512
|
+
var contentElementCount = this._getAllNodesWithTag(paragraph, [
|
|
513
|
+
"img",
|
|
514
|
+
"embed",
|
|
515
|
+
"object",
|
|
516
|
+
"iframe"
|
|
517
|
+
]).length;
|
|
518
|
+
return contentElementCount === 0 && !this._getInnerText(paragraph, false);
|
|
519
|
+
});
|
|
520
|
+
this._forEachNode(this._getAllNodesWithTag(articleContent, ["br"]), function(br) {
|
|
521
|
+
var next = this._nextNode(br.nextSibling);
|
|
522
|
+
if (next && next.tagName == "P") {
|
|
523
|
+
br.remove();
|
|
524
|
+
}
|
|
525
|
+
});
|
|
526
|
+
this._forEachNode(this._getAllNodesWithTag(articleContent, ["table"]), function(table) {
|
|
527
|
+
var tbody = this._hasSingleTagInsideElement(table, "TBODY") ? table.firstElementChild : table;
|
|
528
|
+
if (this._hasSingleTagInsideElement(tbody, "TR")) {
|
|
529
|
+
var row = tbody.firstElementChild;
|
|
530
|
+
if (this._hasSingleTagInsideElement(row, "TD")) {
|
|
531
|
+
var cell = row.firstElementChild;
|
|
532
|
+
cell = this._setNodeTag(cell, this._everyNode(cell.childNodes, this._isPhrasingContent) ? "P" : "DIV");
|
|
533
|
+
table.parentNode.replaceChild(cell, table);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
},
|
|
538
|
+
_initializeNode(node) {
|
|
539
|
+
node.readability = { contentScore: 0 };
|
|
540
|
+
switch (node.tagName) {
|
|
541
|
+
case "DIV":
|
|
542
|
+
node.readability.contentScore += 5;
|
|
543
|
+
break;
|
|
544
|
+
case "PRE":
|
|
545
|
+
case "TD":
|
|
546
|
+
case "BLOCKQUOTE":
|
|
547
|
+
node.readability.contentScore += 3;
|
|
548
|
+
break;
|
|
549
|
+
case "ADDRESS":
|
|
550
|
+
case "OL":
|
|
551
|
+
case "UL":
|
|
552
|
+
case "DL":
|
|
553
|
+
case "DD":
|
|
554
|
+
case "DT":
|
|
555
|
+
case "LI":
|
|
556
|
+
case "FORM":
|
|
557
|
+
node.readability.contentScore -= 3;
|
|
558
|
+
break;
|
|
559
|
+
case "H1":
|
|
560
|
+
case "H2":
|
|
561
|
+
case "H3":
|
|
562
|
+
case "H4":
|
|
563
|
+
case "H5":
|
|
564
|
+
case "H6":
|
|
565
|
+
case "TH":
|
|
566
|
+
node.readability.contentScore -= 5;
|
|
567
|
+
break;
|
|
568
|
+
}
|
|
569
|
+
node.readability.contentScore += this._getClassWeight(node);
|
|
570
|
+
},
|
|
571
|
+
_removeAndGetNext(node) {
|
|
572
|
+
var nextNode = this._getNextNode(node, true);
|
|
573
|
+
node.remove();
|
|
574
|
+
return nextNode;
|
|
575
|
+
},
|
|
576
|
+
_getNextNode(node, ignoreSelfAndKids) {
|
|
577
|
+
if (!ignoreSelfAndKids && node.firstElementChild) {
|
|
578
|
+
return node.firstElementChild;
|
|
579
|
+
}
|
|
580
|
+
if (node.nextElementSibling) {
|
|
581
|
+
return node.nextElementSibling;
|
|
582
|
+
}
|
|
583
|
+
do {
|
|
584
|
+
node = node.parentNode;
|
|
585
|
+
} while (node && !node.nextElementSibling);
|
|
586
|
+
return node && node.nextElementSibling;
|
|
587
|
+
},
|
|
588
|
+
_textSimilarity(textA, textB) {
|
|
589
|
+
var tokensA = textA.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean);
|
|
590
|
+
var tokensB = textB.toLowerCase().split(this.REGEXPS.tokenize).filter(Boolean);
|
|
591
|
+
if (!tokensA.length || !tokensB.length) {
|
|
592
|
+
return 0;
|
|
593
|
+
}
|
|
594
|
+
var uniqTokensB = tokensB.filter((token) => !tokensA.includes(token));
|
|
595
|
+
var distanceB = uniqTokensB.join(" ").length / tokensB.join(" ").length;
|
|
596
|
+
return 1 - distanceB;
|
|
597
|
+
},
|
|
598
|
+
_isValidByline(node, matchString) {
|
|
599
|
+
var rel = node.getAttribute("rel");
|
|
600
|
+
var itemprop = node.getAttribute("itemprop");
|
|
601
|
+
var bylineLength = node.textContent.trim().length;
|
|
602
|
+
return (rel === "author" || itemprop && itemprop.includes("author") || this.REGEXPS.byline.test(matchString)) && !!bylineLength && bylineLength < 100;
|
|
603
|
+
},
|
|
604
|
+
_getNodeAncestors(node, maxDepth) {
|
|
605
|
+
maxDepth = maxDepth || 0;
|
|
606
|
+
var i = 0, ancestors = [];
|
|
607
|
+
while (node.parentNode) {
|
|
608
|
+
ancestors.push(node.parentNode);
|
|
609
|
+
if (maxDepth && ++i === maxDepth) {
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
node = node.parentNode;
|
|
613
|
+
}
|
|
614
|
+
return ancestors;
|
|
615
|
+
},
|
|
616
|
+
_grabArticle(page) {
|
|
617
|
+
this.log("**** grabArticle ****");
|
|
618
|
+
var doc = this._doc;
|
|
619
|
+
var isPaging = page !== null;
|
|
620
|
+
page = page ? page : this._doc.body;
|
|
621
|
+
if (!page) {
|
|
622
|
+
this.log("No body found in document. Abort.");
|
|
623
|
+
return null;
|
|
624
|
+
}
|
|
625
|
+
var pageCacheHtml = page.innerHTML;
|
|
626
|
+
while (true) {
|
|
627
|
+
this.log("Starting grabArticle loop");
|
|
628
|
+
var stripUnlikelyCandidates = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS);
|
|
629
|
+
var elementsToScore = [];
|
|
630
|
+
var node = this._doc.documentElement;
|
|
631
|
+
let shouldRemoveTitleHeader = true;
|
|
632
|
+
while (node) {
|
|
633
|
+
if (node.tagName === "HTML") {
|
|
634
|
+
this._articleLang = node.getAttribute("lang");
|
|
635
|
+
}
|
|
636
|
+
var matchString = node.className + " " + node.id;
|
|
637
|
+
if (!this._isProbablyVisible(node)) {
|
|
638
|
+
this.log("Removing hidden node - " + matchString);
|
|
639
|
+
node = this._removeAndGetNext(node);
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
if (node.getAttribute("aria-modal") == "true" && node.getAttribute("role") == "dialog") {
|
|
643
|
+
node = this._removeAndGetNext(node);
|
|
644
|
+
continue;
|
|
645
|
+
}
|
|
646
|
+
if (!this._articleByline && !this._metadata.byline && this._isValidByline(node, matchString)) {
|
|
647
|
+
var endOfSearchMarkerNode = this._getNextNode(node, true);
|
|
648
|
+
var next = this._getNextNode(node);
|
|
649
|
+
var itemPropNameNode = null;
|
|
650
|
+
while (next && next != endOfSearchMarkerNode) {
|
|
651
|
+
var itemprop = next.getAttribute("itemprop");
|
|
652
|
+
if (itemprop && itemprop.includes("name")) {
|
|
653
|
+
itemPropNameNode = next;
|
|
654
|
+
break;
|
|
655
|
+
} else {
|
|
656
|
+
next = this._getNextNode(next);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
this._articleByline = (itemPropNameNode ?? node).textContent.trim();
|
|
660
|
+
node = this._removeAndGetNext(node);
|
|
661
|
+
continue;
|
|
662
|
+
}
|
|
663
|
+
if (shouldRemoveTitleHeader && this._headerDuplicatesTitle(node)) {
|
|
664
|
+
this.log("Removing header: ", node.textContent.trim(), this._articleTitle.trim());
|
|
665
|
+
shouldRemoveTitleHeader = false;
|
|
666
|
+
node = this._removeAndGetNext(node);
|
|
667
|
+
continue;
|
|
668
|
+
}
|
|
669
|
+
if (stripUnlikelyCandidates) {
|
|
670
|
+
if (this.REGEXPS.unlikelyCandidates.test(matchString) && !this.REGEXPS.okMaybeItsACandidate.test(matchString) && !this._hasAncestorTag(node, "table") && !this._hasAncestorTag(node, "code") && node.tagName !== "BODY" && node.tagName !== "A") {
|
|
671
|
+
this.log("Removing unlikely candidate - " + matchString);
|
|
672
|
+
node = this._removeAndGetNext(node);
|
|
673
|
+
continue;
|
|
674
|
+
}
|
|
675
|
+
if (this.UNLIKELY_ROLES.includes(node.getAttribute("role"))) {
|
|
676
|
+
this.log("Removing content with role " + node.getAttribute("role") + " - " + matchString);
|
|
677
|
+
node = this._removeAndGetNext(node);
|
|
678
|
+
continue;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
if ((node.tagName === "DIV" || node.tagName === "SECTION" || node.tagName === "HEADER" || node.tagName === "H1" || node.tagName === "H2" || node.tagName === "H3" || node.tagName === "H4" || node.tagName === "H5" || node.tagName === "H6") && this._isElementWithoutContent(node)) {
|
|
682
|
+
node = this._removeAndGetNext(node);
|
|
683
|
+
continue;
|
|
684
|
+
}
|
|
685
|
+
if (this.DEFAULT_TAGS_TO_SCORE.includes(node.tagName)) {
|
|
686
|
+
elementsToScore.push(node);
|
|
687
|
+
}
|
|
688
|
+
if (node.tagName === "DIV") {
|
|
689
|
+
var p = null;
|
|
690
|
+
var childNode = node.firstChild;
|
|
691
|
+
while (childNode) {
|
|
692
|
+
var nextSibling = childNode.nextSibling;
|
|
693
|
+
if (this._isPhrasingContent(childNode)) {
|
|
694
|
+
if (p !== null) {
|
|
695
|
+
p.appendChild(childNode);
|
|
696
|
+
} else if (!this._isWhitespace(childNode)) {
|
|
697
|
+
p = doc.createElement("p");
|
|
698
|
+
node.replaceChild(p, childNode);
|
|
699
|
+
p.appendChild(childNode);
|
|
700
|
+
}
|
|
701
|
+
} else if (p !== null) {
|
|
702
|
+
while (p.lastChild && this._isWhitespace(p.lastChild)) {
|
|
703
|
+
p.lastChild.remove();
|
|
704
|
+
}
|
|
705
|
+
p = null;
|
|
706
|
+
}
|
|
707
|
+
childNode = nextSibling;
|
|
708
|
+
}
|
|
709
|
+
if (this._hasSingleTagInsideElement(node, "P") && this._getLinkDensity(node) < 0.25) {
|
|
710
|
+
var newNode = node.children[0];
|
|
711
|
+
node.parentNode.replaceChild(newNode, node);
|
|
712
|
+
node = newNode;
|
|
713
|
+
elementsToScore.push(node);
|
|
714
|
+
} else if (!this._hasChildBlockElement(node)) {
|
|
715
|
+
node = this._setNodeTag(node, "P");
|
|
716
|
+
elementsToScore.push(node);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
node = this._getNextNode(node);
|
|
720
|
+
}
|
|
721
|
+
var candidates = [];
|
|
722
|
+
this._forEachNode(elementsToScore, function(elementToScore) {
|
|
723
|
+
if (!elementToScore.parentNode || typeof elementToScore.parentNode.tagName === "undefined") {
|
|
724
|
+
return;
|
|
725
|
+
}
|
|
726
|
+
var innerText = this._getInnerText(elementToScore);
|
|
727
|
+
if (innerText.length < 25) {
|
|
728
|
+
return;
|
|
729
|
+
}
|
|
730
|
+
var ancestors2 = this._getNodeAncestors(elementToScore, 5);
|
|
731
|
+
if (ancestors2.length === 0) {
|
|
732
|
+
return;
|
|
733
|
+
}
|
|
734
|
+
var contentScore = 0;
|
|
735
|
+
contentScore += 1;
|
|
736
|
+
contentScore += innerText.split(this.REGEXPS.commas).length;
|
|
737
|
+
contentScore += Math.min(Math.floor(innerText.length / 100), 3);
|
|
738
|
+
this._forEachNode(ancestors2, function(ancestor, level) {
|
|
739
|
+
if (!ancestor.tagName || !ancestor.parentNode || typeof ancestor.parentNode.tagName === "undefined") {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (typeof ancestor.readability === "undefined") {
|
|
743
|
+
this._initializeNode(ancestor);
|
|
744
|
+
candidates.push(ancestor);
|
|
745
|
+
}
|
|
746
|
+
if (level === 0) {
|
|
747
|
+
var scoreDivider = 1;
|
|
748
|
+
} else if (level === 1) {
|
|
749
|
+
scoreDivider = 2;
|
|
750
|
+
} else {
|
|
751
|
+
scoreDivider = level * 3;
|
|
752
|
+
}
|
|
753
|
+
ancestor.readability.contentScore += contentScore / scoreDivider;
|
|
754
|
+
});
|
|
755
|
+
});
|
|
756
|
+
var topCandidates = [];
|
|
757
|
+
for (var c = 0, cl = candidates.length;c < cl; c += 1) {
|
|
758
|
+
var candidate = candidates[c];
|
|
759
|
+
var candidateScore = candidate.readability.contentScore * (1 - this._getLinkDensity(candidate));
|
|
760
|
+
candidate.readability.contentScore = candidateScore;
|
|
761
|
+
this.log("Candidate:", candidate, "with score " + candidateScore);
|
|
762
|
+
for (var t = 0;t < this._nbTopCandidates; t++) {
|
|
763
|
+
var aTopCandidate = topCandidates[t];
|
|
764
|
+
if (!aTopCandidate || candidateScore > aTopCandidate.readability.contentScore) {
|
|
765
|
+
topCandidates.splice(t, 0, candidate);
|
|
766
|
+
if (topCandidates.length > this._nbTopCandidates) {
|
|
767
|
+
topCandidates.pop();
|
|
768
|
+
}
|
|
769
|
+
break;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
var topCandidate = topCandidates[0] || null;
|
|
774
|
+
var neededToCreateTopCandidate = false;
|
|
775
|
+
var parentOfTopCandidate;
|
|
776
|
+
if (topCandidate === null || topCandidate.tagName === "BODY") {
|
|
777
|
+
topCandidate = doc.createElement("DIV");
|
|
778
|
+
neededToCreateTopCandidate = true;
|
|
779
|
+
while (page.firstChild) {
|
|
780
|
+
this.log("Moving child out:", page.firstChild);
|
|
781
|
+
topCandidate.appendChild(page.firstChild);
|
|
782
|
+
}
|
|
783
|
+
page.appendChild(topCandidate);
|
|
784
|
+
this._initializeNode(topCandidate);
|
|
785
|
+
} else if (topCandidate) {
|
|
786
|
+
var alternativeCandidateAncestors = [];
|
|
787
|
+
for (var i = 1;i < topCandidates.length; i++) {
|
|
788
|
+
if (topCandidates[i].readability.contentScore / topCandidate.readability.contentScore >= 0.75) {
|
|
789
|
+
alternativeCandidateAncestors.push(this._getNodeAncestors(topCandidates[i]));
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
var MINIMUM_TOPCANDIDATES = 3;
|
|
793
|
+
if (alternativeCandidateAncestors.length >= MINIMUM_TOPCANDIDATES) {
|
|
794
|
+
parentOfTopCandidate = topCandidate.parentNode;
|
|
795
|
+
while (parentOfTopCandidate.tagName !== "BODY") {
|
|
796
|
+
var listsContainingThisAncestor = 0;
|
|
797
|
+
for (var ancestorIndex = 0;ancestorIndex < alternativeCandidateAncestors.length && listsContainingThisAncestor < MINIMUM_TOPCANDIDATES; ancestorIndex++) {
|
|
798
|
+
listsContainingThisAncestor += Number(alternativeCandidateAncestors[ancestorIndex].includes(parentOfTopCandidate));
|
|
799
|
+
}
|
|
800
|
+
if (listsContainingThisAncestor >= MINIMUM_TOPCANDIDATES) {
|
|
801
|
+
topCandidate = parentOfTopCandidate;
|
|
802
|
+
break;
|
|
803
|
+
}
|
|
804
|
+
parentOfTopCandidate = parentOfTopCandidate.parentNode;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
if (!topCandidate.readability) {
|
|
808
|
+
this._initializeNode(topCandidate);
|
|
809
|
+
}
|
|
810
|
+
parentOfTopCandidate = topCandidate.parentNode;
|
|
811
|
+
var lastScore = topCandidate.readability.contentScore;
|
|
812
|
+
var scoreThreshold = lastScore / 3;
|
|
813
|
+
while (parentOfTopCandidate.tagName !== "BODY") {
|
|
814
|
+
if (!parentOfTopCandidate.readability) {
|
|
815
|
+
parentOfTopCandidate = parentOfTopCandidate.parentNode;
|
|
816
|
+
continue;
|
|
817
|
+
}
|
|
818
|
+
var parentScore = parentOfTopCandidate.readability.contentScore;
|
|
819
|
+
if (parentScore < scoreThreshold) {
|
|
820
|
+
break;
|
|
821
|
+
}
|
|
822
|
+
if (parentScore > lastScore) {
|
|
823
|
+
topCandidate = parentOfTopCandidate;
|
|
824
|
+
break;
|
|
825
|
+
}
|
|
826
|
+
lastScore = parentOfTopCandidate.readability.contentScore;
|
|
827
|
+
parentOfTopCandidate = parentOfTopCandidate.parentNode;
|
|
828
|
+
}
|
|
829
|
+
parentOfTopCandidate = topCandidate.parentNode;
|
|
830
|
+
while (parentOfTopCandidate.tagName != "BODY" && parentOfTopCandidate.children.length == 1) {
|
|
831
|
+
topCandidate = parentOfTopCandidate;
|
|
832
|
+
parentOfTopCandidate = topCandidate.parentNode;
|
|
833
|
+
}
|
|
834
|
+
if (!topCandidate.readability) {
|
|
835
|
+
this._initializeNode(topCandidate);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
var articleContent = doc.createElement("DIV");
|
|
839
|
+
if (isPaging) {
|
|
840
|
+
articleContent.id = "readability-content";
|
|
841
|
+
}
|
|
842
|
+
var siblingScoreThreshold = Math.max(10, topCandidate.readability.contentScore * 0.2);
|
|
843
|
+
parentOfTopCandidate = topCandidate.parentNode;
|
|
844
|
+
var siblings = parentOfTopCandidate.children;
|
|
845
|
+
for (var s = 0, sl = siblings.length;s < sl; s++) {
|
|
846
|
+
var sibling = siblings[s];
|
|
847
|
+
var append = false;
|
|
848
|
+
this.log("Looking at sibling node:", sibling, sibling.readability ? "with score " + sibling.readability.contentScore : "");
|
|
849
|
+
this.log("Sibling has score", sibling.readability ? sibling.readability.contentScore : "Unknown");
|
|
850
|
+
if (sibling === topCandidate) {
|
|
851
|
+
append = true;
|
|
852
|
+
} else {
|
|
853
|
+
var contentBonus = 0;
|
|
854
|
+
if (sibling.className === topCandidate.className && topCandidate.className !== "") {
|
|
855
|
+
contentBonus += topCandidate.readability.contentScore * 0.2;
|
|
856
|
+
}
|
|
857
|
+
if (sibling.readability && sibling.readability.contentScore + contentBonus >= siblingScoreThreshold) {
|
|
858
|
+
append = true;
|
|
859
|
+
} else if (sibling.nodeName === "P") {
|
|
860
|
+
var linkDensity = this._getLinkDensity(sibling);
|
|
861
|
+
var nodeContent = this._getInnerText(sibling);
|
|
862
|
+
var nodeLength = nodeContent.length;
|
|
863
|
+
if (nodeLength > 80 && linkDensity < 0.25) {
|
|
864
|
+
append = true;
|
|
865
|
+
} else if (nodeLength < 80 && nodeLength > 0 && linkDensity === 0 && nodeContent.search(/\.( |$)/) !== -1) {
|
|
866
|
+
append = true;
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
if (append) {
|
|
871
|
+
this.log("Appending node:", sibling);
|
|
872
|
+
if (!this.ALTER_TO_DIV_EXCEPTIONS.includes(sibling.nodeName)) {
|
|
873
|
+
this.log("Altering sibling:", sibling, "to div.");
|
|
874
|
+
sibling = this._setNodeTag(sibling, "DIV");
|
|
875
|
+
}
|
|
876
|
+
articleContent.appendChild(sibling);
|
|
877
|
+
siblings = parentOfTopCandidate.children;
|
|
878
|
+
s -= 1;
|
|
879
|
+
sl -= 1;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
if (this._debug) {
|
|
883
|
+
this.log("Article content pre-prep: " + articleContent.innerHTML);
|
|
884
|
+
}
|
|
885
|
+
this._prepArticle(articleContent);
|
|
886
|
+
if (this._debug) {
|
|
887
|
+
this.log("Article content post-prep: " + articleContent.innerHTML);
|
|
888
|
+
}
|
|
889
|
+
if (neededToCreateTopCandidate) {
|
|
890
|
+
topCandidate.id = "readability-page-1";
|
|
891
|
+
topCandidate.className = "page";
|
|
892
|
+
} else {
|
|
893
|
+
var div = doc.createElement("DIV");
|
|
894
|
+
div.id = "readability-page-1";
|
|
895
|
+
div.className = "page";
|
|
896
|
+
while (articleContent.firstChild) {
|
|
897
|
+
div.appendChild(articleContent.firstChild);
|
|
898
|
+
}
|
|
899
|
+
articleContent.appendChild(div);
|
|
900
|
+
}
|
|
901
|
+
if (this._debug) {
|
|
902
|
+
this.log("Article content after paging: " + articleContent.innerHTML);
|
|
903
|
+
}
|
|
904
|
+
var parseSuccessful = true;
|
|
905
|
+
var textLength = this._getInnerText(articleContent, true).length;
|
|
906
|
+
if (textLength < this._charThreshold) {
|
|
907
|
+
parseSuccessful = false;
|
|
908
|
+
page.innerHTML = pageCacheHtml;
|
|
909
|
+
this._attempts.push({
|
|
910
|
+
articleContent,
|
|
911
|
+
textLength
|
|
912
|
+
});
|
|
913
|
+
if (this._flagIsActive(this.FLAG_STRIP_UNLIKELYS)) {
|
|
914
|
+
this._removeFlag(this.FLAG_STRIP_UNLIKELYS);
|
|
915
|
+
} else if (this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) {
|
|
916
|
+
this._removeFlag(this.FLAG_WEIGHT_CLASSES);
|
|
917
|
+
} else if (this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) {
|
|
918
|
+
this._removeFlag(this.FLAG_CLEAN_CONDITIONALLY);
|
|
919
|
+
} else {
|
|
920
|
+
this._attempts.sort(function(a, b) {
|
|
921
|
+
return b.textLength - a.textLength;
|
|
922
|
+
});
|
|
923
|
+
if (!this._attempts[0].textLength) {
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
articleContent = this._attempts[0].articleContent;
|
|
927
|
+
parseSuccessful = true;
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
if (parseSuccessful) {
|
|
931
|
+
var ancestors = [parentOfTopCandidate, topCandidate].concat(this._getNodeAncestors(parentOfTopCandidate));
|
|
932
|
+
this._someNode(ancestors, function(ancestor) {
|
|
933
|
+
if (!ancestor.tagName) {
|
|
934
|
+
return false;
|
|
935
|
+
}
|
|
936
|
+
var articleDir = ancestor.getAttribute("dir");
|
|
937
|
+
if (articleDir) {
|
|
938
|
+
this._articleDir = articleDir;
|
|
939
|
+
return true;
|
|
940
|
+
}
|
|
941
|
+
return false;
|
|
942
|
+
});
|
|
943
|
+
return articleContent;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
},
|
|
947
|
+
_unescapeHtmlEntities(str) {
|
|
948
|
+
if (!str) {
|
|
949
|
+
return str;
|
|
950
|
+
}
|
|
951
|
+
var htmlEscapeMap = this.HTML_ESCAPE_MAP;
|
|
952
|
+
return str.replace(/&(quot|amp|apos|lt|gt);/g, function(_, tag) {
|
|
953
|
+
return htmlEscapeMap[tag];
|
|
954
|
+
}).replace(/&#(?:x([0-9a-f]+)|([0-9]+));/gi, function(_, hex, numStr) {
|
|
955
|
+
var num = parseInt(hex || numStr, hex ? 16 : 10);
|
|
956
|
+
if (num == 0 || num > 1114111 || num >= 55296 && num <= 57343) {
|
|
957
|
+
num = 65533;
|
|
958
|
+
}
|
|
959
|
+
return String.fromCodePoint(num);
|
|
960
|
+
});
|
|
961
|
+
},
|
|
962
|
+
_getJSONLD(doc) {
|
|
963
|
+
var scripts = this._getAllNodesWithTag(doc, ["script"]);
|
|
964
|
+
var metadata;
|
|
965
|
+
this._forEachNode(scripts, function(jsonLdElement) {
|
|
966
|
+
if (!metadata && jsonLdElement.getAttribute("type") === "application/ld+json") {
|
|
967
|
+
try {
|
|
968
|
+
var content = jsonLdElement.textContent.replace(/^\s*<!\[CDATA\[|\]\]>\s*$/g, "");
|
|
969
|
+
var parsed = JSON.parse(content);
|
|
970
|
+
if (Array.isArray(parsed)) {
|
|
971
|
+
parsed = parsed.find((it) => {
|
|
972
|
+
return it["@type"] && it["@type"].match(this.REGEXPS.jsonLdArticleTypes);
|
|
973
|
+
});
|
|
974
|
+
if (!parsed) {
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
var schemaDotOrgRegex = /^https?\:\/\/schema\.org\/?$/;
|
|
979
|
+
var matches = typeof parsed["@context"] === "string" && parsed["@context"].match(schemaDotOrgRegex) || typeof parsed["@context"] === "object" && typeof parsed["@context"]["@vocab"] == "string" && parsed["@context"]["@vocab"].match(schemaDotOrgRegex);
|
|
980
|
+
if (!matches) {
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
if (!parsed["@type"] && Array.isArray(parsed["@graph"])) {
|
|
984
|
+
parsed = parsed["@graph"].find((it) => {
|
|
985
|
+
return (it["@type"] || "").match(this.REGEXPS.jsonLdArticleTypes);
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
if (!parsed || !parsed["@type"] || !parsed["@type"].match(this.REGEXPS.jsonLdArticleTypes)) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
991
|
+
metadata = {};
|
|
992
|
+
if (typeof parsed.name === "string" && typeof parsed.headline === "string" && parsed.name !== parsed.headline) {
|
|
993
|
+
var title = this._getArticleTitle();
|
|
994
|
+
var nameMatches = this._textSimilarity(parsed.name, title) > 0.75;
|
|
995
|
+
var headlineMatches = this._textSimilarity(parsed.headline, title) > 0.75;
|
|
996
|
+
if (headlineMatches && !nameMatches) {
|
|
997
|
+
metadata.title = parsed.headline;
|
|
998
|
+
} else {
|
|
999
|
+
metadata.title = parsed.name;
|
|
1000
|
+
}
|
|
1001
|
+
} else if (typeof parsed.name === "string") {
|
|
1002
|
+
metadata.title = parsed.name.trim();
|
|
1003
|
+
} else if (typeof parsed.headline === "string") {
|
|
1004
|
+
metadata.title = parsed.headline.trim();
|
|
1005
|
+
}
|
|
1006
|
+
if (parsed.author) {
|
|
1007
|
+
if (typeof parsed.author.name === "string") {
|
|
1008
|
+
metadata.byline = parsed.author.name.trim();
|
|
1009
|
+
} else if (Array.isArray(parsed.author) && parsed.author[0] && typeof parsed.author[0].name === "string") {
|
|
1010
|
+
metadata.byline = parsed.author.filter(function(author) {
|
|
1011
|
+
return author && typeof author.name === "string";
|
|
1012
|
+
}).map(function(author) {
|
|
1013
|
+
return author.name.trim();
|
|
1014
|
+
}).join(", ");
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
if (typeof parsed.description === "string") {
|
|
1018
|
+
metadata.excerpt = parsed.description.trim();
|
|
1019
|
+
}
|
|
1020
|
+
if (parsed.publisher && typeof parsed.publisher.name === "string") {
|
|
1021
|
+
metadata.siteName = parsed.publisher.name.trim();
|
|
1022
|
+
}
|
|
1023
|
+
if (typeof parsed.datePublished === "string") {
|
|
1024
|
+
metadata.datePublished = parsed.datePublished.trim();
|
|
1025
|
+
}
|
|
1026
|
+
} catch (err) {
|
|
1027
|
+
this.log(err.message);
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
});
|
|
1031
|
+
return metadata ? metadata : {};
|
|
1032
|
+
},
|
|
1033
|
+
_getArticleMetadata(jsonld) {
|
|
1034
|
+
var metadata = {};
|
|
1035
|
+
var values = {};
|
|
1036
|
+
var metaElements = this._doc.getElementsByTagName("meta");
|
|
1037
|
+
var propertyPattern = /\s*(article|dc|dcterm|og|twitter)\s*:\s*(author|creator|description|published_time|title|site_name)\s*/gi;
|
|
1038
|
+
var namePattern = /^\s*(?:(dc|dcterm|og|twitter|parsely|weibo:(article|webpage))\s*[-\.:]\s*)?(author|creator|pub-date|description|title|site_name)\s*$/i;
|
|
1039
|
+
this._forEachNode(metaElements, function(element) {
|
|
1040
|
+
var elementName = element.getAttribute("name");
|
|
1041
|
+
var elementProperty = element.getAttribute("property");
|
|
1042
|
+
var content = element.getAttribute("content");
|
|
1043
|
+
if (!content) {
|
|
1044
|
+
return;
|
|
1045
|
+
}
|
|
1046
|
+
var matches = null;
|
|
1047
|
+
var name = null;
|
|
1048
|
+
if (elementProperty) {
|
|
1049
|
+
matches = elementProperty.match(propertyPattern);
|
|
1050
|
+
if (matches) {
|
|
1051
|
+
name = matches[0].toLowerCase().replace(/\s/g, "");
|
|
1052
|
+
values[name] = content.trim();
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (!matches && elementName && namePattern.test(elementName)) {
|
|
1056
|
+
name = elementName;
|
|
1057
|
+
if (content) {
|
|
1058
|
+
name = name.toLowerCase().replace(/\s/g, "").replace(/\./g, ":");
|
|
1059
|
+
values[name] = content.trim();
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
});
|
|
1063
|
+
metadata.title = jsonld.title || values["dc:title"] || values["dcterm:title"] || values["og:title"] || values["weibo:article:title"] || values["weibo:webpage:title"] || values.title || values["twitter:title"] || values["parsely-title"];
|
|
1064
|
+
if (!metadata.title) {
|
|
1065
|
+
metadata.title = this._getArticleTitle();
|
|
1066
|
+
}
|
|
1067
|
+
const articleAuthor = typeof values["article:author"] === "string" && !this._isUrl(values["article:author"]) ? values["article:author"] : undefined;
|
|
1068
|
+
metadata.byline = jsonld.byline || values["dc:creator"] || values["dcterm:creator"] || values.author || values["parsely-author"] || articleAuthor;
|
|
1069
|
+
metadata.excerpt = jsonld.excerpt || values["dc:description"] || values["dcterm:description"] || values["og:description"] || values["weibo:article:description"] || values["weibo:webpage:description"] || values.description || values["twitter:description"];
|
|
1070
|
+
metadata.siteName = jsonld.siteName || values["og:site_name"];
|
|
1071
|
+
metadata.publishedTime = jsonld.datePublished || values["article:published_time"] || values["parsely-pub-date"] || null;
|
|
1072
|
+
metadata.title = this._unescapeHtmlEntities(metadata.title);
|
|
1073
|
+
metadata.byline = this._unescapeHtmlEntities(metadata.byline);
|
|
1074
|
+
metadata.excerpt = this._unescapeHtmlEntities(metadata.excerpt);
|
|
1075
|
+
metadata.siteName = this._unescapeHtmlEntities(metadata.siteName);
|
|
1076
|
+
metadata.publishedTime = this._unescapeHtmlEntities(metadata.publishedTime);
|
|
1077
|
+
return metadata;
|
|
1078
|
+
},
|
|
1079
|
+
_isSingleImage(node) {
|
|
1080
|
+
while (node) {
|
|
1081
|
+
if (node.tagName === "IMG") {
|
|
1082
|
+
return true;
|
|
1083
|
+
}
|
|
1084
|
+
if (node.children.length !== 1 || node.textContent.trim() !== "") {
|
|
1085
|
+
return false;
|
|
1086
|
+
}
|
|
1087
|
+
node = node.children[0];
|
|
1088
|
+
}
|
|
1089
|
+
return false;
|
|
1090
|
+
},
|
|
1091
|
+
_unwrapNoscriptImages(doc) {
|
|
1092
|
+
var imgs = Array.from(doc.getElementsByTagName("img"));
|
|
1093
|
+
this._forEachNode(imgs, function(img) {
|
|
1094
|
+
for (var i = 0;i < img.attributes.length; i++) {
|
|
1095
|
+
var attr = img.attributes[i];
|
|
1096
|
+
switch (attr.name) {
|
|
1097
|
+
case "src":
|
|
1098
|
+
case "srcset":
|
|
1099
|
+
case "data-src":
|
|
1100
|
+
case "data-srcset":
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
1103
|
+
if (/\.(jpg|jpeg|png|webp)/i.test(attr.value)) {
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
}
|
|
1107
|
+
img.remove();
|
|
1108
|
+
});
|
|
1109
|
+
var noscripts = Array.from(doc.getElementsByTagName("noscript"));
|
|
1110
|
+
this._forEachNode(noscripts, function(noscript) {
|
|
1111
|
+
if (!this._isSingleImage(noscript)) {
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
var tmp = doc.createElement("div");
|
|
1115
|
+
tmp.innerHTML = noscript.innerHTML;
|
|
1116
|
+
var prevElement = noscript.previousElementSibling;
|
|
1117
|
+
if (prevElement && this._isSingleImage(prevElement)) {
|
|
1118
|
+
var prevImg = prevElement;
|
|
1119
|
+
if (prevImg.tagName !== "IMG") {
|
|
1120
|
+
prevImg = prevElement.getElementsByTagName("img")[0];
|
|
1121
|
+
}
|
|
1122
|
+
var newImg = tmp.getElementsByTagName("img")[0];
|
|
1123
|
+
for (var i = 0;i < prevImg.attributes.length; i++) {
|
|
1124
|
+
var attr = prevImg.attributes[i];
|
|
1125
|
+
if (attr.value === "") {
|
|
1126
|
+
continue;
|
|
1127
|
+
}
|
|
1128
|
+
if (attr.name === "src" || attr.name === "srcset" || /\.(jpg|jpeg|png|webp)/i.test(attr.value)) {
|
|
1129
|
+
if (newImg.getAttribute(attr.name) === attr.value) {
|
|
1130
|
+
continue;
|
|
1131
|
+
}
|
|
1132
|
+
var attrName = attr.name;
|
|
1133
|
+
if (newImg.hasAttribute(attrName)) {
|
|
1134
|
+
attrName = "data-old-" + attrName;
|
|
1135
|
+
}
|
|
1136
|
+
newImg.setAttribute(attrName, attr.value);
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
noscript.parentNode.replaceChild(tmp.firstElementChild, prevElement);
|
|
1140
|
+
}
|
|
1141
|
+
});
|
|
1142
|
+
},
|
|
1143
|
+
_removeScripts(doc) {
|
|
1144
|
+
this._removeNodes(this._getAllNodesWithTag(doc, ["script", "noscript"]));
|
|
1145
|
+
},
|
|
1146
|
+
_hasSingleTagInsideElement(element, tag) {
|
|
1147
|
+
if (element.children.length != 1 || element.children[0].tagName !== tag) {
|
|
1148
|
+
return false;
|
|
1149
|
+
}
|
|
1150
|
+
return !this._someNode(element.childNodes, function(node) {
|
|
1151
|
+
return node.nodeType === this.TEXT_NODE && this.REGEXPS.hasContent.test(node.textContent);
|
|
1152
|
+
});
|
|
1153
|
+
},
|
|
1154
|
+
_isElementWithoutContent(node) {
|
|
1155
|
+
return node.nodeType === this.ELEMENT_NODE && !node.textContent.trim().length && (!node.children.length || node.children.length == node.getElementsByTagName("br").length + node.getElementsByTagName("hr").length);
|
|
1156
|
+
},
|
|
1157
|
+
_hasChildBlockElement(element) {
|
|
1158
|
+
return this._someNode(element.childNodes, function(node) {
|
|
1159
|
+
return this.DIV_TO_P_ELEMS.has(node.tagName) || this._hasChildBlockElement(node);
|
|
1160
|
+
});
|
|
1161
|
+
},
|
|
1162
|
+
_isPhrasingContent(node) {
|
|
1163
|
+
return node.nodeType === this.TEXT_NODE || this.PHRASING_ELEMS.includes(node.tagName) || (node.tagName === "A" || node.tagName === "DEL" || node.tagName === "INS") && this._everyNode(node.childNodes, this._isPhrasingContent);
|
|
1164
|
+
},
|
|
1165
|
+
_isWhitespace(node) {
|
|
1166
|
+
return node.nodeType === this.TEXT_NODE && node.textContent.trim().length === 0 || node.nodeType === this.ELEMENT_NODE && node.tagName === "BR";
|
|
1167
|
+
},
|
|
1168
|
+
_getInnerText(e, normalizeSpaces) {
|
|
1169
|
+
normalizeSpaces = typeof normalizeSpaces === "undefined" ? true : normalizeSpaces;
|
|
1170
|
+
var textContent = e.textContent.trim();
|
|
1171
|
+
if (normalizeSpaces) {
|
|
1172
|
+
return textContent.replace(this.REGEXPS.normalize, " ");
|
|
1173
|
+
}
|
|
1174
|
+
return textContent;
|
|
1175
|
+
},
|
|
1176
|
+
_getCharCount(e, s) {
|
|
1177
|
+
s = s || ",";
|
|
1178
|
+
return this._getInnerText(e).split(s).length - 1;
|
|
1179
|
+
},
|
|
1180
|
+
_cleanStyles(e) {
|
|
1181
|
+
if (!e || e.tagName.toLowerCase() === "svg") {
|
|
1182
|
+
return;
|
|
1183
|
+
}
|
|
1184
|
+
for (var i = 0;i < this.PRESENTATIONAL_ATTRIBUTES.length; i++) {
|
|
1185
|
+
e.removeAttribute(this.PRESENTATIONAL_ATTRIBUTES[i]);
|
|
1186
|
+
}
|
|
1187
|
+
if (this.DEPRECATED_SIZE_ATTRIBUTE_ELEMS.includes(e.tagName)) {
|
|
1188
|
+
e.removeAttribute("width");
|
|
1189
|
+
e.removeAttribute("height");
|
|
1190
|
+
}
|
|
1191
|
+
var cur = e.firstElementChild;
|
|
1192
|
+
while (cur !== null) {
|
|
1193
|
+
this._cleanStyles(cur);
|
|
1194
|
+
cur = cur.nextElementSibling;
|
|
1195
|
+
}
|
|
1196
|
+
},
|
|
1197
|
+
_getLinkDensity(element) {
|
|
1198
|
+
var textLength = this._getInnerText(element).length;
|
|
1199
|
+
if (textLength === 0) {
|
|
1200
|
+
return 0;
|
|
1201
|
+
}
|
|
1202
|
+
var linkLength = 0;
|
|
1203
|
+
this._forEachNode(element.getElementsByTagName("a"), function(linkNode) {
|
|
1204
|
+
var href = linkNode.getAttribute("href");
|
|
1205
|
+
var coefficient = href && this.REGEXPS.hashUrl.test(href) ? 0.3 : 1;
|
|
1206
|
+
linkLength += this._getInnerText(linkNode).length * coefficient;
|
|
1207
|
+
});
|
|
1208
|
+
return linkLength / textLength;
|
|
1209
|
+
},
|
|
1210
|
+
_getClassWeight(e) {
|
|
1211
|
+
if (!this._flagIsActive(this.FLAG_WEIGHT_CLASSES)) {
|
|
1212
|
+
return 0;
|
|
1213
|
+
}
|
|
1214
|
+
var weight = 0;
|
|
1215
|
+
if (typeof e.className === "string" && e.className !== "") {
|
|
1216
|
+
if (this.REGEXPS.negative.test(e.className)) {
|
|
1217
|
+
weight -= 25;
|
|
1218
|
+
}
|
|
1219
|
+
if (this.REGEXPS.positive.test(e.className)) {
|
|
1220
|
+
weight += 25;
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
if (typeof e.id === "string" && e.id !== "") {
|
|
1224
|
+
if (this.REGEXPS.negative.test(e.id)) {
|
|
1225
|
+
weight -= 25;
|
|
1226
|
+
}
|
|
1227
|
+
if (this.REGEXPS.positive.test(e.id)) {
|
|
1228
|
+
weight += 25;
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
return weight;
|
|
1232
|
+
},
|
|
1233
|
+
_clean(e, tag) {
|
|
1234
|
+
var isEmbed = ["object", "embed", "iframe"].includes(tag);
|
|
1235
|
+
this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(element) {
|
|
1236
|
+
if (isEmbed) {
|
|
1237
|
+
for (var i = 0;i < element.attributes.length; i++) {
|
|
1238
|
+
if (this._allowedVideoRegex.test(element.attributes[i].value)) {
|
|
1239
|
+
return false;
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
if (element.tagName === "object" && this._allowedVideoRegex.test(element.innerHTML)) {
|
|
1243
|
+
return false;
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
return true;
|
|
1247
|
+
});
|
|
1248
|
+
},
|
|
1249
|
+
_hasAncestorTag(node, tagName, maxDepth, filterFn) {
|
|
1250
|
+
maxDepth = maxDepth || 3;
|
|
1251
|
+
tagName = tagName.toUpperCase();
|
|
1252
|
+
var depth = 0;
|
|
1253
|
+
while (node.parentNode) {
|
|
1254
|
+
if (maxDepth > 0 && depth > maxDepth) {
|
|
1255
|
+
return false;
|
|
1256
|
+
}
|
|
1257
|
+
if (node.parentNode.tagName === tagName && (!filterFn || filterFn(node.parentNode))) {
|
|
1258
|
+
return true;
|
|
1259
|
+
}
|
|
1260
|
+
node = node.parentNode;
|
|
1261
|
+
depth++;
|
|
1262
|
+
}
|
|
1263
|
+
return false;
|
|
1264
|
+
},
|
|
1265
|
+
_getRowAndColumnCount(table) {
|
|
1266
|
+
var rows = 0;
|
|
1267
|
+
var columns = 0;
|
|
1268
|
+
var trs = table.getElementsByTagName("tr");
|
|
1269
|
+
for (var i = 0;i < trs.length; i++) {
|
|
1270
|
+
var rowspan = trs[i].getAttribute("rowspan") || 0;
|
|
1271
|
+
if (rowspan) {
|
|
1272
|
+
rowspan = parseInt(rowspan, 10);
|
|
1273
|
+
}
|
|
1274
|
+
rows += rowspan || 1;
|
|
1275
|
+
var columnsInThisRow = 0;
|
|
1276
|
+
var cells = trs[i].getElementsByTagName("td");
|
|
1277
|
+
for (var j = 0;j < cells.length; j++) {
|
|
1278
|
+
var colspan = cells[j].getAttribute("colspan") || 0;
|
|
1279
|
+
if (colspan) {
|
|
1280
|
+
colspan = parseInt(colspan, 10);
|
|
1281
|
+
}
|
|
1282
|
+
columnsInThisRow += colspan || 1;
|
|
1283
|
+
}
|
|
1284
|
+
columns = Math.max(columns, columnsInThisRow);
|
|
1285
|
+
}
|
|
1286
|
+
return { rows, columns };
|
|
1287
|
+
},
|
|
1288
|
+
_markDataTables(root) {
|
|
1289
|
+
var tables = root.getElementsByTagName("table");
|
|
1290
|
+
for (var i = 0;i < tables.length; i++) {
|
|
1291
|
+
var table = tables[i];
|
|
1292
|
+
var role = table.getAttribute("role");
|
|
1293
|
+
if (role == "presentation") {
|
|
1294
|
+
table._readabilityDataTable = false;
|
|
1295
|
+
continue;
|
|
1296
|
+
}
|
|
1297
|
+
var datatable = table.getAttribute("datatable");
|
|
1298
|
+
if (datatable == "0") {
|
|
1299
|
+
table._readabilityDataTable = false;
|
|
1300
|
+
continue;
|
|
1301
|
+
}
|
|
1302
|
+
var summary = table.getAttribute("summary");
|
|
1303
|
+
if (summary) {
|
|
1304
|
+
table._readabilityDataTable = true;
|
|
1305
|
+
continue;
|
|
1306
|
+
}
|
|
1307
|
+
var caption = table.getElementsByTagName("caption")[0];
|
|
1308
|
+
if (caption && caption.childNodes.length) {
|
|
1309
|
+
table._readabilityDataTable = true;
|
|
1310
|
+
continue;
|
|
1311
|
+
}
|
|
1312
|
+
var dataTableDescendants = ["col", "colgroup", "tfoot", "thead", "th"];
|
|
1313
|
+
var descendantExists = function(tag) {
|
|
1314
|
+
return !!table.getElementsByTagName(tag)[0];
|
|
1315
|
+
};
|
|
1316
|
+
if (dataTableDescendants.some(descendantExists)) {
|
|
1317
|
+
this.log("Data table because found data-y descendant");
|
|
1318
|
+
table._readabilityDataTable = true;
|
|
1319
|
+
continue;
|
|
1320
|
+
}
|
|
1321
|
+
if (table.getElementsByTagName("table")[0]) {
|
|
1322
|
+
table._readabilityDataTable = false;
|
|
1323
|
+
continue;
|
|
1324
|
+
}
|
|
1325
|
+
var sizeInfo = this._getRowAndColumnCount(table);
|
|
1326
|
+
if (sizeInfo.columns == 1 || sizeInfo.rows == 1) {
|
|
1327
|
+
table._readabilityDataTable = false;
|
|
1328
|
+
continue;
|
|
1329
|
+
}
|
|
1330
|
+
if (sizeInfo.rows >= 10 || sizeInfo.columns > 4) {
|
|
1331
|
+
table._readabilityDataTable = true;
|
|
1332
|
+
continue;
|
|
1333
|
+
}
|
|
1334
|
+
table._readabilityDataTable = sizeInfo.rows * sizeInfo.columns > 10;
|
|
1335
|
+
}
|
|
1336
|
+
},
|
|
1337
|
+
_fixLazyImages(root) {
|
|
1338
|
+
this._forEachNode(this._getAllNodesWithTag(root, ["img", "picture", "figure"]), function(elem) {
|
|
1339
|
+
if (elem.src && this.REGEXPS.b64DataUrl.test(elem.src)) {
|
|
1340
|
+
var parts = this.REGEXPS.b64DataUrl.exec(elem.src);
|
|
1341
|
+
if (parts[1] === "image/svg+xml") {
|
|
1342
|
+
return;
|
|
1343
|
+
}
|
|
1344
|
+
var srcCouldBeRemoved = false;
|
|
1345
|
+
for (var i = 0;i < elem.attributes.length; i++) {
|
|
1346
|
+
var attr = elem.attributes[i];
|
|
1347
|
+
if (attr.name === "src") {
|
|
1348
|
+
continue;
|
|
1349
|
+
}
|
|
1350
|
+
if (/\.(jpg|jpeg|png|webp)/i.test(attr.value)) {
|
|
1351
|
+
srcCouldBeRemoved = true;
|
|
1352
|
+
break;
|
|
1353
|
+
}
|
|
1354
|
+
}
|
|
1355
|
+
if (srcCouldBeRemoved) {
|
|
1356
|
+
var b64starts = parts[0].length;
|
|
1357
|
+
var b64length = elem.src.length - b64starts;
|
|
1358
|
+
if (b64length < 133) {
|
|
1359
|
+
elem.removeAttribute("src");
|
|
1360
|
+
}
|
|
1361
|
+
}
|
|
1362
|
+
}
|
|
1363
|
+
if ((elem.src || elem.srcset && elem.srcset != "null") && !elem.className.toLowerCase().includes("lazy")) {
|
|
1364
|
+
return;
|
|
1365
|
+
}
|
|
1366
|
+
for (var j = 0;j < elem.attributes.length; j++) {
|
|
1367
|
+
attr = elem.attributes[j];
|
|
1368
|
+
if (attr.name === "src" || attr.name === "srcset" || attr.name === "alt") {
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
var copyTo = null;
|
|
1372
|
+
if (/\.(jpg|jpeg|png|webp)\s+\d/.test(attr.value)) {
|
|
1373
|
+
copyTo = "srcset";
|
|
1374
|
+
} else if (/^\s*\S+\.(jpg|jpeg|png|webp)\S*\s*$/.test(attr.value)) {
|
|
1375
|
+
copyTo = "src";
|
|
1376
|
+
}
|
|
1377
|
+
if (copyTo) {
|
|
1378
|
+
if (elem.tagName === "IMG" || elem.tagName === "PICTURE") {
|
|
1379
|
+
elem.setAttribute(copyTo, attr.value);
|
|
1380
|
+
} else if (elem.tagName === "FIGURE" && !this._getAllNodesWithTag(elem, ["img", "picture"]).length) {
|
|
1381
|
+
var img = this._doc.createElement("img");
|
|
1382
|
+
img.setAttribute(copyTo, attr.value);
|
|
1383
|
+
elem.appendChild(img);
|
|
1384
|
+
}
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
});
|
|
1388
|
+
},
|
|
1389
|
+
_getTextDensity(e, tags) {
|
|
1390
|
+
var textLength = this._getInnerText(e, true).length;
|
|
1391
|
+
if (textLength === 0) {
|
|
1392
|
+
return 0;
|
|
1393
|
+
}
|
|
1394
|
+
var childrenLength = 0;
|
|
1395
|
+
var children = this._getAllNodesWithTag(e, tags);
|
|
1396
|
+
this._forEachNode(children, (child) => childrenLength += this._getInnerText(child, true).length);
|
|
1397
|
+
return childrenLength / textLength;
|
|
1398
|
+
},
|
|
1399
|
+
_cleanConditionally(e, tag) {
|
|
1400
|
+
if (!this._flagIsActive(this.FLAG_CLEAN_CONDITIONALLY)) {
|
|
1401
|
+
return;
|
|
1402
|
+
}
|
|
1403
|
+
this._removeNodes(this._getAllNodesWithTag(e, [tag]), function(node) {
|
|
1404
|
+
var isDataTable = function(t) {
|
|
1405
|
+
return t._readabilityDataTable;
|
|
1406
|
+
};
|
|
1407
|
+
var isList = tag === "ul" || tag === "ol";
|
|
1408
|
+
if (!isList) {
|
|
1409
|
+
var listLength = 0;
|
|
1410
|
+
var listNodes = this._getAllNodesWithTag(node, ["ul", "ol"]);
|
|
1411
|
+
this._forEachNode(listNodes, (list) => listLength += this._getInnerText(list).length);
|
|
1412
|
+
isList = listLength / this._getInnerText(node).length > 0.9;
|
|
1413
|
+
}
|
|
1414
|
+
if (tag === "table" && isDataTable(node)) {
|
|
1415
|
+
return false;
|
|
1416
|
+
}
|
|
1417
|
+
if (this._hasAncestorTag(node, "table", -1, isDataTable)) {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
if (this._hasAncestorTag(node, "code")) {
|
|
1421
|
+
return false;
|
|
1422
|
+
}
|
|
1423
|
+
if ([...node.getElementsByTagName("table")].some((tbl) => tbl._readabilityDataTable)) {
|
|
1424
|
+
return false;
|
|
1425
|
+
}
|
|
1426
|
+
var weight = this._getClassWeight(node);
|
|
1427
|
+
this.log("Cleaning Conditionally", node);
|
|
1428
|
+
var contentScore = 0;
|
|
1429
|
+
if (weight + contentScore < 0) {
|
|
1430
|
+
return true;
|
|
1431
|
+
}
|
|
1432
|
+
if (this._getCharCount(node, ",") < 10) {
|
|
1433
|
+
var p = node.getElementsByTagName("p").length;
|
|
1434
|
+
var img = node.getElementsByTagName("img").length;
|
|
1435
|
+
var li = node.getElementsByTagName("li").length - 100;
|
|
1436
|
+
var input = node.getElementsByTagName("input").length;
|
|
1437
|
+
var headingDensity = this._getTextDensity(node, [
|
|
1438
|
+
"h1",
|
|
1439
|
+
"h2",
|
|
1440
|
+
"h3",
|
|
1441
|
+
"h4",
|
|
1442
|
+
"h5",
|
|
1443
|
+
"h6"
|
|
1444
|
+
]);
|
|
1445
|
+
var embedCount = 0;
|
|
1446
|
+
var embeds = this._getAllNodesWithTag(node, [
|
|
1447
|
+
"object",
|
|
1448
|
+
"embed",
|
|
1449
|
+
"iframe"
|
|
1450
|
+
]);
|
|
1451
|
+
for (var i = 0;i < embeds.length; i++) {
|
|
1452
|
+
for (var j = 0;j < embeds[i].attributes.length; j++) {
|
|
1453
|
+
if (this._allowedVideoRegex.test(embeds[i].attributes[j].value)) {
|
|
1454
|
+
return false;
|
|
1455
|
+
}
|
|
1456
|
+
}
|
|
1457
|
+
if (embeds[i].tagName === "object" && this._allowedVideoRegex.test(embeds[i].innerHTML)) {
|
|
1458
|
+
return false;
|
|
1459
|
+
}
|
|
1460
|
+
embedCount++;
|
|
1461
|
+
}
|
|
1462
|
+
var innerText = this._getInnerText(node);
|
|
1463
|
+
if (this.REGEXPS.adWords.test(innerText) || this.REGEXPS.loadingWords.test(innerText)) {
|
|
1464
|
+
return true;
|
|
1465
|
+
}
|
|
1466
|
+
var contentLength = innerText.length;
|
|
1467
|
+
var linkDensity = this._getLinkDensity(node);
|
|
1468
|
+
var textishTags = ["SPAN", "LI", "TD"].concat(Array.from(this.DIV_TO_P_ELEMS));
|
|
1469
|
+
var textDensity = this._getTextDensity(node, textishTags);
|
|
1470
|
+
var isFigureChild = this._hasAncestorTag(node, "figure");
|
|
1471
|
+
const shouldRemoveNode = () => {
|
|
1472
|
+
const errs = [];
|
|
1473
|
+
if (!isFigureChild && img > 1 && p / img < 0.5) {
|
|
1474
|
+
errs.push(`Bad p to img ratio (img=${img}, p=${p})`);
|
|
1475
|
+
}
|
|
1476
|
+
if (!isList && li > p) {
|
|
1477
|
+
errs.push(`Too many li's outside of a list. (li=${li} > p=${p})`);
|
|
1478
|
+
}
|
|
1479
|
+
if (input > Math.floor(p / 3)) {
|
|
1480
|
+
errs.push(`Too many inputs per p. (input=${input}, p=${p})`);
|
|
1481
|
+
}
|
|
1482
|
+
if (!isList && !isFigureChild && headingDensity < 0.9 && contentLength < 25 && (img === 0 || img > 2) && linkDensity > 0) {
|
|
1483
|
+
errs.push(`Suspiciously short. (headingDensity=${headingDensity}, img=${img}, linkDensity=${linkDensity})`);
|
|
1484
|
+
}
|
|
1485
|
+
if (!isList && weight < 25 && linkDensity > 0.2 + this._linkDensityModifier) {
|
|
1486
|
+
errs.push(`Low weight and a little linky. (linkDensity=${linkDensity})`);
|
|
1487
|
+
}
|
|
1488
|
+
if (weight >= 25 && linkDensity > 0.5 + this._linkDensityModifier) {
|
|
1489
|
+
errs.push(`High weight and mostly links. (linkDensity=${linkDensity})`);
|
|
1490
|
+
}
|
|
1491
|
+
if (embedCount === 1 && contentLength < 75 || embedCount > 1) {
|
|
1492
|
+
errs.push(`Suspicious embed. (embedCount=${embedCount}, contentLength=${contentLength})`);
|
|
1493
|
+
}
|
|
1494
|
+
if (img === 0 && textDensity === 0) {
|
|
1495
|
+
errs.push(`No useful content. (img=${img}, textDensity=${textDensity})`);
|
|
1496
|
+
}
|
|
1497
|
+
if (errs.length) {
|
|
1498
|
+
this.log("Checks failed", errs);
|
|
1499
|
+
return true;
|
|
1500
|
+
}
|
|
1501
|
+
return false;
|
|
1502
|
+
};
|
|
1503
|
+
var haveToRemove = shouldRemoveNode();
|
|
1504
|
+
if (isList && haveToRemove) {
|
|
1505
|
+
for (var x = 0;x < node.children.length; x++) {
|
|
1506
|
+
let child = node.children[x];
|
|
1507
|
+
if (child.children.length > 1) {
|
|
1508
|
+
return haveToRemove;
|
|
1509
|
+
}
|
|
1510
|
+
}
|
|
1511
|
+
let li_count = node.getElementsByTagName("li").length;
|
|
1512
|
+
if (img == li_count) {
|
|
1513
|
+
return false;
|
|
1514
|
+
}
|
|
1515
|
+
}
|
|
1516
|
+
return haveToRemove;
|
|
1517
|
+
}
|
|
1518
|
+
return false;
|
|
1519
|
+
});
|
|
1520
|
+
},
|
|
1521
|
+
_cleanMatchedNodes(e, filter) {
|
|
1522
|
+
var endOfSearchMarkerNode = this._getNextNode(e, true);
|
|
1523
|
+
var next = this._getNextNode(e);
|
|
1524
|
+
while (next && next != endOfSearchMarkerNode) {
|
|
1525
|
+
if (filter.call(this, next, next.className + " " + next.id)) {
|
|
1526
|
+
next = this._removeAndGetNext(next);
|
|
1527
|
+
} else {
|
|
1528
|
+
next = this._getNextNode(next);
|
|
1529
|
+
}
|
|
1530
|
+
}
|
|
1531
|
+
},
|
|
1532
|
+
_cleanHeaders(e) {
|
|
1533
|
+
let headingNodes = this._getAllNodesWithTag(e, ["h1", "h2"]);
|
|
1534
|
+
this._removeNodes(headingNodes, function(node) {
|
|
1535
|
+
let shouldRemove = this._getClassWeight(node) < 0;
|
|
1536
|
+
if (shouldRemove) {
|
|
1537
|
+
this.log("Removing header with low class weight:", node);
|
|
1538
|
+
}
|
|
1539
|
+
return shouldRemove;
|
|
1540
|
+
});
|
|
1541
|
+
},
|
|
1542
|
+
_headerDuplicatesTitle(node) {
|
|
1543
|
+
if (node.tagName != "H1" && node.tagName != "H2") {
|
|
1544
|
+
return false;
|
|
1545
|
+
}
|
|
1546
|
+
var heading = this._getInnerText(node, false);
|
|
1547
|
+
this.log("Evaluating similarity of header:", heading, this._articleTitle);
|
|
1548
|
+
return this._textSimilarity(this._articleTitle, heading) > 0.75;
|
|
1549
|
+
},
|
|
1550
|
+
_flagIsActive(flag) {
|
|
1551
|
+
return (this._flags & flag) > 0;
|
|
1552
|
+
},
|
|
1553
|
+
_removeFlag(flag) {
|
|
1554
|
+
this._flags = this._flags & ~flag;
|
|
1555
|
+
},
|
|
1556
|
+
_isProbablyVisible(node) {
|
|
1557
|
+
return (!node.style || node.style.display != "none") && (!node.style || node.style.visibility != "hidden") && !node.hasAttribute("hidden") && (!node.hasAttribute("aria-hidden") || node.getAttribute("aria-hidden") != "true" || node.className && node.className.includes && node.className.includes("fallback-image"));
|
|
1558
|
+
},
|
|
1559
|
+
parse() {
|
|
1560
|
+
if (this._maxElemsToParse > 0) {
|
|
1561
|
+
var numTags = this._doc.getElementsByTagName("*").length;
|
|
1562
|
+
if (numTags > this._maxElemsToParse) {
|
|
1563
|
+
throw new Error("Aborting parsing document; " + numTags + " elements found");
|
|
1564
|
+
}
|
|
1565
|
+
}
|
|
1566
|
+
this._unwrapNoscriptImages(this._doc);
|
|
1567
|
+
var jsonLd = this._disableJSONLD ? {} : this._getJSONLD(this._doc);
|
|
1568
|
+
this._removeScripts(this._doc);
|
|
1569
|
+
this._prepDocument();
|
|
1570
|
+
var metadata = this._getArticleMetadata(jsonLd);
|
|
1571
|
+
this._metadata = metadata;
|
|
1572
|
+
this._articleTitle = metadata.title;
|
|
1573
|
+
var articleContent = this._grabArticle();
|
|
1574
|
+
if (!articleContent) {
|
|
1575
|
+
return null;
|
|
1576
|
+
}
|
|
1577
|
+
this.log("Grabbed: " + articleContent.innerHTML);
|
|
1578
|
+
this._postProcessContent(articleContent);
|
|
1579
|
+
if (!metadata.excerpt) {
|
|
1580
|
+
var paragraphs = articleContent.getElementsByTagName("p");
|
|
1581
|
+
if (paragraphs.length) {
|
|
1582
|
+
metadata.excerpt = paragraphs[0].textContent.trim();
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
var textContent = articleContent.textContent;
|
|
1586
|
+
return {
|
|
1587
|
+
title: this._articleTitle,
|
|
1588
|
+
byline: metadata.byline || this._articleByline,
|
|
1589
|
+
dir: this._articleDir,
|
|
1590
|
+
lang: this._articleLang,
|
|
1591
|
+
content: this._serializer(articleContent),
|
|
1592
|
+
textContent,
|
|
1593
|
+
length: textContent.length,
|
|
1594
|
+
excerpt: metadata.excerpt,
|
|
1595
|
+
siteName: metadata.siteName || this._articleSiteName,
|
|
1596
|
+
publishedTime: metadata.publishedTime
|
|
1597
|
+
};
|
|
1598
|
+
}
|
|
1599
|
+
};
|
|
1600
|
+
if (typeof module === "object") {
|
|
1601
|
+
module.exports = Readability;
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
|
|
1605
|
+
// ../node_modules/.pnpm/@mozilla+readability@0.6.0/node_modules/@mozilla/readability/Readability-readerable.js
|
|
1606
|
+
var require_Readability_readerable = __commonJS((exports, module) => {
|
|
1607
|
+
var REGEXPS = {
|
|
1608
|
+
unlikelyCandidates: /-ad-|ai2html|banner|breadcrumbs|combx|comment|community|cover-wrap|disqus|extra|footer|gdpr|header|legends|menu|related|remark|replies|rss|shoutbox|sidebar|skyscraper|social|sponsor|supplemental|ad-break|agegate|pagination|pager|popup|yom-remote/i,
|
|
1609
|
+
okMaybeItsACandidate: /and|article|body|column|content|main|shadow/i
|
|
1610
|
+
};
|
|
1611
|
+
function isNodeVisible(node) {
|
|
1612
|
+
return (!node.style || node.style.display != "none") && !node.hasAttribute("hidden") && (!node.hasAttribute("aria-hidden") || node.getAttribute("aria-hidden") != "true" || node.className && node.className.includes && node.className.includes("fallback-image"));
|
|
1613
|
+
}
|
|
1614
|
+
function isProbablyReaderable(doc, options = {}) {
|
|
1615
|
+
if (typeof options == "function") {
|
|
1616
|
+
options = { visibilityChecker: options };
|
|
1617
|
+
}
|
|
1618
|
+
var defaultOptions = {
|
|
1619
|
+
minScore: 20,
|
|
1620
|
+
minContentLength: 140,
|
|
1621
|
+
visibilityChecker: isNodeVisible
|
|
1622
|
+
};
|
|
1623
|
+
options = Object.assign(defaultOptions, options);
|
|
1624
|
+
var nodes = doc.querySelectorAll("p, pre, article");
|
|
1625
|
+
var brNodes = doc.querySelectorAll("div > br");
|
|
1626
|
+
if (brNodes.length) {
|
|
1627
|
+
var set = new Set(nodes);
|
|
1628
|
+
[].forEach.call(brNodes, function(node) {
|
|
1629
|
+
set.add(node.parentNode);
|
|
1630
|
+
});
|
|
1631
|
+
nodes = Array.from(set);
|
|
1632
|
+
}
|
|
1633
|
+
var score = 0;
|
|
1634
|
+
return [].some.call(nodes, function(node) {
|
|
1635
|
+
if (!options.visibilityChecker(node)) {
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
var matchString = node.className + " " + node.id;
|
|
1639
|
+
if (REGEXPS.unlikelyCandidates.test(matchString) && !REGEXPS.okMaybeItsACandidate.test(matchString)) {
|
|
1640
|
+
return false;
|
|
1641
|
+
}
|
|
1642
|
+
if (node.matches("li p")) {
|
|
1643
|
+
return false;
|
|
1644
|
+
}
|
|
1645
|
+
var textContentLength = node.textContent.trim().length;
|
|
1646
|
+
if (textContentLength < options.minContentLength) {
|
|
1647
|
+
return false;
|
|
1648
|
+
}
|
|
1649
|
+
score += Math.sqrt(textContentLength - options.minContentLength);
|
|
1650
|
+
if (score > options.minScore) {
|
|
1651
|
+
return true;
|
|
1652
|
+
}
|
|
1653
|
+
return false;
|
|
1654
|
+
});
|
|
1655
|
+
}
|
|
1656
|
+
if (typeof module === "object") {
|
|
1657
|
+
module.exports = isProbablyReaderable;
|
|
1658
|
+
}
|
|
1659
|
+
});
|
|
1660
|
+
|
|
1661
|
+
// ../node_modules/.pnpm/@mozilla+readability@0.6.0/node_modules/@mozilla/readability/index.js
|
|
1662
|
+
var require_readability = __commonJS((exports, module) => {
|
|
1663
|
+
var Readability = require_Readability();
|
|
1664
|
+
var isProbablyReaderable = require_Readability_readerable();
|
|
1665
|
+
module.exports = {
|
|
1666
|
+
Readability,
|
|
1667
|
+
isProbablyReaderable
|
|
1668
|
+
};
|
|
1669
|
+
});
|
|
1670
|
+
|
|
1671
|
+
// dist/_readability-entry-68953-1784086938398.js
|
|
1672
|
+
var import_readability = __toESM(require_readability(), 1);
|
|
1673
|
+
globalThis.__readability = { Readability: import_readability.Readability, isProbablyReaderable: import_readability.isProbablyReaderable };
|
|
1674
|
+
})();
|