Compare commits
No commits in common. "master" and "v1.4.11" have entirely different histories.
@ -1,6 +1,6 @@
|
|||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*.{js,jsm,mjs,json,html,css,pdf.link}]
|
[*.{js,jsm,html,css}]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
@ -9,12 +9,9 @@ insert_final_newline = true
|
|||||||
max_line_length = 80
|
max_line_length = 80
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
[*.{json,pdf.link}]
|
|
||||||
max_line_length = off
|
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
max_line_length = off
|
max_line_length = 0
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[COMMIT_EDITMSG]
|
[COMMIT_EDITMSG]
|
||||||
max_line_length = off
|
max_line_length = 0
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
build/
|
|
||||||
l10n/
|
|
||||||
docs/
|
|
||||||
node_modules/
|
|
||||||
external/bcmaps/
|
|
||||||
external/builder/fixtures/
|
|
||||||
external/builder/fixtures_esprima/
|
|
||||||
external/quickjs/
|
|
||||||
test/tmp/
|
|
||||||
test/pdfs/
|
|
||||||
web/locale/
|
|
||||||
*~/
|
|
267
.eslintrc
@ -1,267 +0,0 @@
|
|||||||
{
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 2022,
|
|
||||||
"sourceType": "module",
|
|
||||||
},
|
|
||||||
|
|
||||||
"plugins": [
|
|
||||||
"import",
|
|
||||||
"json",
|
|
||||||
"mozilla",
|
|
||||||
"no-unsanitized",
|
|
||||||
"sort-exports",
|
|
||||||
"unicorn",
|
|
||||||
],
|
|
||||||
|
|
||||||
"extends": [
|
|
||||||
"plugin:json/recommended",
|
|
||||||
"plugin:prettier/recommended"
|
|
||||||
],
|
|
||||||
|
|
||||||
"env": {
|
|
||||||
"browser": true,
|
|
||||||
"es2022": true,
|
|
||||||
"worker": true,
|
|
||||||
},
|
|
||||||
|
|
||||||
"globals": {
|
|
||||||
"PDFJSDev": "readonly",
|
|
||||||
"__non_webpack_import__": "readonly",
|
|
||||||
},
|
|
||||||
|
|
||||||
"rules": {
|
|
||||||
// Plugins
|
|
||||||
"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-self-import": "error",
|
|
||||||
"import/no-unresolved": ["error", {
|
|
||||||
"ignore": ["display", "pdfjs", "pdfjs-lib", "pdfjs-web", "web", "fluent-bundle", "fluent-dom"],
|
|
||||||
}],
|
|
||||||
"mozilla/avoid-removeChild": "error",
|
|
||||||
"mozilla/use-includes-instead-of-indexOf": "error",
|
|
||||||
"no-unsanitized/method": "error",
|
|
||||||
"no-unsanitized/property": "error",
|
|
||||||
"sort-exports/sort-exports": ["error", {
|
|
||||||
"ignoreCase": true,
|
|
||||||
}],
|
|
||||||
"unicorn/no-abusive-eslint-disable": "error",
|
|
||||||
"unicorn/no-array-push-push": "error",
|
|
||||||
"unicorn/no-instanceof-array": "error",
|
|
||||||
"unicorn/no-invalid-remove-event-listener": "error",
|
|
||||||
"unicorn/no-new-buffer": "error",
|
|
||||||
"unicorn/no-typeof-undefined": ["error", {
|
|
||||||
"checkGlobalVariables": false,
|
|
||||||
}],
|
|
||||||
"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-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-string-replace-all": "error",
|
|
||||||
"unicorn/prefer-string-starts-ends-with": "error",
|
|
||||||
"unicorn/prefer-ternary": ["error", "only-single-line"],
|
|
||||||
|
|
||||||
// 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='Ref']",
|
|
||||||
"message": "Use `Ref.get()` rather than `new Ref()`.",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"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"],
|
|
||||||
},
|
|
||||||
}
|
|
@ -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
@ -4,7 +4,7 @@
|
|||||||
*.css text eol=lf
|
*.css text eol=lf
|
||||||
*.html text eol=lf
|
*.html text eol=lf
|
||||||
*.md text eol=lf
|
*.md text eol=lf
|
||||||
*.ftl text eol=lf
|
*.properties text eol=lf
|
||||||
*.yml text eol=lf
|
*.yml text eol=lf
|
||||||
*.json text eol=lf
|
*.json text eol=lf
|
||||||
*.config text eol=lf
|
*.config text eol=lf
|
||||||
|
1
.github/CODEOWNERS
vendored
@ -1 +0,0 @@
|
|||||||
l10n/en-US/*.ftl @mozilla/pdfjs-l10n
|
|
17
.github/ISSUE_TEMPLATE.md
vendored
@ -1,17 +0,0 @@
|
|||||||
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):
|
|
8
.github/dependabot.yml
vendored
@ -1,8 +0,0 @@
|
|||||||
version: 2
|
|
||||||
updates:
|
|
||||||
- package-ecosystem: "github-actions"
|
|
||||||
directory: "/"
|
|
||||||
schedule:
|
|
||||||
interval: "weekly"
|
|
||||||
labels:
|
|
||||||
- "dependencies"
|
|
27
.github/fluent_linter_config.yml
vendored
@ -1,27 +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: []
|
|
1
.github/requirements.txt
vendored
@ -1 +0,0 @@
|
|||||||
moz-fluent-linter==0.4.*
|
|
37
.github/workflows/ci.yml
vendored
@ -1,37 +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: [18, lts/*, latest]
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Gulp
|
|
||||||
run: npm install -g gulp-cli
|
|
||||||
|
|
||||||
- name: Install other dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Run external tests
|
|
||||||
run: gulp externaltest
|
|
||||||
|
|
||||||
- name: Run CLI unit tests
|
|
||||||
run: gulp unittestcli
|
|
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@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
|
||||||
uses: github/codeql-action/init@v3
|
|
||||||
with:
|
|
||||||
languages: ${{ matrix.language }}
|
|
||||||
queries: security-and-quality
|
|
||||||
|
|
||||||
- name: Autobuild CodeQL
|
|
||||||
uses: github/codeql-action/autobuild@v3
|
|
||||||
|
|
||||||
- name: Perform CodeQL analysis
|
|
||||||
uses: github/codeql-action/analyze@v3
|
|
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@v4
|
|
||||||
|
|
||||||
- name: Use Python 3.12
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
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
|
|
64
.github/workflows/font_tests.yml
vendored
@ -1,64 +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@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Gulp
|
|
||||||
run: npm install -g gulp-cli
|
|
||||||
|
|
||||||
- name: Install other dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Use Python 3.12
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
cache: 'pip'
|
|
||||||
|
|
||||||
- name: Install Fonttools
|
|
||||||
run: pip install fonttools
|
|
||||||
|
|
||||||
- name: Run font tests
|
|
||||||
run: gulp fonttest --headless
|
|
37
.github/workflows/lint.yml
vendored
@ -1,37 +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@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Gulp
|
|
||||||
run: npm install -g gulp-cli
|
|
||||||
|
|
||||||
- name: Install other dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Run lint
|
|
||||||
run: gulp lint
|
|
||||||
|
|
||||||
- name: Run lint-chromium
|
|
||||||
run: gulp lint-chromium
|
|
72
.github/workflows/publish_website.yml
vendored
@ -1,72 +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@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Gulp
|
|
||||||
run: npm install -g gulp-cli
|
|
||||||
|
|
||||||
- name: Install other dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Build the website
|
|
||||||
run: 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@v4
|
|
||||||
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
|
|
34
.github/workflows/types_tests.yml
vendored
@ -1,34 +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@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Use Node.js ${{ matrix.node-version }}
|
|
||||||
uses: actions/setup-node@v4
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
|
|
||||||
- name: Install Gulp
|
|
||||||
run: npm install -g gulp-cli
|
|
||||||
|
|
||||||
- name: Install other dependencies
|
|
||||||
run: npm install
|
|
||||||
|
|
||||||
- name: Run types tests
|
|
||||||
run: gulp typestest
|
|
1
.gitignore
vendored
@ -6,4 +6,3 @@ tags
|
|||||||
Makefile
|
Makefile
|
||||||
node_modules/
|
node_modules/
|
||||||
examples/node/svgdump/
|
examples/node/svgdump/
|
||||||
examples/node/pdf2png/*.png
|
|
||||||
|
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
@ -1,7 +0,0 @@
|
|||||||
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
@ -1,13 +0,0 @@
|
|||||||
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
|
|
17
.jshintignore
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
build/
|
||||||
|
l10n/
|
||||||
|
docs/
|
||||||
|
node_modules/
|
||||||
|
examples/
|
||||||
|
external/webL10n/
|
||||||
|
external/shelljs/
|
||||||
|
external/jpgjs/
|
||||||
|
external/jasmine/
|
||||||
|
external/cmapscompress/
|
||||||
|
external/importL10n/
|
||||||
|
shared/
|
||||||
|
test/tmp/
|
||||||
|
test/features/
|
||||||
|
test/resources/
|
||||||
|
test/font/*_spec.js
|
||||||
|
*~/
|
32
.jshintrc
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
// Environments
|
||||||
|
"browser": true,
|
||||||
|
"devel": true,
|
||||||
|
"worker": true,
|
||||||
|
"predef": [
|
||||||
|
"Promise",
|
||||||
|
"require",
|
||||||
|
"define",
|
||||||
|
"exports"
|
||||||
|
],
|
||||||
|
|
||||||
|
// Enforcing
|
||||||
|
"maxlen": 80,
|
||||||
|
"quotmark": "single",
|
||||||
|
"trailing": true,
|
||||||
|
"curly": true,
|
||||||
|
"undef": true,
|
||||||
|
"noarg": true,
|
||||||
|
"nonbsp": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
|
||||||
|
// Relaxing
|
||||||
|
"boss": true,
|
||||||
|
"funcscope": true,
|
||||||
|
"globalstrict": true,
|
||||||
|
"loopfunc": true,
|
||||||
|
"maxerr": 1000,
|
||||||
|
"nonstandard": true,
|
||||||
|
"sub": true,
|
||||||
|
"validthis": true
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
build/
|
|
||||||
l10n/
|
|
||||||
docs/
|
|
||||||
node_modules/
|
|
||||||
external/bcmaps/
|
|
||||||
external/builder/fixtures/
|
|
||||||
external/builder/fixtures_esprima/
|
|
||||||
external/quickjs/
|
|
||||||
test/tmp/
|
|
||||||
test/pdfs/
|
|
||||||
web/locale/
|
|
||||||
*~/
|
|
18
.prettierrc
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"arrowParens": "avoid",
|
|
||||||
"endOfLine": "lf",
|
|
||||||
"printWidth": 80,
|
|
||||||
"semi": true,
|
|
||||||
"tabWidth": 2,
|
|
||||||
"trailingComma": "es5",
|
|
||||||
"useTabs": false,
|
|
||||||
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
files: ["tsconfig.json"],
|
|
||||||
options: {
|
|
||||||
parser: "json",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
build/
|
|
||||||
l10n/
|
|
||||||
docs/
|
|
||||||
node_modules/
|
|
||||||
external/bcmaps/
|
|
||||||
external/builder/fixtures/
|
|
||||||
external/builder/fixtures_esprima/
|
|
||||||
external/quickjs/
|
|
||||||
test/tmp/
|
|
||||||
test/pdfs/
|
|
||||||
web/locale/
|
|
||||||
*~/
|
|
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,
|
|
||||||
},
|
|
||||||
}
|
|
3
.travis.yml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js:
|
||||||
|
- "0.12"
|
2
AUTHORS
@ -16,11 +16,9 @@ Jonas Jenwald <jonas.jenwald@gmail.com>
|
|||||||
Julian Viereck
|
Julian Viereck
|
||||||
Justin D'Arcangelo <justindarc@gmail.com>
|
Justin D'Arcangelo <justindarc@gmail.com>
|
||||||
Kalervo Kujala
|
Kalervo Kujala
|
||||||
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
|
|
||||||
Ophir Lojkine <@lovasoa>
|
Ophir Lojkine <@lovasoa>
|
||||||
Rob Wu <rob@robwu.nl>
|
Rob Wu <rob@robwu.nl>
|
||||||
Shaon Barman <shaon.barman@gmail.com>
|
Shaon Barman <shaon.barman@gmail.com>
|
||||||
Sehyun Park <premed055515@gmail.com>
|
|
||||||
Tim van der Meij <info@timvandermeij.nl>
|
Tim van der Meij <info@timvandermeij.nl>
|
||||||
Vivin Paliath <vivin.paliath@gmail.com>
|
Vivin Paliath <vivin.paliath@gmail.com>
|
||||||
Vivien Nicolas <21@vingtetun.org>
|
Vivien Nicolas <21@vingtetun.org>
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
# Community Participation Guidelines
|
|
||||||
|
|
||||||
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
|
|
||||||
For more details, please read the
|
|
||||||
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
|
|
||||||
|
|
||||||
## How to Report
|
|
||||||
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
|
|
||||||
|
|
||||||
<!--
|
|
||||||
## Project Specific Etiquette
|
|
||||||
|
|
||||||
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
|
|
||||||
Please update for your project.
|
|
||||||
-->
|
|
@ -4,11 +4,11 @@ The issues are used to track both bugs filed by users and specific work items fo
|
|||||||
|
|
||||||
If the issue is related to errors produced by a specific PDF, please always include the PDF by providing a URL where contributors can download it. Without a PDF for reproduction, such issues will be closed. We understand that many PDFs contain sensitive information, however having a PDF is essential to resolving the issue and building our regression testing suite. If possible, try creating a reduced example exhibiting the problem but not containing sensitive data. Also small PDFs are best suited for our regression testing. If an important issue only shows on sensitive PDFs, contributors might be willing to accept these PDFs via a secure exchange.
|
If the issue is related to errors produced by a specific PDF, please always include the PDF by providing a URL where contributors can download it. Without a PDF for reproduction, such issues will be closed. We understand that many PDFs contain sensitive information, however having a PDF is essential to resolving the issue and building our regression testing suite. If possible, try creating a reduced example exhibiting the problem but not containing sensitive data. Also small PDFs are best suited for our regression testing. If an important issue only shows on sensitive PDFs, contributors might be willing to accept these PDFs via a secure exchange.
|
||||||
|
|
||||||
The issue tracking system is designed to record a single technical problem. A bug report is something where a developer/contributor can work on. The GitHub issue tracker is not a good place for general, not well thought out or unworkable ideas. Most likely a discussion-type issue will not be addressed for a long time or closed as invalid. The best place for general discussions is our Matrix room at https://chat.mozilla.org/#/room/#pdfjs:mozilla.org.
|
The issue tracking system is designed to record a single technical problem. A bug report is something where a developer/contributor can work on. The GitHub issue tracker is not a good place for general, not well thought out or unworkable ideas. Most likely a discussion-type issue will not be addressed for a long time or closed as invalid. The best place is our dev-pdf-js@lists.mozilla.org mailing list. You can subscribe to it using http://lists.mozilla.org or Google Groups. This way you will reach not only developers. As an alternative, you can join our weekly engineering meeting to discuss new ideas for the project.
|
||||||
|
|
||||||
If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us in the Matrix room -- keep in mind that just code snippets won't help us troubleshoot the problem.
|
If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us on the IRC channel -- keep in mind that just code snippets won't help us troubleshoot the problem.
|
||||||
|
|
||||||
Note that the translations for PDF.js in the `l10n` folder are imported from the Nightly channel of Mozilla Firefox, such that we don't have to maintain them ourselves. This means that we will not accept pull requests that add new languages and/or modify existing translations, unless the corresponding changes have been made in Mozilla Firefox first.
|
Note that the translations for PDF.js in the `l10n` folder are synchronized with the Aurora branch of Mozilla Firefox. This means that we will only accept pull requests that add strings currently missing in the Aurora branch (because it will take at least six weeks before the most recent translations are in the Aurora branch), but keep in mind that the changes will be overwritten when we synchronize again.
|
||||||
|
|
||||||
See also:
|
See also:
|
||||||
- https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
|
- https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
|
5
EXPORT
@ -1,5 +0,0 @@
|
|||||||
PDF.js is publicly available software not subject to the Export Administration
|
|
||||||
Regulations (EAR) per EAR 734.3(b) and 734.7. Because PDF.js is not subject
|
|
||||||
to the EAR it does not have an Export Control Classification Number (ECCN).
|
|
||||||
Mozilla has completed the notification for PDF.js publicly available encryption
|
|
||||||
source code per EAR 742.15(b).
|
|
138
README.md
@ -1,46 +1,46 @@
|
|||||||
# PDF.js [](https://github.com/mozilla/pdf.js/actions?query=workflow%3ACI+branch%3Amaster)
|
# 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 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
|
create a general-purpose, web standards-based platform for parsing and
|
||||||
rendering PDFs.
|
rendering PDFs.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
PDF.js is an open source project and always looking for more contributors. To
|
PDF.js is an open source project and always looking for more contributors. To
|
||||||
get involved, visit:
|
get involved checkout:
|
||||||
|
|
||||||
+ [Issue Reporting Guide](https://github.com/mozilla/pdf.js/blob/master/.github/CONTRIBUTING.md)
|
+ [Issue Reporting Guide](https://github.com/mozilla/pdf.js/blob/master/CONTRIBUTING.md)
|
||||||
+ [Code Contribution Guide](https://github.com/mozilla/pdf.js/wiki/Contributing)
|
+ [Code Contribution Guide](https://github.com/mozilla/pdf.js/wiki/Contributing)
|
||||||
+ [Frequently Asked Questions](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions)
|
+ [Frequently Asked Questions](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions)
|
||||||
+ [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?direction=desc&labels=good-beginner-bug&page=1&sort=created&state=open)
|
+ [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)
|
+ [Priorities](https://github.com/mozilla/pdf.js/milestones)
|
||||||
|
+ [Attend a Public Meeting](https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings)
|
||||||
|
|
||||||
Feel free to stop by our [Matrix room](https://chat.mozilla.org/#/room/#pdfjs:mozilla.org) for questions or guidance.
|
For further questions or guidance feel free to stop by #pdfjs on
|
||||||
|
irc.mozilla.org.
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
### Online demo
|
### Online demo
|
||||||
|
|
||||||
Please note that the "Modern browsers" version assumes native support for the
|
+ http://mozilla.github.io/pdf.js/web/viewer.html
|
||||||
latest JavaScript features; please also see [this wiki page](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support).
|
|
||||||
|
|
||||||
+ Modern browsers: https://mozilla.github.io/pdf.js/web/viewer.html
|
|
||||||
|
|
||||||
+ Older browsers: https://mozilla.github.io/pdf.js/legacy/web/viewer.html
|
|
||||||
|
|
||||||
### Browser Extensions
|
### Browser Extensions
|
||||||
|
|
||||||
#### Firefox
|
#### Firefox and Seamonkey
|
||||||
|
|
||||||
PDF.js is built into version 19+ of Firefox.
|
PDF.js is built into version 19+ of Firefox, however the extension is still available:
|
||||||
|
|
||||||
#### Chrome
|
+ [Development Version](http://mozilla.github.io/pdf.js/extensions/firefox/pdf.js.xpi) - This version is updated every time new code is merged into the PDF.js codebase. This should be quite stable but still might break from time to time. This version is also reported to work when installed as extension in Seamonkey 2.39.
|
||||||
|
|
||||||
|
#### Chrome and Opera
|
||||||
|
|
||||||
+ The official extension for Chrome can be installed from the [Chrome Web Store](https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm).
|
+ 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).*
|
*This extension is maintained by [@Rob--W](https://github.com/Rob--W).*
|
||||||
+ Build Your Own - Get the code as explained below and issue `gulp chromium`. Then open
|
+ Opera has also published an extension for their browser at the [Opera add-ons catalog](https://addons.opera.com/en/extensions/details/pdf-viewer/).
|
||||||
|
+ Build Your Own - Get the code as explained below and issue `node make chromium`. Then open
|
||||||
Chrome, go to `Tools > Extension` and load the (unpackaged) extension from the
|
Chrome, go to `Tools > Extension` and load the (unpackaged) extension from the
|
||||||
directory `build/chromium`.
|
directory `build/chromium`.
|
||||||
|
|
||||||
@ -48,99 +48,91 @@ directory `build/chromium`.
|
|||||||
|
|
||||||
To get a local copy of the current code, clone it using git:
|
To get a local copy of the current code, clone it using git:
|
||||||
|
|
||||||
$ git clone https://github.com/mozilla/pdf.js.git
|
$ git clone git://github.com/mozilla/pdf.js.git
|
||||||
$ cd pdf.js
|
$ cd pdf.js
|
||||||
|
|
||||||
Next, install Node.js via the [official package](https://nodejs.org) or via
|
Next, install Node.js via the [official package](http://nodejs.org) or via
|
||||||
[nvm](https://github.com/creationix/nvm). You need to install the gulp package
|
[nvm](https://github.com/creationix/nvm). If everything worked out, run
|
||||||
globally (see also [gulp's getting started](https://github.com/gulpjs/gulp/tree/master/docs/getting-started)):
|
|
||||||
|
|
||||||
$ npm install -g gulp-cli@^2.3.0
|
|
||||||
|
|
||||||
If you prefer to not install `gulp-cli` globally, you have to prefix all the `gulp` commands with `npx` (for example, `npx gulp server` instead of `gulp server`).
|
|
||||||
|
|
||||||
If everything worked out, install all dependencies for PDF.js:
|
|
||||||
|
|
||||||
$ npm install
|
$ npm install
|
||||||
|
|
||||||
> [!NOTE]
|
to install all dependencies for PDF.js.
|
||||||
> On MacOS M1/M2 you may see some `node-gyp`-related errors when running `npm install`. This is because one of our dependencies, `"canvas"`, does not provide pre-built binaries for this platform and instead `npm` will try to build it from source. Please make sure to first install the necessary native dependencies using `brew`: https://github.com/Automattic/node-canvas#compiling.
|
|
||||||
|
|
||||||
Finally, you need to start a local web server as some browsers do not allow opening
|
Finally you need to start a local web server as some browsers do not allow opening
|
||||||
PDF files using a `file://` URL. Run:
|
PDF files using a file:// URL. Run
|
||||||
|
|
||||||
$ gulp server
|
$ node make server
|
||||||
|
|
||||||
and then you can open:
|
and then you can open
|
||||||
|
|
||||||
+ http://localhost:8888/web/viewer.html
|
+ 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.
|
It is also possible to view all test PDF files on the right side by opening
|
||||||
|
|
||||||
It is also possible to view all test PDF files on the right side by opening:
|
|
||||||
|
|
||||||
+ http://localhost:8888/test/pdfs/?frame
|
+ http://localhost:8888/test/pdfs/?frame
|
||||||
|
|
||||||
## Building PDF.js
|
## Building PDF.js
|
||||||
|
|
||||||
In order to bundle all `src/` files into two production scripts and build the generic
|
In order to bundle all `src/` files into two productions scripts and build the generic
|
||||||
viewer, run:
|
viewer, issue:
|
||||||
|
|
||||||
$ gulp generic
|
$ node make generic
|
||||||
|
|
||||||
If you need to support older browsers, run:
|
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory.
|
||||||
|
|
||||||
$ gulp generic-legacy
|
|
||||||
|
|
||||||
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory (respectively `build/generic-legacy/build/`).
|
|
||||||
Both scripts are needed but only `pdf.js` needs to be included since `pdf.worker.js` will
|
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.
|
be loaded by `pdf.js`. If you want to support more browsers than Firefox you'll also need
|
||||||
|
to include `compatibility.js` from `build/generic/web/`. The PDF.js files are large and
|
||||||
## Using PDF.js in a web application
|
should be minified for production.
|
||||||
|
|
||||||
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 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.
|
|
||||||
|
|
||||||
## Including via a CDN
|
|
||||||
|
|
||||||
PDF.js is hosted on several free CDNs:
|
|
||||||
- https://www.jsdelivr.com/package/npm/pdfjs-dist
|
|
||||||
- https://cdnjs.com/libraries/pdf.js
|
|
||||||
- https://unpkg.com/pdfjs-dist/
|
|
||||||
|
|
||||||
## Learning
|
## Learning
|
||||||
|
|
||||||
You can play with the PDF.js API directly from your browser using the live demos below:
|
You can play with the PDF.js API directly from your browser through the live
|
||||||
|
demos below:
|
||||||
|
|
||||||
+ [Interactive examples](https://mozilla.github.io/pdf.js/examples/index.html#interactive-examples)
|
+ [Hello world](http://mozilla.github.io/pdf.js/examples/learning/helloworld.html)
|
||||||
|
+ [Simple reader with prev/next page controls](http://mozilla.github.io/pdf.js/examples/learning/prevnext.html)
|
||||||
|
|
||||||
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.
|
The repo contains a hello world example that you can run locally:
|
||||||
|
|
||||||
|
+ [examples/helloworld/](https://github.com/mozilla/pdf.js/blob/master/examples/helloworld/)
|
||||||
|
|
||||||
For an introduction to the PDF.js code, check out the presentation by our
|
For an introduction to the PDF.js code, check out the presentation by our
|
||||||
contributor Julian Viereck:
|
contributor Julian Viereck:
|
||||||
|
|
||||||
+ https://www.youtube.com/watch?v=Iv15UY-4Fg8
|
+ http://www.youtube.com/watch?v=Iv15UY-4Fg8
|
||||||
|
|
||||||
More learning resources can be found at:
|
You can read more about PDF.js here:
|
||||||
|
|
||||||
|
+ http://andreasgal.com/2011/06/15/pdf-js/
|
||||||
|
+ http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/
|
||||||
|
|
||||||
|
Even more learning resources can be found at:
|
||||||
|
|
||||||
+ https://github.com/mozilla/pdf.js/wiki/Additional-Learning-Resources
|
+ https://github.com/mozilla/pdf.js/wiki/Additional-Learning-Resources
|
||||||
|
|
||||||
The API documentation can be found at:
|
|
||||||
|
|
||||||
+ https://mozilla.github.io/pdf.js/api/
|
|
||||||
|
|
||||||
## Questions
|
## Questions
|
||||||
|
|
||||||
Check out our FAQs and get answers to common questions:
|
Check out our FAQs and get answers to common questions:
|
||||||
|
|
||||||
+ https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
|
+ https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
|
||||||
|
|
||||||
Talk to us on Matrix:
|
Talk to us on IRC:
|
||||||
|
|
||||||
+ https://chat.mozilla.org/#/room/#pdfjs:mozilla.org
|
+ #pdfjs on irc.mozilla.org
|
||||||
|
|
||||||
File an issue:
|
Join our mailing list:
|
||||||
|
|
||||||
+ https://github.com/mozilla/pdf.js/issues/new
|
+ dev-pdf-js@lists.mozilla.org
|
||||||
|
|
||||||
|
Subscribe either using lists.mozilla.org or Google Groups:
|
||||||
|
|
||||||
|
+ https://lists.mozilla.org/listinfo/dev-pdf-js
|
||||||
|
+ https://groups.google.com/group/mozilla.dev.pdf-js/topics
|
||||||
|
|
||||||
|
Follow us on twitter: @pdfjs
|
||||||
|
|
||||||
|
+ http://twitter.com/#!/pdfjs
|
||||||
|
|
||||||
|
Weekly Public Meetings
|
||||||
|
|
||||||
|
+ https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings
|
||||||
|
@ -5,26 +5,22 @@ template: layout.jade
|
|||||||
|
|
||||||
## Hello World Walkthrough
|
## Hello World Walkthrough
|
||||||
|
|
||||||
[Full source](https://github.com/mozilla/pdf.js/blob/master/examples/learning/helloworld.html)
|
[Full source](https://github.com/mozilla/pdf.js/tree/master/examples/helloworld)
|
||||||
|
|
||||||
PDF.js heavily relies on the use of [Promises](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise). If promises are new to you, it's recommended you become familiar with them before continuing on.
|
PDF.js heavily relies on the use of [Promises](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise). If promises are new to you, it's recommended you become familiar with them before continuing on.
|
||||||
|
|
||||||
This tutorial shows how PDF.js can be used as a library in a web browser.
|
|
||||||
[examples/](https://github.com/mozilla/pdf.js/tree/master/examples) provides more examples, including usage in Node.js (at [examples/node/](https://github.com/mozilla/pdf.js/tree/master/examples/node)).
|
|
||||||
|
|
||||||
### Document
|
### Document
|
||||||
|
|
||||||
The object structure of PDF.js loosely follows the structure of an actual PDF. At the top level there is a document object. From the document, more information and individual pages can be fetched. To get the document:
|
The object structure of PDF.js loosely follows the structure of an actual PDF. At the top level there is a document object. From the document, more information and individual pages can be fetched. To get the document:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
pdfjsLib.getDocument('helloworld.pdf')
|
PDFJS.getDocument('helloworld.pdf')
|
||||||
```
|
```
|
||||||
|
|
||||||
Remember though that PDF.js uses promises, and the above will return a `PDFDocumentLoadingTask` instance that has a `promise` property which is resolved with the document object.
|
Remember though that PDF.js uses promises, so the above will return a promise that is resolved with the document object.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var loadingTask = pdfjsLib.getDocument('helloworld.pdf');
|
PDFJS.getDocument('helloworld.pdf').then(function(pdf) {
|
||||||
loadingTask.promise.then(function(pdf) {
|
|
||||||
// you can now use *pdf* here
|
// you can now use *pdf* here
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
@ -39,29 +35,19 @@ pdf.getPage(1).then(function(page) {
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Rendering the Page
|
### Rendering the Page
|
||||||
Each PDF page has its own viewport which defines the size in pixels(72DPI) and initial rotation. By default the viewport is scaled to the original size of the PDF, but this can be changed by modifying the viewport. When the viewport is created, an initial transformation matrix will also be created that takes into account the desired scale, rotation, and it transforms the coordinate system (the 0,0 point in PDF documents the bottom-left whereas canvas 0,0 is top-left).
|
Each PDF page has its own viewport which defines the size in pixels(72DPI) and initial rotation. By default the viewport is scaled to the original size of the PDF, but this can be changed by modifying the viewport. When the viewport is created an initial transformation matrix will also be created that takes into account the desired scale, rotation, and it transforms the coordinate system (the 0,0 point in PDF documents the bottom-left whereas canvas 0,0 is top-left).
|
||||||
|
|
||||||
```js
|
```js
|
||||||
var scale = 1.5;
|
var scale = 1.5;
|
||||||
var viewport = page.getViewport({ scale: scale, });
|
var viewport = page.getViewport(scale);
|
||||||
// Support HiDPI-screens.
|
|
||||||
var outputScale = window.devicePixelRatio || 1;
|
|
||||||
|
|
||||||
var canvas = document.getElementById('the-canvas');
|
var canvas = document.getElementById('the-canvas');
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
|
canvas.height = viewport.height;
|
||||||
canvas.width = Math.floor(viewport.width * outputScale);
|
canvas.width = viewport.width;
|
||||||
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 renderContext = {
|
var renderContext = {
|
||||||
canvasContext: context,
|
canvasContext: context,
|
||||||
transform: transform,
|
|
||||||
viewport: viewport
|
viewport: viewport
|
||||||
};
|
};
|
||||||
page.render(renderContext);
|
page.render(renderContext);
|
||||||
@ -71,29 +57,7 @@ Alternatively, if you want the canvas to render to a certain pixel size you coul
|
|||||||
|
|
||||||
```js
|
```js
|
||||||
var desiredWidth = 100;
|
var desiredWidth = 100;
|
||||||
var viewport = page.getViewport({ scale: 1, });
|
var viewport = page.getViewport(1);
|
||||||
var scale = desiredWidth / viewport.width;
|
var scale = desiredWidth / viewport.width;
|
||||||
var scaledViewport = page.getViewport({ scale: scale, });
|
var scaledViewport = page.getViewport(scale);
|
||||||
```
|
```
|
||||||
|
|
||||||
## Interactive examples
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
<script async src="//jsfiddle.net/pdfjs/9engc9mw/embed/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="//jsfiddle.net/pdfjs/cq0asLqz/embed/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="//jsfiddle.net/pdfjs/wagvs9Lf/embed/html,css,result/"></script>
|
|
||||||
|
@ -21,7 +21,7 @@ Before downloading PDF.js please take a moment to understand the different layer
|
|||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Core</td>
|
<td>Core</td>
|
||||||
<td>The core layer is where a binary PDF is parsed and interpreted. This layer is the foundation for all subsequent layers. It is not documented here because using it directly is considered an advanced usage and the API is likely to change. For an example of using the core layer see the <a href="https://github.com/brendandahl/pdf.js.utils/tree/master/browser">PDF Object Browser</a>.
|
<td>The core layer is where a binary PDF is parsed and interpreted. This layer is the foundation for all subsequent layers. It is not documented here because using it directly is considered an advanced usage and the API is likely to change. For an example of using the core layer see the [PDF Object Browser](https://github.com/brendandahl/pdf.js.utils/tree/master/browser)
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
@ -30,98 +30,85 @@ Before downloading PDF.js please take a moment to understand the different layer
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Viewer</td>
|
<td>Viewer</td>
|
||||||
<td>The viewer is built on the display layer and is the UI for PDF viewer in Firefox and the other browser extensions within the project. It can be a good starting point for building your own viewer. <em>However, we do ask if you plan to embed the viewer in your own site, that it not just be an unmodified version. Please re-skin it or build upon it.</em></td>
|
<td>The viewer is built on the display layer and is the UI for PDF viewer in Firefox and the other browser extensions within the project. It can be a good starting point for building your own viewer. *However, we do ask if you plan to embed the viewer in your own site, that it not just be an unmodified version. Please re-skin it or build upon it.*</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
## Download
|
## 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="row">
|
||||||
<div class="col-md-4">
|
<div class="col-md-6">
|
||||||
<h3>Prebuilt (modern browsers)</h3>
|
<h3>Pre-built</h3>
|
||||||
<p>
|
<p>
|
||||||
Includes the generic build of PDF.js and the viewer.
|
Includes the generic build of PDF.js and the viewer.
|
||||||
</p>
|
</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="btn-group-vertical centered">
|
||||||
|
<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" href="https://github.com/mozilla/pdf.js/releases/download/vBETA_VERSION/pdfjs-BETA_VERSION-dist.zip">Beta (vBETA_VERSION)</a>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-6">
|
||||||
<h3>Prebuilt (older browsers)</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>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-4">
|
|
||||||
<h3>Source</h3>
|
<h3>Source</h3>
|
||||||
To get a local copy of the current code, clone it using git:
|
To get a local copy of the current code, clone it using git:
|
||||||
<pre><code>$ git clone https://github.com/mozilla/pdf.js.git
|
<pre><code>$ git clone git://github.com/mozilla/pdf.js.git
|
||||||
$ cd pdf.js
|
$ cd pdf.js
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
## Including via a CDN
|
|
||||||
|
|
||||||
PDF.js is hosted on several free CDNs:
|
|
||||||
- https://www.jsdelivr.com/package/npm/pdfjs-dist
|
|
||||||
- https://cdnjs.com/libraries/pdf.js
|
|
||||||
- https://unpkg.com/pdfjs-dist/
|
|
||||||
|
|
||||||
## File Layout Overview
|
## File Layout Overview
|
||||||
|
|
||||||
Note that we only mention the most relevant files and folders.
|
|
||||||
|
|
||||||
### Prebuilt
|
### Prebuilt
|
||||||
|
|
||||||
```
|
```
|
||||||
|
├── LICENSE
|
||||||
├── build/
|
├── build/
|
||||||
│ ├── pdf.js - display layer
|
│ ├── pdf.js - display layer
|
||||||
│ ├── pdf.js.map - display layer's source map
|
│ └── pdf.worker.js - core layer
|
||||||
│ ├── pdf.worker.js - core layer
|
└── web/
|
||||||
│ └── pdf.worker.js.map - core layer's source map
|
├── cmaps/ - character maps(required by core)
|
||||||
├── web/
|
├── compatibility.js - polyfills for missing features
|
||||||
│ ├── cmaps/ - character maps (required by core)
|
├── compressed.tracemonkey-pldi-09.pdf - test pdf
|
||||||
│ ├── compressed.tracemonkey-pldi-09.pdf - PDF file for testing purposes
|
├── debugger.js - helpful pdf debugging features
|
||||||
│ ├── debugger.js - helpful debugging features
|
├── images/ - images for the viewer and annotation icons
|
||||||
│ ├── images/ - images for the viewer and annotation icons
|
├── l10n.js - localization
|
||||||
│ ├── locale/ - translation files
|
├── locale/ - translation files
|
||||||
│ ├── viewer.css - viewer style sheet
|
├── viewer.css - viewer style sheet
|
||||||
│ ├── viewer.html - viewer layout
|
├── viewer.html - viewer html
|
||||||
│ ├── viewer.js - viewer layer
|
└── viewer.js - viewer layer
|
||||||
│ └── viewer.js.map - viewer layer's source map
|
|
||||||
└── LICENSE
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Source
|
### Source
|
||||||
|
|
||||||
```
|
```
|
||||||
├── docs/ - website source code
|
├── AUTHORS
|
||||||
├── examples/ - simple usage examples
|
├── CONTRIBUTING.md
|
||||||
├── extensions/ - browser extension source code
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── build/ - output of build steps (empty)
|
||||||
|
├── docs/ - this
|
||||||
|
├── examples/ - bare bones examples
|
||||||
|
├── extensions/ - various browser extensions
|
||||||
├── external/ - third party code
|
├── external/ - third party code
|
||||||
├── l10n/ - translation files
|
├── l10n/ - translation files
|
||||||
|
├── make.js - build script
|
||||||
|
├── package.json
|
||||||
├── src/
|
├── src/
|
||||||
│ ├── core/ - core layer
|
│ ├── core/ - core layer
|
||||||
│ ├── display/ - display layer
|
│ ├── display/ - display layer
|
||||||
│ ├── shared/ - shared code between the core and display layers
|
│ ├── images/
|
||||||
│ ├── interfaces.js - interface definitions for the core/display layers
|
│ ├── pdf.js - wrapper file that everything is bundled into
|
||||||
│ └── pdf.*.js - wrapper files for bundling
|
│ ├── shared/ - shared code between core and display layers
|
||||||
├── test/ - unit, font, reference, and integration tests
|
│ └── worker_loader.js - used for developer builds to load worker files
|
||||||
├── web/ - viewer layer
|
├── test/ - reference, unit, and font tests
|
||||||
├── LICENSE
|
└── web/ - viewer layer
|
||||||
├── README.md
|
|
||||||
├── gulpfile.js - build scripts/logic
|
|
||||||
├── package-lock.json - pinned dependency versions
|
|
||||||
└── package.json - package definition and dependencies
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Trying the Viewer
|
## 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 `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 `node make server`.
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
|
||||||
For a further walkthrough of a minimal viewer, see the hello world example. More documentation can be found in our [wiki](https://github.com/mozilla/pdf.js/wiki) too.
|
For a further walkthrough of a minimal viewer see the hello world example. More documentation can be found in our [wiki](https://github.com/mozilla/pdf.js/wiki) too.
|
||||||
|
@ -9,6 +9,6 @@ template: layout.jade
|
|||||||
</p>
|
</p>
|
||||||
<p class="text-center">
|
<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="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="web/viewer.html">Demo</a>
|
||||||
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js">GitHub Project</a>
|
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js">Github Project</a>
|
||||||
</p>
|
</p>
|
||||||
|
@ -10,6 +10,6 @@ module.exports = (env, callback) ->
|
|||||||
depth = count(source, '/') # 1 being /
|
depth = count(source, '/') # 1 being /
|
||||||
ret = ""
|
ret = ""
|
||||||
ret += "../" while depth = depth - 1
|
ret += "../" while depth = depth - 1
|
||||||
ret + dest.substring(1)
|
ret + dest.substr(1)
|
||||||
|
|
||||||
callback()
|
callback()
|
6
docs/templates/layout.jade
vendored
@ -4,7 +4,7 @@ html(lang='en')
|
|||||||
head
|
head
|
||||||
meta(charset='utf-8')
|
meta(charset='utf-8')
|
||||||
meta(name='viewport', content='width=device-width, initial-scale=1.0')
|
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='description', content='')
|
||||||
meta(name='author', content='')
|
meta(name='author', content='')
|
||||||
link(rel='shortcut icon', href=makeRelative(page.url, '/images/favicon.ico'))
|
link(rel='shortcut icon', href=makeRelative(page.url, '/images/favicon.ico'))
|
||||||
title=page.title
|
title=page.title
|
||||||
@ -43,9 +43,9 @@ html(lang='en')
|
|||||||
.container
|
.container
|
||||||
footer
|
footer
|
||||||
p ©Mozilla and individual contributors
|
p ©Mozilla and individual contributors
|
||||||
:markdown-it
|
:markdown
|
||||||
PDF.js is licensed under [Apache](https://github.com/mozilla/pdf.js/blob/master/LICENSE),
|
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/)
|
documentation is licensed under [CC BY-SA 2.5](http://creativecommons.org/licenses/by-sa/2.5/)
|
||||||
|
|
||||||
// Bootstrap core JavaScript
|
// Bootstrap core JavaScript
|
||||||
script(src=makeRelative(page.url, '/js/jquery-2.1.0.min.js'))
|
script(src=makeRelative(page.url, '/js/jquery-2.1.0.min.js'))
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"../.eslintrc"
|
|
||||||
],
|
|
||||||
|
|
||||||
"globals": {
|
|
||||||
"pdfjsImageDecoders": false,
|
|
||||||
"pdfjsLib": false,
|
|
||||||
"pdfjsViewer": false,
|
|
||||||
},
|
|
||||||
}
|
|
160
examples/acroforms/forms.js
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
|
||||||
|
//
|
||||||
|
// Basic AcroForms input controls rendering
|
||||||
|
//
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Specify the PDF with AcroForm here
|
||||||
|
var pdfWithFormsPath = '../../test/pdfs/f1040.pdf';
|
||||||
|
|
||||||
|
var formFields = {};
|
||||||
|
|
||||||
|
function setupForm(div, content, viewport) {
|
||||||
|
function bindInputItem(input, item) {
|
||||||
|
if (input.name in formFields) {
|
||||||
|
var value = formFields[input.name];
|
||||||
|
if (input.type == 'checkbox') {
|
||||||
|
input.checked = value;
|
||||||
|
} else if (!input.type || input.type == 'text') {
|
||||||
|
input.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input.onchange = function pageViewSetupInputOnBlur() {
|
||||||
|
if (input.type == 'checkbox') {
|
||||||
|
formFields[input.name] = input.checked;
|
||||||
|
} else if (!input.type || input.type == 'text') {
|
||||||
|
formFields[input.name] = input.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function createElementWithStyle(tagName, item) {
|
||||||
|
var element = document.createElement(tagName);
|
||||||
|
var rect = PDFJS.Util.normalizeRect(
|
||||||
|
viewport.convertToViewportRectangle(item.rect));
|
||||||
|
element.style.left = Math.floor(rect[0]) + 'px';
|
||||||
|
element.style.top = Math.floor(rect[1]) + 'px';
|
||||||
|
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
|
||||||
|
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
function assignFontStyle(element, item) {
|
||||||
|
var fontStyles = '';
|
||||||
|
if ('fontSize' in item) {
|
||||||
|
fontStyles += 'font-size: ' + Math.round(item.fontSize *
|
||||||
|
viewport.fontScale) + 'px;';
|
||||||
|
}
|
||||||
|
switch (item.textAlignment) {
|
||||||
|
case 0:
|
||||||
|
fontStyles += 'text-align: left;';
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
fontStyles += 'text-align: center;';
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
fontStyles += 'text-align: right;';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
element.setAttribute('style', element.getAttribute('style') + fontStyles);
|
||||||
|
}
|
||||||
|
|
||||||
|
content.getAnnotations().then(function(items) {
|
||||||
|
for (var i = 0; i < items.length; i++) {
|
||||||
|
var item = items[i];
|
||||||
|
switch (item.subtype) {
|
||||||
|
case 'Widget':
|
||||||
|
if (item.fieldType != 'Tx' && item.fieldType != 'Btn' &&
|
||||||
|
item.fieldType != 'Ch') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
var inputDiv = createElementWithStyle('div', item);
|
||||||
|
inputDiv.className = 'inputHint';
|
||||||
|
div.appendChild(inputDiv);
|
||||||
|
var input;
|
||||||
|
if (item.fieldType == 'Tx') {
|
||||||
|
input = createElementWithStyle('input', item);
|
||||||
|
}
|
||||||
|
if (item.fieldType == 'Btn') {
|
||||||
|
input = createElementWithStyle('input', item);
|
||||||
|
if (item.flags & 32768) {
|
||||||
|
input.type = 'radio';
|
||||||
|
// radio button is not supported
|
||||||
|
} else if (item.flags & 65536) {
|
||||||
|
input.type = 'button';
|
||||||
|
// pushbutton is not supported
|
||||||
|
} else {
|
||||||
|
input.type = 'checkbox';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (item.fieldType == 'Ch') {
|
||||||
|
input = createElementWithStyle('select', item);
|
||||||
|
// select box is not supported
|
||||||
|
}
|
||||||
|
input.className = 'inputControl';
|
||||||
|
input.name = item.fullName;
|
||||||
|
input.title = item.alternativeText;
|
||||||
|
assignFontStyle(input, item);
|
||||||
|
bindInputItem(input, item);
|
||||||
|
div.appendChild(input);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderPage(div, pdf, pageNumber, callback) {
|
||||||
|
pdf.getPage(pageNumber).then(function(page) {
|
||||||
|
var scale = 1.5;
|
||||||
|
var viewport = page.getViewport(scale);
|
||||||
|
|
||||||
|
var pageDisplayWidth = viewport.width;
|
||||||
|
var pageDisplayHeight = viewport.height;
|
||||||
|
|
||||||
|
var pageDivHolder = document.createElement('div');
|
||||||
|
pageDivHolder.className = 'pdfpage';
|
||||||
|
pageDivHolder.style.width = pageDisplayWidth + 'px';
|
||||||
|
pageDivHolder.style.height = pageDisplayHeight + 'px';
|
||||||
|
div.appendChild(pageDivHolder);
|
||||||
|
|
||||||
|
// Prepare canvas using PDF page dimensions
|
||||||
|
var canvas = document.createElement('canvas');
|
||||||
|
var context = canvas.getContext('2d');
|
||||||
|
canvas.width = pageDisplayWidth;
|
||||||
|
canvas.height = pageDisplayHeight;
|
||||||
|
pageDivHolder.appendChild(canvas);
|
||||||
|
|
||||||
|
// Render PDF page into canvas context
|
||||||
|
var renderContext = {
|
||||||
|
canvasContext: context,
|
||||||
|
viewport: viewport
|
||||||
|
};
|
||||||
|
page.render(renderContext).promise.then(callback);
|
||||||
|
|
||||||
|
// Prepare and populate form elements layer
|
||||||
|
var formDiv = document.createElement('div');
|
||||||
|
pageDivHolder.appendChild(formDiv);
|
||||||
|
|
||||||
|
setupForm(formDiv, page, viewport);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// In production, the bundled pdf.js shall be used instead of RequireJS.
|
||||||
|
require.config({paths: {'pdfjs': '../../src'}});
|
||||||
|
require(['pdfjs/display/api'], function (api) {
|
||||||
|
// In production, change this to point to the built `pdf.worker.js` file.
|
||||||
|
PDFJS.workerSrc = '../../src/worker_loader.js';
|
||||||
|
|
||||||
|
// Fetch the PDF document from the URL using promises.
|
||||||
|
api.getDocument(pdfWithFormsPath).then(function getPdfForm(pdf) {
|
||||||
|
// Rendering all pages starting from first
|
||||||
|
var viewer = document.getElementById('viewer');
|
||||||
|
var pageNumber = 1;
|
||||||
|
renderPage(viewer, pdf, pageNumber++, function pageRenderingComplete() {
|
||||||
|
if (pageNumber > pdf.numPages) {
|
||||||
|
return; // All pages rendered
|
||||||
|
}
|
||||||
|
// Continue rendering of the next page
|
||||||
|
renderPage(viewer, pdf, pageNumber++, pageRenderingComplete);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
23
examples/acroforms/index.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="../../node_modules/requirejs/require.js"></script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.pdfpage { position:relative; top: 0; left: 0; border: solid 1px black; margin: 10px; }
|
||||||
|
.pdfpage > canvas { position: absolute; top: 0; left: 0; }
|
||||||
|
.pdfpage > div { position: absolute; top: 0; left: 0; }
|
||||||
|
.inputControl { background: transparent; border: 0px none; position: absolute; margin: auto; }
|
||||||
|
.inputControl[type='checkbox'] { margin: 0px; }
|
||||||
|
.inputHint { opacity: 0.2; background: #ccc; position: absolute; }
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script src="forms.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="viewer"></div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<html dir="ltr" mozdisallowselectionprint>
|
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
@ -29,15 +29,17 @@ limitations under the License.
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
<link rel="stylesheet" href="../../build/components/pdf_viewer.css">
|
||||||
|
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<!-- for legacy browsers -->
|
||||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
<script src="../../build/components/compatibility.js"></script>
|
||||||
|
<script src="../../build/pdf.js"></script>
|
||||||
|
<script src="../../build/components/pdf_viewer.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body tabindex="1">
|
<body tabindex="1">
|
||||||
<div id="pageContainer" class="pdfViewer singlePageView"></div>
|
<div id="pageContainer" class="pdfPage"></div>
|
||||||
|
|
||||||
<script src="pageviewer.mjs" type="module"></script>
|
<script src="pageviewer.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
56
examples/components/pageviewer.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/* 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 (!PDFJS.PDFViewer || !PDFJS.getDocument) {
|
||||||
|
alert('Please build the library and components using\n' +
|
||||||
|
' `node make generic components`');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The workerSrc property shall be specified.
|
||||||
|
//
|
||||||
|
PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
|
|
||||||
|
// Some PDFs need external cmaps.
|
||||||
|
//
|
||||||
|
// PDFJS.cMapUrl = '../../external/bcmaps/';
|
||||||
|
// PDFJS.cMapPacked = true;
|
||||||
|
|
||||||
|
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
|
||||||
|
var PAGE_TO_VIEW = 1;
|
||||||
|
var SCALE = 1.0;
|
||||||
|
|
||||||
|
var container = document.getElementById('pageContainer');
|
||||||
|
|
||||||
|
// Loading document.
|
||||||
|
PDFJS.getDocument(DEFAULT_URL).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 PDFJS.PDFPageView({
|
||||||
|
container: container,
|
||||||
|
id: PAGE_TO_VIEW,
|
||||||
|
scale: SCALE,
|
||||||
|
defaultViewport: pdfPage.getViewport(SCALE),
|
||||||
|
// We can enable text/annotations layers, if needed
|
||||||
|
textLayerFactory: new PDFJS.DefaultTextLayerFactory(),
|
||||||
|
annotationLayerFactory: new PDFJS.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();
|
|
@ -14,7 +14,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||||||
See the License for the specific language governing permissions and
|
See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
-->
|
-->
|
||||||
<html dir="ltr" mozdisallowselectionprint>
|
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||||
@ -35,10 +35,12 @@ limitations under the License.
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
|
<link rel="stylesheet" href="../../build/components/pdf_viewer.css">
|
||||||
|
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<!-- for legacy browsers -->
|
||||||
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
|
<script src="../../build/components/compatibility.js"></script>
|
||||||
|
<script src="../../build/pdf.js"></script>
|
||||||
|
<script src="../../build/components/pdf_viewer.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body tabindex="1">
|
<body tabindex="1">
|
||||||
@ -46,6 +48,6 @@ limitations under the License.
|
|||||||
<div id="viewer" class="pdfViewer"></div>
|
<div id="viewer" class="pdfViewer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="simpleviewer.mjs" type="module"></script>
|
<script src="simpleviewer.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
57
examples/components/simpleviewer.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/* 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 (!PDFJS.PDFViewer || !PDFJS.getDocument) {
|
||||||
|
alert('Please build the library and components using\n' +
|
||||||
|
' `node make generic components`');
|
||||||
|
}
|
||||||
|
|
||||||
|
// The workerSrc property shall be specified.
|
||||||
|
//
|
||||||
|
PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
|
|
||||||
|
// Some PDFs need external cmaps.
|
||||||
|
//
|
||||||
|
// PDFJS.cMapUrl = '../../external/bcmaps/';
|
||||||
|
// PDFJS.cMapPacked = true;
|
||||||
|
|
||||||
|
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
|
||||||
|
|
||||||
|
var container = document.getElementById('viewerContainer');
|
||||||
|
|
||||||
|
// (Optionally) enable hyperlinks within PDF files.
|
||||||
|
var pdfLinkService = new PDFJS.PDFLinkService();
|
||||||
|
|
||||||
|
var pdfViewer = new PDFJS.PDFViewer({
|
||||||
|
container: container,
|
||||||
|
linkService: pdfLinkService,
|
||||||
|
});
|
||||||
|
pdfLinkService.setViewer(pdfViewer);
|
||||||
|
|
||||||
|
container.addEventListener('pagesinit', function () {
|
||||||
|
// We can use pdfViewer now, e.g. let's change default scale.
|
||||||
|
pdfViewer.currentScaleValue = 'page-width';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Loading document.
|
||||||
|
PDFJS.getDocument(DEFAULT_URL).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,51 +0,0 @@
|
|||||||
<!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 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>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<body tabindex="1">
|
|
||||||
<div id="viewerContainer">
|
|
||||||
<div id="viewer" class="pdfViewer"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script src="singlepageviewer.mjs" type="module"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -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);
|
|
16
examples/helloworld/README.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
## Overview
|
||||||
|
|
||||||
|
The "hello world" example is a minimalistic application of the PDF.js project.
|
||||||
|
The file `helloworld.pdf` originates from the GNUpdf project and contains a
|
||||||
|
simple and human-readable PDF.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
Instead of simply opening `index.html` in a browser, you must serve the page
|
||||||
|
using a web server. This can be done on your local machine without an internet
|
||||||
|
connection. In the root directory of PDF.js, run `node make server` in a
|
||||||
|
terminal. The example can then be viewed using the following URL:
|
||||||
|
|
||||||
|
`http://localhost:8888/examples/helloworld/index.html`
|
||||||
|
|
||||||
|
Take a look at `hello.js` to see how to make basic calls to PDF.js.
|
30
examples/helloworld/hello.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// In production, the bundled pdf.js shall be used instead of RequireJS.
|
||||||
|
require.config({paths: {'pdfjs': '../../src'}});
|
||||||
|
require(['pdfjs/display/api'], function (api) {
|
||||||
|
// In production, change this to point to the built `pdf.worker.js` file.
|
||||||
|
PDFJS.workerSrc = '../../src/worker_loader.js';
|
||||||
|
|
||||||
|
// Fetch the PDF document from the URL using promises.
|
||||||
|
api.getDocument('helloworld.pdf').then(function (pdf) {
|
||||||
|
// Fetch the page.
|
||||||
|
pdf.getPage(1).then(function (page) {
|
||||||
|
var scale = 1.5;
|
||||||
|
var viewport = page.getViewport(scale);
|
||||||
|
|
||||||
|
// Prepare canvas using PDF page dimensions.
|
||||||
|
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,
|
||||||
|
viewport: viewport
|
||||||
|
};
|
||||||
|
page.render(renderContext);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
68
examples/helloworld/helloworld.pdf
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
%PDF-1.7
|
||||||
|
|
||||||
|
1 0 obj % entry point
|
||||||
|
<<
|
||||||
|
/Type /Catalog
|
||||||
|
/Pages 2 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Pages
|
||||||
|
/MediaBox [ 0 0 200 200 ]
|
||||||
|
/Count 1
|
||||||
|
/Kids [ 3 0 R ]
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
3 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Page
|
||||||
|
/Parent 2 0 R
|
||||||
|
/Resources <<
|
||||||
|
/Font <<
|
||||||
|
/F1 4 0 R
|
||||||
|
>>
|
||||||
|
>>
|
||||||
|
/Contents 5 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
4 0 obj
|
||||||
|
<<
|
||||||
|
/Type /Font
|
||||||
|
/Subtype /Type1
|
||||||
|
/BaseFont /Times-Roman
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
|
||||||
|
5 0 obj % page content
|
||||||
|
<<
|
||||||
|
/Length 44
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
BT
|
||||||
|
70 50 TD
|
||||||
|
/F1 12 Tf
|
||||||
|
(Hello, world!) Tj
|
||||||
|
ET
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
|
||||||
|
xref
|
||||||
|
0 6
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000010 00000 n
|
||||||
|
0000000079 00000 n
|
||||||
|
0000000173 00000 n
|
||||||
|
0000000301 00000 n
|
||||||
|
0000000380 00000 n
|
||||||
|
trailer
|
||||||
|
<<
|
||||||
|
/Size 6
|
||||||
|
/Root 1 0 R
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
492
|
||||||
|
%%EOF
|
13
examples/helloworld/index.html
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="../../node_modules/requirejs/require.js"></script>
|
||||||
|
<script src="hello.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<canvas id="the-canvas" style="border:1px solid black;"/>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Before Width: | Height: | Size: 22 KiB |
@ -1,40 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--
|
|
||||||
Copyright 2018 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 standalone JpegImage parser</title>
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<body tabindex="1">
|
|
||||||
<canvas id="jpegCanvas" width="0" height="0"></canvas>
|
|
||||||
|
|
||||||
<script src="jpeg_viewer.mjs" type="module"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,59 +0,0 @@
|
|||||||
/* Copyright 2018 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 (!pdfjsImageDecoders.JpegImage) {
|
|
||||||
// eslint-disable-next-line no-alert
|
|
||||||
alert("Please build the pdfjs-dist library using `gulp dist-install`");
|
|
||||||
}
|
|
||||||
|
|
||||||
const JPEG_IMAGE = "fish.jpg";
|
|
||||||
|
|
||||||
const jpegCanvas = document.getElementById("jpegCanvas");
|
|
||||||
const 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);
|
|
||||||
}
|
|
||||||
const typedArrayImage = new Uint8Array(await response.arrayBuffer());
|
|
||||||
|
|
||||||
// Parse the image data using `JpegImage`.
|
|
||||||
//
|
|
||||||
const jpegImage = new pdfjsImageDecoders.JpegImage();
|
|
||||||
jpegImage.parse(typedArrayImage);
|
|
||||||
|
|
||||||
const width = jpegImage.width,
|
|
||||||
height = jpegImage.height;
|
|
||||||
const jpegData = jpegImage.getData({
|
|
||||||
width,
|
|
||||||
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; ) {
|
|
||||||
imageBytes[j++] = jpegData[k++];
|
|
||||||
imageBytes[j++] = jpegData[k++];
|
|
||||||
imageBytes[j++] = jpegData[k++];
|
|
||||||
imageBytes[j++] = 255;
|
|
||||||
}
|
|
||||||
jpegCanvas.width = width;
|
|
||||||
jpegCanvas.height = height;
|
|
||||||
jpegCtx.putImageData(imageData, 0, 0);
|
|
@ -8,61 +8,61 @@
|
|||||||
|
|
||||||
<h1>'Hello, world!' example</h1>
|
<h1>'Hello, world!' example</h1>
|
||||||
|
|
||||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
<canvas id="the-canvas" style="border:1px solid black"></canvas>
|
||||||
|
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<!-- for legacy browsers add compatibility.js -->
|
||||||
|
<!--<script src="../compatibility.js"></script>-->
|
||||||
|
|
||||||
<script id="script" type="module">
|
<script src="../../build/pdf.js"></script>
|
||||||
|
|
||||||
|
<script id="script">
|
||||||
//
|
//
|
||||||
// If absolute URL from the remote server is provided, configure the CORS
|
// If absolute URL from the remote server is provided, configure the CORS
|
||||||
// header on that server.
|
// header on that server.
|
||||||
//
|
//
|
||||||
const url = './helloworld.pdf';
|
var url = './helloworld.pdf';
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable workers to avoid yet another cross-origin issue (workers need
|
||||||
|
// the URL of the script to be loaded, and dynamically loading a cross-origin
|
||||||
|
// script does not work).
|
||||||
|
//
|
||||||
|
// PDFJS.disableWorker = true;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The workerSrc property shall be specified.
|
// The workerSrc property shall be specified.
|
||||||
//
|
//
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Asynchronous download PDF
|
// Asynchronous download PDF
|
||||||
//
|
//
|
||||||
const loadingTask = pdfjsLib.getDocument(url);
|
PDFJS.getDocument(url).then(function getPdfHelloWorld(pdf) {
|
||||||
const pdf = await loadingTask.promise;
|
//
|
||||||
//
|
// Fetch the first page
|
||||||
// Fetch the first page
|
//
|
||||||
//
|
pdf.getPage(1).then(function getPageHelloWorld(page) {
|
||||||
const page = await pdf.getPage(1);
|
var scale = 1.5;
|
||||||
const scale = 1.5;
|
var viewport = page.getViewport(scale);
|
||||||
const viewport = page.getViewport({ scale });
|
|
||||||
// Support HiDPI-screens.
|
|
||||||
const outputScale = window.devicePixelRatio || 1;
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Prepare canvas using PDF page dimensions
|
// Prepare canvas using PDF page dimensions
|
||||||
//
|
//
|
||||||
const canvas = document.getElementById("the-canvas");
|
var canvas = document.getElementById('the-canvas');
|
||||||
const context = canvas.getContext("2d");
|
var context = canvas.getContext('2d');
|
||||||
|
canvas.height = viewport.height;
|
||||||
|
canvas.width = viewport.width;
|
||||||
|
|
||||||
canvas.width = Math.floor(viewport.width * outputScale);
|
//
|
||||||
canvas.height = Math.floor(viewport.height * outputScale);
|
// Render PDF page into canvas context
|
||||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
//
|
||||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
var renderContext = {
|
||||||
|
canvasContext: context,
|
||||||
const transform = outputScale !== 1
|
viewport: viewport
|
||||||
? [outputScale, 0, 0, outputScale, 0, 0]
|
};
|
||||||
: null;
|
page.render(renderContext);
|
||||||
|
});
|
||||||
//
|
});
|
||||||
// Render PDF page into canvas context
|
|
||||||
//
|
|
||||||
const renderContext = {
|
|
||||||
canvasContext: context,
|
|
||||||
transform,
|
|
||||||
viewport,
|
|
||||||
};
|
|
||||||
page.render(renderContext);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -8,11 +8,14 @@
|
|||||||
|
|
||||||
<h1>'Hello, world!' example</h1>
|
<h1>'Hello, world!' example</h1>
|
||||||
|
|
||||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
<canvas id="the-canvas" style="border:1px solid black"></canvas>
|
||||||
|
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<!-- for legacy browsers we need to use compatibility.js -->
|
||||||
|
<script src="../../web/compatibility.js"></script>
|
||||||
|
|
||||||
<script id="script" type="module">
|
<script src="../../build/pdf.js"></script>
|
||||||
|
|
||||||
|
<script id="script">
|
||||||
// atob() is used to convert base64 encoded PDF to binary-like data.
|
// atob() is used to convert base64 encoded PDF to binary-like data.
|
||||||
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
|
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
|
||||||
// Base64_encoding_and_decoding.)
|
// Base64_encoding_and_decoding.)
|
||||||
@ -31,43 +34,39 @@
|
|||||||
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
|
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
|
||||||
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
|
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
|
||||||
|
|
||||||
|
// Disable workers to avoid yet another cross-origin issue (workers need
|
||||||
|
// the URL of the script to be loaded, and dynamically loading a cross-origin
|
||||||
|
// script does not work).
|
||||||
|
//
|
||||||
|
// PDFJS.disableWorker = true;
|
||||||
|
|
||||||
//
|
//
|
||||||
// The workerSrc property shall be specified.
|
// The workerSrc property shall be specified.
|
||||||
//
|
//
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
|
|
||||||
|
|
||||||
// Opening PDF by passing its binary data as a string. It is still preferable
|
// 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.
|
// to use Uint8Array, but string or array-like structure will work too.
|
||||||
var loadingTask = pdfjsLib.getDocument({ data: pdfData, });
|
PDFJS.getDocument({data: pdfData}).then(function getPdfHelloWorld(pdf) {
|
||||||
var pdf = await loadingTask.promise;
|
// Fetch the first page.
|
||||||
// Fetch the first page.
|
pdf.getPage(1).then(function getPageHelloWorld(page) {
|
||||||
var page = await pdf.getPage(1);
|
var scale = 1.5;
|
||||||
var scale = 1.5;
|
var viewport = page.getViewport(scale);
|
||||||
var viewport = page.getViewport({ scale: scale, });
|
|
||||||
// Support HiDPI-screens.
|
|
||||||
var outputScale = window.devicePixelRatio || 1;
|
|
||||||
|
|
||||||
// Prepare canvas using PDF page dimensions.
|
// Prepare canvas using PDF page dimensions.
|
||||||
var canvas = document.getElementById('the-canvas');
|
var canvas = document.getElementById('the-canvas');
|
||||||
var context = canvas.getContext('2d');
|
var context = canvas.getContext('2d');
|
||||||
|
canvas.height = viewport.height;
|
||||||
|
canvas.width = viewport.width;
|
||||||
|
|
||||||
canvas.width = Math.floor(viewport.width * outputScale);
|
// Render PDF page into canvas context.
|
||||||
canvas.height = Math.floor(viewport.height * outputScale);
|
var renderContext = {
|
||||||
canvas.style.width = Math.floor(viewport.width) + "px";
|
canvasContext: context,
|
||||||
canvas.style.height = Math.floor(viewport.height) + "px";
|
viewport: viewport
|
||||||
|
};
|
||||||
var transform = outputScale !== 1
|
page.render(renderContext);
|
||||||
? [outputScale, 0, 0, outputScale, 0, 0]
|
});
|
||||||
: null;
|
});
|
||||||
|
|
||||||
// Render PDF page into canvas context.
|
|
||||||
var renderContext = {
|
|
||||||
canvasContext: context,
|
|
||||||
transform,
|
|
||||||
viewport,
|
|
||||||
};
|
|
||||||
page.render(renderContext);
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -16,25 +16,35 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
|
<canvas id="the-canvas" style="border:1px solid black"></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<!-- for legacy browsers add compatibility.js -->
|
||||||
|
<!--<script src="../compatibility.js"></script>-->
|
||||||
|
|
||||||
<script id="script" type="module">
|
<script src="../../build/pdf.js"></script>
|
||||||
|
|
||||||
|
<script id="script">
|
||||||
//
|
//
|
||||||
// If absolute URL from the remote server is provided, configure the CORS
|
// If absolute URL from the remote server is provided, configure the CORS
|
||||||
// header on that server.
|
// header on that server.
|
||||||
//
|
//
|
||||||
var url = '../../web/compressed.tracemonkey-pldi-09.pdf';
|
var url = '../../web/compressed.tracemonkey-pldi-09.pdf';
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disable workers to avoid yet another cross-origin issue (workers need
|
||||||
|
// the URL of the script to be loaded, and dynamically loading a cross-origin
|
||||||
|
// script does not work).
|
||||||
|
//
|
||||||
|
// PDFJS.disableWorker = true;
|
||||||
|
|
||||||
//
|
//
|
||||||
// In cases when the pdf.worker.js is located at the different folder than the
|
// 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
|
// pdf.js's one, or the pdf.js is executed via eval(), the workerSrc property
|
||||||
// shall be specified.
|
// shall be specified.
|
||||||
//
|
//
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
// PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
|
|
||||||
|
|
||||||
var pdfDoc = null,
|
var pdfDoc = null,
|
||||||
pageNum = 1,
|
pageNum = 1,
|
||||||
@ -52,24 +62,14 @@
|
|||||||
pageRendering = true;
|
pageRendering = true;
|
||||||
// Using promise to fetch the page
|
// Using promise to fetch the page
|
||||||
pdfDoc.getPage(num).then(function(page) {
|
pdfDoc.getPage(num).then(function(page) {
|
||||||
var viewport = page.getViewport({ scale: scale, });
|
var viewport = page.getViewport(scale);
|
||||||
// Support HiDPI-screens.
|
canvas.height = viewport.height;
|
||||||
var outputScale = window.devicePixelRatio || 1;
|
canvas.width = viewport.width;
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
// Render PDF page into canvas context
|
// Render PDF page into canvas context
|
||||||
var renderContext = {
|
var renderContext = {
|
||||||
canvasContext: ctx,
|
canvasContext: ctx,
|
||||||
transform: transform,
|
viewport: viewport
|
||||||
viewport: viewport,
|
|
||||||
};
|
};
|
||||||
var renderTask = page.render(renderContext);
|
var renderTask = page.render(renderContext);
|
||||||
|
|
||||||
@ -85,12 +85,12 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Update page counters
|
// Update page counters
|
||||||
document.getElementById('page_num').textContent = num;
|
document.getElementById('page_num').textContent = pageNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If another page rendering in progress, waits until the rendering is
|
* If another page rendering in progress, waits until the rendering is
|
||||||
* finished. Otherwise, executes rendering immediately.
|
* finised. Otherwise, executes rendering immediately.
|
||||||
*/
|
*/
|
||||||
function queueRenderPage(num) {
|
function queueRenderPage(num) {
|
||||||
if (pageRendering) {
|
if (pageRendering) {
|
||||||
@ -127,12 +127,13 @@
|
|||||||
/**
|
/**
|
||||||
* Asynchronously downloads PDF.
|
* Asynchronously downloads PDF.
|
||||||
*/
|
*/
|
||||||
var loadingTask = pdfjsLib.getDocument(url);
|
PDFJS.getDocument(url).then(function (pdfDoc_) {
|
||||||
pdfDoc = await loadingTask.promise;
|
pdfDoc = pdfDoc_;
|
||||||
document.getElementById('page_count').textContent = pdfDoc.numPages;
|
document.getElementById('page_count').textContent = pdfDoc.numPages;
|
||||||
|
|
||||||
// Initial/first page rendering
|
// Initial/first page rendering
|
||||||
renderPage(pageNum);
|
renderPage(pageNum);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
## Overview
|
|
||||||
|
|
||||||
Example to demonstrate PDF.js library usage with a viewer optimized for mobile usage.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
Build PDF.js using `gulp dist-install` and run `gulp server` to start a web server.
|
|
||||||
You can then work with the mobile viewer at
|
|
||||||
http://localhost:8888/examples/mobile-viewer/viewer.html.
|
|
||||||
|
|
||||||
Refer to `viewer.js` for the source code of the mobile viewer.
|
|
Before Width: | Height: | Size: 169 B |
Before Width: | Height: | Size: 185 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 184 B |
Before Width: | Height: | Size: 295 B |
Before Width: | Height: | Size: 560 B |
Before Width: | Height: | Size: 310 B |
Before Width: | Height: | Size: 338 B |
Before Width: | Height: | Size: 372 B |
Before Width: | Height: | Size: 395 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 4.5 KiB |
@ -1,57 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<!--
|
|
||||||
Copyright 2016 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">
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<header>
|
|
||||||
<h1 id="title"></h1>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div id="viewerContainer">
|
|
||||||
<div id="viewer" class="pdfViewer"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="loadingBar">
|
|
||||||
<div class="progress"></div>
|
|
||||||
<div class="glimmer"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<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">
|
|
||||||
|
|
||||||
<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>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -1,371 +0,0 @@
|
|||||||
/* Copyright 2016 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`");
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
|
||||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
const PDFViewerApplication = {
|
|
||||||
pdfLoadingTask: null,
|
|
||||||
pdfDocument: null,
|
|
||||||
pdfViewer: null,
|
|
||||||
pdfHistory: null,
|
|
||||||
pdfLinkService: null,
|
|
||||||
eventBus: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens PDF document specified by URL.
|
|
||||||
* @returns {Promise} - Returns the promise, which is resolved when document
|
|
||||||
* is opened.
|
|
||||||
*/
|
|
||||||
open(params) {
|
|
||||||
if (this.pdfLoadingTask) {
|
|
||||||
// We need to destroy already opened document
|
|
||||||
return this.close().then(
|
|
||||||
function () {
|
|
||||||
// ... and repeat the open() call.
|
|
||||||
return this.open(params);
|
|
||||||
}.bind(this)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const url = params.url;
|
|
||||||
const self = this;
|
|
||||||
this.setTitleUsingUrl(url);
|
|
||||||
|
|
||||||
// Loading document.
|
|
||||||
const loadingTask = pdfjsLib.getDocument({
|
|
||||||
url,
|
|
||||||
maxImageSize: MAX_IMAGE_SIZE,
|
|
||||||
cMapUrl: CMAP_URL,
|
|
||||||
cMapPacked: CMAP_PACKED,
|
|
||||||
});
|
|
||||||
this.pdfLoadingTask = loadingTask;
|
|
||||||
|
|
||||||
loadingTask.onProgress = function (progressData) {
|
|
||||||
self.progress(progressData.loaded / progressData.total);
|
|
||||||
};
|
|
||||||
|
|
||||||
return loadingTask.promise.then(
|
|
||||||
function (pdfDocument) {
|
|
||||||
// Document loaded, specifying document for the viewer.
|
|
||||||
self.pdfDocument = pdfDocument;
|
|
||||||
self.pdfViewer.setDocument(pdfDocument);
|
|
||||||
self.pdfLinkService.setDocument(pdfDocument);
|
|
||||||
self.pdfHistory.initialize({
|
|
||||||
fingerprint: pdfDocument.fingerprints[0],
|
|
||||||
});
|
|
||||||
|
|
||||||
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.MissingPDFException) {
|
|
||||||
key = "pdfjs-missing-file-error";
|
|
||||||
} else if (reason instanceof pdfjsLib.UnexpectedResponseException) {
|
|
||||||
key = "pdfjs-unexpected-response-error";
|
|
||||||
}
|
|
||||||
self.l10n.get(key).then(msg => {
|
|
||||||
self.error(msg, { message: reason?.message });
|
|
||||||
});
|
|
||||||
self.loadingBar.hide();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes opened PDF document.
|
|
||||||
* @returns {Promise} - Returns the promise, which is resolved when all
|
|
||||||
* destruction is completed.
|
|
||||||
*/
|
|
||||||
close() {
|
|
||||||
if (!this.pdfLoadingTask) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
const promise = this.pdfLoadingTask.destroy();
|
|
||||||
this.pdfLoadingTask = null;
|
|
||||||
|
|
||||||
if (this.pdfDocument) {
|
|
||||||
this.pdfDocument = null;
|
|
||||||
|
|
||||||
this.pdfViewer.setDocument(null);
|
|
||||||
this.pdfLinkService.setDocument(null, null);
|
|
||||||
|
|
||||||
if (this.pdfHistory) {
|
|
||||||
this.pdfHistory.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
},
|
|
||||||
|
|
||||||
get loadingBar() {
|
|
||||||
const bar = document.getElementById("loadingBar");
|
|
||||||
return pdfjsLib.shadow(
|
|
||||||
this,
|
|
||||||
"loadingBar",
|
|
||||||
new pdfjsViewer.ProgressBar(bar)
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
|
|
||||||
this.url = url;
|
|
||||||
let title = pdfjsLib.getFilenameFromUrl(url) || url;
|
|
||||||
try {
|
|
||||||
title = decodeURIComponent(title);
|
|
||||||
} catch {
|
|
||||||
// decodeURIComponent may throw URIError,
|
|
||||||
// fall back to using the unprocessed url in that case
|
|
||||||
}
|
|
||||||
this.setTitle(title);
|
|
||||||
},
|
|
||||||
|
|
||||||
setTitleUsingMetadata(pdfDocument) {
|
|
||||||
const self = this;
|
|
||||||
pdfDocument.getMetadata().then(function (data) {
|
|
||||||
const info = data.info,
|
|
||||||
metadata = data.metadata;
|
|
||||||
self.documentInfo = info;
|
|
||||||
self.metadata = metadata;
|
|
||||||
|
|
||||||
// Provides some basic debug information
|
|
||||||
console.log(
|
|
||||||
"PDF " +
|
|
||||||
pdfDocument.fingerprints[0] +
|
|
||||||
" [" +
|
|
||||||
info.PDFFormatVersion +
|
|
||||||
" " +
|
|
||||||
(info.Producer || "-").trim() +
|
|
||||||
" / " +
|
|
||||||
(info.Creator || "-").trim() +
|
|
||||||
"]" +
|
|
||||||
" (PDF.js: " +
|
|
||||||
(pdfjsLib.version || "-") +
|
|
||||||
")"
|
|
||||||
);
|
|
||||||
|
|
||||||
let pdfTitle;
|
|
||||||
if (metadata && metadata.has("dc:title")) {
|
|
||||||
const title = metadata.get("dc:title");
|
|
||||||
// Ghostscript sometimes returns 'Untitled', so prevent setting the
|
|
||||||
// title to 'Untitled.
|
|
||||||
if (title !== "Untitled") {
|
|
||||||
pdfTitle = title;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pdfTitle && info && info.Title) {
|
|
||||||
pdfTitle = info.Title;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pdfTitle) {
|
|
||||||
self.setTitle(pdfTitle + " - " + document.title);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
setTitle: function pdfViewSetTitle(title) {
|
|
||||||
document.title = title;
|
|
||||||
document.getElementById("title").textContent = title;
|
|
||||||
},
|
|
||||||
|
|
||||||
error: function pdfViewError(message, moreInfo) {
|
|
||||||
const moreInfoText = [
|
|
||||||
`PDF.js v${pdfjsLib.version || "?"} (build: ${pdfjsLib.build || "?"})`,
|
|
||||||
];
|
|
||||||
if (moreInfo) {
|
|
||||||
moreInfoText.push(`Message: ${moreInfo.message}`);
|
|
||||||
|
|
||||||
if (moreInfo.stack) {
|
|
||||||
moreInfoText.push(`Stack: ${moreInfo.stack}`);
|
|
||||||
} else {
|
|
||||||
if (moreInfo.filename) {
|
|
||||||
moreInfoText.push(`File: ${moreInfo.filename}`);
|
|
||||||
}
|
|
||||||
if (moreInfo.lineNumber) {
|
|
||||||
moreInfoText.push(`Line: ${moreInfo.lineNumber}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.error(`${message}\n\n${moreInfoText.join("\n")}`);
|
|
||||||
},
|
|
||||||
|
|
||||||
progress: function pdfViewProgress(level) {
|
|
||||||
const percent = Math.round(level * 100);
|
|
||||||
// Updating the bar if value increases.
|
|
||||||
if (percent > this.loadingBar.percent || isNaN(percent)) {
|
|
||||||
this.loadingBar.percent = percent;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
get pagesCount() {
|
|
||||||
return this.pdfDocument.numPages;
|
|
||||||
},
|
|
||||||
|
|
||||||
get page() {
|
|
||||||
return this.pdfViewer.currentPageNumber;
|
|
||||||
},
|
|
||||||
|
|
||||||
set page(val) {
|
|
||||||
this.pdfViewer.currentPageNumber = val;
|
|
||||||
},
|
|
||||||
|
|
||||||
zoomIn: function pdfViewZoomIn(ticks) {
|
|
||||||
let newScale = this.pdfViewer.currentScale;
|
|
||||||
do {
|
|
||||||
newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
|
|
||||||
newScale = Math.ceil(newScale * 10) / 10;
|
|
||||||
newScale = Math.min(MAX_SCALE, newScale);
|
|
||||||
} while (--ticks && newScale < MAX_SCALE);
|
|
||||||
this.pdfViewer.currentScaleValue = newScale;
|
|
||||||
},
|
|
||||||
|
|
||||||
zoomOut: function pdfViewZoomOut(ticks) {
|
|
||||||
let newScale = this.pdfViewer.currentScale;
|
|
||||||
do {
|
|
||||||
newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
|
|
||||||
newScale = Math.floor(newScale * 10) / 10;
|
|
||||||
newScale = Math.max(MIN_SCALE, newScale);
|
|
||||||
} while (--ticks && newScale > MIN_SCALE);
|
|
||||||
this.pdfViewer.currentScaleValue = newScale;
|
|
||||||
},
|
|
||||||
|
|
||||||
initUI: function pdfViewInitUI() {
|
|
||||||
const eventBus = new pdfjsViewer.EventBus();
|
|
||||||
this.eventBus = eventBus;
|
|
||||||
|
|
||||||
const linkService = new pdfjsViewer.PDFLinkService({
|
|
||||||
eventBus,
|
|
||||||
});
|
|
||||||
this.pdfLinkService = linkService;
|
|
||||||
|
|
||||||
this.l10n = new pdfjsViewer.GenericL10n();
|
|
||||||
|
|
||||||
const container = document.getElementById("viewerContainer");
|
|
||||||
const pdfViewer = new pdfjsViewer.PDFViewer({
|
|
||||||
container,
|
|
||||||
eventBus,
|
|
||||||
linkService,
|
|
||||||
l10n: this.l10n,
|
|
||||||
maxCanvasPixels: MAX_CANVAS_PIXELS,
|
|
||||||
textLayerMode: TEXT_LAYER_MODE,
|
|
||||||
});
|
|
||||||
this.pdfViewer = pdfViewer;
|
|
||||||
linkService.setViewer(pdfViewer);
|
|
||||||
|
|
||||||
this.pdfHistory = new pdfjsViewer.PDFHistory({
|
|
||||||
eventBus,
|
|
||||||
linkService,
|
|
||||||
});
|
|
||||||
linkService.setHistory(this.pdfHistory);
|
|
||||||
|
|
||||||
document.getElementById("previous").addEventListener("click", function () {
|
|
||||||
PDFViewerApplication.page--;
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("next").addEventListener("click", function () {
|
|
||||||
PDFViewerApplication.page++;
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("zoomIn").addEventListener("click", function () {
|
|
||||||
PDFViewerApplication.zoomIn();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById("zoomOut").addEventListener("click", function () {
|
|
||||||
PDFViewerApplication.zoomOut();
|
|
||||||
});
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById("pageNumber")
|
|
||||||
.addEventListener("click", function () {
|
|
||||||
this.select();
|
|
||||||
});
|
|
||||||
|
|
||||||
document
|
|
||||||
.getElementById("pageNumber")
|
|
||||||
.addEventListener("change", function () {
|
|
||||||
PDFViewerApplication.page = this.value | 0;
|
|
||||||
|
|
||||||
// Ensure that the page number input displays the correct value,
|
|
||||||
// even if the value entered by the user was invalid
|
|
||||||
// (e.g. a floating point number).
|
|
||||||
if (this.value !== PDFViewerApplication.page.toString()) {
|
|
||||||
this.value = PDFViewerApplication.page;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
eventBus.on("pagesinit", function () {
|
|
||||||
// We can use pdfViewer now, e.g. let's change default scale.
|
|
||||||
pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
|
|
||||||
});
|
|
||||||
|
|
||||||
eventBus.on(
|
|
||||||
"pagechanging",
|
|
||||||
function (evt) {
|
|
||||||
const page = evt.pageNumber;
|
|
||||||
const numPages = PDFViewerApplication.pagesCount;
|
|
||||||
|
|
||||||
document.getElementById("pageNumber").value = page;
|
|
||||||
document.getElementById("previous").disabled = page <= 1;
|
|
||||||
document.getElementById("next").disabled = page >= numPages;
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
window.PDFViewerApplication = PDFViewerApplication;
|
|
||||||
|
|
||||||
document.addEventListener(
|
|
||||||
"DOMContentLoaded",
|
|
||||||
function () {
|
|
||||||
PDFViewerApplication.initUI();
|
|
||||||
},
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
// We need to delay opening until all HTML is loaded.
|
|
||||||
animationStarted.then(function () {
|
|
||||||
PDFViewerApplication.open({
|
|
||||||
url: DEFAULT_URL,
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"../.eslintrc"
|
|
||||||
],
|
|
||||||
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
},
|
|
||||||
}
|
|
105
examples/node/domparsermock.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Dummy XML Parser
|
||||||
|
|
||||||
|
function DOMNodeMock(nodeName, nodeValue) {
|
||||||
|
this.nodeName = nodeName;
|
||||||
|
this.nodeValue = nodeValue;
|
||||||
|
Object.defineProperty(this, 'parentNode', {value: null, writable: true});
|
||||||
|
}
|
||||||
|
DOMNodeMock.prototype = {
|
||||||
|
get firstChild() {
|
||||||
|
return this.childNodes[0];
|
||||||
|
},
|
||||||
|
get nextSibling() {
|
||||||
|
var index = this.parentNode.childNodes.indexOf(this);
|
||||||
|
return this.parentNode.childNodes[index + 1];
|
||||||
|
},
|
||||||
|
get textContent() {
|
||||||
|
if (!this.childNodes) {
|
||||||
|
return this.nodeValue || '';
|
||||||
|
}
|
||||||
|
return this.childNodes.map(function (child) {
|
||||||
|
return child.textContent;
|
||||||
|
}).join('');
|
||||||
|
},
|
||||||
|
hasChildNodes: function () {
|
||||||
|
return this.childNodes && this.childNodes.length > 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function decodeXML(text) {
|
||||||
|
if (text.indexOf('&') < 0) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return text.replace(/&(#(x[0-9a-f]+|\d+)|\w+);/gi, function (all, entityName, number) {
|
||||||
|
if (number) {
|
||||||
|
return String.fromCharCode(number[0] === 'x' ? parseInt(number.substring(1), 16) : +number);
|
||||||
|
}
|
||||||
|
switch (entityName) {
|
||||||
|
case 'amp':
|
||||||
|
return '&';
|
||||||
|
case 'lt':
|
||||||
|
return '<';
|
||||||
|
case 'gt':
|
||||||
|
return '>';
|
||||||
|
case 'quot':
|
||||||
|
return '\"';
|
||||||
|
case 'apos':
|
||||||
|
return '\'';
|
||||||
|
}
|
||||||
|
return '&' + entityName + ';';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function DOMParserMock() {};
|
||||||
|
DOMParserMock.prototype = {
|
||||||
|
parseFromString: function (content) {
|
||||||
|
content = content.replace(/<\?[\s\S]*?\?>|<!--[\s\S]*?-->/g, '').trim();
|
||||||
|
var nodes = [];
|
||||||
|
content = content.replace(/>([\s\S]+?)</g, function (all, text) {
|
||||||
|
var i = nodes.length;
|
||||||
|
var node = new DOMNodeMock('#text', decodeXML(text));
|
||||||
|
nodes.push(node);
|
||||||
|
if (node.textContent.trim().length === 0) {
|
||||||
|
return '><'; // ignoring whitespaces
|
||||||
|
}
|
||||||
|
return '>' + i + ',<';
|
||||||
|
});
|
||||||
|
content = content.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, function (all, text) {
|
||||||
|
var i = nodes.length;
|
||||||
|
var node = new DOMNodeMock('#text', text);
|
||||||
|
nodes.push(node);
|
||||||
|
return i + ',';
|
||||||
|
});
|
||||||
|
var lastLength;
|
||||||
|
do {
|
||||||
|
lastLength = nodes.length;
|
||||||
|
content = content.replace(/<([\w\:]+)((?:[\s\w:=]|'[^']*'|"[^"]*")*)(?:\/>|>([\d,]*)<\/[^>]+>)/g,
|
||||||
|
function (all, name, attrs, content) {
|
||||||
|
var i = nodes.length;
|
||||||
|
var node = new DOMNodeMock(name);
|
||||||
|
var children = [];
|
||||||
|
if (content) {
|
||||||
|
content = content.split(',');
|
||||||
|
content.pop();
|
||||||
|
content.forEach(function (child) {
|
||||||
|
var childNode = nodes[+child];
|
||||||
|
childNode.parentNode = node;
|
||||||
|
children.push(childNode);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
node.childNodes = children;
|
||||||
|
nodes.push(node);
|
||||||
|
return i + ',';
|
||||||
|
|
||||||
|
});
|
||||||
|
} while(lastLength < nodes.length);
|
||||||
|
return {
|
||||||
|
documentElement: nodes.pop()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.DOMParserMock = DOMParserMock;
|
153
examples/node/domstubs.js
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
global.btoa = function btoa(chars) {
|
||||||
|
var digits =
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||||
|
var buffer = '';
|
||||||
|
var i, n;
|
||||||
|
for (i = 0, n = chars.length; i < n; i += 3) {
|
||||||
|
var b1 = chars.charCodeAt(i) & 0xFF;
|
||||||
|
var b2 = chars.charCodeAt(i + 1) & 0xFF;
|
||||||
|
var b3 = chars.charCodeAt(i + 2) & 0xFF;
|
||||||
|
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
|
||||||
|
var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
|
||||||
|
var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
|
||||||
|
buffer += (digits.charAt(d1) + digits.charAt(d2) +
|
||||||
|
digits.charAt(d3) + digits.charAt(d4));
|
||||||
|
}
|
||||||
|
return buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
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 = {
|
||||||
|
|
||||||
|
setAttributeNS: function DOMElement_setAttributeNS(NS, name, value) {
|
||||||
|
value = value || '';
|
||||||
|
value = xmlEncode(value);
|
||||||
|
this.attributes[name] = value;
|
||||||
|
},
|
||||||
|
|
||||||
|
appendChild: function DOMElement_appendChild(element) {
|
||||||
|
var childNodes = this.childNodes;
|
||||||
|
if (childNodes.indexOf(element) === -1) {
|
||||||
|
childNodes.push(element);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function DOMElement_toString() {
|
||||||
|
var attrList = [];
|
||||||
|
for (i in this.attributes) {
|
||||||
|
attrList.push(i + '="' + xmlEncode(this.attributes[i]) + '"');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.nodeName === 'svg:tspan' || this.nodeName === 'svg:style') {
|
||||||
|
var encText = xmlEncode(this.textContent);
|
||||||
|
return '<' + this.nodeName + ' ' + attrList.join(' ') + '>' +
|
||||||
|
encText + '</' + this.nodeName + '>';
|
||||||
|
} else if (this.nodeName === 'svg:svg') {
|
||||||
|
var ns = 'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
|
||||||
|
'xmlns:svg="http://www.w3.org/2000/svg"'
|
||||||
|
return '<' + this.nodeName + ' ' + ns + ' ' + attrList.join(' ') + '>' +
|
||||||
|
this.childNodes.join('') + '</' + this.nodeName + '>';
|
||||||
|
} else {
|
||||||
|
return '<' + this.nodeName + ' ' + attrList.join(' ') + '>' +
|
||||||
|
this.childNodes.join('') + '</' + this.nodeName + '>';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cloneNode: function DOMElement_cloneNode() {
|
||||||
|
var newNode = new DOMElement(this.nodeName);
|
||||||
|
newNode.childNodes = this.childNodes;
|
||||||
|
newNode.attributes = this.attributes;
|
||||||
|
newNode.textContent = this.textContent;
|
||||||
|
return newNode;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
global.window = global;
|
||||||
|
|
||||||
|
global.navigator = { userAgent: 'node' };
|
||||||
|
|
||||||
|
global.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 [];
|
||||||
|
}
|
||||||
|
};
|
72
examples/node/getinfo.js
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
//
|
||||||
|
// Basic node example that prints document metadata and text content.
|
||||||
|
// Requires single file built version of PDF.js -- please run
|
||||||
|
// `node make singlefile` before running the example.
|
||||||
|
//
|
||||||
|
|
||||||
|
var fs = require('fs');
|
||||||
|
|
||||||
|
// HACK adding DOMParser to read XMP metadata.
|
||||||
|
global.DOMParser = require('./domparsermock.js').DOMParserMock;
|
||||||
|
|
||||||
|
// Run `node make dist` to generate 'pdfjs-dist' npm package files.
|
||||||
|
require('../../build/dist');
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Will be using promises to load document, pages and misc data instead of
|
||||||
|
// callback.
|
||||||
|
PDFJS.getDocument(data).then(function (doc) {
|
||||||
|
var numPages = doc.numPages;
|
||||||
|
console.log('# Document Loaded');
|
||||||
|
console.log('Number of Pages: ' + numPages);
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
var lastPromise; // will be used to chain promises
|
||||||
|
lastPromise = doc.getMetadata().then(function (data) {
|
||||||
|
console.log('# Metadata Is Loaded');
|
||||||
|
console.log('## Info');
|
||||||
|
console.log(JSON.stringify(data.info, null, 2));
|
||||||
|
console.log();
|
||||||
|
if (data.metadata) {
|
||||||
|
console.log('## Metadata');
|
||||||
|
console.log(JSON.stringify(data.metadata.metadata, null, 2));
|
||||||
|
console.log();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var loadPage = function (pageNum) {
|
||||||
|
return doc.getPage(pageNum).then(function (page) {
|
||||||
|
console.log('# Page ' + pageNum);
|
||||||
|
var viewport = page.getViewport(1.0 /* scale */);
|
||||||
|
console.log('Size: ' + viewport.width + 'x' + viewport.height);
|
||||||
|
console.log();
|
||||||
|
return page.getTextContent().then(function (content) {
|
||||||
|
// Content contains lots of information about the text layout and
|
||||||
|
// styles, but we need only strings at the moment
|
||||||
|
var strings = content.items.map(function (item) {
|
||||||
|
return item.str;
|
||||||
|
});
|
||||||
|
console.log('## Text Content');
|
||||||
|
console.log(strings.join(' '));
|
||||||
|
}).then(function () {
|
||||||
|
console.log();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
// Loading of the first page will wait on metadata and subsequent loadings
|
||||||
|
// will wait on the previous pages.
|
||||||
|
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);
|
||||||
|
});
|
@ -1,76 +0,0 @@
|
|||||||
/* Any copyright is dedicated to the Public Domain.
|
|
||||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
||||||
|
|
||||||
//
|
|
||||||
// Basic node example that prints document metadata and text content.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Run `gulp dist-install` to generate 'pdfjs-dist' npm package files.
|
|
||||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
||||||
|
|
||||||
// Loading file from file system into typed array
|
|
||||||
const 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);
|
|
||||||
loadingTask.promise
|
|
||||||
.then(function (doc) {
|
|
||||||
const numPages = doc.numPages;
|
|
||||||
console.log("# Document Loaded");
|
|
||||||
console.log("Number of Pages: " + numPages);
|
|
||||||
console.log();
|
|
||||||
|
|
||||||
let lastPromise; // will be used to chain promises
|
|
||||||
lastPromise = doc.getMetadata().then(function (data) {
|
|
||||||
console.log("# Metadata Is Loaded");
|
|
||||||
console.log("## Info");
|
|
||||||
console.log(JSON.stringify(data.info, null, 2));
|
|
||||||
console.log();
|
|
||||||
if (data.metadata) {
|
|
||||||
console.log("## Metadata");
|
|
||||||
console.log(JSON.stringify(data.metadata.getAll(), null, 2));
|
|
||||||
console.log();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const loadPage = function (pageNum) {
|
|
||||||
return doc.getPage(pageNum).then(function (page) {
|
|
||||||
console.log("# Page " + pageNum);
|
|
||||||
const viewport = page.getViewport({ scale: 1.0 });
|
|
||||||
console.log("Size: " + viewport.width + "x" + viewport.height);
|
|
||||||
console.log();
|
|
||||||
return page
|
|
||||||
.getTextContent()
|
|
||||||
.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) {
|
|
||||||
return item.str;
|
|
||||||
});
|
|
||||||
console.log("## Text Content");
|
|
||||||
console.log(strings.join(" "));
|
|
||||||
// Release page resources.
|
|
||||||
page.cleanup();
|
|
||||||
})
|
|
||||||
.then(function () {
|
|
||||||
console.log();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 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++) {
|
|
||||||
lastPromise = lastPromise.then(loadPage.bind(null, i));
|
|
||||||
}
|
|
||||||
return lastPromise;
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
function () {
|
|
||||||
console.log("# End of Document");
|
|
||||||
},
|
|
||||||
function (err) {
|
|
||||||
console.error("Error: " + err);
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,17 +0,0 @@
|
|||||||
## Overview
|
|
||||||
|
|
||||||
Example to demonstrate converting a PDF file to a PNG image using the PDF.js library.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
Install the dependencies and build the PDF.js library:
|
|
||||||
|
|
||||||
$ npm install
|
|
||||||
$ gulp dist-install
|
|
||||||
|
|
||||||
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.js
|
|
@ -1,106 +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 { strict as assert } from "assert";
|
|
||||||
import Canvas from "canvas";
|
|
||||||
import fs from "fs";
|
|
||||||
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
|
|
||||||
|
|
||||||
class NodeCanvasFactory {
|
|
||||||
create(width, height) {
|
|
||||||
assert(width > 0 && height > 0, "Invalid canvas size");
|
|
||||||
const canvas = Canvas.createCanvas(width, height);
|
|
||||||
const context = canvas.getContext("2d");
|
|
||||||
return {
|
|
||||||
canvas,
|
|
||||||
context,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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(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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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/";
|
|
||||||
|
|
||||||
const canvasFactory = new NodeCanvasFactory();
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
canvasFactory,
|
|
||||||
});
|
|
||||||
|
|
||||||
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 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();
|
|
||||||
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);
|
|
||||||
}
|
|
80
examples/node/pdf2svg.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
/* 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');
|
||||||
|
|
||||||
|
// HACK few hacks to let PDF.js be loaded not as a module in global space.
|
||||||
|
require('./domstubs.js');
|
||||||
|
|
||||||
|
// Run `node make dist` to generate 'pdfjs-dist' npm package files.
|
||||||
|
require('../../build/dist');
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// Dumps svg outputs to a folder called svgdump
|
||||||
|
function writeToFile(svgdump, pageNum) {
|
||||||
|
var name = getFileNameFromPath(pdfPath);
|
||||||
|
fs.mkdir('./svgdump/', function(err) {
|
||||||
|
if (!err || err.code === 'EEXIST') {
|
||||||
|
fs.writeFile('./svgdump/' + name + "-" + pageNum + '.svg', svgdump,
|
||||||
|
function(err) {
|
||||||
|
if (err) {
|
||||||
|
console.log('Error: ' + err);
|
||||||
|
} else {
|
||||||
|
console.log('Page: ' + pageNum);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get filename from the path
|
||||||
|
|
||||||
|
function getFileNameFromPath(path) {
|
||||||
|
var index = path.lastIndexOf('/');
|
||||||
|
var extIndex = path.lastIndexOf('.');
|
||||||
|
return path.substring(index , extIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will be using promises to load document, pages and misc data instead of
|
||||||
|
// callback.
|
||||||
|
PDFJS.getDocument(data).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(1.0 /* scale */);
|
||||||
|
console.log('Size: ' + viewport.width + 'x' + viewport.height);
|
||||||
|
console.log();
|
||||||
|
|
||||||
|
return page.getOperatorList().then(function (opList) {
|
||||||
|
var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
|
||||||
|
svgGfx.embedFonts = true;
|
||||||
|
return svgGfx.getSVG(opList, viewport).then(function (svg) {
|
||||||
|
var svgDump = svg.toString();
|
||||||
|
writeToFile(svgDump, pageNum);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
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
@ -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.
|
25
examples/svgviewer/index.html
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<script src="../../node_modules/requirejs/require.js"></script>
|
||||||
|
<script src="viewer.js"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background-color: gray;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pageContainer {
|
||||||
|
border : 1px solid black;
|
||||||
|
margin : 5px auto;
|
||||||
|
background-color : white;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<title>SVG Viewer Example</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
58
examples/svgviewer/viewer.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
// Parse query string to extract some parameters (it can fail for some input)
|
||||||
|
var query = document.location.href.replace(/^[^?]*(\?([^#]*))?(#.*)?/, '$2');
|
||||||
|
var queryParams = query ? JSON.parse('{' + query.split('&').map(function (a) {
|
||||||
|
return a.split('=').map(decodeURIComponent).map(JSON.stringify).join(': ');
|
||||||
|
}).join(',') + '}') : {};
|
||||||
|
|
||||||
|
var url = queryParams.file || '../../test/pdfs/liveprogramming.pdf';
|
||||||
|
var scale = +queryParams.scale || 1.5;
|
||||||
|
|
||||||
|
function renderDocument(pdf) {
|
||||||
|
var numPages = pdf.numPages;
|
||||||
|
// Using promise to fetch the page
|
||||||
|
|
||||||
|
// For testing only.
|
||||||
|
var MAX_NUM_PAGES = 50;
|
||||||
|
var ii = Math.min(MAX_NUM_PAGES, numPages);
|
||||||
|
|
||||||
|
var promise = Promise.resolve();
|
||||||
|
for (var i = 1; i <= ii; i++) {
|
||||||
|
var anchor = document.createElement('a');
|
||||||
|
anchor.setAttribute('name', 'page=' + i);
|
||||||
|
anchor.setAttribute('title', 'Page ' + i);
|
||||||
|
document.body.appendChild(anchor);
|
||||||
|
|
||||||
|
// Using promise to fetch and render the next page
|
||||||
|
promise = promise.then(function (pageNum, anchor) {
|
||||||
|
return pdf.getPage(pageNum).then(function (page) {
|
||||||
|
var viewport = page.getViewport(scale);
|
||||||
|
|
||||||
|
var container = document.createElement('div');
|
||||||
|
container.id = 'pageContainer' + pageNum;
|
||||||
|
container.className = 'pageContainer';
|
||||||
|
container.style.width = viewport.width + 'px';
|
||||||
|
container.style.height = viewport.height + 'px';
|
||||||
|
anchor.appendChild(container);
|
||||||
|
|
||||||
|
return page.getOperatorList().then(function (opList) {
|
||||||
|
var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
|
||||||
|
return svgGfx.getSVG(opList, viewport).then(function (svg) {
|
||||||
|
container.appendChild(svg);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}.bind(null, i, anchor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In production, the bundled pdf.js shall be used instead of RequireJS.
|
||||||
|
require.config({paths: {'pdfjs': '../../src'}});
|
||||||
|
require(['pdfjs/display/api', 'pdfjs/display/svg'], function (api, svg) {
|
||||||
|
// In production, change this to point to the built `pdf.worker.js` file.
|
||||||
|
PDFJS.workerSrc = '../../src/worker_loader.js';
|
||||||
|
|
||||||
|
// Fetch the PDF document from the URL using promises.
|
||||||
|
api.getDocument(url).then(renderDocument);
|
||||||
|
});
|
@ -1,10 +1,9 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>Text-only PDF.js example</title>
|
<title>Text-only PDF.js example</title>
|
||||||
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
|
<script src="../../build/generic/build/pdf.js"></script>
|
||||||
<script src="pdf2svg.mjs" type="module"></script>
|
<script src="pdf2svg.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<p>Text-only PDF.js example</p>
|
<p>Text-only PDF.js example</p>
|
||||||
|
70
examples/text-only/pdf2svg.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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';
|
||||||
|
|
||||||
|
PDFJS.workerSrc = '../../build/pdf.worker.js';
|
||||||
|
|
||||||
|
function buildSVG(viewport, textContent) {
|
||||||
|
// Building SVG with size of the viewport (for simplicity)
|
||||||
|
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
|
||||||
|
svg.setAttribute('font-size', 1);
|
||||||
|
|
||||||
|
// processing all items
|
||||||
|
textContent.items.forEach(function (textItem) {
|
||||||
|
// we have to take in account viewport transform, which incudes scale,
|
||||||
|
// rotation and Y-axis flip, and not forgetting to flip text.
|
||||||
|
var tx = PDFJS.Util.transform(
|
||||||
|
PDFJS.Util.transform(viewport.transform, textItem.transform),
|
||||||
|
[1, 0, 0, -1, 0, 0]);
|
||||||
|
var style = textContent.styles[textItem.fontName];
|
||||||
|
// adding text element
|
||||||
|
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.appendChild(text);
|
||||||
|
});
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
function pageLoaded() {
|
||||||
|
// Loading document and page text content
|
||||||
|
PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) {
|
||||||
|
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
|
||||||
|
var viewport = page.getViewport(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 PDFJS === 'undefined') {
|
||||||
|
alert('Built version of PDF.js was not found.\n' +
|
||||||
|
'Please run `node make generic`.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pageLoaded();
|
||||||
|
});
|
@ -1,72 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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";
|
|
||||||
|
|
||||||
pdfjsLib.GlobalWorkerOptions.workerSrc =
|
|
||||||
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
|
|
||||||
|
|
||||||
function buildSVG(viewport, textContent) {
|
|
||||||
// Building SVG with size of the viewport (for simplicity)
|
|
||||||
const 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
|
|
||||||
svg.setAttribute("font-size", 1);
|
|
||||||
|
|
||||||
// processing all items
|
|
||||||
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(
|
|
||||||
pdfjsLib.Util.transform(viewport.transform, textItem.transform),
|
|
||||||
[1, 0, 0, -1, 0, 0]
|
|
||||||
);
|
|
||||||
const style = textContent.styles[textItem.fontName];
|
|
||||||
// adding text element
|
|
||||||
const 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);
|
|
||||||
});
|
|
||||||
return svg;
|
|
||||||
}
|
|
||||||
|
|
||||||
async 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
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`");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pageLoaded();
|
|
||||||
});
|
|
@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": [
|
|
||||||
"../.eslintrc"
|
|
||||||
],
|
|
||||||
|
|
||||||
"env": {
|
|
||||||
"node": true,
|
|
||||||
},
|
|
||||||
}
|
|
@ -1,33 +1,18 @@
|
|||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Example to demonstrate PDF.js library usage with Webpack.
|
Example to demonstrate PDF.js library usage with webpack.
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Install the example dependencies and build the project:
|
Build project and install the example dependencies:
|
||||||
|
|
||||||
$ gulp dist-install
|
$ node make dist
|
||||||
$ cd examples/webpack
|
$ cd examples/webpack
|
||||||
$ npm install
|
$ npm install
|
||||||
$ ./node_modules/webpack/bin/webpack.js
|
|
||||||
|
|
||||||
You can observe the build results by running `gulp server` and navigating to
|
To build webpack bundles, run `node_modules/.bin/webpack`. If you are running
|
||||||
http://localhost:8888/examples/webpack/index.html.
|
a web server, you can observe the build results at
|
||||||
|
http://localhost:8888/examples/webpack/index.html
|
||||||
|
|
||||||
Refer to the `main.js` and `webpack.config.js` files for the source code.
|
See main.js and webpack.config.js files. Please notice that PDF.js packaging
|
||||||
Note that PDF.js packaging requires packaging of the main application and
|
requires 'entry' loader.
|
||||||
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.
|
|
||||||
|
|
||||||
import * as pdfjsLib from 'pdfjs-dist/webpack.mjs';
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>webpack example</title>
|
<title>webpack example</title>
|
||||||
<script src="../../build/webpack/main.bundle.js"></script>
|
<script src="../../build/webpack/bundle.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<canvas id="theCanvas"></canvas>
|
<canvas id="theCanvas"></canvas>
|
||||||
|
32
examples/webpack/main.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Any copyright is dedicated to the Public Domain.
|
||||||
|
// http://creativecommons.org/licenses/publicdomain/
|
||||||
|
|
||||||
|
// Hello world example for webpack.
|
||||||
|
|
||||||
|
require('pdfjs-dist');
|
||||||
|
|
||||||
|
var pdfPath = '../helloworld/helloworld.pdf';
|
||||||
|
|
||||||
|
// It is also possible to disable workers via `PDFJS.disableWorker = true`,
|
||||||
|
// however that might degrade the UI performance in web browsers.
|
||||||
|
|
||||||
|
// Loading a document.
|
||||||
|
var loadingTask = PDFJS.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(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,9 @@
|
|||||||
{
|
{
|
||||||
"name": "webpack-pdf.js-example",
|
"name": "webpack-pdf.js-example",
|
||||||
"version": "0.2.0",
|
"version": "0.1.0",
|
||||||
"scripts": {
|
|
||||||
"build": "webpack"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"webpack": "^5.89.0",
|
"webpack": "~1.12.9",
|
||||||
"webpack-cli": "^5.1.4",
|
"entry-loader": "~0.1.0",
|
||||||
"pdfjs-dist": "../../node_modules/pdfjs-dist"
|
"pdfjs-dist": "../../build/dist"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
/* eslint-disable import/no-commonjs */
|
var webpack = require('webpack');
|
||||||
|
var path = require('path');
|
||||||
const webpack = require("webpack"); // eslint-disable-line no-unused-vars
|
|
||||||
const path = require("path");
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
context: __dirname,
|
context: __dirname,
|
||||||
entry: {
|
entry: './main.js',
|
||||||
main: "./main.mjs",
|
|
||||||
"pdf.worker": "pdfjs-dist/build/pdf.worker.mjs",
|
|
||||||
},
|
|
||||||
mode: "none",
|
|
||||||
output: {
|
output: {
|
||||||
path: path.join(__dirname, "../../build/webpack"),
|
path: path.join(__dirname, '../../build/webpack'),
|
||||||
publicPath: "../../build/webpack/",
|
publicPath: '../../build/webpack/',
|
||||||
filename: "[name].bundle.js",
|
filename: 'bundle.js'
|
||||||
},
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.optimize.UglifyJsPlugin({
|
||||||
|
compressor: {
|
||||||
|
screw_ie8: true,
|
||||||
|
warnings: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
BIN
extensions/b2g/images/div_line_left.png
Normal file
After Width: | Height: | Size: 174 B |