Compare commits
No commits in common. "master" and "v2.5.207" have entirely different histories.
@ -1,6 +1,6 @@
|
||||
root = true
|
||||
|
||||
[*.{js,jsm,mjs,json,html,css,pdf.link}]
|
||||
[*.{js,jsm,html,css}]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 2
|
||||
@ -9,12 +9,9 @@ insert_final_newline = true
|
||||
max_line_length = 80
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{json,pdf.link}]
|
||||
max_line_length = off
|
||||
|
||||
[*.md]
|
||||
max_line_length = off
|
||||
max_line_length = 0
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[COMMIT_EDITMSG]
|
||||
max_line_length = off
|
||||
max_line_length = 0
|
||||
|
||||
17
.eslintignore
Normal file
17
.eslintignore
Normal file
@ -0,0 +1,17 @@
|
||||
build/
|
||||
l10n/
|
||||
docs/
|
||||
node_modules/
|
||||
external/bcmaps/
|
||||
external/webL10n/
|
||||
external/cmapscompress/
|
||||
external/builder/fixtures/
|
||||
external/builder/fixtures_esprima/
|
||||
src/shared/cffStandardStrings.js
|
||||
src/shared/fonts_utils.js
|
||||
test/tmp/
|
||||
test/features/
|
||||
test/pdfs/
|
||||
test/resources/
|
||||
test/font/*_spec.js
|
||||
*~/
|
||||
195
.eslintrc
Normal file
195
.eslintrc
Normal file
@ -0,0 +1,195 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2020,
|
||||
"sourceType": "module",
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"import",
|
||||
"mozilla",
|
||||
"no-unsanitized",
|
||||
"unicorn",
|
||||
],
|
||||
|
||||
"extends": [
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2020": true,
|
||||
"worker": true,
|
||||
"amd": true,
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"PDFJSDev": false,
|
||||
"exports": false,
|
||||
"SystemJS": false,
|
||||
},
|
||||
|
||||
"rules": {
|
||||
// Plugins
|
||||
"import/extensions": ["error", "always", { "ignorePackages": true, }],
|
||||
"import/no-unresolved": "error",
|
||||
"mozilla/avoid-removeChild": "error",
|
||||
"mozilla/use-includes-instead-of-indexOf": "error",
|
||||
"no-unsanitized/method": "error",
|
||||
"no-unsanitized/property": "error",
|
||||
"unicorn/no-array-instanceof": "error",
|
||||
"unicorn/prefer-starts-ends-with": "error",
|
||||
|
||||
// Possible errors
|
||||
"for-direction": "error",
|
||||
"getter-return": "error",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-cond-assign": ["error", "except-parens"],
|
||||
"no-constant-condition": ["error", { "checkLoops": false, }],
|
||||
"no-dupe-args": "error",
|
||||
"no-dupe-else-if": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-empty": ["error", { "allowEmptyCatch": true, }],
|
||||
"no-ex-assign": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-inner-declarations": ["error", "functions"],
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"no-setter-return": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unsafe-negation": "error",
|
||||
"use-isnan": ["error", { "enforceForIndexOf": true, }],
|
||||
"valid-typeof": ["error", { "requireStringLiterals": true, }],
|
||||
|
||||
// Best Practices
|
||||
"accessor-pairs": ["error", {
|
||||
"setWithoutGet": true,
|
||||
"enforceForClassMembers": true,
|
||||
}],
|
||||
"consistent-return": "error",
|
||||
"curly": ["error", "all"],
|
||||
"default-case-last": "error",
|
||||
"dot-notation": "error",
|
||||
"eqeqeq": ["error", "always"],
|
||||
"grouped-accessor-pairs": ["error", "getBeforeSet"],
|
||||
"no-caller": "error",
|
||||
"no-else-return": "error",
|
||||
"no-empty-pattern": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-floating-decimal": "error",
|
||||
"no-global-assign": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-iterator": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-multi-str": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-new": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-octal": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-return-await": "error",
|
||||
"no-self-assign": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-catch": "error",
|
||||
"no-useless-concat": "error",
|
||||
"no-useless-return": "error",
|
||||
"prefer-promise-reject-errors": "error",
|
||||
"wrap-iife": ["error", "any"],
|
||||
"yoda": ["error", "never", {
|
||||
"exceptRange": true,
|
||||
}],
|
||||
|
||||
// Strict Mode
|
||||
"strict": ["off", "global"],
|
||||
|
||||
// Variables
|
||||
"no-catch-shadow": "error",
|
||||
"no-delete-var": "error",
|
||||
"no-label-var": "error",
|
||||
"no-shadow": "error",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-undef": ["error", { "typeof": true, }],
|
||||
"no-unused-vars": ["error", {
|
||||
"vars": "local",
|
||||
"args": "none",
|
||||
}],
|
||||
|
||||
// Node.js and CommonJS
|
||||
"no-buffer-constructor": "error",
|
||||
|
||||
// Stylistic Issues
|
||||
"lines-between-class-members": ["error", "always"],
|
||||
"max-len": ["error", {
|
||||
"code": 1000,
|
||||
"comments": 80,
|
||||
"ignoreUrls": true
|
||||
}],
|
||||
"new-cap": ["error", { "newIsCap": true, "capIsNew": false, }],
|
||||
"no-array-constructor": "error",
|
||||
"no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0, "maxBOF": 1, }],
|
||||
"no-nested-ternary": "error",
|
||||
"no-new-object": "error",
|
||||
"no-restricted-syntax": ["error",
|
||||
{
|
||||
"selector": "CallExpression[callee.name='assert'][arguments.length!=2]",
|
||||
"message": "`assert()` must always be invoked with two arguments.",
|
||||
},
|
||||
{
|
||||
"selector": "NewExpression[callee.name='Cmd']",
|
||||
"message": "Use `Cmd.get()` rather than `new Cmd()`.",
|
||||
},
|
||||
{
|
||||
"selector": "NewExpression[callee.name='Name']",
|
||||
"message": "Use `Name.get()` rather than `new Name()`.",
|
||||
},
|
||||
{
|
||||
"selector": "NewExpression[callee.name='Ref']",
|
||||
"message": "Use `Ref.get()` rather than `new Ref()`.",
|
||||
},
|
||||
],
|
||||
"no-unneeded-ternary": "error",
|
||||
"prefer-exponentiation-operator": "error",
|
||||
"spaced-comment": ["error", "always", {
|
||||
"block": {
|
||||
"balanced": true,
|
||||
}
|
||||
}],
|
||||
|
||||
// ECMAScript 6
|
||||
"constructor-super": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-confusing-arrow": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-this-before-super": "error",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-rename": "error",
|
||||
"no-var": "off",
|
||||
"object-shorthand": ["error", "always", {
|
||||
"avoidQuotes": true,
|
||||
}],
|
||||
"prefer-const": "error",
|
||||
"sort-imports": ["error", {
|
||||
"ignoreCase": true,
|
||||
}],
|
||||
"template-curly-spacing": ["error", "never"],
|
||||
},
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
# Auto-format `.js` files with ESLint/Prettier
|
||||
de36b2aabab2b7fd647d9591f959c4540129541d
|
||||
# Auto-format `.css` files with Stylelint/Prettier
|
||||
8aa2718d225ad701a5b8a2788b42d221f1e4327d
|
||||
# Auto-format `.json` files with Prettier
|
||||
29de9bdce6c9785574994fda0e51533d796a9bb4
|
||||
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -4,7 +4,7 @@
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.md text eol=lf
|
||||
*.ftl text eol=lf
|
||||
*.properties text eol=lf
|
||||
*.yml text eol=lf
|
||||
*.json text eol=lf
|
||||
*.config text eol=lf
|
||||
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@ -1 +0,0 @@
|
||||
l10n/en-US/*.ftl @mozilla/pdfjs-l10n
|
||||
17
.github/ISSUE_TEMPLATE.md
vendored
Normal file
17
.github/ISSUE_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
Attach (recommended) or Link to PDF file here:
|
||||
|
||||
Configuration:
|
||||
- Web browser and its version:
|
||||
- Operating system and its version:
|
||||
- PDF.js version:
|
||||
- Is a browser extension:
|
||||
|
||||
Steps to reproduce the problem:
|
||||
1.
|
||||
2.
|
||||
|
||||
What is the expected behavior? (add screenshot)
|
||||
|
||||
What went wrong? (add screenshot)
|
||||
|
||||
Link to a viewer (if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension):
|
||||
81
.github/ISSUE_TEMPLATE/bug.yml
vendored
81
.github/ISSUE_TEMPLATE/bug.yml
vendored
@ -1,81 +0,0 @@
|
||||
name: Bug Report
|
||||
description: Report a bug in PDF.js
|
||||
title: "[Bug]: "
|
||||
body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Attach (recommended) or Link to PDF file
|
||||
description: Without this information the issue may be closed without comment
|
||||
placeholder: Please place only the PDF file in this field
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes: { value: "---" }
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Web browser and its version
|
||||
description: Please ensure that it's supported, refer to [the FAQ](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support)
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Operating system and its version
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: PDF.js version
|
||||
description: Please find official releases [here](https://github.com/mozilla/pdf.js/releases)
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Is the bug present in the latest PDF.js version?
|
||||
description: Please check the [online demo](https://github.com/mozilla/pdf.js#online-demo)
|
||||
options: ["Yes", "No"]
|
||||
default: 0
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Is a browser extension
|
||||
options: ["Yes", "No"]
|
||||
default: 1
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: markdown
|
||||
attributes: { value: "---" }
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Steps to reproduce the problem
|
||||
placeholder: "1.\n2."
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What is the expected behavior?
|
||||
description: Also add a screenshot
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: What went wrong?
|
||||
description: Also add a screenshot
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: Link to a viewer
|
||||
description: Needed if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Do you have anything to add that doesn't fit in the issue template?
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
5
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -1,5 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Need help?
|
||||
url: https://github.com/mozilla/pdf.js/discussions
|
||||
about: If you need help on how to use PDF.js, please open a discussion where other community members can reply
|
||||
23
.github/ISSUE_TEMPLATE/feature.yml
vendored
23
.github/ISSUE_TEMPLATE/feature.yml
vendored
@ -1,23 +0,0 @@
|
||||
name: Feature request
|
||||
description: Propose a new feature or enhancement for PDF.js
|
||||
title: "[Feature]: "
|
||||
body:
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Is the feature relevant to the Firefox PDF Viewer?
|
||||
options: ["Yes", "No"]
|
||||
default: 1
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Feature description
|
||||
description: What new feature would you like PDF.js to have? Why would it be useful? What are the current workarounds?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Other PDF viewers
|
||||
description: Do other PDF viewers implement similar functionality? Add descriptions, links, and/or screenshots.
|
||||
13
.github/SECURITY.md
vendored
13
.github/SECURITY.md
vendored
@ -1,13 +0,0 @@
|
||||
# Security policy
|
||||
|
||||
Mozilla takes the security of our software seriously. If you believe you have found a security vulnerability in PDF.js, please report it to us as described below.
|
||||
|
||||
## Reporting security vulnerabilities
|
||||
|
||||
**Please don't report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report security vulnerabilities in [Bugzilla](https://bugzilla.mozilla.org/enter_bug.cgi?product=Firefox&component=PDF%20Viewer&groups=firefox-core-security) and make sure that the checkbox in the "Security" section is checked so the required access controls are automatically configured:
|
||||
|
||||

|
||||
|
||||
The Mozilla security team will process the bug as described in [Mozilla's security bugs policy](https://www.mozilla.org/en-US/about/governance/policies/security-group/bugs).
|
||||
8
.github/dependabot.yml
vendored
8
.github/dependabot.yml
vendored
@ -1,8 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
labels:
|
||||
- "dependencies"
|
||||
29
.github/fluent_linter_config.yml
vendored
29
.github/fluent_linter_config.yml
vendored
@ -1,29 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# See https://github.com/mozilla-l10n/moz-fluent-linter/blob/main/src/fluent_linter/config.yml
|
||||
# for details
|
||||
|
||||
---
|
||||
ID01:
|
||||
enabled: true
|
||||
exclusions:
|
||||
messages: []
|
||||
files: []
|
||||
ID02:
|
||||
enabled: true
|
||||
min_length: 9
|
||||
exclusions:
|
||||
messages: []
|
||||
files: []
|
||||
CO01:
|
||||
enabled: true
|
||||
brands:
|
||||
- Firefox
|
||||
- Mozilla
|
||||
exclusions:
|
||||
files: []
|
||||
messages: []
|
||||
VC:
|
||||
disabled: false
|
||||
1
.github/requirements.txt
vendored
1
.github/requirements.txt
vendored
@ -1 +0,0 @@
|
||||
moz-fluent-linter==0.4.*
|
||||
BIN
.github/security.png
vendored
BIN
.github/security.png
vendored
Binary file not shown.
|
Before Width: | Height: | Size: 11 KiB |
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
@ -1,34 +0,0 @@
|
||||
name: CI
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [20, 22, 24]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run external tests
|
||||
run: npx gulp externaltest
|
||||
|
||||
- name: Run CLI unit tests
|
||||
run: npx gulp unittestcli
|
||||
35
.github/workflows/codeql.yml
vendored
35
.github/workflows/codeql.yml
vendored
@ -1,35 +0,0 @@
|
||||
name: CodeQL
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [javascript]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
queries: security-and-quality
|
||||
|
||||
- name: Autobuild CodeQL
|
||||
uses: github/codeql-action/autobuild@v4
|
||||
|
||||
- name: Perform CodeQL analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
42
.github/workflows/fluent_linter.yml
vendored
42
.github/workflows/fluent_linter.yml
vendored
@ -1,42 +0,0 @@
|
||||
name: Lint Fluent Reference Files
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'l10n/en-US/**.ftl'
|
||||
- '.github/fluent_linter_config.yml'
|
||||
- '.github/workflows/fluent_linter.yml'
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- 'l10n/en-US/**.ftl'
|
||||
- '.github/fluent_linter_config.yml'
|
||||
- '.github/workflows/fluent_linter.yml'
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Use Python 3.14
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.14'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Fluent dependencies
|
||||
run: |
|
||||
pip install -r .github/requirements.txt
|
||||
|
||||
- name: Lint Fluent reference files
|
||||
run: |
|
||||
moz-fluent-lint ./l10n/en-US --config .github/fluent_linter_config.yml
|
||||
61
.github/workflows/font_tests.yml
vendored
61
.github/workflows/font_tests.yml
vendored
@ -1,61 +0,0 @@
|
||||
name: Font tests
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'gulpfile.mjs'
|
||||
- 'src/**'
|
||||
- 'test/test.mjs'
|
||||
- 'test/font/**'
|
||||
- '.github/workflows/font_tests.yml'
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
- 'gulpfile.mjs'
|
||||
- 'src/**'
|
||||
- 'test/test.mjs'
|
||||
- 'test/font/**'
|
||||
- '.github/workflows/font_tests.yml'
|
||||
branches:
|
||||
- master
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [lts/*]
|
||||
os: [windows-latest, ubuntu-latest]
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Use Python 3.14
|
||||
uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '3.14'
|
||||
cache: 'pip'
|
||||
|
||||
- name: Install Fonttools
|
||||
run: pip install fonttools
|
||||
|
||||
- name: Run font tests
|
||||
run: npx gulp fonttest --headless
|
||||
34
.github/workflows/lint.yml
vendored
34
.github/workflows/lint.yml
vendored
@ -1,34 +0,0 @@
|
||||
name: Lint
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [lts/*]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run lint
|
||||
run: npx gulp lint
|
||||
|
||||
- name: Run lint-chromium
|
||||
run: npx gulp lint-chromium
|
||||
37
.github/workflows/publish_release.yml
vendored
37
.github/workflows/publish_release.yml
vendored
@ -1,37 +0,0 @@
|
||||
name: Publish release
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [lts/*]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build the `pdfjs-dist` library
|
||||
run: npx gulp dist
|
||||
|
||||
- name: Publish the `pdfjs-dist` library to NPM
|
||||
run: npm publish ./build/dist
|
||||
69
.github/workflows/publish_website.yml
vendored
69
.github/workflows/publish_website.yml
vendored
@ -1,69 +0,0 @@
|
||||
name: Publish website
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [lts/*]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Build the website
|
||||
run: npx gulp web
|
||||
|
||||
- name: Archive the website
|
||||
shell: sh
|
||||
run: |
|
||||
chmod -c -R +rX "$INPUT_PATH" | while read line; do
|
||||
echo "::warning title=Invalid file permissions automatically fixed::$line"
|
||||
done
|
||||
tar \
|
||||
--dereference --hard-dereference \
|
||||
--directory "$INPUT_PATH" \
|
||||
-cvf "$RUNNER_TEMP/website.tar" \
|
||||
--exclude=.git \
|
||||
--exclude=.github \
|
||||
.
|
||||
env:
|
||||
INPUT_PATH: build/gh-pages
|
||||
|
||||
- name: Upload the website
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
name: github-pages
|
||||
path: ${{ runner.temp }}/website.tar
|
||||
retention-days: 1
|
||||
if-no-files-found: error
|
||||
|
||||
deploy:
|
||||
name: Deploy
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
permissions:
|
||||
pages: write # Required to deploy to GitHub Pages.
|
||||
id-token: write # Required to verify that the deployment originates from this workflow.
|
||||
|
||||
steps:
|
||||
- name: Deploy the website
|
||||
uses: actions/deploy-pages@v4
|
||||
31
.github/workflows/types_tests.yml
vendored
31
.github/workflows/types_tests.yml
vendored
@ -1,31 +0,0 @@
|
||||
name: Types tests
|
||||
on: [push, pull_request]
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
node-version: [lts/*]
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
|
||||
- name: Run types tests
|
||||
run: npx gulp typestest
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
[submodule "test/ttx/fonttools-code"]
|
||||
path = test/ttx/fonttools-code
|
||||
url = https://github.com/behdad/fonttools.git
|
||||
7
.gitpod.Dockerfile
vendored
Normal file
7
.gitpod.Dockerfile
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
FROM gitpod/workspace-full-vnc
|
||||
|
||||
USER gitpod
|
||||
|
||||
RUN sudo apt-get update && \
|
||||
sudo apt-get install -yq firefox && \
|
||||
sudo rm -rf /var/lib/apt/lists/*
|
||||
13
.gitpod.yml
Normal file
13
.gitpod.yml
Normal file
@ -0,0 +1,13 @@
|
||||
image:
|
||||
file: .gitpod.Dockerfile
|
||||
tasks:
|
||||
- command: |
|
||||
gp await-port 8888 && gp preview $(gp url 8888)/web/viewer.html && echo '[{"name": "Firefox","path": "/usr/bin/firefox"}]' | jq '.' > test/resources/browser_manifests/browser_manifest.json
|
||||
|
||||
- init: npm install -g gulp-cli && npm install
|
||||
command: gulp server
|
||||
ports:
|
||||
- port: 8888
|
||||
onOpen: ignore
|
||||
- port: 6080
|
||||
onOpen: ignore
|
||||
@ -1,15 +0,0 @@
|
||||
build/
|
||||
l10n/
|
||||
docs/
|
||||
node_modules/
|
||||
external/bcmaps/
|
||||
external/builder/fixtures/
|
||||
external/builder/fixtures_babel/
|
||||
external/openjpeg/
|
||||
external/qcms/
|
||||
external/quickjs/
|
||||
test/stats/results/
|
||||
test/tmp/
|
||||
test/pdfs/
|
||||
web/locale/
|
||||
*~/
|
||||
18
.prettierrc
18
.prettierrc
@ -5,21 +5,5 @@
|
||||
"semi": true,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5",
|
||||
"useTabs": false,
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["tsconfig.json", ".prettierrc"],
|
||||
"options": {
|
||||
"parser": "json"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["**/*.html"],
|
||||
"options": {
|
||||
"parser": "html",
|
||||
"printWidth": 160
|
||||
}
|
||||
}
|
||||
]
|
||||
"useTabs": false
|
||||
}
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
{
|
||||
"chrome": {
|
||||
"skipDownload": false
|
||||
},
|
||||
"firefox": {
|
||||
"skipDownload": false,
|
||||
"version": "nightly"
|
||||
}
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
build/
|
||||
l10n/
|
||||
docs/
|
||||
node_modules/
|
||||
external/bcmaps/
|
||||
external/builder/fixtures/
|
||||
external/builder/fixtures_babel/
|
||||
external/quickjs/
|
||||
test/stats/results/
|
||||
test/tmp/
|
||||
test/pdfs/
|
||||
web/locale/
|
||||
*~/
|
||||
25
.stylelintrc
25
.stylelintrc
@ -1,25 +0,0 @@
|
||||
{
|
||||
"plugins": [
|
||||
"stylelint-prettier"
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"prettier/prettier": true,
|
||||
|
||||
"alpha-value-notation": "number",
|
||||
"block-no-empty": true,
|
||||
"color-function-notation": "modern",
|
||||
"color-hex-length": "short",
|
||||
"color-no-invalid-hex": true,
|
||||
"declaration-block-no-duplicate-properties": true,
|
||||
"declaration-block-no-redundant-longhand-properties": true,
|
||||
"declaration-property-value-disallowed-list": {
|
||||
"float": ["inline-start", "inline-end"]
|
||||
},
|
||||
"length-zero-no-unit": [true, {
|
||||
ignore: ["custom-properties"]
|
||||
}],
|
||||
"selector-pseudo-element-colon-notation": "double",
|
||||
"shorthand-property-no-redundant-values": true,
|
||||
},
|
||||
}
|
||||
@ -1,35 +0,0 @@
|
||||
export default {
|
||||
rules: {
|
||||
valid: true,
|
||||
|
||||
custom: [
|
||||
(reporter, $, ast, { filename }) => {
|
||||
reporter.name = "no-svg-fill-context-fill";
|
||||
|
||||
const svg = $.find("svg");
|
||||
const fill = svg.attr("fill");
|
||||
if (fill === "context-fill") {
|
||||
reporter.error(
|
||||
"Fill attribute on svg element must not be set to 'context-fill'",
|
||||
svg[0],
|
||||
ast
|
||||
);
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
ignore: [
|
||||
"build/**",
|
||||
"l10n/**",
|
||||
"docs/**",
|
||||
"node_modules/**",
|
||||
"external/bcmaps/**",
|
||||
"external/builder/fixtures/**",
|
||||
"external/builder/fixtures_babel/**",
|
||||
"external/quickjs/**",
|
||||
"test/tmp/**",
|
||||
"test/pdfs/**",
|
||||
"web/locale/**",
|
||||
"*~/**",
|
||||
],
|
||||
};
|
||||
10
.travis.yml
Normal file
10
.travis.yml
Normal file
@ -0,0 +1,10 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- lts/*
|
||||
cache:
|
||||
directories:
|
||||
- node_modules
|
||||
install:
|
||||
- npm install -g npm@latest
|
||||
- npm install -g gulp-cli
|
||||
- npm install
|
||||
5
AUTHORS
5
AUTHORS
@ -8,21 +8,16 @@ Andreas Gal <gal@mozilla.com>
|
||||
Artur Adib <aadib@mozilla.com>
|
||||
Brendan Dahl <bdahl@mozilla.com>
|
||||
Bill Walker <bwalker@mozilla.com>
|
||||
Calixte Denizet <calixte@mozilla.com>
|
||||
Chris G Jones <cjones@mozilla.com>
|
||||
David Quintana <gigaherz@gmail.com>
|
||||
Emily Wachowiak <ewachowiak@mozilla.com>
|
||||
Felix Kälberer <@fkaelberer>
|
||||
Jakob Miland <saebekassebil@gmail.com>
|
||||
Jonas Jenwald <jonas.jenwald@gmail.com>
|
||||
Julian Viereck
|
||||
Justin D'Arcangelo <justindarc@gmail.com>
|
||||
Kalervo Kujala
|
||||
Marco Castelluccio <mcastelluccio@mozilla.com>
|
||||
Marie-Lilas Onanga Ozavino <monangaozavino@mozilla.com>
|
||||
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
|
||||
Ophir Lojkine <@lovasoa>
|
||||
Ryan Casey <rcasey@mozilla.com>
|
||||
Rob Wu <rob@robwu.nl>
|
||||
Shaon Barman <shaon.barman@gmail.com>
|
||||
Sehyun Park <premed055515@gmail.com>
|
||||
|
||||
44
README.md
44
README.md
@ -1,8 +1,8 @@
|
||||
# PDF.js [](https://github.com/mozilla/pdf.js/actions/workflows/ci.yml?query=branch%3Amaster)
|
||||
# PDF.js [](https://travis-ci.org/mozilla/pdf.js)
|
||||
|
||||
[PDF.js](https://mozilla.github.io/pdf.js/) is a Portable Document Format (PDF) viewer that is built with HTML5.
|
||||
|
||||
PDF.js is community-driven and supported by Mozilla. Our goal is to
|
||||
PDF.js is community-driven and supported by Mozilla Labs. Our goal is to
|
||||
create a general-purpose, web standards-based platform for parsing and
|
||||
rendering PDFs.
|
||||
|
||||
@ -14,7 +14,7 @@ get involved, visit:
|
||||
+ [Issue Reporting Guide](https://github.com/mozilla/pdf.js/blob/master/.github/CONTRIBUTING.md)
|
||||
+ [Code Contribution Guide](https://github.com/mozilla/pdf.js/wiki/Contributing)
|
||||
+ [Frequently Asked Questions](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions)
|
||||
+ [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?q=is%3Aissue%20state%3Aopen%20label%3Agood-beginner-bug)
|
||||
+ [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?direction=desc&labels=5-good-beginner-bug&page=1&sort=created&state=open)
|
||||
+ [Projects](https://github.com/mozilla/pdf.js/projects)
|
||||
|
||||
Feel free to stop by our [Matrix room](https://chat.mozilla.org/#/room/#pdfjs:mozilla.org) for questions or guidance.
|
||||
@ -23,12 +23,12 @@ Feel free to stop by our [Matrix room](https://chat.mozilla.org/#/room/#pdfjs:mo
|
||||
|
||||
### Online demo
|
||||
|
||||
Please note that the "Modern browsers" version assumes native support for the
|
||||
latest JavaScript features; please also see [this wiki page](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support).
|
||||
Please note that the "Modern browsers" version assumes native support for
|
||||
features such as e.g. `async`/`await`, `Promise`, and `ReadableStream`.
|
||||
|
||||
+ Modern browsers: https://mozilla.github.io/pdf.js/web/viewer.html
|
||||
|
||||
+ Older browsers: https://mozilla.github.io/pdf.js/legacy/web/viewer.html
|
||||
+ Older browsers: https://mozilla.github.io/pdf.js/es5/web/viewer.html
|
||||
|
||||
### Browser Extensions
|
||||
|
||||
@ -40,7 +40,7 @@ PDF.js is built into version 19+ of Firefox.
|
||||
|
||||
+ The official extension for Chrome can be installed from the [Chrome Web Store](https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm).
|
||||
*This extension is maintained by [@Rob--W](https://github.com/Rob--W).*
|
||||
+ Build Your Own - Get the code as explained below and issue `npx gulp chromium`. Then open
|
||||
+ Build Your Own - Get the code as explained below and issue `gulp chromium`. Then open
|
||||
Chrome, go to `Tools > Extension` and load the (unpackaged) extension from the
|
||||
directory `build/chromium`.
|
||||
|
||||
@ -52,21 +52,25 @@ To get a local copy of the current code, clone it using git:
|
||||
$ cd pdf.js
|
||||
|
||||
Next, install Node.js via the [official package](https://nodejs.org) or via
|
||||
[nvm](https://github.com/creationix/nvm). If everything worked out, install
|
||||
all dependencies for PDF.js:
|
||||
[nvm](https://github.com/creationix/nvm). You need to install the gulp package
|
||||
globally (see also [gulp's getting started](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md#getting-started)):
|
||||
|
||||
$ npm install -g gulp-cli
|
||||
|
||||
If everything worked out, install all dependencies for PDF.js:
|
||||
|
||||
$ npm install
|
||||
|
||||
Finally, you need to start a local web server as some browsers do not allow opening
|
||||
PDF files using a `file://` URL. Run:
|
||||
|
||||
$ npx gulp server
|
||||
$ gulp server
|
||||
|
||||
and then you can open:
|
||||
|
||||
+ http://localhost:8888/web/viewer.html
|
||||
|
||||
Please keep in mind that this assumes the latest version of Mozilla Firefox; refer to [Building PDF.js](https://github.com/mozilla/pdf.js/blob/master/README.md#building-pdfjs) for non-development usage of the PDF.js library.
|
||||
Please keep in mind that this requires an ES6 compatible browser; refer to [Building PDF.js](https://github.com/mozilla/pdf.js/blob/master/README.md#building-pdfjs) for usage with older browsers.
|
||||
|
||||
It is also possible to view all test PDF files on the right side by opening:
|
||||
|
||||
@ -77,20 +81,16 @@ It is also possible to view all test PDF files on the right side by opening:
|
||||
In order to bundle all `src/` files into two production scripts and build the generic
|
||||
viewer, run:
|
||||
|
||||
$ npx gulp generic
|
||||
$ gulp generic
|
||||
|
||||
If you need to support older browsers, run:
|
||||
|
||||
$ npx gulp generic-legacy
|
||||
|
||||
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory (respectively `build/generic-legacy/build/`).
|
||||
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory.
|
||||
Both scripts are needed but only `pdf.js` needs to be included since `pdf.worker.js` will
|
||||
be loaded by `pdf.js`. The PDF.js files are large and should be minified for production.
|
||||
|
||||
## Using PDF.js in a web application
|
||||
|
||||
To use PDF.js in a web application you can choose to use a pre-built version of the library
|
||||
or to build it from source. We supply pre-built versions for usage with NPM under
|
||||
or to build it from source. We supply pre-built versions for usage with NPM and Bower under
|
||||
the `pdfjs-dist` name. For more information and examples please refer to the
|
||||
[wiki page](https://github.com/mozilla/pdf.js/wiki/Setup-pdf.js-in-a-website) on this subject.
|
||||
|
||||
@ -107,7 +107,7 @@ You can play with the PDF.js API directly from your browser using the live demos
|
||||
|
||||
+ [Interactive examples](https://mozilla.github.io/pdf.js/examples/index.html#interactive-examples)
|
||||
|
||||
More examples can be found in the [examples folder](https://github.com/mozilla/pdf.js/tree/master/examples/). Some of them are using the pdfjs-dist package, which can be built and installed in this repo directory via `npx gulp dist-install` command.
|
||||
More examples can be found in the [examples folder](https://github.com/mozilla/pdf.js/tree/master/examples/). Some of them are using the pdfjs-dist package, which can be built and installed in this repo directory via `gulp dist-install` command.
|
||||
|
||||
For an introduction to the PDF.js code, check out the presentation by our
|
||||
contributor Julian Viereck:
|
||||
@ -134,4 +134,8 @@ Talk to us on Matrix:
|
||||
|
||||
File an issue:
|
||||
|
||||
+ https://github.com/mozilla/pdf.js/issues/new/choose
|
||||
+ https://github.com/mozilla/pdf.js/issues/new
|
||||
|
||||
Follow us on twitter: @pdfjs
|
||||
|
||||
+ https://twitter.com/pdfjs
|
||||
|
||||
20
docs/config.json
Normal file
20
docs/config.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"locals": {
|
||||
"url": "http://localhost:8080",
|
||||
"name": "PDF.js Documentation",
|
||||
"description": ""
|
||||
},
|
||||
"require": {
|
||||
"typogr": "typogr"
|
||||
},
|
||||
"jade": {
|
||||
"pretty": true
|
||||
},
|
||||
"markdown": {
|
||||
"smartLists": true,
|
||||
"smartypants": true
|
||||
},
|
||||
"plugins": [
|
||||
"./plugins/wintersmith-makerelative.coffee"
|
||||
]
|
||||
}
|
||||
@ -1,11 +1,8 @@
|
||||
---
|
||||
title: API
|
||||
layout: layout.njk
|
||||
slug: api
|
||||
template: layout.jade
|
||||
---
|
||||
|
||||
# API
|
||||
|
||||
The generated API documentation, from the inline comments in [api.js](https://github.com/mozilla/pdf.js/blob/master/src/display/api.js), is available below.
|
||||
|
||||
<iframe src="draft/index.html" title="PDF.js API documentation"></iframe>
|
||||
We're currently working on <a href="draft/index.html">better API docs</a>, but the API is well documented in [api.js](https://github.com/mozilla/pdf.js/blob/master/src/display/api.js).
|
||||
|
||||
@ -1,100 +0,0 @@
|
||||
/*!
|
||||
Theme: a11y-light
|
||||
Author: @ericwbailey
|
||||
Maintainer: @ericwbailey
|
||||
|
||||
Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css
|
||||
|
||||
Original source: https://github.com/highlightjs/highlight.js/blob/main/src/styles/a11y-light.css
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
background: #fefefe;
|
||||
color: #545454;
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #696969;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class,
|
||||
.hljs-regexp,
|
||||
.hljs-deletion {
|
||||
color: #d91e18;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-built_in,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params,
|
||||
.hljs-meta,
|
||||
.hljs-link {
|
||||
color: #aa5d00;
|
||||
}
|
||||
|
||||
/* Yellow */
|
||||
.hljs-attribute {
|
||||
color: #aa5d00;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet,
|
||||
.hljs-addition {
|
||||
color: #008000;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #007faa;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #7928a1;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
@media screen and (-ms-high-contrast: active) {
|
||||
.hljs-addition,
|
||||
.hljs-attribute,
|
||||
.hljs-built_in,
|
||||
.hljs-bullet,
|
||||
.hljs-comment,
|
||||
.hljs-link,
|
||||
.hljs-literal,
|
||||
.hljs-meta,
|
||||
.hljs-number,
|
||||
.hljs-params,
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-type,
|
||||
.hljs-quote {
|
||||
color: highlight;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
10
docs/contents/css/bootstrap.min.css
vendored
10
docs/contents/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
@ -1,40 +1,119 @@
|
||||
header {
|
||||
background-color: #f8f8f8;
|
||||
border-bottom: 1px solid #e5e7e8;
|
||||
|
||||
.navbar-brand {
|
||||
padding: 0;
|
||||
|
||||
img {
|
||||
height: 42px;
|
||||
}
|
||||
}
|
||||
body {
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 50px 0;
|
||||
|
||||
.description {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
pre {
|
||||
background-color: #f5f5f5;
|
||||
border: 1px solid #cccccc;
|
||||
border-radius: 4px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
iframe {
|
||||
border: none;
|
||||
height: calc(0.55 * 100vh);
|
||||
width: 100%;
|
||||
}
|
||||
.starter-template {
|
||||
padding: 0 15px;
|
||||
}
|
||||
.navbar-brand {
|
||||
padding: 4px 15px;
|
||||
}
|
||||
.navbar-brand img {
|
||||
height: 42px;
|
||||
}
|
||||
.navbar {
|
||||
border-color: #e5e7e8;
|
||||
}
|
||||
.navbar-default .navbar-nav > .active > a,
|
||||
.navbar-default .navbar-nav > .active > a:hover,
|
||||
.navbar-default .navbar-nav > .active > a:focus {
|
||||
background-color: #fff;
|
||||
border: 1px solid #e5e7e8;
|
||||
border-width: 0 1px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
|
||||
footer {
|
||||
border-top: 1px solid #e5e5e5;
|
||||
color: #777777;
|
||||
padding: 40px 0;
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px;
|
||||
margin-top: 100px;
|
||||
color: #777;
|
||||
text-align: center;
|
||||
border-top: 1px solid #E5E5E5;
|
||||
}
|
||||
|
||||
/* code styling */
|
||||
|
||||
code {
|
||||
font-family: 'Anonymous Pro', monospace;
|
||||
font-size: 0.85em;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
pre code {
|
||||
display: block;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
p code {
|
||||
padding: 0.1em 0.3em 0.2em;
|
||||
border-radius: 0.3em;
|
||||
position: relative;
|
||||
top: -0.15em;
|
||||
background: #444;
|
||||
color: #fff;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* syntax hl stuff */
|
||||
|
||||
code.lang-markdown {
|
||||
color: #424242;
|
||||
}
|
||||
|
||||
code.lang-markdown .header,
|
||||
code.lang-markdown .strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
code.lang-markdown .emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
code.lang-markdown .horizontal_rule,
|
||||
code.lang-markdown .link_label,
|
||||
code.lang-markdown .code,
|
||||
code.lang-markdown .header,
|
||||
code.lang-markdown .link_url {
|
||||
color: #555;
|
||||
}
|
||||
|
||||
code.lang-markdown .blockquote,
|
||||
code.lang-markdown .bullet {
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
/* Tomorrow Theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
.tomorrow-comment, pre .comment, pre .title {
|
||||
color: #8e908c;
|
||||
}
|
||||
|
||||
.tomorrow-red, pre .variable, pre .attribute, pre .tag, pre .regexp, pre .ruby .constant, pre .xml .tag .title, pre .xml .pi, pre .xml .doctype, pre .html .doctype, pre .css .id, pre .css .class, pre .css .pseudo {
|
||||
color: #c82829;
|
||||
}
|
||||
|
||||
.tomorrow-orange, pre .number, pre .preprocessor, pre .built_in, pre .literal, pre .params, pre .constant {
|
||||
color: #f5871f;
|
||||
}
|
||||
|
||||
.tomorrow-yellow, pre .class, pre .ruby .class .title, pre .css .rules .attribute {
|
||||
color: #eab700;
|
||||
}
|
||||
|
||||
.tomorrow-green, pre .string, pre .value, pre .inheritance, pre .header, pre .ruby .symbol, pre .xml .cdata {
|
||||
color: #718c00;
|
||||
}
|
||||
|
||||
.tomorrow-aqua, pre .css .hexcolor {
|
||||
color: #3e999f;
|
||||
}
|
||||
|
||||
.tomorrow-blue, pre .function, pre .python .decorator, pre .python .title, pre .ruby .function .title, pre .ruby .title .keyword, pre .perl .sub, pre .javascript .title, pre .coffeescript .title {
|
||||
color: #4271ae;
|
||||
}
|
||||
|
||||
.tomorrow-purple, pre .keyword, pre .javascript .function {
|
||||
color: #8959a8;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Examples
|
||||
layout: layout.njk
|
||||
slug: examples
|
||||
template: layout.jade
|
||||
---
|
||||
|
||||
## Hello World Walkthrough
|
||||
@ -45,24 +44,14 @@ Each PDF page has its own viewport which defines the size in pixels(72DPI) and i
|
||||
```js
|
||||
var scale = 1.5;
|
||||
var viewport = page.getViewport({ scale: scale, });
|
||||
// Support HiDPI-screens.
|
||||
var outputScale = window.devicePixelRatio || 1;
|
||||
|
||||
var canvas = document.getElementById('the-canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
|
||||
canvas.width = Math.floor(viewport.width * outputScale);
|
||||
canvas.height = Math.floor(viewport.height * outputScale);
|
||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
||||
|
||||
var transform = outputScale !== 1
|
||||
? [outputScale, 0, 0, outputScale, 0, 0]
|
||||
: null;
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
var renderContext = {
|
||||
canvasContext: context,
|
||||
transform: transform,
|
||||
viewport: viewport
|
||||
};
|
||||
page.render(renderContext);
|
||||
@ -82,19 +71,19 @@ var scaledViewport = page.getViewport({ scale: scale, });
|
||||
### Hello World with document load error handling
|
||||
|
||||
The example demonstrates how promises can be used to handle errors during loading.
|
||||
It also demonstrates how to wait until a page is loaded and rendered.
|
||||
It also demonstrates how to wait until page loaded and rendered.
|
||||
|
||||
<script async src="https://jsfiddle.net/pdfjs/9engc9mw/embed/html,css,result/"></script>
|
||||
<script async src="//jsfiddle.net/pdfjs/9engc9mw/embed/js,html,css,result/"></script>
|
||||
|
||||
### Hello World using base64 encoded PDF
|
||||
|
||||
The PDF.js can accept any decoded base64 data as an array.
|
||||
|
||||
<script async src="https://jsfiddle.net/pdfjs/cq0asLqz/embed/html,css,result/"></script>
|
||||
<script async src="//jsfiddle.net/pdfjs/cq0asLqz/embed/js,html,css,result/"></script>
|
||||
|
||||
### Previous/Next example
|
||||
|
||||
The same canvas cannot be used to perform to draw two pages at the same time --
|
||||
the example demonstrates how to wait on previous operation to be complete.
|
||||
|
||||
<script async src="https://jsfiddle.net/pdfjs/wagvs9Lf/embed/html,css,result/"></script>
|
||||
<script async src="//jsfiddle.net/pdfjs/wagvs9Lf/embed/js,html,css,result/"></script>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
---
|
||||
title: Getting Started
|
||||
layout: layout.njk
|
||||
slug: getting_started
|
||||
template: layout.jade
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
@ -38,22 +37,25 @@ Before downloading PDF.js please take a moment to understand the different layer
|
||||
|
||||
## Download
|
||||
|
||||
Please refer to [this wiki page](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support) for information about supported browsers.
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h3>Prebuilt (modern browsers)</h3>
|
||||
<h3>Prebuilt</h3>
|
||||
<p>
|
||||
Includes the generic build of PDF.js and the viewer.
|
||||
</p>
|
||||
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-dist.zip">Stable (vSTABLE_VERSION)</a>
|
||||
<span class="GROUP_CLASS">
|
||||
<a type="button" class="btn btn-warning HIDDEN_CLASS" href="https://github.com/mozilla/pdf.js/releases/download/vBETA_VERSION/pdfjs-BETA_VERSION-dist.zip">Beta (vBETA_VERSION)</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h3>Prebuilt (older browsers)</h3>
|
||||
<h3>Prebuilt (ES5-compatible)</h3>
|
||||
<p>
|
||||
Includes the generic build of PDF.js and the viewer.
|
||||
</p>
|
||||
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-legacy-dist.zip">Stable (vSTABLE_VERSION)</a>
|
||||
<span class="GROUP_CLASS">
|
||||
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-dist.zip">Stable (vSTABLE_VERSION)</a>
|
||||
<a type="button" class="btn btn-warning HIDDEN_CLASS" href="https://github.com/mozilla/pdf.js/releases/download/vBETA_VERSION/pdfjs-BETA_VERSION-es5-dist.zip">Beta (vBETA_VERSION)</a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<h3>Source</h3>
|
||||
@ -77,50 +79,52 @@ Note that we only mention the most relevant files and folders.
|
||||
|
||||
### Prebuilt
|
||||
|
||||
```plaintext
|
||||
```
|
||||
├── build/
|
||||
│ ├── pdf.mjs - display layer
|
||||
│ ├── pdf.mjs.map - display layer's source map
|
||||
│ ├── pdf.worker.mjs - core layer
|
||||
│ └── pdf.worker.mjs.map - core layer's source map
|
||||
│ ├── pdf.js - display layer
|
||||
│ ├── pdf.js.map - display layer's source map
|
||||
│ ├── pdf.worker.js - core layer
|
||||
│ └── pdf.worker.js.map - core layer's source map
|
||||
├── web/
|
||||
│ ├── cmaps/ - character maps (required by core)
|
||||
│ ├── compressed.tracemonkey-pldi-09.pdf - PDF file for testing purposes
|
||||
│ ├── debugger.js - helpful debugging features
|
||||
│ ├── images/ - images for the viewer and annotation icons
|
||||
│ ├── locale/ - translation files
|
||||
│ ├── viewer.css - viewer style sheet
|
||||
│ ├── viewer.html - viewer layout
|
||||
│ ├── viewer.mjs - viewer layer
|
||||
│ └── viewer.mjs.map - viewer layer's source map
|
||||
│ ├── viewer.js - viewer layer
|
||||
│ └── viewer.js.map - viewer layer's source map
|
||||
└── LICENSE
|
||||
```
|
||||
|
||||
### Source
|
||||
|
||||
```plaintext
|
||||
```
|
||||
├── docs/ - website source code
|
||||
├── examples/ - simple usage examples
|
||||
├── extensions/ - browser extension source code
|
||||
├── external/ - third party code
|
||||
├── l10n/ - translation files
|
||||
├── src/
|
||||
│ ├── core/ - core layer
|
||||
│ ├── display/ - display layer
|
||||
│ ├── shared/ - shared code between the core and display layers
|
||||
│ ├── interfaces.js - interface definitions for the core/display layers
|
||||
│ └── pdf.*.js - wrapper files for bundling
|
||||
├── test/ - unit, font, reference, and integration tests
|
||||
│ ├── core/ - core layer
|
||||
│ ├── display/ - display layer
|
||||
│ ├── shared/ - shared code between the core and display layers
|
||||
│ ├── interfaces.js - interface definitions for the core/display layers
|
||||
│ ├── pdf.*.js - wrapper files for bundling
|
||||
│ └── worker_loader.js - used for developer builds to load worker files
|
||||
├── test/ - unit, font and reference tests
|
||||
├── web/ - viewer layer
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
├── gulpfile.mjs - build scripts/logic
|
||||
├── gulpfile.js - build scripts/logic
|
||||
├── package-lock.json - pinned dependency versions
|
||||
└── package.json - package definition and dependencies
|
||||
```
|
||||
|
||||
## Trying the Viewer
|
||||
|
||||
With the prebuilt or source version, open `web/viewer.html` in a browser and the test pdf should load. Note: the worker is not enabled for file:// urls, so use a server. If you're using the source build and have node, you can run `npx gulp server`.
|
||||
With the prebuilt or source version, open `web/viewer.html` in a browser and the test pdf should load. Note: the worker is not enabled for file:// urls, so use a server. If you're using the source build and have node, you can run `gulp server`.
|
||||
|
||||
## More Information
|
||||
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
---
|
||||
title: Home
|
||||
layout: layout.njk
|
||||
slug: home
|
||||
title: PDF.js
|
||||
template: layout.jade
|
||||
---
|
||||
|
||||
|
||||
<h1 class="text-center">PDF.js</h1>
|
||||
<p class="text-center description">A general-purpose, web standards-based platform for parsing and rendering PDFs.</p>
|
||||
<p class="text-center">
|
||||
<a type="button" class="btn btn-outline-dark" href="/getting_started/#download">Download</a>
|
||||
<a type="button" class="btn btn-outline-dark" href="https://github.com/mozilla/pdf.js#online-demo">Demo</a>
|
||||
<a type="button" class="btn btn-outline-dark" href="https://github.com/mozilla/pdf.js">GitHub Project</a>
|
||||
<p class="text-center" style="font-size: 20px">A general-purpose, web standards-based platform for parsing and rendering PDFs.
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<a type="button" class="btn btn-lg btn-default" href="getting_started/#download">Download</a>
|
||||
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js#online-demo">Demo</a>
|
||||
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js">GitHub Project</a>
|
||||
</p>
|
||||
|
||||
11
docs/contents/js/bootstrap.min.js
vendored
11
docs/contents/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
4
docs/contents/js/jquery-2.1.0.min.js
vendored
Normal file
4
docs/contents/js/jquery-2.1.0.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
2
docs/contents/js/jquery-3.7.1.min.js
vendored
2
docs/contents/js/jquery-3.7.1.min.js
vendored
File diff suppressed because one or more lines are too long
15
docs/plugins/wintersmith-makerelative.coffee
Normal file
15
docs/plugins/wintersmith-makerelative.coffee
Normal file
@ -0,0 +1,15 @@
|
||||
module.exports = (env, callback) ->
|
||||
count = (string, substr) ->
|
||||
num = pos = 0
|
||||
return 1/0 unless substr.length
|
||||
num++ while pos = 1 + string.indexOf(substr, pos)
|
||||
num
|
||||
|
||||
env.helpers.makeRelative = (source, dest) ->
|
||||
return dest unless dest.indexOf("/") == 0
|
||||
depth = count(source, '/') # 1 being /
|
||||
ret = ""
|
||||
ret += "../" while depth = depth - 1
|
||||
ret + dest.substring(1)
|
||||
|
||||
callback()
|
||||
52
docs/templates/layout.jade
vendored
Normal file
52
docs/templates/layout.jade
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
- makeRelative = env.helpers.makeRelative
|
||||
doctype html
|
||||
html(lang='en')
|
||||
head
|
||||
meta(charset='utf-8')
|
||||
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
||||
meta(name='description', content='A general-purpose, web standards-based platform for parsing and rendering PDFs.')
|
||||
meta(name='author', content='')
|
||||
link(rel='shortcut icon', href=makeRelative(page.url, '/images/favicon.ico'))
|
||||
title=page.title
|
||||
// Bootstrap core CSS
|
||||
link(href=makeRelative(page.url, '/css/bootstrap.min.css'), rel='stylesheet')
|
||||
// Custom styles for this template
|
||||
link(href=makeRelative(page.url, '/css/main.css'), rel='stylesheet')
|
||||
|
||||
body
|
||||
header.navbar.navbar-default.navbar-static-top
|
||||
.container
|
||||
.navbar-header
|
||||
button.navbar-toggle(type='button', data-toggle='collapse', data-target='.navbar-collapse')
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
span.icon-bar
|
||||
a.navbar-brand(href='#')
|
||||
img(src=makeRelative(page.url, '/images/logo.svg'))
|
||||
.collapse.navbar-collapse
|
||||
ul.nav.navbar-nav
|
||||
li(class=(page.url === '/' ? 'active' : ''))
|
||||
a(href=makeRelative(page.url, '/')) Home
|
||||
li(class=(page.url === '/getting_started/' ? 'active' : ''))
|
||||
a(href=makeRelative(page.url, '/getting_started/')) Getting Started
|
||||
li(class=(page.url === '/examples/' ? 'active' : ''))
|
||||
a(href=makeRelative(page.url, '/examples/')) Examples
|
||||
li
|
||||
a(href='https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions') FAQ
|
||||
li(class=(page.url === '/api/' ? 'active' : ''))
|
||||
a(href=makeRelative(page.url, '/api/')) API
|
||||
|
||||
.container
|
||||
.starter-template
|
||||
section.content!= typogr(page.html).typogrify()
|
||||
|
||||
.container
|
||||
footer
|
||||
p ©Mozilla and individual contributors
|
||||
:markdown-it
|
||||
PDF.js is licensed under [Apache](https://github.com/mozilla/pdf.js/blob/master/LICENSE),
|
||||
documentation is licensed under [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/)
|
||||
|
||||
// Bootstrap core JavaScript
|
||||
script(src=makeRelative(page.url, '/js/jquery-2.1.0.min.js'))
|
||||
script(src=makeRelative(page.url, '/js/bootstrap.min.js'))
|
||||
56
docs/templates/layout.njk
vendored
56
docs/templates/layout.njk
vendored
@ -1,56 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>{{ sitename }} - {{ title }}</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="description" content="{{ description }}">
|
||||
<meta name="viewport" content="device-width, initial-scale=1.0">
|
||||
<script src="/js/jquery-3.7.1.min.js"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<link rel="shortcut icon" href="/images/favicon.ico">
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/css/a11y-light.css">
|
||||
<link rel="stylesheet" href="/css/main.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-lg navbar-light bg-light">
|
||||
<div class="container">
|
||||
<div class="navbar-brand"><img src="/images/logo.svg"></div>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
<li class="nav-item {{ 'active' if slug == 'home' else '' }}">
|
||||
<a class="nav-link" href="/">Home</a>
|
||||
</li>
|
||||
<li class="nav-item {{ 'active' if slug == 'getting_started' else '' }}">
|
||||
<a class="nav-link" href="/getting_started">Getting started</a>
|
||||
</li>
|
||||
<li class="nav-item {{ 'active' if slug == 'examples' else '' }}">
|
||||
<a class="nav-link" href="/examples">Examples</a>
|
||||
</li>
|
||||
<li class="nav-item {{ 'active' if slug == 'api' else '' }}">
|
||||
<a class="nav-link" href="/api">API</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions">FAQ</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="container">
|
||||
{{ contents | safe }}
|
||||
</main>
|
||||
<footer>
|
||||
<p>© Mozilla and individual contributors</p>
|
||||
<p>
|
||||
PDF.js is licensed under <a href="https://github.com/mozilla/pdf.js/blob/master/LICENSE">Apache 2.0</a>,
|
||||
documentation is licensed under <a href="https://creativecommons.org/licenses/by-sa/2.5">CC BY-SA 2.5</a>.
|
||||
</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@ -1,473 +0,0 @@
|
||||
import globals from "globals";
|
||||
|
||||
import import_ from "eslint-plugin-import";
|
||||
import jasmine from "eslint-plugin-jasmine";
|
||||
import json from "eslint-plugin-json";
|
||||
import noUnsanitized from "eslint-plugin-no-unsanitized";
|
||||
import perfectionist from "eslint-plugin-perfectionist";
|
||||
import prettierRecommended from "eslint-plugin-prettier/recommended";
|
||||
import unicorn from "eslint-plugin-unicorn";
|
||||
|
||||
const jsFiles = folder => {
|
||||
const prefix = folder === "." ? "" : folder + "/";
|
||||
return [prefix + "**/*.js", prefix + "**/*.jsm", prefix + "**/*.mjs"];
|
||||
};
|
||||
|
||||
// Include all files referenced in extensions/chromium/background.js
|
||||
const chromiumExtensionServiceWorkerFiles = [
|
||||
"extensions/chromium/extension-router.js",
|
||||
"extensions/chromium/options/migration.js",
|
||||
"extensions/chromium/pdfHandler.js",
|
||||
"extensions/chromium/preserve-referer.js",
|
||||
"extensions/chromium/suppress-update.js",
|
||||
"extensions/chromium/telemetry.js",
|
||||
];
|
||||
|
||||
export default [
|
||||
{
|
||||
ignores: [
|
||||
"**/build/",
|
||||
"**/l10n/",
|
||||
"**/docs/",
|
||||
"**/node_modules/",
|
||||
"external/bcmaps/",
|
||||
"external/builder/fixtures/",
|
||||
"external/builder/fixtures_babel/",
|
||||
"external/openjpeg/",
|
||||
"external/qcms/",
|
||||
"external/quickjs/",
|
||||
"test/stats/results/",
|
||||
"test/tmp/",
|
||||
"test/pdfs/",
|
||||
"web/locale/",
|
||||
"web/wasm/",
|
||||
"**/*~/",
|
||||
],
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
Base configuration
|
||||
\* ======================================================================== */
|
||||
|
||||
prettierRecommended,
|
||||
{
|
||||
files: ["**/*.json"],
|
||||
...json.configs.recommended,
|
||||
},
|
||||
{
|
||||
files: jsFiles("."),
|
||||
ignores: chromiumExtensionServiceWorkerFiles,
|
||||
languageOptions: {
|
||||
globals: globals.browser,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: jsFiles("."),
|
||||
|
||||
plugins: {
|
||||
import: import_.flatConfigs.recommended.plugins.import,
|
||||
json,
|
||||
"no-unsanitized": noUnsanitized,
|
||||
perfectionist,
|
||||
unicorn,
|
||||
},
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.worker,
|
||||
PDFJSDev: "readonly",
|
||||
__raw_import__: "readonly",
|
||||
},
|
||||
|
||||
ecmaVersion: 2025,
|
||||
sourceType: "module",
|
||||
},
|
||||
|
||||
rules: {
|
||||
"import/export": "error",
|
||||
"import/exports-last": "error",
|
||||
"import/extensions": ["error", "always", { ignorePackages: true }],
|
||||
"import/first": "error",
|
||||
"import/named": "error",
|
||||
"import/no-cycle": "error",
|
||||
"import/no-empty-named-blocks": "error",
|
||||
"import/no-commonjs": "error",
|
||||
"import/no-mutable-exports": "error",
|
||||
"import/no-restricted-paths": [
|
||||
"error",
|
||||
{
|
||||
zones: [
|
||||
{
|
||||
target: "./web",
|
||||
from: "./src",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
"import/no-self-import": "error",
|
||||
"import/no-unresolved": [
|
||||
"error",
|
||||
{
|
||||
ignore: [
|
||||
"display",
|
||||
"pdfjs",
|
||||
"pdfjs-lib",
|
||||
"pdfjs-web",
|
||||
"web",
|
||||
"fluent-bundle",
|
||||
"fluent-dom",
|
||||
// See https://github.com/firebase/firebase-admin-node/discussions/1359.
|
||||
"eslint-plugin-perfectionist",
|
||||
],
|
||||
},
|
||||
],
|
||||
"no-unsanitized/method": "error",
|
||||
"no-unsanitized/property": "error",
|
||||
"perfectionist/sort-exports": "error",
|
||||
"perfectionist/sort-named-exports": "error",
|
||||
"unicorn/no-abusive-eslint-disable": "error",
|
||||
"unicorn/no-array-reduce": ["error", { allowSimpleOperations: true }],
|
||||
"unicorn/no-console-spaces": "error",
|
||||
"unicorn/no-instanceof-builtins": "error",
|
||||
"unicorn/no-invalid-remove-event-listener": "error",
|
||||
"unicorn/no-new-buffer": "error",
|
||||
"unicorn/no-single-promise-in-promise-methods": "error",
|
||||
"unicorn/no-typeof-undefined": ["error", { checkGlobalVariables: false }],
|
||||
"unicorn/no-unnecessary-array-flat-depth": "error",
|
||||
"unicorn/no-unnecessary-array-splice-count": "error",
|
||||
"unicorn/no-unnecessary-slice-end": "error",
|
||||
"unicorn/no-useless-promise-resolve-reject": "error",
|
||||
"unicorn/no-useless-spread": "error",
|
||||
"unicorn/prefer-array-find": "error",
|
||||
"unicorn/prefer-array-flat": "error",
|
||||
"unicorn/prefer-array-flat-map": "error",
|
||||
"unicorn/prefer-array-index-of": "error",
|
||||
"unicorn/prefer-array-some": "error",
|
||||
"unicorn/prefer-at": "error",
|
||||
"unicorn/prefer-date-now": "error",
|
||||
"unicorn/prefer-dom-node-append": "error",
|
||||
"unicorn/prefer-dom-node-remove": "error",
|
||||
"unicorn/prefer-import-meta-properties": "error",
|
||||
"unicorn/prefer-includes": "error",
|
||||
"unicorn/prefer-logical-operator-over-ternary": "error",
|
||||
"unicorn/prefer-modern-dom-apis": "error",
|
||||
"unicorn/prefer-modern-math-apis": "error",
|
||||
"unicorn/prefer-negative-index": "error",
|
||||
"unicorn/prefer-optional-catch-binding": "error",
|
||||
"unicorn/prefer-regexp-test": "error",
|
||||
"unicorn/prefer-single-call": "error",
|
||||
"unicorn/prefer-string-replace-all": "error",
|
||||
"unicorn/prefer-string-starts-ends-with": "error",
|
||||
"unicorn/prefer-ternary": ["error", "only-single-line"],
|
||||
"unicorn/throw-new-error": "error",
|
||||
|
||||
// Possible errors
|
||||
"for-direction": "error",
|
||||
"getter-return": "error",
|
||||
"no-async-promise-executor": "error",
|
||||
"no-cond-assign": ["error", "except-parens"],
|
||||
"no-constant-condition": ["error", { checkLoops: false }],
|
||||
"no-debugger": "error",
|
||||
"no-dupe-args": "error",
|
||||
"no-dupe-else-if": "error",
|
||||
"no-dupe-keys": "error",
|
||||
"no-duplicate-case": "error",
|
||||
"no-empty": ["error", { allowEmptyCatch: true }],
|
||||
"no-empty-character-class": "error",
|
||||
"no-ex-assign": "error",
|
||||
"no-extra-boolean-cast": "error",
|
||||
"no-func-assign": "error",
|
||||
"no-inner-declarations": ["error", "functions"],
|
||||
"no-invalid-regexp": "error",
|
||||
"no-irregular-whitespace": "error",
|
||||
"no-loss-of-precision": "error",
|
||||
"no-obj-calls": "error",
|
||||
"no-promise-executor-return": "error",
|
||||
"no-regex-spaces": "error",
|
||||
"no-setter-return": "error",
|
||||
"no-sparse-arrays": "error",
|
||||
"no-template-curly-in-string": "error",
|
||||
"no-unexpected-multiline": "error",
|
||||
"no-unreachable": "error",
|
||||
"no-unsafe-finally": "error",
|
||||
"no-unsafe-negation": "error",
|
||||
"no-unsafe-optional-chaining": [
|
||||
"error",
|
||||
{ disallowArithmeticOperators: true },
|
||||
],
|
||||
"no-unused-private-class-members": "error",
|
||||
"use-isnan": ["error", { enforceForIndexOf: true }],
|
||||
"valid-typeof": ["error", { requireStringLiterals: true }],
|
||||
|
||||
// Best Practices
|
||||
"accessor-pairs": [
|
||||
"error",
|
||||
{ setWithoutGet: true, enforceForClassMembers: true },
|
||||
],
|
||||
"consistent-return": "error",
|
||||
curly: ["error", "all"],
|
||||
"default-case-last": "error",
|
||||
"dot-notation": "error",
|
||||
eqeqeq: ["error", "always"],
|
||||
"grouped-accessor-pairs": ["error", "getBeforeSet"],
|
||||
"no-alert": "error",
|
||||
"no-caller": "error",
|
||||
"no-else-return": "error",
|
||||
"no-empty-pattern": "error",
|
||||
"no-eval": "error",
|
||||
"no-extend-native": "error",
|
||||
"no-extra-bind": "error",
|
||||
"no-extra-label": "error",
|
||||
"no-fallthrough": "error",
|
||||
"no-floating-decimal": "error",
|
||||
"no-global-assign": "error",
|
||||
"no-implied-eval": "error",
|
||||
"no-iterator": "error",
|
||||
"no-lone-blocks": "error",
|
||||
"no-lonely-if": "error",
|
||||
"no-multi-str": "error",
|
||||
"no-new": "error",
|
||||
"no-new-func": "error",
|
||||
"no-new-symbol": "error",
|
||||
"no-new-wrappers": "error",
|
||||
"no-octal-escape": "error",
|
||||
"no-octal": "error",
|
||||
"no-redeclare": "error",
|
||||
"no-return-await": "error",
|
||||
"no-self-assign": "error",
|
||||
"no-self-compare": "error",
|
||||
"no-throw-literal": "error",
|
||||
"no-unused-expressions": "error",
|
||||
"no-unused-labels": "error",
|
||||
"no-useless-call": "error",
|
||||
"no-useless-catch": "error",
|
||||
"no-useless-concat": "error",
|
||||
"no-useless-escape": "error",
|
||||
"no-useless-return": "error",
|
||||
"prefer-promise-reject-errors": "error",
|
||||
"prefer-spread": "error",
|
||||
"wrap-iife": ["error", "any"],
|
||||
yoda: ["error", "never", { exceptRange: true }],
|
||||
|
||||
// Strict Mode
|
||||
strict: ["off", "global"],
|
||||
|
||||
// Variables
|
||||
"no-delete-var": "error",
|
||||
"no-label-var": "error",
|
||||
"no-shadow": "error",
|
||||
"no-shadow-restricted-names": "error",
|
||||
"no-undef-init": "error",
|
||||
"no-undef": ["error", { typeof: true }],
|
||||
"no-unused-vars": ["error", { vars: "all", args: "none" }],
|
||||
"no-use-before-define": [
|
||||
"error",
|
||||
{ functions: false, classes: false, variables: false },
|
||||
],
|
||||
|
||||
// Stylistic Issues
|
||||
"lines-between-class-members": ["error", "always"],
|
||||
"max-len": ["error", { code: 1000, comments: 80, ignoreUrls: true }],
|
||||
"new-cap": ["error", { newIsCap: true, capIsNew: false }],
|
||||
"no-array-constructor": "error",
|
||||
"no-multiple-empty-lines": ["error", { max: 1, maxEOF: 0, maxBOF: 1 }],
|
||||
"no-nested-ternary": "error",
|
||||
"no-new-object": "error",
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
selector:
|
||||
"BinaryExpression[operator='instanceof'][right.name='Object']",
|
||||
message: "Use `typeof` rather than `instanceof Object`.",
|
||||
},
|
||||
{
|
||||
selector: "CallExpression[callee.name='assert'][arguments.length!=2]",
|
||||
message: "`assert()` must always be invoked with two arguments.",
|
||||
},
|
||||
{
|
||||
selector: "CallExpression[callee.name='isCmd'][arguments.length<2]",
|
||||
message:
|
||||
"Use `instanceof Cmd` rather than `isCmd()` with one argument.",
|
||||
},
|
||||
{
|
||||
selector: "CallExpression[callee.name='isDict'][arguments.length<2]",
|
||||
message:
|
||||
"Use `instanceof Dict` rather than `isDict()` with one argument.",
|
||||
},
|
||||
{
|
||||
selector: "CallExpression[callee.name='isName'][arguments.length<2]",
|
||||
message:
|
||||
"Use `instanceof Name` rather than `isName()` with one argument.",
|
||||
},
|
||||
{
|
||||
selector: "NewExpression[callee.name='Cmd']",
|
||||
message: "Use `Cmd.get()` rather than `new Cmd()`.",
|
||||
},
|
||||
{
|
||||
selector: "NewExpression[callee.name='Name']",
|
||||
message: "Use `Name.get()` rather than `new Name()`.",
|
||||
},
|
||||
{
|
||||
selector: "NewExpression[callee.name='ObjectLoader']",
|
||||
message:
|
||||
"Use `ObjectLoader.load()` rather than `new ObjectLoader()`.",
|
||||
},
|
||||
{
|
||||
selector: "NewExpression[callee.name='Ref']",
|
||||
message: "Use `Ref.get()` rather than `new Ref()`.",
|
||||
},
|
||||
{
|
||||
selector: "ExportNamedDeclaration[declaration]",
|
||||
message:
|
||||
"Separate the declaration and the export statement, using `export { ... }`.",
|
||||
},
|
||||
{
|
||||
selector: "ExportDefaultDeclaration:has(> :declaration)",
|
||||
message:
|
||||
"Separate the declaration and the export statement, using `export default <variable name>`.",
|
||||
},
|
||||
],
|
||||
"no-unneeded-ternary": "error",
|
||||
"operator-assignment": "error",
|
||||
"prefer-exponentiation-operator": "error",
|
||||
"spaced-comment": ["error", "always", { block: { balanced: true } }],
|
||||
|
||||
// ECMAScript 6
|
||||
"arrow-body-style": ["error", "as-needed"],
|
||||
"constructor-super": "error",
|
||||
"no-class-assign": "error",
|
||||
"no-const-assign": "error",
|
||||
"no-dupe-class-members": "error",
|
||||
"no-duplicate-imports": "error",
|
||||
"no-this-before-super": "error",
|
||||
"no-useless-computed-key": "error",
|
||||
"no-useless-constructor": "error",
|
||||
"no-useless-rename": "error",
|
||||
"no-var": "error",
|
||||
"object-shorthand": ["error", "always", { avoidQuotes: true }],
|
||||
"prefer-const": "error",
|
||||
"require-yield": "error",
|
||||
"sort-imports": ["error", { ignoreCase: true }],
|
||||
"template-curly-spacing": ["error", "never"],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: jsFiles("src"),
|
||||
rules: {
|
||||
"no-console": "error",
|
||||
},
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
Test-specific rules
|
||||
\* ======================================================================== */
|
||||
|
||||
{
|
||||
files: jsFiles("test"),
|
||||
|
||||
plugins: { jasmine },
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.node,
|
||||
...globals.jasmine,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
...jasmine.configs.recommended.rules,
|
||||
"jasmine/new-line-before-expect": "off",
|
||||
"jasmine/new-line-between-declarations": "off",
|
||||
"jasmine/no-focused-tests": "error",
|
||||
"jasmine/no-pending-tests": "off",
|
||||
"jasmine/no-spec-dupes": ["error", "branch"],
|
||||
"jasmine/no-suite-dupes": ["error", "branch"],
|
||||
"jasmine/prefer-jasmine-matcher": "off",
|
||||
"jasmine/prefer-toHaveBeenCalledWith": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: jsFiles("test/unit"),
|
||||
rules: {
|
||||
"import/no-unresolved": ["error", { ignore: ["pdfjs/"] }],
|
||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: jsFiles("test/integration"),
|
||||
rules: {
|
||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
{
|
||||
selector: "CallExpression[callee.name='waitForTimeout']",
|
||||
message:
|
||||
"`waitForTimeout` can cause intermittent failures and should not be used (see issue #17656 for replacements).",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
External libraries
|
||||
\* ======================================================================== */
|
||||
|
||||
{
|
||||
files: jsFiles("external"),
|
||||
|
||||
languageOptions: { globals: globals.node },
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
Examples
|
||||
\* ======================================================================== */
|
||||
|
||||
{
|
||||
files: jsFiles("examples"),
|
||||
|
||||
languageOptions: {
|
||||
globals: {
|
||||
pdfjsImageDecoders: false,
|
||||
pdfjsLib: false,
|
||||
pdfjsViewer: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [...jsFiles("examples/node"), ...jsFiles("examples/webpack")],
|
||||
|
||||
languageOptions: { globals: globals.node },
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
Chromium extension
|
||||
\* ======================================================================== */
|
||||
|
||||
{
|
||||
files: jsFiles("extensions/chromium"),
|
||||
|
||||
languageOptions: {
|
||||
globals: globals.webextensions,
|
||||
sourceType: "script",
|
||||
},
|
||||
|
||||
rules: {
|
||||
"no-var": "off",
|
||||
},
|
||||
},
|
||||
{
|
||||
files: chromiumExtensionServiceWorkerFiles,
|
||||
|
||||
languageOptions: {
|
||||
globals: globals.serviceworker,
|
||||
sourceType: "script",
|
||||
},
|
||||
},
|
||||
|
||||
/* ======================================================================== *\
|
||||
Other
|
||||
\* ======================================================================== */
|
||||
{
|
||||
files: ["gulpfile.mjs"],
|
||||
languageOptions: { globals: globals.node },
|
||||
},
|
||||
];
|
||||
24
examples/.eslintrc
Normal file
24
examples/.eslintrc
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"extends": [
|
||||
"../.eslintrc"
|
||||
],
|
||||
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
},
|
||||
|
||||
"env": {
|
||||
"es6": false,
|
||||
},
|
||||
|
||||
"globals": {
|
||||
"pdfjsImageDecoders": false,
|
||||
"pdfjsLib": false,
|
||||
"pdfjsViewer": false,
|
||||
"Uint8Array": false,
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"object-shorthand": ["error", "never"]
|
||||
}
|
||||
}
|
||||
11
examples/acroforms/README.md
Normal file
11
examples/acroforms/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
## Overview
|
||||
|
||||
Example to demonstrate PDF.js library usage for rendering files with AcroForms.
|
||||
|
||||
## Getting started
|
||||
|
||||
Build and install PDF.js using `gulp dist-install` and run `gulp server` to
|
||||
start a web server. You can then work with the example at
|
||||
http://localhost:8888/examples/acroforms/acroforms.html.
|
||||
|
||||
Refer to `acroforms.js` for the source code of the example.
|
||||
44
examples/acroforms/acroforms.html
Normal file
44
examples/acroforms/acroforms.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2017 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<title>AcroForms example</title>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
.page {
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="pageContainer"></div>
|
||||
|
||||
<script src="acroforms.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
56
examples/acroforms/acroforms.js
Normal file
56
examples/acroforms/acroforms.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* Copyright 2017 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
var DEFAULT_URL = "../../test/pdfs/f1040.pdf";
|
||||
var DEFAULT_SCALE = 1.0;
|
||||
|
||||
var container = document.getElementById("pageContainer");
|
||||
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// Fetch the PDF document from the URL using promises.
|
||||
var loadingTask = pdfjsLib.getDocument(DEFAULT_URL);
|
||||
loadingTask.promise.then(function (doc) {
|
||||
// Use a promise to fetch and render the next page.
|
||||
var promise = Promise.resolve();
|
||||
|
||||
for (var i = 1; i <= doc.numPages; i++) {
|
||||
promise = promise.then(
|
||||
function (pageNum) {
|
||||
return doc.getPage(pageNum).then(function (pdfPage) {
|
||||
// Create the page view.
|
||||
var pdfPageView = new pdfjsViewer.PDFPageView({
|
||||
container: container,
|
||||
id: pageNum,
|
||||
scale: DEFAULT_SCALE,
|
||||
defaultViewport: pdfPage.getViewport({ scale: DEFAULT_SCALE }),
|
||||
eventBus: eventBus,
|
||||
annotationLayerFactory: new pdfjsViewer.DefaultAnnotationLayerFactory(),
|
||||
renderInteractiveForms: true,
|
||||
});
|
||||
|
||||
// Associate the actual page with the view and draw it.
|
||||
pdfPageView.setPdfPage(pdfPage);
|
||||
return pdfPageView.draw();
|
||||
});
|
||||
}.bind(null, i)
|
||||
);
|
||||
}
|
||||
});
|
||||
1
examples/browserify/.gitignore
vendored
Normal file
1
examples/browserify/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
node_modules/
|
||||
26
examples/browserify/README.md
Normal file
26
examples/browserify/README.md
Normal file
@ -0,0 +1,26 @@
|
||||
## Overview
|
||||
|
||||
Example to demonstrate PDF.js library usage with Browserify.
|
||||
|
||||
## Getting started
|
||||
|
||||
Build project and install the example dependencies:
|
||||
|
||||
$ gulp dist-install
|
||||
$ cd examples/browserify
|
||||
$ npm install
|
||||
|
||||
To build Browserify bundles, run `gulp build`. If you are running
|
||||
a web server, you can observe the build results at
|
||||
http://localhost:8888/examples/browserify/index.html
|
||||
|
||||
See main.js, worker.js and gulpfile.js files. Please notice that PDF.js
|
||||
packaging requires packaging of the main application and PDF.js worker code,
|
||||
and the `workerSrc` path shall be set to the latter file. The pdf.worker.js file
|
||||
shall be excluded from the main bundle.
|
||||
|
||||
Alternatives to the gulp commands (without compression) are:
|
||||
|
||||
$ mkdir -p ../../build/browserify
|
||||
$ node_modules/.bin/browserify main.js -u ./node_modules/pdfjs-dist/build/pdf.worker.js -o ../../build/browserify/main.bundle.js
|
||||
$ node_modules/.bin/browserify worker.js -o ../../build/browserify/pdf.worker.bundle.js
|
||||
40
examples/browserify/gulpfile.js
Normal file
40
examples/browserify/gulpfile.js
Normal file
@ -0,0 +1,40 @@
|
||||
var gulp = require("gulp");
|
||||
var browserify = require("browserify");
|
||||
var streamify = require("gulp-streamify");
|
||||
var rename = require("gulp-rename");
|
||||
var uglify = require("gulp-uglify");
|
||||
var source = require("vinyl-source-stream");
|
||||
|
||||
var OUTPUT_PATH = "../../build/browserify";
|
||||
var TMP_FILE_PREFIX = "../../build/browserify_";
|
||||
|
||||
gulp.task("build-bundle", function () {
|
||||
return browserify("main.js", { output: TMP_FILE_PREFIX + "main.tmp" })
|
||||
.ignore(require.resolve("pdfjs-dist/build/pdf.worker")) // Reducing size
|
||||
.bundle()
|
||||
.pipe(source(TMP_FILE_PREFIX + "main.tmp"))
|
||||
.pipe(streamify(uglify()))
|
||||
.pipe(rename("main.bundle.js"))
|
||||
.pipe(gulp.dest(OUTPUT_PATH));
|
||||
});
|
||||
|
||||
gulp.task("build-worker", function () {
|
||||
// We can create our own viewer (see worker.js) or use already defined one.
|
||||
var workerSrc = require.resolve("pdfjs-dist/build/pdf.worker.entry");
|
||||
return browserify(workerSrc, { output: TMP_FILE_PREFIX + "worker.tmp" })
|
||||
.bundle()
|
||||
.pipe(source(TMP_FILE_PREFIX + "worker.tmp"))
|
||||
.pipe(
|
||||
streamify(
|
||||
uglify({
|
||||
compress: {
|
||||
sequences: false, // Chrome has issue with the generated code if true
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(rename("pdf.worker.bundle.js"))
|
||||
.pipe(gulp.dest(OUTPUT_PATH));
|
||||
});
|
||||
|
||||
gulp.task("build", gulp.series("build-bundle", "build-worker"));
|
||||
11
examples/browserify/index.html
Normal file
11
examples/browserify/index.html
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>browserify example</title>
|
||||
<script src="../../build/browserify/main.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="theCanvas"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
35
examples/browserify/main.js
Normal file
35
examples/browserify/main.js
Normal file
@ -0,0 +1,35 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Hello world example for browserify.
|
||||
|
||||
var pdfjsLib = require("pdfjs-dist");
|
||||
|
||||
var pdfPath = "../learning/helloworld.pdf";
|
||||
|
||||
// Setting worker path to worker bundle.
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../build/browserify/pdf.worker.bundle.js";
|
||||
|
||||
// Loading a document.
|
||||
var loadingTask = pdfjsLib.getDocument(pdfPath);
|
||||
loadingTask.promise
|
||||
.then(function (pdfDocument) {
|
||||
// Request a first page
|
||||
return pdfDocument.getPage(1).then(function (pdfPage) {
|
||||
// Display page on the existing canvas with 100% scale.
|
||||
var viewport = pdfPage.getViewport({ scale: 1.0 });
|
||||
var canvas = document.getElementById("theCanvas");
|
||||
canvas.width = viewport.width;
|
||||
canvas.height = viewport.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
var renderTask = pdfPage.render({
|
||||
canvasContext: ctx,
|
||||
viewport: viewport,
|
||||
});
|
||||
return renderTask.promise;
|
||||
});
|
||||
})
|
||||
.catch(function (reason) {
|
||||
console.error("Error: " + reason);
|
||||
});
|
||||
16
examples/browserify/package.json
Normal file
16
examples/browserify/package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "browserify-pdf.js-example",
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
"browserify": "^13.0.0",
|
||||
"gulp": "^3.9.1",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-streamify": "^1.0.2",
|
||||
"gulp-uglify": "^1.5.3",
|
||||
"pdfjs-dist": "../../node_modules/pdfjs-dist",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp build"
|
||||
}
|
||||
}
|
||||
9
examples/browserify/worker.js
Normal file
9
examples/browserify/worker.js
Normal file
@ -0,0 +1,9 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Hello world example for browserify: worker bundle.
|
||||
|
||||
(typeof window !== "undefined"
|
||||
? window
|
||||
: {}
|
||||
).pdfjsWorker = require("pdfjs-dist/build/pdf.worker");
|
||||
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2014 Mozilla Foundation
|
||||
|
||||
@ -15,29 +15,29 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<title>PDF.js page viewer using built components</title>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="google" content="notranslate">
|
||||
<title>PDF.js page viewer using built components</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
||||
</head>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body tabindex="1">
|
||||
<div id="pageContainer" class="pdfViewer singlePageView"></div>
|
||||
<body tabindex="1">
|
||||
<div id="pageContainer" class="pdfViewer singlePageView"></div>
|
||||
|
||||
<script src="pageviewer.mjs" type="module"></script>
|
||||
</body>
|
||||
<script src="pageviewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
64
examples/components/pageviewer.js
Normal file
64
examples/components/pageviewer.js
Normal file
@ -0,0 +1,64 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFPageView) {
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
var CMAP_PACKED = true;
|
||||
|
||||
var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var PAGE_TO_VIEW = 1;
|
||||
var SCALE = 1.0;
|
||||
|
||||
var container = document.getElementById("pageContainer");
|
||||
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// Loading document.
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
});
|
||||
loadingTask.promise.then(function (pdfDocument) {
|
||||
// Document loaded, retrieving the page.
|
||||
return pdfDocument.getPage(PAGE_TO_VIEW).then(function (pdfPage) {
|
||||
// Creating the page view with default parameters.
|
||||
var pdfPageView = new pdfjsViewer.PDFPageView({
|
||||
container: container,
|
||||
id: PAGE_TO_VIEW,
|
||||
scale: SCALE,
|
||||
defaultViewport: pdfPage.getViewport({ scale: SCALE }),
|
||||
eventBus: eventBus,
|
||||
// We can enable text/annotations layers, if needed
|
||||
textLayerFactory: new pdfjsViewer.DefaultTextLayerFactory(),
|
||||
annotationLayerFactory: new pdfjsViewer.DefaultAnnotationLayerFactory(),
|
||||
});
|
||||
// Associates the actual page with the view, and drawing it
|
||||
pdfPageView.setPdfPage(pdfPage);
|
||||
return pdfPageView.draw();
|
||||
});
|
||||
});
|
||||
@ -1,63 +0,0 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFPageView) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
const CMAP_PACKED = true;
|
||||
|
||||
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
const PAGE_TO_VIEW = 1;
|
||||
const SCALE = 1.0;
|
||||
|
||||
const ENABLE_XFA = true;
|
||||
|
||||
const container = document.getElementById("pageContainer");
|
||||
|
||||
const eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// Loading document.
|
||||
const loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
enableXfa: ENABLE_XFA,
|
||||
});
|
||||
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
// Document loaded, retrieving the page.
|
||||
const pdfPage = await pdfDocument.getPage(PAGE_TO_VIEW);
|
||||
|
||||
// Creating the page view with default parameters.
|
||||
const pdfPageView = new pdfjsViewer.PDFPageView({
|
||||
container,
|
||||
id: PAGE_TO_VIEW,
|
||||
scale: SCALE,
|
||||
defaultViewport: pdfPage.getViewport({ scale: SCALE }),
|
||||
eventBus,
|
||||
});
|
||||
// Associate the actual page with the view, and draw it.
|
||||
pdfPageView.setPdfPage(pdfPage);
|
||||
pdfPageView.draw();
|
||||
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2014 Mozilla Foundation
|
||||
|
||||
@ -15,37 +15,37 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<title>PDF.js viewer using built components</title>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="google" content="notranslate">
|
||||
<title>PDF.js viewer using built components</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#viewerContainer {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#viewerContainer {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
||||
</head>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" class="pdfViewer"></div>
|
||||
</div>
|
||||
<body tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" class="pdfViewer"></div>
|
||||
</div>
|
||||
|
||||
<script src="simpleviewer.mjs" type="module"></script>
|
||||
</body>
|
||||
<script src="simpleviewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
80
examples/components/simpleviewer.js
Normal file
80
examples/components/simpleviewer.js
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
var CMAP_PACKED = true;
|
||||
|
||||
var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var SEARCH_FOR = ""; // try 'Mozilla';
|
||||
|
||||
var container = document.getElementById("viewerContainer");
|
||||
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// (Optionally) enable hyperlinks within PDF files.
|
||||
var pdfLinkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus: eventBus,
|
||||
});
|
||||
|
||||
// (Optionally) enable find controller.
|
||||
var pdfFindController = new pdfjsViewer.PDFFindController({
|
||||
eventBus: eventBus,
|
||||
linkService: pdfLinkService,
|
||||
});
|
||||
|
||||
var pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
container: container,
|
||||
eventBus: eventBus,
|
||||
linkService: pdfLinkService,
|
||||
findController: pdfFindController,
|
||||
});
|
||||
pdfLinkService.setViewer(pdfViewer);
|
||||
|
||||
eventBus.on("pagesinit", function () {
|
||||
// We can use pdfViewer now, e.g. let's change default scale.
|
||||
pdfViewer.currentScaleValue = "page-width";
|
||||
|
||||
// We can try searching for things.
|
||||
if (SEARCH_FOR) {
|
||||
pdfFindController.executeCommand("find", { query: SEARCH_FOR });
|
||||
}
|
||||
});
|
||||
|
||||
// Loading document.
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
});
|
||||
loadingTask.promise.then(function (pdfDocument) {
|
||||
// Document loaded, specifying document for the viewer and
|
||||
// the (optional) linkService.
|
||||
pdfViewer.setDocument(pdfDocument);
|
||||
|
||||
pdfLinkService.setDocument(pdfDocument, null);
|
||||
});
|
||||
@ -1,97 +0,0 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
const CMAP_PACKED = true;
|
||||
|
||||
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
// To test the AcroForm and/or scripting functionality, try e.g. this file:
|
||||
// "../../test/pdfs/160F-2019.pdf"
|
||||
|
||||
const ENABLE_XFA = true;
|
||||
const SEARCH_FOR = ""; // try "Mozilla";
|
||||
|
||||
const SANDBOX_BUNDLE_SRC = new URL(
|
||||
"../../node_modules/pdfjs-dist/build/pdf.sandbox.mjs",
|
||||
window.location
|
||||
);
|
||||
|
||||
const container = document.getElementById("viewerContainer");
|
||||
|
||||
const eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// (Optionally) enable hyperlinks within PDF files.
|
||||
const pdfLinkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus,
|
||||
});
|
||||
|
||||
// (Optionally) enable find controller.
|
||||
const pdfFindController = new pdfjsViewer.PDFFindController({
|
||||
eventBus,
|
||||
linkService: pdfLinkService,
|
||||
});
|
||||
|
||||
// (Optionally) enable scripting support.
|
||||
const pdfScriptingManager = new pdfjsViewer.PDFScriptingManager({
|
||||
eventBus,
|
||||
sandboxBundleSrc: SANDBOX_BUNDLE_SRC,
|
||||
});
|
||||
|
||||
const pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
container,
|
||||
eventBus,
|
||||
linkService: pdfLinkService,
|
||||
findController: pdfFindController,
|
||||
scriptingManager: pdfScriptingManager,
|
||||
});
|
||||
pdfLinkService.setViewer(pdfViewer);
|
||||
pdfScriptingManager.setViewer(pdfViewer);
|
||||
|
||||
eventBus.on("pagesinit", function () {
|
||||
// We can use pdfViewer now, e.g. let's change default scale.
|
||||
pdfViewer.currentScaleValue = "page-width";
|
||||
|
||||
// We can try searching for things.
|
||||
if (SEARCH_FOR) {
|
||||
eventBus.dispatch("find", { type: "", query: SEARCH_FOR });
|
||||
}
|
||||
});
|
||||
|
||||
// Loading document.
|
||||
const loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
enableXfa: ENABLE_XFA,
|
||||
});
|
||||
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
// Document loaded, specifying document for the viewer and
|
||||
// the (optional) linkService.
|
||||
pdfViewer.setDocument(pdfDocument);
|
||||
|
||||
pdfLinkService.setDocument(pdfDocument, null);
|
||||
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2014 Mozilla Foundation
|
||||
|
||||
@ -15,37 +15,37 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<title>PDF.js Single Page Viewer using built components</title>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="google" content="notranslate">
|
||||
<title>PDF.js Single Page Viewer using built components</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#viewerContainer {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#viewerContainer {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
||||
</head>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" class="pdfViewer"></div>
|
||||
</div>
|
||||
<body tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" class="pdfViewer"></div>
|
||||
</div>
|
||||
|
||||
<script src="singlepageviewer.mjs" type="module"></script>
|
||||
</body>
|
||||
<script src="singlepageviewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
80
examples/components/singlepageviewer.js
Normal file
80
examples/components/singlepageviewer.js
Normal file
@ -0,0 +1,80 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFSinglePageViewer) {
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
var CMAP_PACKED = true;
|
||||
|
||||
var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var SEARCH_FOR = ""; // try 'Mozilla';
|
||||
|
||||
var container = document.getElementById("viewerContainer");
|
||||
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// (Optionally) enable hyperlinks within PDF files.
|
||||
var pdfLinkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus: eventBus,
|
||||
});
|
||||
|
||||
// (Optionally) enable find controller.
|
||||
var pdfFindController = new pdfjsViewer.PDFFindController({
|
||||
eventBus: eventBus,
|
||||
linkService: pdfLinkService,
|
||||
});
|
||||
|
||||
var pdfSinglePageViewer = new pdfjsViewer.PDFSinglePageViewer({
|
||||
container: container,
|
||||
eventBus: eventBus,
|
||||
linkService: pdfLinkService,
|
||||
findController: pdfFindController,
|
||||
});
|
||||
pdfLinkService.setViewer(pdfSinglePageViewer);
|
||||
|
||||
eventBus.on("pagesinit", function () {
|
||||
// We can use pdfSinglePageViewer now, e.g. let's change default scale.
|
||||
pdfSinglePageViewer.currentScaleValue = "page-width";
|
||||
|
||||
// We can try searching for things.
|
||||
if (SEARCH_FOR) {
|
||||
pdfFindController.executeCommand("find", { query: SEARCH_FOR });
|
||||
}
|
||||
});
|
||||
|
||||
// Loading document.
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
});
|
||||
loadingTask.promise.then(function (pdfDocument) {
|
||||
// Document loaded, specifying document for the viewer and
|
||||
// the (optional) linkService.
|
||||
pdfSinglePageViewer.setDocument(pdfDocument);
|
||||
|
||||
pdfLinkService.setDocument(pdfDocument, null);
|
||||
});
|
||||
@ -1,97 +0,0 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFSinglePageViewer) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
const CMAP_PACKED = true;
|
||||
|
||||
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
// To test the AcroForm and/or scripting functionality, try e.g. this file:
|
||||
// "../../test/pdfs/160F-2019.pdf"
|
||||
|
||||
const ENABLE_XFA = true;
|
||||
const SEARCH_FOR = ""; // try "Mozilla";
|
||||
|
||||
const SANDBOX_BUNDLE_SRC = new URL(
|
||||
"../../node_modules/pdfjs-dist/build/pdf.sandbox.mjs",
|
||||
window.location
|
||||
);
|
||||
|
||||
const container = document.getElementById("viewerContainer");
|
||||
|
||||
const eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// (Optionally) enable hyperlinks within PDF files.
|
||||
const pdfLinkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus,
|
||||
});
|
||||
|
||||
// (Optionally) enable find controller.
|
||||
const pdfFindController = new pdfjsViewer.PDFFindController({
|
||||
eventBus,
|
||||
linkService: pdfLinkService,
|
||||
});
|
||||
|
||||
// (Optionally) enable scripting support.
|
||||
const pdfScriptingManager = new pdfjsViewer.PDFScriptingManager({
|
||||
eventBus,
|
||||
sandboxBundleSrc: SANDBOX_BUNDLE_SRC,
|
||||
});
|
||||
|
||||
const pdfSinglePageViewer = new pdfjsViewer.PDFSinglePageViewer({
|
||||
container,
|
||||
eventBus,
|
||||
linkService: pdfLinkService,
|
||||
findController: pdfFindController,
|
||||
scriptingManager: pdfScriptingManager,
|
||||
});
|
||||
pdfLinkService.setViewer(pdfSinglePageViewer);
|
||||
pdfScriptingManager.setViewer(pdfSinglePageViewer);
|
||||
|
||||
eventBus.on("pagesinit", function () {
|
||||
// We can use pdfSinglePageViewer now, e.g. let's change default scale.
|
||||
pdfSinglePageViewer.currentScaleValue = "page-width";
|
||||
|
||||
// We can try searching for things.
|
||||
if (SEARCH_FOR) {
|
||||
eventBus.dispatch("find", { type: "", query: SEARCH_FOR });
|
||||
}
|
||||
});
|
||||
|
||||
// Loading document.
|
||||
const loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
enableXfa: ENABLE_XFA,
|
||||
});
|
||||
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
// Document loaded, specifying document for the viewer and
|
||||
// the (optional) linkService.
|
||||
pdfSinglePageViewer.setDocument(pdfDocument);
|
||||
|
||||
pdfLinkService.setDocument(pdfDocument, null);
|
||||
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2018 Mozilla Foundation
|
||||
|
||||
@ -15,26 +15,26 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta name="google" content="notranslate" />
|
||||
<title>PDF.js standalone JpegImage parser</title>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="google" content="notranslate">
|
||||
<title>PDF.js standalone JpegImage parser</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/image_decoders/pdf.image_decoders.mjs" type="module"></script>
|
||||
</head>
|
||||
<script src="../../node_modules/pdfjs-dist/image_decoders/pdf.image_decoders.js"></script>
|
||||
</head>
|
||||
|
||||
<body tabindex="1">
|
||||
<canvas id="jpegCanvas" width="0" height="0"></canvas>
|
||||
<body tabindex="1">
|
||||
<canvas id="jpegCanvas" width="0" height="0"></canvas>
|
||||
|
||||
<script src="jpeg_viewer.mjs" type="module"></script>
|
||||
</body>
|
||||
<script src="jpeg_viewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -13,42 +13,64 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsImageDecoders.JpegImage) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using `gulp dist-install`");
|
||||
}
|
||||
|
||||
const JPEG_IMAGE = "fish.jpg";
|
||||
var JPEG_IMAGE = "fish.jpg";
|
||||
|
||||
const jpegCanvas = document.getElementById("jpegCanvas");
|
||||
const jpegCtx = jpegCanvas.getContext("2d");
|
||||
var jpegCanvas = document.getElementById("jpegCanvas");
|
||||
var jpegCtx = jpegCanvas.getContext("2d");
|
||||
|
||||
// Load the image data, and convert it to a Uint8Array.
|
||||
//
|
||||
const response = await fetch(JPEG_IMAGE);
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
var nonBinaryRequest = false;
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", JPEG_IMAGE, false);
|
||||
try {
|
||||
request.responseType = "arraybuffer";
|
||||
nonBinaryRequest = request.responseType !== "arraybuffer";
|
||||
} catch (e) {
|
||||
nonBinaryRequest = true;
|
||||
}
|
||||
if (nonBinaryRequest && request.overrideMimeType) {
|
||||
request.overrideMimeType("text/plain; charset=x-user-defined");
|
||||
}
|
||||
request.send(null);
|
||||
|
||||
var typedArrayImage;
|
||||
if (nonBinaryRequest) {
|
||||
var str = request.responseText,
|
||||
length = str.length;
|
||||
var bytes = new Uint8Array(length);
|
||||
for (var i = 0; i < length; ++i) {
|
||||
bytes[i] = str.charCodeAt(i) & 0xff;
|
||||
}
|
||||
typedArrayImage = bytes;
|
||||
} else {
|
||||
typedArrayImage = new Uint8Array(request.response);
|
||||
}
|
||||
const typedArrayImage = new Uint8Array(await response.arrayBuffer());
|
||||
|
||||
// Parse the image data using `JpegImage`.
|
||||
//
|
||||
const jpegImage = new pdfjsImageDecoders.JpegImage();
|
||||
var jpegImage = new pdfjsImageDecoders.JpegImage();
|
||||
jpegImage.parse(typedArrayImage);
|
||||
|
||||
const width = jpegImage.width,
|
||||
var width = jpegImage.width,
|
||||
height = jpegImage.height;
|
||||
const jpegData = jpegImage.getData({
|
||||
width,
|
||||
height,
|
||||
var jpegData = jpegImage.getData({
|
||||
width: width,
|
||||
height: height,
|
||||
forceRGB: true,
|
||||
});
|
||||
|
||||
// Render the JPEG image on a <canvas>.
|
||||
//
|
||||
const imageData = jpegCtx.createImageData(width, height);
|
||||
const imageBytes = imageData.data;
|
||||
for (let j = 0, k = 0, jj = width * height * 4; j < jj; ) {
|
||||
var imageData = jpegCtx.createImageData(width, height);
|
||||
var imageBytes = imageData.data;
|
||||
for (var j = 0, k = 0, jj = width * height * 4; j < jj; ) {
|
||||
imageBytes[j++] = jpegData[k++];
|
||||
imageBytes[j++] = jpegData[k++];
|
||||
imageBytes[j++] = jpegData[k++];
|
||||
@ -1,71 +1,68 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>'Hello, world!' example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>'Hello, world!' example</h1>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>'Hello, world!' example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr"></canvas>
|
||||
<h1>'Hello, world!' example</h1>
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
||||
|
||||
<script id="script" type="module">
|
||||
//
|
||||
// If absolute URL from the remote server is provided, configure the CORS
|
||||
// header on that server.
|
||||
//
|
||||
const url = "./helloworld.pdf";
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
|
||||
//
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
<script id="script">
|
||||
//
|
||||
// If absolute URL from the remote server is provided, configure the CORS
|
||||
// header on that server.
|
||||
//
|
||||
var url = './helloworld.pdf';
|
||||
|
||||
//
|
||||
// Asynchronous download PDF
|
||||
//
|
||||
const loadingTask = pdfjsLib.getDocument(url);
|
||||
const pdf = await loadingTask.promise;
|
||||
//
|
||||
// Fetch the first page
|
||||
//
|
||||
const page = await pdf.getPage(1);
|
||||
const scale = 1.5;
|
||||
const viewport = page.getViewport({ scale });
|
||||
// Support HiDPI-screens.
|
||||
const outputScale = window.devicePixelRatio || 1;
|
||||
//
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
'../../node_modules/pdfjs-dist/build/pdf.worker.js';
|
||||
|
||||
//
|
||||
// Asynchronous download PDF
|
||||
//
|
||||
var loadingTask = pdfjsLib.getDocument(url);
|
||||
loadingTask.promise.then(function(pdf) {
|
||||
//
|
||||
// Fetch the first page
|
||||
//
|
||||
pdf.getPage(1).then(function(page) {
|
||||
var scale = 1.5;
|
||||
var viewport = page.getViewport({ scale: scale, });
|
||||
|
||||
//
|
||||
// Prepare canvas using PDF page dimensions
|
||||
//
|
||||
const canvas = document.getElementById("the-canvas");
|
||||
const context = canvas.getContext("2d");
|
||||
|
||||
canvas.width = Math.floor(viewport.width * outputScale);
|
||||
canvas.height = Math.floor(viewport.height * outputScale);
|
||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
||||
|
||||
const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
|
||||
var canvas = document.getElementById('the-canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
//
|
||||
// Render PDF page into canvas context
|
||||
//
|
||||
const renderContext = {
|
||||
var renderContext = {
|
||||
canvasContext: context,
|
||||
transform,
|
||||
viewport,
|
||||
viewport: viewport,
|
||||
};
|
||||
page.render(renderContext);
|
||||
</script>
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<hr />
|
||||
<h2>JavaScript code:</h2>
|
||||
<pre id="code"></pre>
|
||||
<script>
|
||||
document.getElementById("code").textContent = document.getElementById("script").text;
|
||||
</script>
|
||||
</body>
|
||||
<hr>
|
||||
<h2>JavaScript code:</h2>
|
||||
<pre id="code"></pre>
|
||||
<script>
|
||||
document.getElementById('code').textContent =
|
||||
document.getElementById('script').text;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,77 +1,73 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>'Hello, world!' base64 example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>'Hello, world!' example</h1>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>'Hello, world!' base64 example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr"></canvas>
|
||||
<h1>'Hello, world!' example</h1>
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
||||
|
||||
<script id="script" type="module">
|
||||
// atob() is used to convert base64 encoded PDF to binary-like data.
|
||||
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
|
||||
// Base64_encoding_and_decoding.)
|
||||
var pdfData = atob(
|
||||
"JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog" +
|
||||
"IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv" +
|
||||
"TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K" +
|
||||
"Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg" +
|
||||
"L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+" +
|
||||
"PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u" +
|
||||
"dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq" +
|
||||
"Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU" +
|
||||
"CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu" +
|
||||
"ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g" +
|
||||
"CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw" +
|
||||
"MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v" +
|
||||
"dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G"
|
||||
);
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
|
||||
//
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
<script id="script">
|
||||
// atob() is used to convert base64 encoded PDF to binary-like data.
|
||||
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
|
||||
// Base64_encoding_and_decoding.)
|
||||
var pdfData = atob(
|
||||
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
|
||||
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
|
||||
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
|
||||
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
|
||||
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
|
||||
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
|
||||
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
|
||||
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
|
||||
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
|
||||
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
|
||||
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
|
||||
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
|
||||
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
|
||||
|
||||
// Opening PDF by passing its binary data as a string. It is still preferable
|
||||
// to use Uint8Array, but string or array-like structure will work too.
|
||||
var loadingTask = pdfjsLib.getDocument({ data: pdfData });
|
||||
var pdf = await loadingTask.promise;
|
||||
// Fetch the first page.
|
||||
var page = await pdf.getPage(1);
|
||||
//
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
'../../node_modules/pdfjs-dist/build/pdf.worker.js';
|
||||
|
||||
// Opening PDF by passing its binary data as a string. It is still preferable
|
||||
// to use Uint8Array, but string or array-like structure will work too.
|
||||
var loadingTask = pdfjsLib.getDocument({ data: pdfData, });
|
||||
loadingTask.promise.then(function(pdf) {
|
||||
// Fetch the first page.
|
||||
pdf.getPage(1).then(function(page) {
|
||||
var scale = 1.5;
|
||||
var viewport = page.getViewport({ scale: scale });
|
||||
// Support HiDPI-screens.
|
||||
var outputScale = window.devicePixelRatio || 1;
|
||||
var viewport = page.getViewport({ scale: scale, });
|
||||
|
||||
// Prepare canvas using PDF page dimensions.
|
||||
var canvas = document.getElementById("the-canvas");
|
||||
var context = canvas.getContext("2d");
|
||||
|
||||
canvas.width = Math.floor(viewport.width * outputScale);
|
||||
canvas.height = Math.floor(viewport.height * outputScale);
|
||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
||||
|
||||
var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
|
||||
var canvas = document.getElementById('the-canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
// Render PDF page into canvas context.
|
||||
var renderContext = {
|
||||
canvasContext: context,
|
||||
transform,
|
||||
viewport,
|
||||
viewport: viewport,
|
||||
};
|
||||
page.render(renderContext);
|
||||
</script>
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<hr />
|
||||
<h2>JavaScript code:</h2>
|
||||
<pre id="code"></pre>
|
||||
<script>
|
||||
document.getElementById("code").textContent = document.getElementById("script").text;
|
||||
</script>
|
||||
</body>
|
||||
<hr>
|
||||
<h2>JavaScript code:</h2>
|
||||
<pre id="code"></pre>
|
||||
<script>
|
||||
document.getElementById('code').textContent =
|
||||
document.getElementById('script').text;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -1,134 +1,131 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Previous/Next example</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>'Previous/Next' example</h1>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Previous/Next example</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
<button id="prev" type="button">Previous</button>
|
||||
<button id="next" type="button">Next</button>
|
||||
|
||||
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
|
||||
</div>
|
||||
<h1>'Previous/Next' example</h1>
|
||||
|
||||
<div>
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr"></canvas>
|
||||
</div>
|
||||
<div>
|
||||
<button id="prev">Previous</button>
|
||||
<button id="next">Next</button>
|
||||
|
||||
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
|
||||
</div>
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<div>
|
||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
||||
</div>
|
||||
|
||||
<script id="script" type="module">
|
||||
//
|
||||
// If absolute URL from the remote server is provided, configure the CORS
|
||||
// header on that server.
|
||||
//
|
||||
var url = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
|
||||
//
|
||||
// In cases when the pdf.worker.js is located at the different folder than the
|
||||
// PDF.js's one, or the PDF.js is executed via eval(), the workerSrc property
|
||||
// shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
<script id="script">
|
||||
//
|
||||
// If absolute URL from the remote server is provided, configure the CORS
|
||||
// header on that server.
|
||||
//
|
||||
var url = '../../web/compressed.tracemonkey-pldi-09.pdf';
|
||||
|
||||
var pdfDoc = null,
|
||||
pageNum = 1,
|
||||
pageRendering = false,
|
||||
pageNumPending = null,
|
||||
scale = 0.8,
|
||||
canvas = document.getElementById("the-canvas"),
|
||||
ctx = canvas.getContext("2d");
|
||||
//
|
||||
// In cases when the pdf.worker.js is located at the different folder than the
|
||||
// PDF.js's one, or the PDF.js is executed via eval(), the workerSrc property
|
||||
// shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
'../../node_modules/pdfjs-dist/build/pdf.worker.js';
|
||||
|
||||
/**
|
||||
* Get page info from document, resize canvas accordingly, and render page.
|
||||
* @param num Page number.
|
||||
*/
|
||||
function renderPage(num) {
|
||||
pageRendering = true;
|
||||
// Using promise to fetch the page
|
||||
pdfDoc.getPage(num).then(function (page) {
|
||||
var viewport = page.getViewport({ scale: scale });
|
||||
// Support HiDPI-screens.
|
||||
var outputScale = window.devicePixelRatio || 1;
|
||||
var pdfDoc = null,
|
||||
pageNum = 1,
|
||||
pageRendering = false,
|
||||
pageNumPending = null,
|
||||
scale = 0.8,
|
||||
canvas = document.getElementById('the-canvas'),
|
||||
ctx = canvas.getContext('2d');
|
||||
|
||||
canvas.width = Math.floor(viewport.width * outputScale);
|
||||
canvas.height = Math.floor(viewport.height * outputScale);
|
||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
||||
/**
|
||||
* Get page info from document, resize canvas accordingly, and render page.
|
||||
* @param num Page number.
|
||||
*/
|
||||
function renderPage(num) {
|
||||
pageRendering = true;
|
||||
// Using promise to fetch the page
|
||||
pdfDoc.getPage(num).then(function(page) {
|
||||
var viewport = page.getViewport({ scale: scale, });
|
||||
canvas.height = viewport.height;
|
||||
canvas.width = viewport.width;
|
||||
|
||||
var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
|
||||
// Render PDF page into canvas context
|
||||
var renderContext = {
|
||||
canvasContext: ctx,
|
||||
viewport: viewport,
|
||||
};
|
||||
var renderTask = page.render(renderContext);
|
||||
|
||||
// Render PDF page into canvas context
|
||||
var renderContext = {
|
||||
canvasContext: ctx,
|
||||
transform: transform,
|
||||
viewport: viewport,
|
||||
};
|
||||
var renderTask = page.render(renderContext);
|
||||
|
||||
// Wait for rendering to finish
|
||||
renderTask.promise.then(function () {
|
||||
pageRendering = false;
|
||||
if (pageNumPending !== null) {
|
||||
// New page rendering is pending
|
||||
renderPage(pageNumPending);
|
||||
pageNumPending = null;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Update page counters
|
||||
document.getElementById("page_num").textContent = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* If another page rendering in progress, waits until the rendering is
|
||||
* finished. Otherwise, executes rendering immediately.
|
||||
*/
|
||||
function queueRenderPage(num) {
|
||||
if (pageRendering) {
|
||||
pageNumPending = num;
|
||||
} else {
|
||||
renderPage(num);
|
||||
// Wait for rendering to finish
|
||||
renderTask.promise.then(function () {
|
||||
pageRendering = false;
|
||||
if (pageNumPending !== null) {
|
||||
// New page rendering is pending
|
||||
renderPage(pageNumPending);
|
||||
pageNumPending = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Displays previous page.
|
||||
*/
|
||||
function onPrevPage() {
|
||||
if (pageNum <= 1) {
|
||||
return;
|
||||
}
|
||||
pageNum--;
|
||||
queueRenderPage(pageNum);
|
||||
}
|
||||
document.getElementById("prev").addEventListener("click", onPrevPage);
|
||||
// Update page counters
|
||||
document.getElementById('page_num').textContent = num;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays next page.
|
||||
*/
|
||||
function onNextPage() {
|
||||
if (pageNum >= pdfDoc.numPages) {
|
||||
return;
|
||||
}
|
||||
pageNum++;
|
||||
queueRenderPage(pageNum);
|
||||
}
|
||||
document.getElementById("next").addEventListener("click", onNextPage);
|
||||
/**
|
||||
* If another page rendering in progress, waits until the rendering is
|
||||
* finised. Otherwise, executes rendering immediately.
|
||||
*/
|
||||
function queueRenderPage(num) {
|
||||
if (pageRendering) {
|
||||
pageNumPending = num;
|
||||
} else {
|
||||
renderPage(num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously downloads PDF.
|
||||
*/
|
||||
var loadingTask = pdfjsLib.getDocument(url);
|
||||
pdfDoc = await loadingTask.promise;
|
||||
document.getElementById("page_count").textContent = pdfDoc.numPages;
|
||||
/**
|
||||
* Displays previous page.
|
||||
*/
|
||||
function onPrevPage() {
|
||||
if (pageNum <= 1) {
|
||||
return;
|
||||
}
|
||||
pageNum--;
|
||||
queueRenderPage(pageNum);
|
||||
}
|
||||
document.getElementById('prev').addEventListener('click', onPrevPage);
|
||||
|
||||
// Initial/first page rendering
|
||||
renderPage(pageNum);
|
||||
</script>
|
||||
</body>
|
||||
/**
|
||||
* Displays next page.
|
||||
*/
|
||||
function onNextPage() {
|
||||
if (pageNum >= pdfDoc.numPages) {
|
||||
return;
|
||||
}
|
||||
pageNum++;
|
||||
queueRenderPage(pageNum);
|
||||
}
|
||||
document.getElementById('next').addEventListener('click', onNextPage);
|
||||
|
||||
/**
|
||||
* Asynchronously downloads PDF.
|
||||
*/
|
||||
var loadingTask = pdfjsLib.getDocument(url);
|
||||
loadingTask.promise.then(function(pdfDoc_) {
|
||||
pdfDoc = pdfDoc_;
|
||||
document.getElementById('page_count').textContent = pdfDoc.numPages;
|
||||
|
||||
// Initial/first page rendering
|
||||
renderPage(pageNum);
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -26,12 +26,12 @@ html {
|
||||
}
|
||||
|
||||
header {
|
||||
background-color: rgb(244 244 244 / 1);
|
||||
background-color: rgba(244, 244, 244, 1);
|
||||
}
|
||||
|
||||
header h1 {
|
||||
border-bottom: 1px solid rgb(216 216 216 / 1);
|
||||
color: rgb(133 133 133 / 1);
|
||||
border-bottom: 1px solid rgba(216, 216, 216, 1);
|
||||
color: rgba(133, 133, 133, 1);
|
||||
font-size: 23px;
|
||||
font-style: italic;
|
||||
font-weight: normal;
|
||||
@ -44,7 +44,7 @@ header h1 {
|
||||
|
||||
body {
|
||||
background: url(images/document_bg.png);
|
||||
color: rgb(255 255 255 / 1);
|
||||
color: rgba(255, 255, 255, 1);
|
||||
font-family: sans-serif;
|
||||
font-size: 10px;
|
||||
height: 100%;
|
||||
@ -71,7 +71,7 @@ footer {
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1;
|
||||
box-shadow: 0 -0.2rem 0.5rem rgb(50 50 50 / 0.75);
|
||||
box-shadow: 0 -0.2rem 0.5rem rgba(50, 50, 50, 0.75);
|
||||
}
|
||||
|
||||
.toolbarButton {
|
||||
@ -81,7 +81,7 @@ footer {
|
||||
border-width: 0;
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
background-color: rgb(0 0 0 / 0);
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.toolbarButton.pageUp {
|
||||
@ -110,11 +110,10 @@ footer {
|
||||
left: 36%;
|
||||
text-align: center;
|
||||
border: 0;
|
||||
background-color: rgb(0 0 0 / 0);
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
font-size: 1.2rem;
|
||||
color: rgb(255 255 255 / 1);
|
||||
background-image:
|
||||
url(images/div_line_left.png), url(images/div_line_right.png);
|
||||
color: rgba(255, 255, 255, 1);
|
||||
background-image: url(images/div_line_left.png), url(images/div_line_right.png);
|
||||
background-repeat: no-repeat;
|
||||
background-position: left, right;
|
||||
background-size: 0.2rem, 0.2rem;
|
||||
@ -139,7 +138,7 @@ footer {
|
||||
}
|
||||
|
||||
.toolbarButton[disabled] {
|
||||
opacity: 0.3;
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
@ -153,7 +152,10 @@ footer {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
inset: 5rem 0 4rem;
|
||||
top: 5rem;
|
||||
bottom: 4rem;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
canvas {
|
||||
@ -164,7 +166,7 @@ canvas {
|
||||
.pdfViewer .page .loadingIcon {
|
||||
width: 2.9rem;
|
||||
height: 2.9rem;
|
||||
background: url("images/spinner.png") no-repeat left top / 38rem;
|
||||
background: url("images/spinner.png") no-repeat left top / 38rem ;
|
||||
border: medium none;
|
||||
animation: 1s steps(10, end) 0s normal none infinite moveDefault;
|
||||
display: block;
|
||||
@ -184,59 +186,73 @@ canvas {
|
||||
}
|
||||
|
||||
#loadingBar {
|
||||
/* Define this variable here, and not in :root, to avoid reflowing the
|
||||
entire viewer when updating progress (see issue 15958). */
|
||||
--progressBar-percent: 0%;
|
||||
|
||||
position: relative;
|
||||
height: 0.6rem;
|
||||
background-color: rgb(51 51 51 / 1);
|
||||
border-bottom: 1px solid rgb(51 51 51 / 1);
|
||||
height: .6rem;
|
||||
background-color: rgba(51, 51, 51, 1);
|
||||
border-bottom: 1px solid rgba(51, 51, 51, 1);
|
||||
margin-top: 5rem;
|
||||
}
|
||||
|
||||
#loadingBar .progress {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
transform: scaleX(var(--progressBar-percent));
|
||||
transform-origin: 0 0;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
background-color: rgb(221 221 221 / 1);
|
||||
background-color: rgba(221, 221, 221, 1);
|
||||
overflow: hidden;
|
||||
transition: transform 200ms;
|
||||
transition: width 200ms;
|
||||
}
|
||||
|
||||
@keyframes progressIndeterminate {
|
||||
0% {
|
||||
transform: translateX(0%);
|
||||
}
|
||||
50% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
0% { left: 0; }
|
||||
50% { left: 100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
#loadingBar.indeterminate .progress {
|
||||
transform: none;
|
||||
background-color: rgb(153 153 153 / 1);
|
||||
#loadingBar .progress.indeterminate {
|
||||
background-color: rgba(153, 153, 153, 1);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
#loadingBar.indeterminate .progress .glimmer {
|
||||
#loadingBar .indeterminate .glimmer {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 5rem;
|
||||
background-image: linear-gradient(
|
||||
to right,
|
||||
rgb(153 153 153 / 1) 0%,
|
||||
rgb(255 255 255 / 1) 50%,
|
||||
rgb(153 153 153 / 1) 100%
|
||||
);
|
||||
background-image: linear-gradient(to right,
|
||||
rgba(153, 153, 153, 1) 0%,
|
||||
rgba(255, 255, 255, 1) 50%,
|
||||
rgba(153, 153, 153, 1) 100%);
|
||||
background-size: 100% 100%;
|
||||
background-repeat: no-repeat;
|
||||
animation: progressIndeterminate 2s linear infinite;
|
||||
}
|
||||
|
||||
#errorWrapper {
|
||||
background: none repeat scroll 0 0 rgba(255, 85, 85, 1);
|
||||
color: rgba(255, 255, 255, 1);
|
||||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 3.2rem;
|
||||
z-index: 1000;
|
||||
padding: 0.3rem;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
#errorMessageLeft {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#errorMessageRight {
|
||||
float: right;
|
||||
}
|
||||
|
||||
#errorMoreInfo {
|
||||
background-color: rgba(255, 255, 255, 1);
|
||||
color: rgba(0, 0, 0, 1);
|
||||
padding: 0.3rem;
|
||||
margin: 0.3rem;
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2016 Mozilla Foundation
|
||||
|
||||
@ -16,16 +16,16 @@ limitations under the License.
|
||||
-->
|
||||
<html dir="ltr">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
|
||||
<title>PDF.js viewer</title>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
|
||||
<link rel="stylesheet" type="text/css" href="viewer.css" />
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
<link rel="stylesheet" type="text/css" href="viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -42,16 +42,35 @@ limitations under the License.
|
||||
<div class="glimmer"></div>
|
||||
</div>
|
||||
|
||||
<div id="errorWrapper" hidden="true">
|
||||
<div id="errorMessageLeft">
|
||||
<span id="errorMessage"></span>
|
||||
<button id="errorShowMore">
|
||||
More Information
|
||||
</button>
|
||||
<button id="errorShowLess">
|
||||
Less Information
|
||||
</button>
|
||||
</div>
|
||||
<div id="errorMessageRight">
|
||||
<button id="errorClose">
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
<div class="clearBoth"></div>
|
||||
<textarea id="errorMoreInfo" hidden="true" readonly="readonly"></textarea>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<button class="toolbarButton pageUp" title="Previous Page" id="previous" type="button"></button>
|
||||
<button class="toolbarButton pageDown" title="Next Page" id="next" type="button"></button>
|
||||
<button class="toolbarButton pageUp" title="Previous Page" id="previous"></button>
|
||||
<button class="toolbarButton pageDown" title="Next Page" id="next"></button>
|
||||
|
||||
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" />
|
||||
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1">
|
||||
|
||||
<button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut" type="button"></button>
|
||||
<button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn" type="button"></button>
|
||||
<button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut"></button>
|
||||
<button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn"></button>
|
||||
</footer>
|
||||
|
||||
<script src="viewer.mjs" type="module"></script>
|
||||
<script src="viewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -13,27 +13,28 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
const MAX_CANVAS_PIXELS = 0; // CSS-only zooming.
|
||||
const TEXT_LAYER_MODE = 0; // DISABLE
|
||||
const MAX_IMAGE_SIZE = 1024 * 1024;
|
||||
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
const CMAP_PACKED = true;
|
||||
var USE_ONLY_CSS_ZOOM = true;
|
||||
var TEXT_LAYER_MODE = 0; // DISABLE
|
||||
var MAX_IMAGE_SIZE = 1024 * 1024;
|
||||
var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
var CMAP_PACKED = true;
|
||||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
const DEFAULT_SCALE_DELTA = 1.1;
|
||||
const MIN_SCALE = 0.25;
|
||||
const MAX_SCALE = 10.0;
|
||||
const DEFAULT_SCALE_VALUE = "auto";
|
||||
var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var DEFAULT_SCALE_DELTA = 1.1;
|
||||
var MIN_SCALE = 0.25;
|
||||
var MAX_SCALE = 10.0;
|
||||
var DEFAULT_SCALE_VALUE = "auto";
|
||||
|
||||
const PDFViewerApplication = {
|
||||
var PDFViewerApplication = {
|
||||
pdfLoadingTask: null,
|
||||
pdfDocument: null,
|
||||
pdfViewer: null,
|
||||
@ -46,7 +47,7 @@ const PDFViewerApplication = {
|
||||
* @returns {Promise} - Returns the promise, which is resolved when document
|
||||
* is opened.
|
||||
*/
|
||||
open(params) {
|
||||
open: function (params) {
|
||||
if (this.pdfLoadingTask) {
|
||||
// We need to destroy already opened document
|
||||
return this.close().then(
|
||||
@ -57,13 +58,13 @@ const PDFViewerApplication = {
|
||||
);
|
||||
}
|
||||
|
||||
const url = params.url;
|
||||
const self = this;
|
||||
var url = params.url;
|
||||
var self = this;
|
||||
this.setTitleUsingUrl(url);
|
||||
|
||||
// Loading document.
|
||||
const loadingTask = pdfjsLib.getDocument({
|
||||
url,
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
url: url,
|
||||
maxImageSize: MAX_IMAGE_SIZE,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
@ -80,24 +81,46 @@ const PDFViewerApplication = {
|
||||
self.pdfDocument = pdfDocument;
|
||||
self.pdfViewer.setDocument(pdfDocument);
|
||||
self.pdfLinkService.setDocument(pdfDocument);
|
||||
self.pdfHistory.initialize({
|
||||
fingerprint: pdfDocument.fingerprints[0],
|
||||
});
|
||||
self.pdfHistory.initialize({ fingerprint: pdfDocument.fingerprint });
|
||||
|
||||
self.loadingBar.hide();
|
||||
self.setTitleUsingMetadata(pdfDocument);
|
||||
},
|
||||
function (reason) {
|
||||
let key = "pdfjs-loading-error";
|
||||
if (reason instanceof pdfjsLib.InvalidPDFException) {
|
||||
key = "pdfjs-invalid-file-error";
|
||||
} else if (reason instanceof pdfjsLib.ResponseException) {
|
||||
key = reason.missing
|
||||
? "pdfjs-missing-file-error"
|
||||
: "pdfjs-unexpected-response-error";
|
||||
function (exception) {
|
||||
var message = exception && exception.message;
|
||||
var l10n = self.l10n;
|
||||
var loadingErrorMessage;
|
||||
|
||||
if (exception instanceof pdfjsLib.InvalidPDFException) {
|
||||
// change error message also for other builds
|
||||
loadingErrorMessage = l10n.get(
|
||||
"invalid_file_error",
|
||||
null,
|
||||
"Invalid or corrupted PDF file."
|
||||
);
|
||||
} else if (exception instanceof pdfjsLib.MissingPDFException) {
|
||||
// special message for missing PDFs
|
||||
loadingErrorMessage = l10n.get(
|
||||
"missing_file_error",
|
||||
null,
|
||||
"Missing PDF file."
|
||||
);
|
||||
} else if (exception instanceof pdfjsLib.UnexpectedResponseException) {
|
||||
loadingErrorMessage = l10n.get(
|
||||
"unexpected_response_error",
|
||||
null,
|
||||
"Unexpected server response."
|
||||
);
|
||||
} else {
|
||||
loadingErrorMessage = l10n.get(
|
||||
"loading_error",
|
||||
null,
|
||||
"An error occurred while loading the PDF."
|
||||
);
|
||||
}
|
||||
self.l10n.get(key).then(msg => {
|
||||
self.error(msg, { message: reason?.message });
|
||||
|
||||
loadingErrorMessage.then(function (msg) {
|
||||
self.error(msg, { message: message });
|
||||
});
|
||||
self.loadingBar.hide();
|
||||
}
|
||||
@ -109,12 +132,15 @@ const PDFViewerApplication = {
|
||||
* @returns {Promise} - Returns the promise, which is resolved when all
|
||||
* destruction is completed.
|
||||
*/
|
||||
close() {
|
||||
close: function () {
|
||||
var errorWrapper = document.getElementById("errorWrapper");
|
||||
errorWrapper.setAttribute("hidden", "true");
|
||||
|
||||
if (!this.pdfLoadingTask) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
const promise = this.pdfLoadingTask.destroy();
|
||||
var promise = this.pdfLoadingTask.destroy();
|
||||
this.pdfLoadingTask = null;
|
||||
|
||||
if (this.pdfDocument) {
|
||||
@ -132,30 +158,27 @@ const PDFViewerApplication = {
|
||||
},
|
||||
|
||||
get loadingBar() {
|
||||
const bar = document.getElementById("loadingBar");
|
||||
return pdfjsLib.shadow(
|
||||
this,
|
||||
"loadingBar",
|
||||
new pdfjsViewer.ProgressBar(bar)
|
||||
);
|
||||
var bar = new pdfjsViewer.ProgressBar("#loadingBar", {});
|
||||
|
||||
return pdfjsLib.shadow(this, "loadingBar", bar);
|
||||
},
|
||||
|
||||
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
|
||||
this.url = url;
|
||||
let title = pdfjsLib.getFilenameFromUrl(url) || url;
|
||||
var title = pdfjsLib.getFilenameFromUrl(url) || url;
|
||||
try {
|
||||
title = decodeURIComponent(title);
|
||||
} catch {
|
||||
} catch (e) {
|
||||
// decodeURIComponent may throw URIError,
|
||||
// fall back to using the unprocessed url in that case
|
||||
}
|
||||
this.setTitle(title);
|
||||
},
|
||||
|
||||
setTitleUsingMetadata(pdfDocument) {
|
||||
const self = this;
|
||||
setTitleUsingMetadata: function (pdfDocument) {
|
||||
var self = this;
|
||||
pdfDocument.getMetadata().then(function (data) {
|
||||
const info = data.info,
|
||||
var info = data.info,
|
||||
metadata = data.metadata;
|
||||
self.documentInfo = info;
|
||||
self.metadata = metadata;
|
||||
@ -163,7 +186,7 @@ const PDFViewerApplication = {
|
||||
// Provides some basic debug information
|
||||
console.log(
|
||||
"PDF " +
|
||||
pdfDocument.fingerprints[0] +
|
||||
pdfDocument.fingerprint +
|
||||
" [" +
|
||||
info.PDFFormatVersion +
|
||||
" " +
|
||||
@ -176,9 +199,9 @@ const PDFViewerApplication = {
|
||||
")"
|
||||
);
|
||||
|
||||
let pdfTitle;
|
||||
var pdfTitle;
|
||||
if (metadata && metadata.has("dc:title")) {
|
||||
const title = metadata.get("dc:title");
|
||||
var title = metadata.get("dc:title");
|
||||
// Ghostscript sometimes returns 'Untitled', so prevent setting the
|
||||
// title to 'Untitled.
|
||||
if (title !== "Untitled") {
|
||||
@ -202,29 +225,83 @@ const PDFViewerApplication = {
|
||||
},
|
||||
|
||||
error: function pdfViewError(message, moreInfo) {
|
||||
const moreInfoText = [
|
||||
`PDF.js v${pdfjsLib.version || "?"} (build: ${pdfjsLib.build || "?"})`,
|
||||
var l10n = this.l10n;
|
||||
var moreInfoText = [
|
||||
l10n.get(
|
||||
"error_version_info",
|
||||
{ version: pdfjsLib.version || "?", build: pdfjsLib.build || "?" },
|
||||
"PDF.js v{{version}} (build: {{build}})"
|
||||
),
|
||||
];
|
||||
if (moreInfo) {
|
||||
moreInfoText.push(`Message: ${moreInfo.message}`);
|
||||
|
||||
if (moreInfo) {
|
||||
moreInfoText.push(
|
||||
l10n.get(
|
||||
"error_message",
|
||||
{ message: moreInfo.message },
|
||||
"Message: {{message}}"
|
||||
)
|
||||
);
|
||||
if (moreInfo.stack) {
|
||||
moreInfoText.push(`Stack: ${moreInfo.stack}`);
|
||||
moreInfoText.push(
|
||||
l10n.get("error_stack", { stack: moreInfo.stack }, "Stack: {{stack}}")
|
||||
);
|
||||
} else {
|
||||
if (moreInfo.filename) {
|
||||
moreInfoText.push(`File: ${moreInfo.filename}`);
|
||||
moreInfoText.push(
|
||||
l10n.get(
|
||||
"error_file",
|
||||
{ file: moreInfo.filename },
|
||||
"File: {{file}}"
|
||||
)
|
||||
);
|
||||
}
|
||||
if (moreInfo.lineNumber) {
|
||||
moreInfoText.push(`Line: ${moreInfo.lineNumber}`);
|
||||
moreInfoText.push(
|
||||
l10n.get(
|
||||
"error_line",
|
||||
{ line: moreInfo.lineNumber },
|
||||
"Line: {{line}}"
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.error(`${message}\n\n${moreInfoText.join("\n")}`);
|
||||
var errorWrapper = document.getElementById("errorWrapper");
|
||||
errorWrapper.removeAttribute("hidden");
|
||||
|
||||
var errorMessage = document.getElementById("errorMessage");
|
||||
errorMessage.textContent = message;
|
||||
|
||||
var closeButton = document.getElementById("errorClose");
|
||||
closeButton.onclick = function () {
|
||||
errorWrapper.setAttribute("hidden", "true");
|
||||
};
|
||||
|
||||
var errorMoreInfo = document.getElementById("errorMoreInfo");
|
||||
var moreInfoButton = document.getElementById("errorShowMore");
|
||||
var lessInfoButton = document.getElementById("errorShowLess");
|
||||
moreInfoButton.onclick = function () {
|
||||
errorMoreInfo.removeAttribute("hidden");
|
||||
moreInfoButton.setAttribute("hidden", "true");
|
||||
lessInfoButton.removeAttribute("hidden");
|
||||
errorMoreInfo.style.height = errorMoreInfo.scrollHeight + "px";
|
||||
};
|
||||
lessInfoButton.onclick = function () {
|
||||
errorMoreInfo.setAttribute("hidden", "true");
|
||||
moreInfoButton.removeAttribute("hidden");
|
||||
lessInfoButton.setAttribute("hidden", "true");
|
||||
};
|
||||
moreInfoButton.removeAttribute("hidden");
|
||||
lessInfoButton.setAttribute("hidden", "true");
|
||||
Promise.all(moreInfoText).then(function (parts) {
|
||||
errorMoreInfo.value = parts.join("\n");
|
||||
});
|
||||
},
|
||||
|
||||
progress: function pdfViewProgress(level) {
|
||||
const percent = Math.round(level * 100);
|
||||
var percent = Math.round(level * 100);
|
||||
// Updating the bar if value increases.
|
||||
if (percent > this.loadingBar.percent || isNaN(percent)) {
|
||||
this.loadingBar.percent = percent;
|
||||
@ -244,7 +321,7 @@ const PDFViewerApplication = {
|
||||
},
|
||||
|
||||
zoomIn: function pdfViewZoomIn(ticks) {
|
||||
let newScale = this.pdfViewer.currentScale;
|
||||
var newScale = this.pdfViewer.currentScale;
|
||||
do {
|
||||
newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
|
||||
newScale = Math.ceil(newScale * 10) / 10;
|
||||
@ -254,7 +331,7 @@ const PDFViewerApplication = {
|
||||
},
|
||||
|
||||
zoomOut: function pdfViewZoomOut(ticks) {
|
||||
let newScale = this.pdfViewer.currentScale;
|
||||
var newScale = this.pdfViewer.currentScale;
|
||||
do {
|
||||
newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
|
||||
newScale = Math.floor(newScale * 10) / 10;
|
||||
@ -264,31 +341,31 @@ const PDFViewerApplication = {
|
||||
},
|
||||
|
||||
initUI: function pdfViewInitUI() {
|
||||
const eventBus = new pdfjsViewer.EventBus();
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
this.eventBus = eventBus;
|
||||
|
||||
const linkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus,
|
||||
var linkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus: eventBus,
|
||||
});
|
||||
this.pdfLinkService = linkService;
|
||||
|
||||
this.l10n = new pdfjsViewer.GenericL10n();
|
||||
this.l10n = pdfjsViewer.NullL10n;
|
||||
|
||||
const container = document.getElementById("viewerContainer");
|
||||
const pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
container,
|
||||
eventBus,
|
||||
linkService,
|
||||
var container = document.getElementById("viewerContainer");
|
||||
var pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
container: container,
|
||||
eventBus: eventBus,
|
||||
linkService: linkService,
|
||||
l10n: this.l10n,
|
||||
maxCanvasPixels: MAX_CANVAS_PIXELS,
|
||||
useOnlyCssZoom: USE_ONLY_CSS_ZOOM,
|
||||
textLayerMode: TEXT_LAYER_MODE,
|
||||
});
|
||||
this.pdfViewer = pdfViewer;
|
||||
linkService.setViewer(pdfViewer);
|
||||
|
||||
this.pdfHistory = new pdfjsViewer.PDFHistory({
|
||||
eventBus,
|
||||
linkService,
|
||||
eventBus: eventBus,
|
||||
linkService: linkService,
|
||||
});
|
||||
linkService.setHistory(this.pdfHistory);
|
||||
|
||||
@ -335,8 +412,8 @@ const PDFViewerApplication = {
|
||||
eventBus.on(
|
||||
"pagechanging",
|
||||
function (evt) {
|
||||
const page = evt.pageNumber;
|
||||
const numPages = PDFViewerApplication.pagesCount;
|
||||
var page = evt.pageNumber;
|
||||
var numPages = PDFViewerApplication.pagesCount;
|
||||
|
||||
document.getElementById("pageNumber").value = page;
|
||||
document.getElementById("previous").disabled = page <= 1;
|
||||
@ -347,8 +424,6 @@ const PDFViewerApplication = {
|
||||
},
|
||||
};
|
||||
|
||||
window.PDFViewerApplication = PDFViewerApplication;
|
||||
|
||||
document.addEventListener(
|
||||
"DOMContentLoaded",
|
||||
function () {
|
||||
@ -357,14 +432,18 @@ document.addEventListener(
|
||||
true
|
||||
);
|
||||
|
||||
// The offsetParent is not set until the PDF.js iframe or object is visible;
|
||||
// waiting for first animation.
|
||||
const animationStarted = new Promise(function (resolve) {
|
||||
window.requestAnimationFrame(resolve);
|
||||
});
|
||||
(function animationStartedClosure() {
|
||||
// The offsetParent is not set until the PDF.js iframe or object is visible.
|
||||
// Waiting for first animation.
|
||||
PDFViewerApplication.animationStartedPromise = new Promise(function (
|
||||
resolve
|
||||
) {
|
||||
window.requestAnimationFrame(resolve);
|
||||
});
|
||||
})();
|
||||
|
||||
// We need to delay opening until all HTML is loaded.
|
||||
animationStarted.then(function () {
|
||||
PDFViewerApplication.animationStartedPromise.then(function () {
|
||||
PDFViewerApplication.open({
|
||||
url: DEFAULT_URL,
|
||||
});
|
||||
9
examples/node/.eslintrc
Normal file
9
examples/node/.eslintrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": [
|
||||
"../.eslintrc"
|
||||
],
|
||||
|
||||
"env": {
|
||||
"node": true,
|
||||
},
|
||||
}
|
||||
278
examples/node/domstubs.js
Normal file
278
examples/node/domstubs.js
Normal file
@ -0,0 +1,278 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function xmlEncode(s) {
|
||||
var i = 0,
|
||||
ch;
|
||||
s = String(s);
|
||||
while (
|
||||
i < s.length &&
|
||||
(ch = s[i]) !== "&" &&
|
||||
ch !== "<" &&
|
||||
ch !== '"' &&
|
||||
ch !== "\n" &&
|
||||
ch !== "\r" &&
|
||||
ch !== "\t"
|
||||
) {
|
||||
i++;
|
||||
}
|
||||
if (i >= s.length) {
|
||||
return s;
|
||||
}
|
||||
var buf = s.substring(0, i);
|
||||
while (i < s.length) {
|
||||
ch = s[i++];
|
||||
switch (ch) {
|
||||
case "&":
|
||||
buf += "&";
|
||||
break;
|
||||
case "<":
|
||||
buf += "<";
|
||||
break;
|
||||
case '"':
|
||||
buf += """;
|
||||
break;
|
||||
case "\n":
|
||||
buf += "
";
|
||||
break;
|
||||
case "\r":
|
||||
buf += "
";
|
||||
break;
|
||||
case "\t":
|
||||
buf += "	";
|
||||
break;
|
||||
default:
|
||||
buf += ch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
function DOMElement(name) {
|
||||
this.nodeName = name;
|
||||
this.childNodes = [];
|
||||
this.attributes = {};
|
||||
this.textContent = "";
|
||||
|
||||
if (name === "style") {
|
||||
this.sheet = {
|
||||
cssRules: [],
|
||||
insertRule: function (rule) {
|
||||
this.cssRules.push(rule);
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
DOMElement.prototype = {
|
||||
getAttribute: function DOMElement_getAttribute(name) {
|
||||
if (name in this.attributes) {
|
||||
return this.attributes[name];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
getAttributeNS: function DOMElement_getAttributeNS(NS, name) {
|
||||
// Fast path
|
||||
if (name in this.attributes) {
|
||||
return this.attributes[name];
|
||||
}
|
||||
// Slow path - used by test/unit/display_svg_spec.js
|
||||
// Assuming that there is only one matching attribute for a given name,
|
||||
// across all namespaces.
|
||||
if (NS) {
|
||||
var suffix = ":" + name;
|
||||
for (var fullName in this.attributes) {
|
||||
if (fullName.slice(-suffix.length) === suffix) {
|
||||
return this.attributes[fullName];
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
setAttribute: function DOMElement_setAttribute(name, value) {
|
||||
value = value || "";
|
||||
value = xmlEncode(value);
|
||||
this.attributes[name] = value;
|
||||
},
|
||||
|
||||
setAttributeNS: function DOMElement_setAttributeNS(NS, name, value) {
|
||||
this.setAttribute(name, value);
|
||||
},
|
||||
|
||||
appendChild: function DOMElement_appendChild(element) {
|
||||
var childNodes = this.childNodes;
|
||||
if (!childNodes.includes(element)) {
|
||||
childNodes.push(element);
|
||||
}
|
||||
},
|
||||
|
||||
hasChildNodes: function DOMElement_hasChildNodes() {
|
||||
return this.childNodes.length !== 0;
|
||||
},
|
||||
|
||||
cloneNode: function DOMElement_cloneNode() {
|
||||
var newNode = new DOMElement(this.nodeName);
|
||||
newNode.childNodes = this.childNodes;
|
||||
newNode.attributes = this.attributes;
|
||||
newNode.textContent = this.textContent;
|
||||
return newNode;
|
||||
},
|
||||
|
||||
// This method is offered for convenience. It is recommended to directly use
|
||||
// getSerializer because that allows you to process the chunks as they come
|
||||
// instead of requiring the whole image to fit in memory.
|
||||
toString: function DOMElement_toString() {
|
||||
var buf = [];
|
||||
var serializer = this.getSerializer();
|
||||
var chunk;
|
||||
while ((chunk = serializer.getNext()) !== null) {
|
||||
buf.push(chunk);
|
||||
}
|
||||
return buf.join("");
|
||||
},
|
||||
|
||||
getSerializer: function DOMElement_getSerializer() {
|
||||
return new DOMElementSerializer(this);
|
||||
},
|
||||
};
|
||||
|
||||
function DOMElementSerializer(node) {
|
||||
this._node = node;
|
||||
this._state = 0;
|
||||
this._loopIndex = 0;
|
||||
this._attributeKeys = null;
|
||||
this._childSerializer = null;
|
||||
}
|
||||
DOMElementSerializer.prototype = {
|
||||
/**
|
||||
* Yields the next chunk in the serialization of the element.
|
||||
*
|
||||
* @returns {string|null} null if the element has fully been serialized.
|
||||
*/
|
||||
getNext: function DOMElementSerializer_getNext() {
|
||||
var node = this._node;
|
||||
switch (this._state) {
|
||||
case 0: // Start opening tag.
|
||||
++this._state;
|
||||
return "<" + node.nodeName;
|
||||
case 1: // Add SVG namespace if this is the root element.
|
||||
++this._state;
|
||||
if (node.nodeName === "svg:svg") {
|
||||
return (
|
||||
' xmlns:xlink="http://www.w3.org/1999/xlink"' +
|
||||
' xmlns:svg="http://www.w3.org/2000/svg"'
|
||||
);
|
||||
}
|
||||
/* falls through */
|
||||
case 2: // Initialize variables for looping over attributes.
|
||||
++this._state;
|
||||
this._loopIndex = 0;
|
||||
this._attributeKeys = Object.keys(node.attributes);
|
||||
/* falls through */
|
||||
case 3: // Serialize any attributes and end opening tag.
|
||||
if (this._loopIndex < this._attributeKeys.length) {
|
||||
var name = this._attributeKeys[this._loopIndex++];
|
||||
return " " + name + '="' + xmlEncode(node.attributes[name]) + '"';
|
||||
}
|
||||
++this._state;
|
||||
return ">";
|
||||
case 4: // Serialize textContent for tspan/style elements.
|
||||
if (node.nodeName === "svg:tspan" || node.nodeName === "svg:style") {
|
||||
this._state = 6;
|
||||
return xmlEncode(node.textContent);
|
||||
}
|
||||
++this._state;
|
||||
this._loopIndex = 0;
|
||||
/* falls through */
|
||||
case 5: // Serialize child nodes (only for non-tspan/style elements).
|
||||
var value;
|
||||
while (true) {
|
||||
value = this._childSerializer && this._childSerializer.getNext();
|
||||
if (value !== null) {
|
||||
return value;
|
||||
}
|
||||
var nextChild = node.childNodes[this._loopIndex++];
|
||||
if (nextChild) {
|
||||
this._childSerializer = new DOMElementSerializer(nextChild);
|
||||
} else {
|
||||
this._childSerializer = null;
|
||||
++this._state;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* falls through */
|
||||
case 6: // Ending tag.
|
||||
++this._state;
|
||||
return "</" + node.nodeName + ">";
|
||||
case 7: // Done.
|
||||
return null;
|
||||
default:
|
||||
throw new Error("Unexpected serialization state: " + this._state);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
const document = {
|
||||
childNodes: [],
|
||||
|
||||
get currentScript() {
|
||||
return { src: "" };
|
||||
},
|
||||
|
||||
get documentElement() {
|
||||
return this;
|
||||
},
|
||||
|
||||
createElementNS: function (NS, element) {
|
||||
var elObject = new DOMElement(element);
|
||||
return elObject;
|
||||
},
|
||||
|
||||
createElement: function (element) {
|
||||
return this.createElementNS("", element);
|
||||
},
|
||||
|
||||
getElementsByTagName: function (element) {
|
||||
if (element === "head") {
|
||||
return [this.head || (this.head = new DOMElement("head"))];
|
||||
}
|
||||
return [];
|
||||
},
|
||||
};
|
||||
|
||||
function Image() {
|
||||
this._src = null;
|
||||
this.onload = null;
|
||||
}
|
||||
Image.prototype = {
|
||||
get src() {
|
||||
return this._src;
|
||||
},
|
||||
set src(value) {
|
||||
this._src = value;
|
||||
if (this.onload) {
|
||||
this.onload();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
exports.document = document;
|
||||
exports.Image = Image;
|
||||
|
||||
var exported_symbols = Object.keys(exports);
|
||||
|
||||
exports.setStubs = function (namespace) {
|
||||
exported_symbols.forEach(function (key) {
|
||||
console.assert(!(key in namespace), "property should not be set: " + key);
|
||||
namespace[key] = exports[key];
|
||||
});
|
||||
};
|
||||
exports.unsetStubs = function (namespace) {
|
||||
exported_symbols.forEach(function (key) {
|
||||
console.assert(key in namespace, "property should be set: " + key);
|
||||
delete namespace[key];
|
||||
});
|
||||
};
|
||||
@ -3,26 +3,27 @@
|
||||
|
||||
//
|
||||
// Basic node example that prints document metadata and text content.
|
||||
// Requires single file built version of PDF.js -- please run
|
||||
// `gulp singlefile` before running the example.
|
||||
//
|
||||
|
||||
// Run `gulp dist-install` to generate 'pdfjs-dist' npm package files.
|
||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
||||
var pdfjsLib = require("pdfjs-dist/es5/build/pdf.js");
|
||||
|
||||
// Loading file from file system into typed array
|
||||
const pdfPath =
|
||||
process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var pdfPath = process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
|
||||
// Will be using promises to load document, pages and misc data instead of
|
||||
// callback.
|
||||
const loadingTask = getDocument(pdfPath);
|
||||
var loadingTask = pdfjsLib.getDocument(pdfPath);
|
||||
loadingTask.promise
|
||||
.then(function (doc) {
|
||||
const numPages = doc.numPages;
|
||||
var numPages = doc.numPages;
|
||||
console.log("# Document Loaded");
|
||||
console.log("Number of Pages: " + numPages);
|
||||
console.log();
|
||||
|
||||
let lastPromise; // will be used to chain promises
|
||||
var lastPromise; // will be used to chain promises
|
||||
lastPromise = doc.getMetadata().then(function (data) {
|
||||
console.log("# Metadata Is Loaded");
|
||||
console.log("## Info");
|
||||
@ -35,10 +36,10 @@ loadingTask.promise
|
||||
}
|
||||
});
|
||||
|
||||
const loadPage = function (pageNum) {
|
||||
var loadPage = function (pageNum) {
|
||||
return doc.getPage(pageNum).then(function (page) {
|
||||
console.log("# Page " + pageNum);
|
||||
const viewport = page.getViewport({ scale: 1.0 });
|
||||
var viewport = page.getViewport({ scale: 1.0 });
|
||||
console.log("Size: " + viewport.width + "x" + viewport.height);
|
||||
console.log();
|
||||
return page
|
||||
@ -46,13 +47,11 @@ loadingTask.promise
|
||||
.then(function (content) {
|
||||
// Content contains lots of information about the text layout and
|
||||
// styles, but we need only strings at the moment
|
||||
const strings = content.items.map(function (item) {
|
||||
var strings = content.items.map(function (item) {
|
||||
return item.str;
|
||||
});
|
||||
console.log("## Text Content");
|
||||
console.log(strings.join(" "));
|
||||
// Release page resources.
|
||||
page.cleanup();
|
||||
})
|
||||
.then(function () {
|
||||
console.log();
|
||||
@ -61,7 +60,7 @@ loadingTask.promise
|
||||
};
|
||||
// Loading of the first page will wait on metadata and subsequent loadings
|
||||
// will wait on the previous pages.
|
||||
for (let i = 1; i <= numPages; i++) {
|
||||
for (var i = 1; i <= numPages; i++) {
|
||||
lastPromise = lastPromise.then(loadPage.bind(null, i));
|
||||
}
|
||||
return lastPromise;
|
||||
@ -9,7 +9,9 @@ Install the dependencies and build the PDF.js library:
|
||||
$ npm install
|
||||
$ gulp dist-install
|
||||
|
||||
Run the example to convert the first page of a PDF file to a PNG image:
|
||||
Install the Node canvas library and run the example to convert the first page of a
|
||||
PDF file to a PNG image:
|
||||
|
||||
$ npm install canvas
|
||||
$ cd examples/node/pdf2png
|
||||
$ node pdf2png.mjs
|
||||
$ node pdf2png.js
|
||||
|
||||
98
examples/node/pdf2png/pdf2png.js
Normal file
98
examples/node/pdf2png/pdf2png.js
Normal file
@ -0,0 +1,98 @@
|
||||
/* Copyright 2017 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
var Canvas = require("canvas");
|
||||
var assert = require("assert").strict;
|
||||
var fs = require("fs");
|
||||
|
||||
function NodeCanvasFactory() {}
|
||||
NodeCanvasFactory.prototype = {
|
||||
create: function NodeCanvasFactory_create(width, height) {
|
||||
assert(width > 0 && height > 0, "Invalid canvas size");
|
||||
var canvas = Canvas.createCanvas(width, height);
|
||||
var context = canvas.getContext("2d");
|
||||
return {
|
||||
canvas: canvas,
|
||||
context: context,
|
||||
};
|
||||
},
|
||||
|
||||
reset: function NodeCanvasFactory_reset(canvasAndContext, width, height) {
|
||||
assert(canvasAndContext.canvas, "Canvas is not specified");
|
||||
assert(width > 0 && height > 0, "Invalid canvas size");
|
||||
canvasAndContext.canvas.width = width;
|
||||
canvasAndContext.canvas.height = height;
|
||||
},
|
||||
|
||||
destroy: function NodeCanvasFactory_destroy(canvasAndContext) {
|
||||
assert(canvasAndContext.canvas, "Canvas is not specified");
|
||||
|
||||
// Zeroing the width and height cause Firefox to release graphics
|
||||
// resources immediately, which can greatly reduce memory consumption.
|
||||
canvasAndContext.canvas.width = 0;
|
||||
canvasAndContext.canvas.height = 0;
|
||||
canvasAndContext.canvas = null;
|
||||
canvasAndContext.context = null;
|
||||
},
|
||||
};
|
||||
|
||||
var pdfjsLib = require("pdfjs-dist/es5/build/pdf.js");
|
||||
|
||||
// Relative path of the PDF file.
|
||||
var pdfURL = "../../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
|
||||
// Read the PDF file into a typed array so PDF.js can load it.
|
||||
var rawData = new Uint8Array(fs.readFileSync(pdfURL));
|
||||
|
||||
// Load the PDF file.
|
||||
var loadingTask = pdfjsLib.getDocument(rawData);
|
||||
loadingTask.promise
|
||||
.then(function (pdfDocument) {
|
||||
console.log("# PDF document loaded.");
|
||||
|
||||
// Get the first page.
|
||||
pdfDocument.getPage(1).then(function (page) {
|
||||
// Render the page on a Node canvas with 100% scale.
|
||||
var viewport = page.getViewport({ scale: 1.0 });
|
||||
var canvasFactory = new NodeCanvasFactory();
|
||||
var canvasAndContext = canvasFactory.create(
|
||||
viewport.width,
|
||||
viewport.height
|
||||
);
|
||||
var renderContext = {
|
||||
canvasContext: canvasAndContext.context,
|
||||
viewport: viewport,
|
||||
canvasFactory: canvasFactory,
|
||||
};
|
||||
|
||||
var renderTask = page.render(renderContext);
|
||||
renderTask.promise.then(function () {
|
||||
// Convert the canvas to an image buffer.
|
||||
var image = canvasAndContext.canvas.toBuffer();
|
||||
fs.writeFile("output.png", image, function (error) {
|
||||
if (error) {
|
||||
console.error("Error: " + error);
|
||||
} else {
|
||||
console.log(
|
||||
"Finished converting first page of PDF file to a PNG image."
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(function (reason) {
|
||||
console.log(reason);
|
||||
});
|
||||
@ -1,72 +0,0 @@
|
||||
/* Copyright 2017 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import fs from "fs";
|
||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
|
||||
const CMAP_PACKED = true;
|
||||
|
||||
// Where the standard fonts are located.
|
||||
const STANDARD_FONT_DATA_URL =
|
||||
"../../../node_modules/pdfjs-dist/standard_fonts/";
|
||||
|
||||
// Loading file from file system into typed array.
|
||||
const pdfPath =
|
||||
process.argv[2] || "../../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
const data = new Uint8Array(fs.readFileSync(pdfPath));
|
||||
|
||||
// Load the PDF file.
|
||||
const loadingTask = getDocument({
|
||||
data,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
standardFontDataUrl: STANDARD_FONT_DATA_URL,
|
||||
});
|
||||
|
||||
try {
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
console.log("# PDF document loaded.");
|
||||
// Get the first page.
|
||||
const page = await pdfDocument.getPage(1);
|
||||
// Render the page on a Node canvas with 100% scale.
|
||||
const canvasFactory = pdfDocument.canvasFactory;
|
||||
const viewport = page.getViewport({ scale: 1.0 });
|
||||
const canvasAndContext = canvasFactory.create(
|
||||
viewport.width,
|
||||
viewport.height
|
||||
);
|
||||
const renderContext = {
|
||||
canvasContext: canvasAndContext.context,
|
||||
viewport,
|
||||
};
|
||||
|
||||
const renderTask = page.render(renderContext);
|
||||
await renderTask.promise;
|
||||
// Convert the canvas to an image buffer.
|
||||
const image = canvasAndContext.canvas.toBuffer("image/png");
|
||||
fs.writeFile("output.png", image, function (error) {
|
||||
if (error) {
|
||||
console.error("Error: " + error);
|
||||
} else {
|
||||
console.log("Finished converting first page of PDF file to a PNG image.");
|
||||
}
|
||||
});
|
||||
// Release page resources.
|
||||
page.cleanup();
|
||||
} catch (reason) {
|
||||
console.log(reason);
|
||||
}
|
||||
135
examples/node/pdf2svg.js
Normal file
135
examples/node/pdf2svg.js
Normal file
@ -0,0 +1,135 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
//
|
||||
// Node tool to dump SVG output into a file.
|
||||
//
|
||||
|
||||
var fs = require("fs");
|
||||
var util = require("util");
|
||||
var path = require("path");
|
||||
var stream = require("stream");
|
||||
|
||||
// HACK few hacks to let PDF.js be loaded not as a module in global space.
|
||||
require("./domstubs.js").setStubs(global);
|
||||
|
||||
// Run `gulp dist-install` to generate 'pdfjs-dist' npm package files.
|
||||
var pdfjsLib = require("pdfjs-dist/es5/build/pdf.js");
|
||||
|
||||
// Loading file from file system into typed array
|
||||
var pdfPath = process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var data = new Uint8Array(fs.readFileSync(pdfPath));
|
||||
|
||||
var outputDirectory = "./svgdump";
|
||||
|
||||
try {
|
||||
// Note: This creates a directory only one level deep. If you want to create
|
||||
// multiple subdirectories on the fly, use the mkdirp module from npm.
|
||||
fs.mkdirSync(outputDirectory);
|
||||
} catch (e) {
|
||||
if (e.code !== "EEXIST") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Dumps svg outputs to a folder called svgdump
|
||||
function getFilePathForPage(pageNum) {
|
||||
var name = path.basename(pdfPath, path.extname(pdfPath));
|
||||
return path.join(outputDirectory, name + "-" + pageNum + ".svg");
|
||||
}
|
||||
|
||||
/**
|
||||
* A readable stream which offers a stream representing the serialization of a
|
||||
* given DOM element (as defined by domstubs.js).
|
||||
*
|
||||
* @param {object} options
|
||||
* @param {DOMElement} options.svgElement The element to serialize
|
||||
*/
|
||||
function ReadableSVGStream(options) {
|
||||
if (!(this instanceof ReadableSVGStream)) {
|
||||
return new ReadableSVGStream(options);
|
||||
}
|
||||
stream.Readable.call(this, options);
|
||||
this.serializer = options.svgElement.getSerializer();
|
||||
}
|
||||
util.inherits(ReadableSVGStream, stream.Readable);
|
||||
// Implements https://nodejs.org/api/stream.html#stream_readable_read_size_1
|
||||
ReadableSVGStream.prototype._read = function () {
|
||||
var chunk;
|
||||
while ((chunk = this.serializer.getNext()) !== null) {
|
||||
if (!this.push(chunk)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.push(null);
|
||||
};
|
||||
|
||||
// Streams the SVG element to the given file path.
|
||||
function writeSvgToFile(svgElement, filePath) {
|
||||
var readableSvgStream = new ReadableSVGStream({
|
||||
svgElement: svgElement,
|
||||
});
|
||||
var writableStream = fs.createWriteStream(filePath);
|
||||
return new Promise(function (resolve, reject) {
|
||||
readableSvgStream.once("error", reject);
|
||||
writableStream.once("error", reject);
|
||||
writableStream.once("finish", resolve);
|
||||
readableSvgStream.pipe(writableStream);
|
||||
}).catch(function (err) {
|
||||
readableSvgStream = null; // Explicitly null because of v8 bug 6512.
|
||||
writableStream.end();
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
// Will be using promises to load document, pages and misc data instead of
|
||||
// callback.
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
data: data,
|
||||
fontExtraProperties: true,
|
||||
});
|
||||
loadingTask.promise
|
||||
.then(function (doc) {
|
||||
var numPages = doc.numPages;
|
||||
console.log("# Document Loaded");
|
||||
console.log("Number of Pages: " + numPages);
|
||||
console.log();
|
||||
|
||||
var lastPromise = Promise.resolve(); // will be used to chain promises
|
||||
var loadPage = function (pageNum) {
|
||||
return doc.getPage(pageNum).then(function (page) {
|
||||
console.log("# Page " + pageNum);
|
||||
var viewport = page.getViewport({ scale: 1.0 });
|
||||
console.log("Size: " + viewport.width + "x" + viewport.height);
|
||||
console.log();
|
||||
|
||||
return page.getOperatorList().then(function (opList) {
|
||||
var svgGfx = new pdfjsLib.SVGGraphics(page.commonObjs, page.objs);
|
||||
svgGfx.embedFonts = true;
|
||||
return svgGfx.getSVG(opList, viewport).then(function (svg) {
|
||||
return writeSvgToFile(svg, getFilePathForPage(pageNum)).then(
|
||||
function () {
|
||||
console.log("Page: " + pageNum);
|
||||
},
|
||||
function (err) {
|
||||
console.log("Error: " + err);
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
for (var i = 1; i <= numPages; i++) {
|
||||
lastPromise = lastPromise.then(loadPage.bind(null, i));
|
||||
}
|
||||
return lastPromise;
|
||||
})
|
||||
.then(
|
||||
function () {
|
||||
console.log("# End of Document");
|
||||
},
|
||||
function (err) {
|
||||
console.error("Error: " + err);
|
||||
}
|
||||
);
|
||||
8
examples/svgviewer/README.md
Normal file
8
examples/svgviewer/README.md
Normal file
@ -0,0 +1,8 @@
|
||||
## PDF.js using SVG
|
||||
|
||||
This is a project for implementing alternate backend for PDF.js using Scalable Vector Graphics. This is still a WIP.
|
||||
Take a look at [proposal](https://docs.google.com/document/d/1k4nPx1RrHbxXi94kSdvW5ay8KMkjwLmBEiCNupyzlwk/pub) for this project.
|
||||
|
||||
## Getting started
|
||||
|
||||
Take a look at src/display/svg.js to see the SVG rendering code.
|
||||
51
examples/svgviewer/index.html
Normal file
51
examples/svgviewer/index.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
Copyright 2014 Mozilla Foundation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<html dir="ltr" mozdisallowselectionprint>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
<meta name="google" content="notranslate">
|
||||
<title>PDF.js SVG viewer using built components</title>
|
||||
|
||||
<style>
|
||||
body {
|
||||
background-color: #808080;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
#viewerContainer {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
||||
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.js"></script>
|
||||
</head>
|
||||
|
||||
<body tabindex="1">
|
||||
<div id="viewerContainer">
|
||||
<div id="viewer" class="pdfViewer"></div>
|
||||
</div>
|
||||
|
||||
<script src="viewer.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
69
examples/svgviewer/viewer.js
Normal file
69
examples/svgviewer/viewer.js
Normal file
@ -0,0 +1,69 @@
|
||||
/* Copyright 2014 Mozilla Foundation
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
}
|
||||
|
||||
// The workerSrc property shall be specified.
|
||||
//
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
// Some PDFs need external cmaps.
|
||||
//
|
||||
var CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
|
||||
var CMAP_PACKED = true;
|
||||
|
||||
var DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
|
||||
var container = document.getElementById("viewerContainer");
|
||||
|
||||
var eventBus = new pdfjsViewer.EventBus();
|
||||
|
||||
// (Optionally) enable hyperlinks within PDF files.
|
||||
var pdfLinkService = new pdfjsViewer.PDFLinkService({
|
||||
eventBus: eventBus,
|
||||
});
|
||||
|
||||
var pdfViewer = new pdfjsViewer.PDFViewer({
|
||||
container: container,
|
||||
eventBus: eventBus,
|
||||
linkService: pdfLinkService,
|
||||
renderer: "svg",
|
||||
textLayerMode: 0,
|
||||
});
|
||||
pdfLinkService.setViewer(pdfViewer);
|
||||
|
||||
eventBus.on("pagesinit", function () {
|
||||
// We can use pdfViewer now, e.g. let's change default scale.
|
||||
pdfViewer.currentScaleValue = "page-width";
|
||||
});
|
||||
|
||||
// Loading document.
|
||||
var loadingTask = pdfjsLib.getDocument({
|
||||
url: DEFAULT_URL,
|
||||
cMapUrl: CMAP_URL,
|
||||
cMapPacked: CMAP_PACKED,
|
||||
});
|
||||
loadingTask.promise.then(function (pdfDocument) {
|
||||
// Document loaded, specifying document for the viewer and
|
||||
// the (optional) linkService.
|
||||
pdfViewer.setDocument(pdfDocument);
|
||||
|
||||
pdfLinkService.setDocument(pdfDocument, null);
|
||||
});
|
||||
@ -1,13 +1,14 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Text-only PDF.js example</title>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
||||
<script src="pdf2svg.mjs" type="module"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Text-only PDF.js example</p>
|
||||
<div id="pageContainer" style="display: inline-block; border: solid 1px black"></div>
|
||||
</body>
|
||||
<script src="../../node_modules/pdfjs-dist/build/pdf.js"></script>
|
||||
<script src="pdf2svg.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<p>Text-only PDF.js example</p>
|
||||
<div id="pageContainer" style="display: inline-block; border: solid 1px black;">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -13,17 +13,17 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
const PDF_PATH = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
const PAGE_NUMBER = 1;
|
||||
const PAGE_SCALE = 1.5;
|
||||
const SVG_NS = "http://www.w3.org/2000/svg";
|
||||
var PDF_PATH = "../../web/compressed.tracemonkey-pldi-09.pdf";
|
||||
var PAGE_NUMBER = 1;
|
||||
var PAGE_SCALE = 1.5;
|
||||
var SVG_NS = "http://www.w3.org/2000/svg";
|
||||
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
||||
"../../node_modules/pdfjs-dist/build/pdf.worker.js";
|
||||
|
||||
function buildSVG(viewport, textContent) {
|
||||
// Building SVG with size of the viewport (for simplicity)
|
||||
const svg = document.createElementNS(SVG_NS, "svg:svg");
|
||||
var svg = document.createElementNS(SVG_NS, "svg:svg");
|
||||
svg.setAttribute("width", viewport.width + "px");
|
||||
svg.setAttribute("height", viewport.height + "px");
|
||||
// items are transformed to have 1px font size
|
||||
@ -33,39 +33,42 @@ function buildSVG(viewport, textContent) {
|
||||
textContent.items.forEach(function (textItem) {
|
||||
// we have to take in account viewport transform, which includes scale,
|
||||
// rotation and Y-axis flip, and not forgetting to flip text.
|
||||
const tx = pdfjsLib.Util.transform(
|
||||
var tx = pdfjsLib.Util.transform(
|
||||
pdfjsLib.Util.transform(viewport.transform, textItem.transform),
|
||||
[1, 0, 0, -1, 0, 0]
|
||||
);
|
||||
const style = textContent.styles[textItem.fontName];
|
||||
var style = textContent.styles[textItem.fontName];
|
||||
// adding text element
|
||||
const text = document.createElementNS(SVG_NS, "svg:text");
|
||||
var text = document.createElementNS(SVG_NS, "svg:text");
|
||||
text.setAttribute("transform", "matrix(" + tx.join(" ") + ")");
|
||||
text.setAttribute("font-family", style.fontFamily);
|
||||
text.textContent = textItem.str;
|
||||
svg.append(text);
|
||||
svg.appendChild(text);
|
||||
});
|
||||
return svg;
|
||||
}
|
||||
|
||||
async function pageLoaded() {
|
||||
function pageLoaded() {
|
||||
// Loading document and page text content
|
||||
const loadingTask = pdfjsLib.getDocument({ url: PDF_PATH });
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
const page = await pdfDocument.getPage(PAGE_NUMBER);
|
||||
const viewport = page.getViewport({ scale: PAGE_SCALE });
|
||||
const textContent = await page.getTextContent();
|
||||
// building SVG and adding that to the DOM
|
||||
const svg = buildSVG(viewport, textContent);
|
||||
document.getElementById("pageContainer").append(svg);
|
||||
// Release page resources.
|
||||
page.cleanup();
|
||||
var loadingTask = pdfjsLib.getDocument({ url: PDF_PATH });
|
||||
loadingTask.promise.then(function (pdfDocument) {
|
||||
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
|
||||
var viewport = page.getViewport({ scale: PAGE_SCALE });
|
||||
page.getTextContent().then(function (textContent) {
|
||||
// building SVG and adding that to the DOM
|
||||
var svg = buildSVG(viewport, textContent);
|
||||
document.getElementById("pageContainer").appendChild(svg);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
if (typeof pdfjsLib === "undefined") {
|
||||
// eslint-disable-next-line no-alert
|
||||
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
|
||||
alert(
|
||||
"Built version of PDF.js was not found.\n" +
|
||||
"Please run `gulp dist-install`."
|
||||
);
|
||||
return;
|
||||
}
|
||||
pageLoaded();
|
||||
9
examples/webpack/.eslintrc
Normal file
9
examples/webpack/.eslintrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": [
|
||||
"../.eslintrc"
|
||||
],
|
||||
|
||||
"env": {
|
||||
"node": true,
|
||||
},
|
||||
}
|
||||
@ -18,16 +18,10 @@ Refer to the `main.js` and `webpack.config.js` files for the source code.
|
||||
Note that PDF.js packaging requires packaging of the main application and
|
||||
the worker code, and the `workerSrc` path shall be set to the latter file.
|
||||
|
||||
### Minification
|
||||
|
||||
If you are configuring Webpack to output a minified build, please note that you
|
||||
*must* configure the minifier to keep original class/function names intact;
|
||||
otherwise the build is not guaranteed to work correctly.
|
||||
|
||||
## Worker loading
|
||||
|
||||
If you are getting the `Setting up fake worker` warning, make sure you are
|
||||
importing `pdfjs-dist/webpack.mjs` which is the zero-configuration method for
|
||||
Webpack users. Installing `worker-loader` is no longer necessary.
|
||||
If you are getting the `Setting up fake worker` warning, make sure you are importing `pdfjs-dist/webpack` which is the zero-configuration method for Webpack users:
|
||||
|
||||
import * as pdfjsLib from 'pdfjs-dist/webpack.mjs';
|
||||
import pdfjsLib from 'pdfjs-dist/webpack';
|
||||
|
||||
For a full working example refer to [this repository](https://github.com/yurydelendik/pdfjs-react).
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>webpack example</title>
|
||||
<script src="../../build/webpack/main.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="theCanvas"></canvas>
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>webpack example</title>
|
||||
<script src="../../build/webpack/main.bundle.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="theCanvas"></canvas>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
35
examples/webpack/main.js
Normal file
35
examples/webpack/main.js
Normal file
@ -0,0 +1,35 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Hello world example for webpack.
|
||||
|
||||
var pdfjsLib = require("pdfjs-dist");
|
||||
|
||||
var pdfPath = "../learning/helloworld.pdf";
|
||||
|
||||
// Setting worker path to worker bundle.
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../build/webpack/pdf.worker.bundle.js";
|
||||
|
||||
// Loading a document.
|
||||
var loadingTask = pdfjsLib.getDocument(pdfPath);
|
||||
loadingTask.promise
|
||||
.then(function (pdfDocument) {
|
||||
// Request a first page
|
||||
return pdfDocument.getPage(1).then(function (pdfPage) {
|
||||
// Display page on the existing canvas with 100% scale.
|
||||
var viewport = pdfPage.getViewport({ scale: 1.0 });
|
||||
var canvas = document.getElementById("theCanvas");
|
||||
canvas.width = viewport.width;
|
||||
canvas.height = viewport.height;
|
||||
var ctx = canvas.getContext("2d");
|
||||
var renderTask = pdfPage.render({
|
||||
canvasContext: ctx,
|
||||
viewport: viewport,
|
||||
});
|
||||
return renderTask.promise;
|
||||
});
|
||||
})
|
||||
.catch(function (reason) {
|
||||
console.error("Error: " + reason);
|
||||
});
|
||||
@ -1,29 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Hello world example for webpack.
|
||||
|
||||
import * as pdfjsLib from "pdfjs-dist";
|
||||
|
||||
const pdfPath = "../learning/helloworld.pdf";
|
||||
|
||||
// Setting worker path to worker bundle.
|
||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
||||
"../../build/webpack/pdf.worker.bundle.js";
|
||||
|
||||
// Loading a document.
|
||||
const loadingTask = pdfjsLib.getDocument(pdfPath);
|
||||
const pdfDocument = await loadingTask.promise;
|
||||
// Request a first page
|
||||
const pdfPage = await pdfDocument.getPage(1);
|
||||
// Display page on the existing canvas with 100% scale.
|
||||
const viewport = pdfPage.getViewport({ scale: 1.0 });
|
||||
const canvas = document.getElementById("theCanvas");
|
||||
canvas.width = viewport.width;
|
||||
canvas.height = viewport.height;
|
||||
const ctx = canvas.getContext("2d");
|
||||
const renderTask = pdfPage.render({
|
||||
canvasContext: ctx,
|
||||
viewport,
|
||||
});
|
||||
await renderTask.promise;
|
||||
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "webpack-pdf.js-example",
|
||||
"version": "0.2.0",
|
||||
"version": "0.1.0",
|
||||
"scripts": {
|
||||
"build": "webpack"
|
||||
},
|
||||
"devDependencies": {
|
||||
"webpack": "^5.89.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack": "4.21.0",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"pdfjs-dist": "../../node_modules/pdfjs-dist"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,11 @@
|
||||
/* eslint-disable import/no-commonjs */
|
||||
|
||||
const webpack = require("webpack"); // eslint-disable-line no-unused-vars
|
||||
const path = require("path");
|
||||
var webpack = require("webpack"); // eslint-disable-line no-unused-vars
|
||||
var path = require("path");
|
||||
|
||||
module.exports = {
|
||||
context: __dirname,
|
||||
entry: {
|
||||
main: "./main.mjs",
|
||||
"pdf.worker": "pdfjs-dist/build/pdf.worker.mjs",
|
||||
main: "./main.js",
|
||||
"pdf.worker": "pdfjs-dist/build/pdf.worker.entry",
|
||||
},
|
||||
mode: "none",
|
||||
output: {
|
||||
|
||||
9
extensions/.eslintrc
Normal file
9
extensions/.eslintrc
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": [
|
||||
../.eslintrc
|
||||
],
|
||||
|
||||
"rules": {
|
||||
"no-restricted-globals": "off",
|
||||
},
|
||||
}
|
||||
22
extensions/chromium/.eslintrc
Normal file
22
extensions/chromium/.eslintrc
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"extends": [
|
||||
../../.eslintrc
|
||||
],
|
||||
|
||||
"env": {
|
||||
"webextensions": true
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"mozilla"
|
||||
],
|
||||
|
||||
"parserOptions": {
|
||||
"sourceType": "script"
|
||||
},
|
||||
|
||||
"rules": {
|
||||
"mozilla/import-globals": "error",
|
||||
"object-shorthand": "off",
|
||||
},
|
||||
}
|
||||
@ -16,15 +16,16 @@ limitations under the License.
|
||||
|
||||
"use strict";
|
||||
|
||||
var VIEWER_URL = chrome.runtime.getURL("content/web/viewer.html");
|
||||
var VIEWER_URL = chrome.extension.getURL("content/web/viewer.html");
|
||||
|
||||
function getViewerURL(pdf_url) {
|
||||
return VIEWER_URL + "?file=" + encodeURIComponent(pdf_url);
|
||||
}
|
||||
|
||||
document.addEventListener("animationstart", onAnimationStart, true);
|
||||
if (document.contentType === "application/pdf") {
|
||||
chrome.runtime.sendMessage({ action: "canRequestBody" }, maybeRenderPdfDoc);
|
||||
if (CSS.supports("animation", "0s")) {
|
||||
document.addEventListener("animationstart", onAnimationStart, true);
|
||||
} else {
|
||||
document.addEventListener("webkitAnimationStart", onAnimationStart, true);
|
||||
}
|
||||
|
||||
function onAnimationStart(event) {
|
||||
@ -127,15 +128,11 @@ function updateEmbedElement(elem) {
|
||||
var parentNode = elem.parentNode;
|
||||
var nextSibling = elem.nextSibling;
|
||||
if (parentNode) {
|
||||
elem.remove();
|
||||
parentNode.removeChild(elem);
|
||||
}
|
||||
elem.type = "text/html";
|
||||
elem.src = getEmbeddedViewerURL(elem.src);
|
||||
|
||||
if (parentNode) {
|
||||
// Suppress linter warning: insertBefore is preferable to
|
||||
// nextSibling.before(elem) because nextSibling may be null.
|
||||
// eslint-disable-next-line unicorn/prefer-modern-dom-apis
|
||||
parentNode.insertBefore(elem, nextSibling);
|
||||
}
|
||||
}
|
||||
@ -153,7 +150,7 @@ function updateObjectElement(elem) {
|
||||
// attribute reloads the content (provided that the type was correctly set).
|
||||
// - When <object type=text/html data="chrome-extension://..."> is used
|
||||
// (tested with a data-URL, data:text/html,<object...>, the extension's
|
||||
// origin allowlist is not set up, so the viewer can't load the PDF file.
|
||||
// origin whitelist is not set up, so the viewer can't load the PDF file.
|
||||
// - The content of the <object> tag may be affected by <param> tags.
|
||||
//
|
||||
// To make sure that our solution works for all cases, we will insert a frame
|
||||
@ -163,7 +160,7 @@ function updateObjectElement(elem) {
|
||||
if (!iframe || !iframe.__inserted_by_pdfjs) {
|
||||
iframe = createFullSizeIframe();
|
||||
elem.textContent = "";
|
||||
elem.append(iframe);
|
||||
elem.appendChild(iframe);
|
||||
iframe.__inserted_by_pdfjs = true;
|
||||
}
|
||||
iframe.src = getEmbeddedViewerURL(elem.data);
|
||||
@ -224,38 +221,3 @@ function getEmbeddedViewerURL(path) {
|
||||
path = a.href;
|
||||
return getViewerURL(path) + fragment;
|
||||
}
|
||||
|
||||
function maybeRenderPdfDoc(isNotPOST) {
|
||||
if (!isNotPOST) {
|
||||
// The document was loaded through a POST request, but we cannot access the
|
||||
// original response body, nor safely send a new request to fetch the PDF.
|
||||
// Until #4483 is fixed, POST requests should be ignored.
|
||||
return;
|
||||
}
|
||||
|
||||
// Detected PDF that was not redirected by the declarativeNetRequest rules.
|
||||
// Maybe because this was served without Content-Type and sniffed as PDF.
|
||||
// Or because this is Chrome 127-, which does not support responseHeaders
|
||||
// condition in declarativeNetRequest (DNR), and PDF requests are therefore
|
||||
// not redirected via DNR.
|
||||
|
||||
// In any case, load the viewer.
|
||||
console.log(`Detected PDF via document, opening viewer for ${document.URL}`);
|
||||
|
||||
// Ideally we would use logic consistent with the DNR logic, like this:
|
||||
// location.href = getEmbeddedViewerURL(document.URL);
|
||||
// ... unfortunately, this causes Chrome to crash until version 129, fixed by
|
||||
// https://chromium.googlesource.com/chromium/src/+/8c42358b2cc549553d939efe7d36515d80563da7%5E%21/
|
||||
// Work around this by replacing the body with an iframe of the viewer.
|
||||
// Interestingly, Chrome's built-in PDF viewer uses a similar technique.
|
||||
const shadowRoot = document.body.attachShadow({ mode: "closed" });
|
||||
const iframe = document.createElement("iframe");
|
||||
iframe.style.position = "absolute";
|
||||
iframe.style.top = "0";
|
||||
iframe.style.left = "0";
|
||||
iframe.style.width = "100%";
|
||||
iframe.style.height = "100%";
|
||||
iframe.style.border = "0 none";
|
||||
iframe.src = getEmbeddedViewerURL(document.URL);
|
||||
shadowRoot.append(iframe);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user