Merge branch 'master' into marked-content-lang

This commit is contained in:
calixteman 2025-11-21 18:22:30 +01:00 committed by GitHub
commit 9f576beee8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
125 changed files with 4710 additions and 2196 deletions

View File

@ -9,10 +9,17 @@
"overrides": [ "overrides": [
{ {
files: ["tsconfig.json"], "files": ["tsconfig.json", ".prettierrc"],
options: { "options": {
parser: "json", "parser": "json"
}, }
}, },
{
"files": ["**/*.html"],
"options": {
"parser": "html",
"printWidth": 160
}
}
] ]
} }

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<!-- <!--
Copyright 2014 Mozilla Foundation Copyright 2014 Mozilla Foundation
@ -15,29 +15,29 @@ 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>
<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" />
<meta name="google" content="notranslate"> <meta name="google" content="notranslate" />
<title>PDF.js page viewer using built components</title> <title>PDF.js page viewer using built components</title>
<style> <style>
body { body {
background-color: #808080; background-color: #808080;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
</style> </style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css"> <link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head> </head>
<body tabindex="1"> <body tabindex="1">
<div id="pageContainer" class="pdfViewer singlePageView"></div> <div id="pageContainer" class="pdfViewer singlePageView"></div>
<script src="pageviewer.mjs" type="module"></script> <script src="pageviewer.mjs" type="module"></script>
</body> </body>
</html> </html>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<!-- <!--
Copyright 2014 Mozilla Foundation Copyright 2014 Mozilla Foundation
@ -15,37 +15,37 @@ 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>
<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" />
<meta name="google" content="notranslate"> <meta name="google" content="notranslate" />
<title>PDF.js viewer using built components</title> <title>PDF.js viewer using built components</title>
<style> <style>
body { body {
background-color: #808080; background-color: #808080;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#viewerContainer { #viewerContainer {
overflow: auto; overflow: auto;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css"> <link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head> </head>
<body tabindex="1"> <body tabindex="1">
<div id="viewerContainer"> <div id="viewerContainer">
<div id="viewer" class="pdfViewer"></div> <div id="viewer" class="pdfViewer"></div>
</div> </div>
<script src="simpleviewer.mjs" type="module"></script> <script src="simpleviewer.mjs" type="module"></script>
</body> </body>
</html> </html>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<!-- <!--
Copyright 2014 Mozilla Foundation Copyright 2014 Mozilla Foundation
@ -15,37 +15,37 @@ 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>
<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" />
<meta name="google" content="notranslate"> <meta name="google" content="notranslate" />
<title>PDF.js Single Page Viewer using built components</title> <title>PDF.js Single Page Viewer using built components</title>
<style> <style>
body { body {
background-color: #808080; background-color: #808080;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
#viewerContainer { #viewerContainer {
overflow: auto; overflow: auto;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }
</style> </style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css"> <link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head> </head>
<body tabindex="1"> <body tabindex="1">
<div id="viewerContainer"> <div id="viewerContainer">
<div id="viewer" class="pdfViewer"></div> <div id="viewer" class="pdfViewer"></div>
</div> </div>
<script src="singlepageviewer.mjs" type="module"></script> <script src="singlepageviewer.mjs" type="module"></script>
</body> </body>
</html> </html>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<!-- <!--
Copyright 2018 Mozilla Foundation Copyright 2018 Mozilla Foundation
@ -15,26 +15,26 @@ 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>
<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" />
<meta name="google" content="notranslate"> <meta name="google" content="notranslate" />
<title>PDF.js standalone JpegImage parser</title> <title>PDF.js standalone JpegImage parser</title>
<style> <style>
body { body {
background-color: #808080; background-color: #808080;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
</style> </style>
<script src="../../node_modules/pdfjs-dist/image_decoders/pdf.image_decoders.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/image_decoders/pdf.image_decoders.mjs" type="module"></script>
</head> </head>
<body tabindex="1"> <body tabindex="1">
<canvas id="jpegCanvas" width="0" height="0"></canvas> <canvas id="jpegCanvas" width="0" height="0"></canvas>
<script src="jpeg_viewer.mjs" type="module"></script> <script src="jpeg_viewer.mjs" type="module"></script>
</body> </body>
</html> </html>

View File

@ -1,76 +1,71 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>'Hello, world!' example</title> <title>'Hello, world!' example</title>
</head> </head>
<body> <body>
<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; direction: ltr;"></canvas> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script id="script" type="module">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
const url = "./helloworld.pdf";
<script id="script" type="module"> //
// // The workerSrc property shall be specified.
// If absolute URL from the remote server is provided, configure the CORS //
// header on that server. pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
//
const url = './helloworld.pdf';
// //
// The workerSrc property shall be specified. // Asynchronous download PDF
// //
pdfjsLib.GlobalWorkerOptions.workerSrc = const loadingTask = pdfjsLib.getDocument(url);
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs'; const pdf = await loadingTask.promise;
//
// Fetch the first page
//
const page = await pdf.getPage(1);
const scale = 1.5;
const viewport = page.getViewport({ scale });
// Support HiDPI-screens.
const outputScale = window.devicePixelRatio || 1;
// //
// Asynchronous download PDF // Prepare canvas using PDF page dimensions
// //
const loadingTask = pdfjsLib.getDocument(url); const canvas = document.getElementById("the-canvas");
const pdf = await loadingTask.promise; const context = canvas.getContext("2d");
//
// Fetch the first page
//
const page = await pdf.getPage(1);
const scale = 1.5;
const viewport = page.getViewport({ scale });
// Support HiDPI-screens.
const outputScale = window.devicePixelRatio || 1;
// canvas.width = Math.floor(viewport.width * outputScale);
// Prepare canvas using PDF page dimensions canvas.height = Math.floor(viewport.height * outputScale);
// canvas.style.width = Math.floor(viewport.width) + "px";
const canvas = document.getElementById("the-canvas"); canvas.style.height = Math.floor(viewport.height) + "px";
const context = canvas.getContext("2d");
canvas.width = Math.floor(viewport.width * outputScale); const transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
const transform = outputScale !== 1 //
? [outputScale, 0, 0, outputScale, 0, 0] // Render PDF page into canvas context
: null; //
const renderContext = {
canvasContext: context,
transform,
viewport,
};
page.render(renderContext);
</script>
// <hr />
// Render PDF page into canvas context <h2>JavaScript code:</h2>
// <pre id="code"></pre>
const renderContext = { <script>
canvasContext: context, document.getElementById("code").textContent = document.getElementById("script").text;
transform, </script>
viewport, </body>
};
page.render(renderContext);
</script>
<hr>
<h2>JavaScript code:</h2>
<pre id="code"></pre>
<script>
document.getElementById('code').textContent =
document.getElementById('script').text;
</script>
</body>
</html> </html>

View File

@ -1,81 +1,77 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>'Hello, world!' base64 example</title> <title>'Hello, world!' base64 example</title>
</head> </head>
<body> <body>
<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; direction: ltr;"></canvas> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script id="script" type="module">
// atob() is used to convert base64 encoded PDF to binary-like data.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
// Base64_encoding_and_decoding.)
var pdfData = atob(
"JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog" +
"IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv" +
"TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K" +
"Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg" +
"L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+" +
"PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u" +
"dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq" +
"Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU" +
"CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu" +
"ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g" +
"CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw" +
"MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v" +
"dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G"
);
<script id="script" type="module"> //
// atob() is used to convert base64 encoded PDF to binary-like data. // The workerSrc property shall be specified.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/ //
// Base64_encoding_and_decoding.) pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
var pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
// // Opening PDF by passing its binary data as a string. It is still preferable
// The workerSrc property shall be specified. // to use Uint8Array, but string or array-like structure will work too.
// var loadingTask = pdfjsLib.getDocument({ data: pdfData });
pdfjsLib.GlobalWorkerOptions.workerSrc = var pdf = await loadingTask.promise;
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs'; // Fetch the first page.
var page = await pdf.getPage(1);
var scale = 1.5;
var viewport = page.getViewport({ scale: scale });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
// Opening PDF by passing its binary data as a string. It is still preferable // Prepare canvas using PDF page dimensions.
// to use Uint8Array, but string or array-like structure will work too. var canvas = document.getElementById("the-canvas");
var loadingTask = pdfjsLib.getDocument({ data: pdfData, }); var context = canvas.getContext("2d");
var pdf = await loadingTask.promise;
// Fetch the first page.
var page = await pdf.getPage(1);
var scale = 1.5;
var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
// Prepare canvas using PDF page dimensions. canvas.width = Math.floor(viewport.width * outputScale);
var canvas = document.getElementById('the-canvas'); canvas.height = Math.floor(viewport.height * outputScale);
var context = canvas.getContext('2d'); canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
canvas.width = Math.floor(viewport.width * outputScale); var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
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 // Render PDF page into canvas context.
? [outputScale, 0, 0, outputScale, 0, 0] var renderContext = {
: null; canvasContext: context,
transform,
viewport,
};
page.render(renderContext);
</script>
// Render PDF page into canvas context. <hr />
var renderContext = { <h2>JavaScript code:</h2>
canvasContext: context, <pre id="code"></pre>
transform, <script>
viewport, document.getElementById("code").textContent = document.getElementById("script").text;
}; </script>
page.render(renderContext); </body>
</script>
<hr>
<h2>JavaScript code:</h2>
<pre id="code"></pre>
<script>
document.getElementById('code').textContent =
document.getElementById('script').text;
</script>
</body>
</html> </html>

View File

@ -1,139 +1,134 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<title>Previous/Next example</title> <title>Previous/Next example</title>
</head> </head>
<body> <body>
<h1>'Previous/Next' example</h1>
<h1>'Previous/Next' example</h1> <div>
<button id="prev" type="button">Previous</button>
<button id="next" type="button">Next</button>
&nbsp; &nbsp;
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>
<div> <div>
<button id="prev" type="button">Previous</button> <canvas id="the-canvas" style="border: 1px solid black; direction: ltr"></canvas>
<button id="next" type="button">Next</button> </div>
&nbsp; &nbsp;
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>
<div> <script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
</div>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script> <script id="script" type="module">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
var url = "../../web/compressed.tracemonkey-pldi-09.pdf";
<script id="script" type="module"> //
// // In cases when the pdf.worker.js is located at the different folder than the
// If absolute URL from the remote server is provided, configure the CORS // PDF.js's one, or the PDF.js is executed via eval(), the workerSrc property
// header on that server. // shall be specified.
// //
var url = '../../web/compressed.tracemonkey-pldi-09.pdf'; pdfjsLib.GlobalWorkerOptions.workerSrc = "../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
// var pdfDoc = null,
// In cases when the pdf.worker.js is located at the different folder than the pageNum = 1,
// PDF.js's one, or the PDF.js is executed via eval(), the workerSrc property pageRendering = false,
// shall be specified. pageNumPending = null,
// scale = 0.8,
pdfjsLib.GlobalWorkerOptions.workerSrc = canvas = document.getElementById("the-canvas"),
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs'; ctx = canvas.getContext("2d");
var pdfDoc = null, /**
pageNum = 1, * Get page info from document, resize canvas accordingly, and render page.
pageRendering = false, * @param num Page number.
pageNumPending = null, */
scale = 0.8, function renderPage(num) {
canvas = document.getElementById('the-canvas'), pageRendering = true;
ctx = canvas.getContext('2d'); // Using promise to fetch the page
pdfDoc.getPage(num).then(function (page) {
var viewport = page.getViewport({ scale: scale });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
/** canvas.width = Math.floor(viewport.width * outputScale);
* Get page info from document, resize canvas accordingly, and render page. canvas.height = Math.floor(viewport.height * outputScale);
* @param num Page number. canvas.style.width = Math.floor(viewport.width) + "px";
*/ canvas.style.height = Math.floor(viewport.height) + "px";
function renderPage(num) {
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
canvas.width = Math.floor(viewport.width * outputScale); var transform = outputScale !== 1 ? [outputScale, 0, 0, outputScale, 0, 0] : null;
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 // Render PDF page into canvas context
? [outputScale, 0, 0, outputScale, 0, 0] var renderContext = {
: null; canvasContext: ctx,
transform: transform,
viewport: viewport,
};
var renderTask = page.render(renderContext);
// Render PDF page into canvas context // Wait for rendering to finish
var renderContext = { renderTask.promise.then(function () {
canvasContext: ctx, pageRendering = false;
transform: transform, if (pageNumPending !== null) {
viewport: viewport, // New page rendering is pending
}; renderPage(pageNumPending);
var renderTask = page.render(renderContext); pageNumPending = null;
}
});
});
// Wait for rendering to finish // Update page counters
renderTask.promise.then(function () { document.getElementById("page_num").textContent = num;
pageRendering = false; }
if (pageNumPending !== null) {
// New page rendering is pending /**
renderPage(pageNumPending); * If another page rendering in progress, waits until the rendering is
pageNumPending = null; * finished. Otherwise, executes rendering immediately.
*/
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
} }
}); }
});
// Update page counters /**
document.getElementById('page_num').textContent = num; * Displays previous page.
} */
function onPrevPage() {
if (pageNum <= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById("prev").addEventListener("click", onPrevPage);
/** /**
* If another page rendering in progress, waits until the rendering is * Displays next page.
* finished. Otherwise, executes rendering immediately. */
*/ function onNextPage() {
function queueRenderPage(num) { if (pageNum >= pdfDoc.numPages) {
if (pageRendering) { return;
pageNumPending = num; }
} else { pageNum++;
renderPage(num); queueRenderPage(pageNum);
} }
} document.getElementById("next").addEventListener("click", onNextPage);
/** /**
* Displays previous page. * Asynchronously downloads PDF.
*/ */
function onPrevPage() { var loadingTask = pdfjsLib.getDocument(url);
if (pageNum <= 1) { pdfDoc = await loadingTask.promise;
return; document.getElementById("page_count").textContent = pdfDoc.numPages;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('prev').addEventListener('click', onPrevPage);
/** // Initial/first page rendering
* Displays next page. renderPage(pageNum);
*/ </script>
function onNextPage() { </body>
if (pageNum >= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('next').addEventListener('click', onNextPage);
/**
* Asynchronously downloads PDF.
*/
var loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
document.getElementById('page_count').textContent = pdfDoc.numPages;
// Initial/first page rendering
renderPage(pageNum);
</script>
</body>
</html> </html>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html> <!doctype html>
<!-- <!--
Copyright 2016 Mozilla Foundation Copyright 2016 Mozilla Foundation
@ -16,13 +16,13 @@ limitations under the License.
--> -->
<html dir="ltr"> <html dir="ltr">
<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" />
<title>PDF.js viewer</title> <title>PDF.js viewer</title>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css"> <link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css" />
<link rel="stylesheet" type="text/css" href="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/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script> <script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
@ -46,12 +46,12 @@ limitations under the License.
<button class="toolbarButton pageUp" title="Previous Page" id="previous" type="button"></button> <button class="toolbarButton pageUp" title="Previous Page" id="previous" type="button"></button>
<button class="toolbarButton pageDown" title="Next Page" id="next" type="button"></button> <button class="toolbarButton pageDown" title="Next Page" id="next" type="button"></button>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1"> <input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1" />
<button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut" type="button"></button> <button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut" type="button"></button>
<button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn" type="button"></button> <button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn" type="button"></button>
</footer> </footer>
<script src="viewer.mjs" type="module"></script> <script src="viewer.mjs" type="module"></script>
</body> </body>
</html> </html>

View File

@ -1,14 +1,13 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <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="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="pdf2svg.mjs" type="module"></script> <script src="pdf2svg.mjs" type="module"></script>
</head> </head>
<body> <body>
<p>Text-only PDF.js example</p> <p>Text-only PDF.js example</p>
<div id="pageContainer" style="display: inline-block; border: solid 1px black;"> <div id="pageContainer" style="display: inline-block; border: solid 1px black"></div>
</div> </body>
</body>
</html> </html>

View File

@ -1,11 +1,11 @@
<!DOCTYPE html> <!doctype html>
<html lang="en"> <html lang="en">
<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/main.bundle.js"></script>
</head> </head>
<body> <body>
<canvas id="theCanvas"></canvas> <canvas id="theCanvas"></canvas>
</body> </body>
</html> </html>

View File

@ -15,171 +15,171 @@ See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
--> -->
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8" />
<title>PDF.js viewer options</title> <title>PDF.js viewer options</title>
<style> <style>
body { body {
min-width: 400px; /* a page at the settings page is at least 400px wide */ min-width: 400px; /* a page at the settings page is at least 400px wide */
margin: 14px 17px; /* already added by default in Chrome 40.0.2212.0 */ margin: 14px 17px; /* already added by default in Chrome 40.0.2212.0 */
} }
.settings-row { .settings-row {
margin: 1em 0; margin: 1em 0;
} }
.checkbox label { .checkbox label {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
} }
.checkbox label input { .checkbox label input {
flex-shrink: 0; flex-shrink: 0;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="settings-boxes"></div> <div id="settings-boxes"></div>
<button id="reset-button" type="button">Restore default settings</button> <button id="reset-button" type="button">Restore default settings</button>
<template id="checkbox-template"> <template id="checkbox-template">
<div class="settings-row checkbox"> <div class="settings-row checkbox">
<label> <label>
<input type="checkbox"> <input type="checkbox" />
<span></span> <span></span>
</label> </label>
</div> </div>
</template> </template>
<template id="viewerCssTheme-template"> <template id="viewerCssTheme-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="0">Use system theme</option> <option value="0">Use system theme</option>
<option value="1">Light theme</option> <option value="1">Light theme</option>
<option value="2">Dark theme</option> <option value="2">Dark theme</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="viewOnLoad-template"> <template id="viewOnLoad-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="-1">Default</option> <option value="-1">Default</option>
<option value="0">Show previous position</option> <option value="0">Show previous position</option>
<option value="1">Show initial position</option> <option value="1">Show initial position</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="defaultZoomValue-template"> <template id="defaultZoomValue-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="auto" selected="selected">Automatic Zoom</option> <option value="auto" selected="selected">Automatic Zoom</option>
<option value="page-actual">Actual Size</option> <option value="page-actual">Actual Size</option>
<option value="page-fit">Page Fit</option> <option value="page-fit">Page Fit</option>
<option value="page-width">Page Width</option> <option value="page-width">Page Width</option>
<option value="custom" class="custom-zoom" hidden></option> <option value="custom" class="custom-zoom" hidden></option>
<option value="50">50%</option> <option value="50">50%</option>
<option value="75">75%</option> <option value="75">75%</option>
<option value="100">100%</option> <option value="100">100%</option>
<option value="125">125%</option> <option value="125">125%</option>
<option value="150">150%</option> <option value="150">150%</option>
<option value="200">200%</option> <option value="200">200%</option>
<option value="300">300%</option> <option value="300">300%</option>
<option value="400">400%</option> <option value="400">400%</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="sidebarViewOnLoad-template"> <template id="sidebarViewOnLoad-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="-1">Default</option> <option value="-1">Default</option>
<option value="0">Do not show sidebar</option> <option value="0">Do not show sidebar</option>
<option value="1">Show thumbnails in sidebar</option> <option value="1">Show thumbnails in sidebar</option>
<option value="2">Show document outline in sidebar</option> <option value="2">Show document outline in sidebar</option>
<option value="3">Show attachments in sidebar</option> <option value="3">Show attachments in sidebar</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="cursorToolOnLoad-template"> <template id="cursorToolOnLoad-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="0">Text selection tool</option> <option value="0">Text selection tool</option>
<option value="1">Hand tool</option> <option value="1">Hand tool</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="textLayerMode-template"> <template id="textLayerMode-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="0">Disable text selection</option> <option value="0">Disable text selection</option>
<option value="1">Enable text selection</option> <option value="1">Enable text selection</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="externalLinkTarget-template"> <template id="externalLinkTarget-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="0">Default</option> <option value="0">Default</option>
<option value="1">Current window/tab</option> <option value="1">Current window/tab</option>
<option value="2">New window/tab</option> <option value="2">New window/tab</option>
<option value="3">Parent window/tab</option> <option value="3">Parent window/tab</option>
<option value="4">Top window/tab</option> <option value="4">Top window/tab</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="scrollModeOnLoad-template"> <template id="scrollModeOnLoad-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="-1">Default</option> <option value="-1">Default</option>
<option value="3">Page scrolling</option> <option value="3">Page scrolling</option>
<option value="0">Vertical scrolling</option> <option value="0">Vertical scrolling</option>
<option value="1">Horizontal scrolling</option> <option value="1">Horizontal scrolling</option>
<option value="2">Wrapped scrolling</option> <option value="2">Wrapped scrolling</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<template id="spreadModeOnLoad-template"> <template id="spreadModeOnLoad-template">
<div class="settings-row"> <div class="settings-row">
<label> <label>
<span></span> <span></span>
<select> <select>
<option value="-1">Default</option> <option value="-1">Default</option>
<option value="0">No spreads</option> <option value="0">No spreads</option>
<option value="1">Odd spreads</option> <option value="1">Odd spreads</option>
<option value="2">Even spreads</option> <option value="2">Even spreads</option>
</select> </select>
</label> </label>
</div> </div>
</template> </template>
<script src="options.js"></script> <script src="options.js"></script>
</body> </body>
</html> </html>

View File

@ -151,7 +151,7 @@ function preprocess(inFilename, outFilename, defines) {
let state = STATE_NONE; let state = STATE_NONE;
const stack = []; const stack = [];
const control = const control =
/^(?:\/\/|\s*\/\*|<!--)\s*#(if|elif|else|endif|expand|include|error)\b(?:\s+(.*?)(?:\*\/|-->)?$)?/; /^(?:\/\/|\s*\/\*|\s*<!--)\s*#(if|elif|else|endif|expand|include|error)\b(?:\s+(.*?)(?:\*\/|-->)?$)?/;
while ((line = readLine()) !== null) { while ((line = readLine()) !== null) {
++lineNumber; ++lineNumber;
@ -213,7 +213,7 @@ function preprocess(inFilename, outFilename, defines) {
) { ) {
writeLine( writeLine(
line line
.replaceAll(/^\/\/|^<!--/g, " ") .replaceAll(/^\/\/|^\s*<!--/g, " ")
.replaceAll(/(^\s*)\/\*/g, "$1 ") .replaceAll(/(^\s*)\/\*/g, "$1 ")
.replaceAll(/\*\/$|-->$/g, "") .replaceAll(/\*\/$|-->$/g, "")
); );

View File

@ -2023,7 +2023,7 @@ gulp.task(
gulp.task("lint", function (done) { gulp.task("lint", function (done) {
console.log(); console.log();
console.log("### Linting JS/CSS/JSON/SVG files"); console.log("### Linting JS/CSS/JSON/SVG/HTML files");
// Ensure that we lint the Firefox specific *.jsm files too. // Ensure that we lint the Firefox specific *.jsm files too.
const esLintOptions = [ const esLintOptions = [
@ -2047,9 +2047,10 @@ gulp.task("lint", function (done) {
const prettierOptions = [ const prettierOptions = [
"node_modules/prettier/bin/prettier.cjs", "node_modules/prettier/bin/prettier.cjs",
"**/*.json", "**/*.json",
"**/*.html",
]; ];
if (process.argv.includes("--fix")) { if (process.argv.includes("--fix")) {
prettierOptions.push("--log-level", "silent", "--write"); prettierOptions.push("--log-level", "error", "--write");
} else { } else {
prettierOptions.push("--log-level", "warn", "--check"); prettierOptions.push("--log-level", "warn", "--check");
} }

View File

@ -622,18 +622,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Дзеянні
pdfjs-editor-edit-comment-actions-button =
.title = Дзеянні
pdfjs-editor-edit-comment-close-button-label = Закрыць
pdfjs-editor-edit-comment-close-button =
.title = Закрыць
pdfjs-editor-edit-comment-actions-edit-button-label = Праўка
pdfjs-editor-edit-comment-actions-delete-button-label = Выдаліць
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Увядзіце свой каментарый
pdfjs-editor-edit-comment-manager-cancel-button = Скасаваць
pdfjs-editor-edit-comment-manager-save-button = Захаваць
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Змяніць каментарый pdfjs-editor-edit-comment-dialog-title-when-editing = Змяніць каментарый
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Абнавіць pdfjs-editor-edit-comment-dialog-save-button-when-editing = Абнавіць
@ -648,6 +636,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Скасаваць
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Змяніць каментарый .title = Змяніць каментарый
pdfjs-editor-add-comment-button =
.title = Дадаць каментарый
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -382,3 +382,7 @@ pdfjs-editor-colorpicker-red =
pdfjs-editor-new-alt-text-disclaimer-learn-more-url = Научете повече pdfjs-editor-new-alt-text-disclaimer-learn-more-url = Научете повече
pdfjs-editor-new-alt-text-not-now-button = Не сега pdfjs-editor-new-alt-text-not-now-button = Не сега
## Image alt-text settings
pdfjs-editor-alt-text-settings-delete-model-button = Изтриване

View File

@ -573,21 +573,6 @@ pdfjs-editor-add-signature-cancel-button = Otkaži
pdfjs-editor-add-signature-add-button = Dodaj pdfjs-editor-add-signature-add-button = Dodaj
pdfjs-editor-edit-signature-update-button = Ažuriraj pdfjs-editor-edit-signature-update-button = Ažuriraj
## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Radnje
pdfjs-editor-edit-comment-actions-button =
.title = Radnje
pdfjs-editor-edit-comment-close-button-label = Zatvori
pdfjs-editor-edit-comment-close-button =
.title = Zatvori
pdfjs-editor-edit-comment-actions-edit-button-label = Uredi
pdfjs-editor-edit-comment-actions-delete-button-label = Izbriši
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Unesite svoj komentar
pdfjs-editor-edit-comment-manager-cancel-button = Otkaži
pdfjs-editor-edit-comment-manager-save-button = Sačuvaj
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =

View File

@ -272,7 +272,3 @@ pdfjs-editor-alt-text-cancel-button = Cancel·la
## Dialog buttons ## Dialog buttons
pdfjs-editor-add-signature-cancel-button = Cancel·la pdfjs-editor-add-signature-cancel-button = Cancel·la
## Edit a comment dialog
pdfjs-editor-edit-comment-manager-cancel-button = Cancel·la

View File

@ -564,8 +564,8 @@ pdfjs-editor-add-signature-dialog-title = Přidat podpis
## Tab names ## Tab names
# Type is a verb (you can type your name as signature) # Type is a verb (you can type your name as signature)
pdfjs-editor-add-signature-type-button = Typ pdfjs-editor-add-signature-type-button = Psát
.title = Typ .title = Psát
# Draw is a verb (you can draw your signature) # Draw is a verb (you can draw your signature)
pdfjs-editor-add-signature-draw-button = Kreslit pdfjs-editor-add-signature-draw-button = Kreslit
.title = Kreslit .title = Kreslit
@ -626,18 +626,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Akce
pdfjs-editor-edit-comment-actions-button =
.title = Akce
pdfjs-editor-edit-comment-close-button-label = Zavřít
pdfjs-editor-edit-comment-close-button =
.title = Zavřít
pdfjs-editor-edit-comment-actions-edit-button-label = Upravit
pdfjs-editor-edit-comment-actions-delete-button-label = Smazat
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Zadejte komentář
pdfjs-editor-edit-comment-manager-cancel-button = Zrušit
pdfjs-editor-edit-comment-manager-save-button = Uložit
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Upravit komentář pdfjs-editor-edit-comment-dialog-title-when-editing = Upravit komentář
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizovat pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizovat
@ -652,6 +640,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Zrušit
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Upravit komentář .title = Upravit komentář
pdfjs-editor-add-comment-button =
.title = Přidání komentáře
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -634,18 +634,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Gweithredoedd
pdfjs-editor-edit-comment-actions-button =
.title = Gweithredoedd
pdfjs-editor-edit-comment-close-button-label = Cau
pdfjs-editor-edit-comment-close-button =
.title = Cau
pdfjs-editor-edit-comment-actions-edit-button-label = Golygu
pdfjs-editor-edit-comment-actions-delete-button-label = Dileu
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Rhowch eich sylw
pdfjs-editor-edit-comment-manager-cancel-button = Diddymu
pdfjs-editor-edit-comment-manager-save-button = Cadw
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Golygu sylw pdfjs-editor-edit-comment-dialog-title-when-editing = Golygu sylw
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Diweddaru pdfjs-editor-edit-comment-dialog-save-button-when-editing = Diweddaru
@ -660,6 +648,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Diddymu
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Golygu sylw .title = Golygu sylw
pdfjs-editor-add-comment-button =
.title = Ychwanegu sylw
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Handlinger
pdfjs-editor-edit-comment-actions-button =
.title = Handlinger
pdfjs-editor-edit-comment-close-button-label = Luk
pdfjs-editor-edit-comment-close-button =
.title = Luk
pdfjs-editor-edit-comment-actions-edit-button-label = Rediger
pdfjs-editor-edit-comment-actions-delete-button-label = Slet
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Indtast din kommentar
pdfjs-editor-edit-comment-manager-cancel-button = Annuller
pdfjs-editor-edit-comment-manager-save-button = Gem
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Opdater pdfjs-editor-edit-comment-dialog-save-button-when-editing = Opdater
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Annuller
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Rediger kommentar .title = Rediger kommentar
pdfjs-editor-add-comment-button =
.title = Tilføj kommentar
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Aktionen
pdfjs-editor-edit-comment-actions-button =
.title = Aktionen
pdfjs-editor-edit-comment-close-button-label = Schließen
pdfjs-editor-edit-comment-close-button =
.title = Schließen
pdfjs-editor-edit-comment-actions-edit-button-label = Bearbeiten
pdfjs-editor-edit-comment-actions-delete-button-label = Löschen
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Kommentar eingeben
pdfjs-editor-edit-comment-manager-cancel-button = Abbrechen
pdfjs-editor-edit-comment-manager-save-button = Speichern
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Kommentar bearbeiten pdfjs-editor-edit-comment-dialog-title-when-editing = Kommentar bearbeiten
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualisieren pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualisieren

View File

@ -626,18 +626,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Akcije
pdfjs-editor-edit-comment-actions-button =
.title = Akcije
pdfjs-editor-edit-comment-close-button-label = Zacyniś
pdfjs-editor-edit-comment-close-button =
.title = Zacyniś
pdfjs-editor-edit-comment-actions-edit-button-label = Wobźěłaś
pdfjs-editor-edit-comment-actions-delete-button-label = Lašowaś
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Zapódajśo swój komentar
pdfjs-editor-edit-comment-manager-cancel-button = Pśetergnuś
pdfjs-editor-edit-comment-manager-save-button = Składowaś
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Komentar wobźěłaś pdfjs-editor-edit-comment-dialog-title-when-editing = Komentar wobźěłaś
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizěrowaś pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizěrowaś

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Ενέργειες
pdfjs-editor-edit-comment-actions-button =
.title = Ενέργειες
pdfjs-editor-edit-comment-close-button-label = Κλείσιμο
pdfjs-editor-edit-comment-close-button =
.title = Κλείσιμο
pdfjs-editor-edit-comment-actions-edit-button-label = Επεξεργασία
pdfjs-editor-edit-comment-actions-delete-button-label = Διαγραφή
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Εισαγάγετε το σχόλιό σας
pdfjs-editor-edit-comment-manager-cancel-button = Ακύρωση
pdfjs-editor-edit-comment-manager-save-button = Αποθήκευση
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Επεξεργασία σχολίου pdfjs-editor-edit-comment-dialog-title-when-editing = Επεξεργασία σχολίου
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Ενημέρωση pdfjs-editor-edit-comment-dialog-save-button-when-editing = Ενημέρωση
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Ακύρωση
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Επεξεργασία σχολίου .title = Επεξεργασία σχολίου
pdfjs-editor-add-comment-button =
.title = Προσθήκη σχολίου
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -616,18 +616,6 @@ pdfjs-editor-delete-comment-popup-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Actions
pdfjs-editor-edit-comment-actions-button =
.title = Actions
pdfjs-editor-edit-comment-close-button-label = Close
pdfjs-editor-edit-comment-close-button =
.title = Close
pdfjs-editor-edit-comment-actions-edit-button-label = Edit
pdfjs-editor-edit-comment-actions-delete-button-label = Delete
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Enter your comment
pdfjs-editor-edit-comment-manager-cancel-button = Cancel
pdfjs-editor-edit-comment-manager-save-button = Save
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment pdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment
# No existing comment # No existing comment

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Actions
pdfjs-editor-edit-comment-actions-button =
.title = Actions
pdfjs-editor-edit-comment-close-button-label = Close
pdfjs-editor-edit-comment-close-button =
.title = Close
pdfjs-editor-edit-comment-actions-edit-button-label = Edit
pdfjs-editor-edit-comment-actions-delete-button-label = Delete
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Enter your comment
pdfjs-editor-edit-comment-manager-cancel-button = Cancel
pdfjs-editor-edit-comment-manager-save-button = Save
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment pdfjs-editor-edit-comment-dialog-title-when-editing = Edit comment
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Update pdfjs-editor-edit-comment-dialog-save-button-when-editing = Update

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Agoj
pdfjs-editor-edit-comment-actions-button =
.title = Agoj
pdfjs-editor-edit-comment-close-button-label = Fermi
pdfjs-editor-edit-comment-close-button =
.title = Fermi
pdfjs-editor-edit-comment-actions-edit-button-label = Modifi
pdfjs-editor-edit-comment-actions-delete-button-label = Forigi
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Tajpu vian komenton
pdfjs-editor-edit-comment-manager-cancel-button = Nuligi
pdfjs-editor-edit-comment-manager-save-button = Konservi
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Modifi komenton pdfjs-editor-edit-comment-dialog-title-when-editing = Modifi komenton
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Ĝisdatigi pdfjs-editor-edit-comment-dialog-save-button-when-editing = Ĝisdatigi
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Nuligi
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Modifi komenton .title = Modifi komenton
pdfjs-editor-add-comment-button =
.title = Aldoni komenton
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acciones
pdfjs-editor-edit-comment-actions-button =
.title = Acciones
pdfjs-editor-edit-comment-close-button-label = Cerrar
pdfjs-editor-edit-comment-close-button =
.title = Cerrar
pdfjs-editor-edit-comment-actions-edit-button-label = Editar
pdfjs-editor-edit-comment-actions-delete-button-label = Borrar
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Ingresar un comentario
pdfjs-editor-edit-comment-manager-cancel-button = Cancelar
pdfjs-editor-edit-comment-manager-save-button = Guardar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acciones
pdfjs-editor-edit-comment-actions-button =
.title = Acciones
pdfjs-editor-edit-comment-close-button-label = Cerrar
pdfjs-editor-edit-comment-close-button =
.title = Cerrar
pdfjs-editor-edit-comment-actions-edit-button-label = Editar
pdfjs-editor-edit-comment-actions-delete-button-label = Eliminar
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Ingresa tu comentario
pdfjs-editor-edit-comment-manager-cancel-button = Cancelar
pdfjs-editor-edit-comment-manager-save-button = Guardar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Cancelar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Editar comentario .title = Editar comentario
pdfjs-editor-add-comment-button =
.title = Añadir comentario
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acciones
pdfjs-editor-edit-comment-actions-button =
.title = Acciones
pdfjs-editor-edit-comment-close-button-label = Cerrar
pdfjs-editor-edit-comment-close-button =
.title = Cerrar
pdfjs-editor-edit-comment-actions-edit-button-label = Editar
pdfjs-editor-edit-comment-actions-delete-button-label = Eliminar
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Introduzca su comentario
pdfjs-editor-edit-comment-manager-cancel-button = Cancelar
pdfjs-editor-edit-comment-manager-save-button = Guardar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Cancelar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Editar comentario .title = Editar comentario
pdfjs-editor-add-comment-button =
.title = Añadir comentario
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acciones
pdfjs-editor-edit-comment-actions-button =
.title = Acciones
pdfjs-editor-edit-comment-close-button-label = Cerrar
pdfjs-editor-edit-comment-close-button =
.title = Cerrar
pdfjs-editor-edit-comment-actions-edit-button-label = Editar
pdfjs-editor-edit-comment-actions-delete-button-label = Eliminar
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Ingresa tu comentario
pdfjs-editor-edit-comment-manager-cancel-button = Cancelar
pdfjs-editor-edit-comment-manager-save-button = Guardar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentario
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizar

View File

@ -622,18 +622,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Ekintzak
pdfjs-editor-edit-comment-actions-button =
.title = Ekintzak
pdfjs-editor-edit-comment-close-button-label = Itxi
pdfjs-editor-edit-comment-close-button =
.title = Itxi
pdfjs-editor-edit-comment-actions-edit-button-label = Editatu
pdfjs-editor-edit-comment-actions-delete-button-label = Ezabatu
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Idatzi zure iruzkina
pdfjs-editor-edit-comment-manager-cancel-button = Utzi
pdfjs-editor-edit-comment-manager-save-button = Gorde
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editatu iruzkina pdfjs-editor-edit-comment-dialog-title-when-editing = Editatu iruzkina
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Eguneratu pdfjs-editor-edit-comment-dialog-save-button-when-editing = Eguneratu

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Toiminnot
pdfjs-editor-edit-comment-actions-button =
.title = Toiminnot
pdfjs-editor-edit-comment-close-button-label = Sulje
pdfjs-editor-edit-comment-close-button =
.title = Sulje
pdfjs-editor-edit-comment-actions-edit-button-label = Muokkaa
pdfjs-editor-edit-comment-actions-delete-button-label = Poista
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Kirjoita kommenttisi
pdfjs-editor-edit-comment-manager-cancel-button = Peruuta
pdfjs-editor-edit-comment-manager-save-button = Tallenna
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Muokkaa kommenttia pdfjs-editor-edit-comment-dialog-title-when-editing = Muokkaa kommenttia
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Päivitä pdfjs-editor-edit-comment-dialog-save-button-when-editing = Päivitä

View File

@ -614,18 +614,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Actions
pdfjs-editor-edit-comment-actions-button =
.title = Actions
pdfjs-editor-edit-comment-close-button-label = Fermer
pdfjs-editor-edit-comment-close-button =
.title = Fermer
pdfjs-editor-edit-comment-actions-edit-button-label = Modifier
pdfjs-editor-edit-comment-actions-delete-button-label = Supprimer
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Saisissez votre commentaire
pdfjs-editor-edit-comment-manager-cancel-button = Annuler
pdfjs-editor-edit-comment-manager-save-button = Enregistrer
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Modifier le commentaire pdfjs-editor-edit-comment-dialog-title-when-editing = Modifier le commentaire
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Mettre à jour pdfjs-editor-edit-comment-dialog-save-button-when-editing = Mettre à jour

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Azions
pdfjs-editor-edit-comment-actions-button =
.title = Azions
pdfjs-editor-edit-comment-close-button-label = Siere
pdfjs-editor-edit-comment-close-button =
.title = Siere
pdfjs-editor-edit-comment-actions-edit-button-label = Modifiche
pdfjs-editor-edit-comment-actions-delete-button-label = Elimine
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Inserìs il to coment
pdfjs-editor-edit-comment-manager-cancel-button = Anule
pdfjs-editor-edit-comment-manager-save-button = Salve
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Modifiche coment pdfjs-editor-edit-comment-dialog-title-when-editing = Modifiche coment
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Inzorne pdfjs-editor-edit-comment-dialog-save-button-when-editing = Inzorne

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Aksjes
pdfjs-editor-edit-comment-actions-button =
.title = Aksjes
pdfjs-editor-edit-comment-close-button-label = Slute
pdfjs-editor-edit-comment-close-button =
.title = Slute
pdfjs-editor-edit-comment-actions-edit-button-label = Bewurkje
pdfjs-editor-edit-comment-actions-delete-button-label = Fuortsmite
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Fier jo opmerking yn
pdfjs-editor-edit-comment-manager-cancel-button = Annulearje
pdfjs-editor-edit-comment-manager-save-button = Bewarje
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Opmerking bewurkje pdfjs-editor-edit-comment-dialog-title-when-editing = Opmerking bewurkje
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Bywurkje pdfjs-editor-edit-comment-dialog-save-button-when-editing = Bywurkje

View File

@ -617,18 +617,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Ñemongue
pdfjs-editor-edit-comment-actions-button =
.title = Ñemongue
pdfjs-editor-edit-comment-close-button-label = Mboty
pdfjs-editor-edit-comment-close-button =
.title = Mboty
pdfjs-editor-edit-comment-actions-edit-button-label = Mbosakoi
pdfjs-editor-edit-comment-actions-delete-button-label = Mboguete
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Ehai peteĩ jeerei
pdfjs-editor-edit-comment-manager-cancel-button = Heja
pdfjs-editor-edit-comment-manager-save-button = Ñongatu
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Jeerei mbosakoi pdfjs-editor-edit-comment-dialog-title-when-editing = Jeerei mbosakoi
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Mbohekopyahu pdfjs-editor-edit-comment-dialog-save-button-when-editing = Mbohekopyahu
@ -643,6 +631,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Eheja
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Jeerei mbosakoi .title = Jeerei mbosakoi
pdfjs-editor-add-comment-button =
.title = Jeerei mbojuaju
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = פעולות
pdfjs-editor-edit-comment-actions-button =
.title = פעולות
pdfjs-editor-edit-comment-close-button-label = סגירה
pdfjs-editor-edit-comment-close-button =
.title = סגירה
pdfjs-editor-edit-comment-actions-edit-button-label = עריכה
pdfjs-editor-edit-comment-actions-delete-button-label = מחיקה
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = נא להכניס את ההערה שלך
pdfjs-editor-edit-comment-manager-cancel-button = ביטול
pdfjs-editor-edit-comment-manager-save-button = שמירה
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = עריכת הערה pdfjs-editor-edit-comment-dialog-title-when-editing = עריכת הערה
pdfjs-editor-edit-comment-dialog-save-button-when-editing = עדכון pdfjs-editor-edit-comment-dialog-save-button-when-editing = עדכון

View File

@ -626,18 +626,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Akcije
pdfjs-editor-edit-comment-actions-button =
.title = Akcije
pdfjs-editor-edit-comment-close-button-label = Začinić
pdfjs-editor-edit-comment-close-button =
.title = Začinić
pdfjs-editor-edit-comment-actions-edit-button-label = Wobdźěłać
pdfjs-editor-edit-comment-actions-delete-button-label = Zhašeć
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Zapodajće swój komentar
pdfjs-editor-edit-comment-manager-cancel-button = Přetorhnyć
pdfjs-editor-edit-comment-manager-save-button = Składować
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Komentar wobdźěłać pdfjs-editor-edit-comment-dialog-title-when-editing = Komentar wobdźěłać
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizować pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizować

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Műveletek
pdfjs-editor-edit-comment-actions-button =
.title = Műveletek
pdfjs-editor-edit-comment-close-button-label = Bezárás
pdfjs-editor-edit-comment-close-button =
.title = Bezárás
pdfjs-editor-edit-comment-actions-edit-button-label = Szerkesztés
pdfjs-editor-edit-comment-actions-delete-button-label = Törlés
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Írja be a megjegyzését
pdfjs-editor-edit-comment-manager-cancel-button = Mégse
pdfjs-editor-edit-comment-manager-save-button = Mentés
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Megjegyzés szerkesztése pdfjs-editor-edit-comment-dialog-title-when-editing = Megjegyzés szerkesztése
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Frissítés pdfjs-editor-edit-comment-dialog-save-button-when-editing = Frissítés

View File

@ -586,21 +586,6 @@ pdfjs-editor-add-signature-cancel-button = Չեղարկել
pdfjs-editor-add-signature-add-button = Ավելացնել pdfjs-editor-add-signature-add-button = Ավելացնել
pdfjs-editor-edit-signature-update-button = Թարմացնել pdfjs-editor-edit-signature-update-button = Թարմացնել
## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Գործողություններ
pdfjs-editor-edit-comment-actions-button =
.title = Գործողություններ
pdfjs-editor-edit-comment-close-button-label = Փակել
pdfjs-editor-edit-comment-close-button =
.title = Փակել
pdfjs-editor-edit-comment-actions-edit-button-label = Խմբագրել
pdfjs-editor-edit-comment-actions-delete-button-label = Ջնջել
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Մուտքագրեք ձեր մեկնաբանությունը
pdfjs-editor-edit-comment-manager-cancel-button = Չեղարկել
pdfjs-editor-edit-comment-manager-save-button = Պահպանել
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Actiones
pdfjs-editor-edit-comment-actions-button =
.title = Actiones
pdfjs-editor-edit-comment-close-button-label = Clauder
pdfjs-editor-edit-comment-close-button =
.title = Clauder
pdfjs-editor-edit-comment-actions-edit-button-label = Rediger
pdfjs-editor-edit-comment-actions-delete-button-label = Deler
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Insere tu commento
pdfjs-editor-edit-comment-manager-cancel-button = Cancellar
pdfjs-editor-edit-comment-manager-save-button = Salvar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger commento pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger commento
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualisar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualisar

View File

@ -574,21 +574,6 @@ pdfjs-editor-add-signature-cancel-button = Batal
pdfjs-editor-add-signature-add-button = Tambah pdfjs-editor-add-signature-add-button = Tambah
pdfjs-editor-edit-signature-update-button = Perbarui pdfjs-editor-edit-signature-update-button = Perbarui
## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Aksi
pdfjs-editor-edit-comment-actions-button =
.title = Aksi
pdfjs-editor-edit-comment-close-button-label = Tutup
pdfjs-editor-edit-comment-close-button =
.title = Tutup
pdfjs-editor-edit-comment-actions-edit-button-label = Sunting
pdfjs-editor-edit-comment-actions-delete-button-label = Hapus
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Masukkan komentar Anda
pdfjs-editor-edit-comment-manager-cancel-button = Batal
pdfjs-editor-edit-comment-manager-save-button = Simpan
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =

View File

@ -557,21 +557,6 @@ pdfjs-editor-add-signature-cancel-button = Hætta við
pdfjs-editor-add-signature-add-button = Bæta við pdfjs-editor-add-signature-add-button = Bæta við
pdfjs-editor-edit-signature-update-button = Uppfæra pdfjs-editor-edit-signature-update-button = Uppfæra
## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Aðgerðir
pdfjs-editor-edit-comment-actions-button =
.title = Aðgerðir
pdfjs-editor-edit-comment-close-button-label = Loka
pdfjs-editor-edit-comment-close-button =
.title = Loka
pdfjs-editor-edit-comment-actions-edit-button-label = Breyta
pdfjs-editor-edit-comment-actions-delete-button-label = Eyða
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Settu inn athugasemdina þína
pdfjs-editor-edit-comment-manager-cancel-button = Hætta við
pdfjs-editor-edit-comment-manager-save-button = Vista
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =

View File

@ -290,10 +290,10 @@ pdfjs-editor-color-picker-free-text-input =
.title = Cambia colore del testo .title = Cambia colore del testo
pdfjs-editor-free-text-button-label = Testo pdfjs-editor-free-text-button-label = Testo
pdfjs-editor-ink-button = pdfjs-editor-ink-button =
.title = Disegno .title = Disegna
pdfjs-editor-color-picker-ink-input = pdfjs-editor-color-picker-ink-input =
.title = Cambia colore del disegno .title = Cambia colore del disegno
pdfjs-editor-ink-button-label = Disegno pdfjs-editor-ink-button-label = Disegna
pdfjs-editor-stamp-button = pdfjs-editor-stamp-button =
.title = Aggiungi o rimuovi immagine .title = Aggiungi o rimuovi immagine
pdfjs-editor-stamp-button-label = Aggiungi o rimuovi immagine pdfjs-editor-stamp-button-label = Aggiungi o rimuovi immagine
@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Azioni
pdfjs-editor-edit-comment-actions-button =
.title = Azioni
pdfjs-editor-edit-comment-close-button-label = Chiudi
pdfjs-editor-edit-comment-close-button =
.title = Chiudi
pdfjs-editor-edit-comment-actions-edit-button-label = Modifica
pdfjs-editor-edit-comment-actions-delete-button-label = Elimina
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Inserisci il tuo commento
pdfjs-editor-edit-comment-manager-cancel-button = Annulla
pdfjs-editor-edit-comment-manager-save-button = Salva
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Modifica commento pdfjs-editor-edit-comment-dialog-title-when-editing = Modifica commento
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aggiorna pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aggiorna

View File

@ -597,6 +597,8 @@ pdfjs-editor-edit-comment-popup-button =
pdfjs-editor-delete-comment-popup-button-label = コメントを削除 pdfjs-editor-delete-comment-popup-button-label = コメントを削除
pdfjs-editor-delete-comment-popup-button = pdfjs-editor-delete-comment-popup-button =
.title = コメントを削除します .title = コメントを削除します
pdfjs-show-comment-button =
.title = コメントを表示します
## Edit a comment dialog ## Edit a comment dialog
@ -614,17 +616,20 @@ pdfjs-editor-edit-comment-manager-cancel-button = キャンセル
pdfjs-editor-edit-comment-manager-save-button = 保存 pdfjs-editor-edit-comment-manager-save-button = 保存
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = コメントを編集 pdfjs-editor-edit-comment-dialog-title-when-editing = コメントを編集
pdfjs-editor-edit-comment-dialog-save-button-when-editing = 更新
# No existing comment # No existing comment
pdfjs-editor-edit-comment-dialog-title-when-adding = コメントを追加 pdfjs-editor-edit-comment-dialog-title-when-adding = コメントを追加
pdfjs-editor-edit-comment-dialog-save-button-when-adding = 追加
pdfjs-editor-edit-comment-dialog-text-input = pdfjs-editor-edit-comment-dialog-text-input =
.placeholder = コメントを入力してください... .placeholder = コメントを入力してください...
pdfjs-editor-edit-comment-dialog-cancel-button = キャンセル pdfjs-editor-edit-comment-dialog-cancel-button = キャンセル
pdfjs-editor-edit-comment-dialog-save-button = 保存
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Edit comment .title = コメントを編集します
pdfjs-editor-add-comment-button =
.title = コメントを追加します
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = მოქმედებები
pdfjs-editor-edit-comment-actions-button =
.title = მოქმედებები
pdfjs-editor-edit-comment-close-button-label = დახურვა
pdfjs-editor-edit-comment-close-button =
.title = დახურვა
pdfjs-editor-edit-comment-actions-edit-button-label = ჩასწორება
pdfjs-editor-edit-comment-actions-delete-button-label = წაშლა
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = შეიყვანეთ დასართავი შენიშვნა
pdfjs-editor-edit-comment-manager-cancel-button = გაუქმება
pdfjs-editor-edit-comment-manager-save-button = შენახვა
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = შენიშვნის ჩასწორება pdfjs-editor-edit-comment-dialog-title-when-editing = შენიშვნის ჩასწორება
pdfjs-editor-edit-comment-dialog-save-button-when-editing = განახლება pdfjs-editor-edit-comment-dialog-save-button-when-editing = განახლება

View File

@ -601,18 +601,6 @@ pdfjs-editor-delete-comment-popup-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Tigawin
pdfjs-editor-edit-comment-actions-button =
.title = Tigawin
pdfjs-editor-edit-comment-close-button-label = Mdel
pdfjs-editor-edit-comment-close-button =
.title = Mdel
pdfjs-editor-edit-comment-actions-edit-button-label = Ẓreg
pdfjs-editor-edit-comment-actions-delete-button-label = Kkes
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Aru awennit-ik⋅im
pdfjs-editor-edit-comment-manager-cancel-button = Sefsex
pdfjs-editor-edit-comment-manager-save-button = Sekles
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Ẓreg awennit pdfjs-editor-edit-comment-dialog-title-when-editing = Ẓreg awennit
# No existing comment # No existing comment

View File

@ -596,25 +596,16 @@ pdfjs-editor-edit-signature-update-button = Жаңарту
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Әрекеттер
pdfjs-editor-edit-comment-actions-button =
.title = Әрекеттер
pdfjs-editor-edit-comment-close-button-label = Жабу
pdfjs-editor-edit-comment-close-button =
.title = Жабу
pdfjs-editor-edit-comment-actions-edit-button-label = Түзету
pdfjs-editor-edit-comment-actions-delete-button-label = Өшіру
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Пікіріңізді енгізіңіз
pdfjs-editor-edit-comment-manager-cancel-button = Бас тарту
pdfjs-editor-edit-comment-manager-save-button = Сақтау
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Жаңарту pdfjs-editor-edit-comment-dialog-save-button-when-editing = Жаңарту
pdfjs-editor-edit-comment-dialog-save-button-when-adding = Қосу
pdfjs-editor-edit-comment-dialog-cancel-button = Бас тарту pdfjs-editor-edit-comment-dialog-cancel-button = Бас тарту
## Edit a comment button in the editor toolbar ## Edit a comment button in the editor toolbar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Пікірді түзету .title = Пікірді түзету
pdfjs-editor-add-comment-button =
.title = Пікір қосу
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -602,18 +602,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = 동작
pdfjs-editor-edit-comment-actions-button =
.title = 동작
pdfjs-editor-edit-comment-close-button-label = 닫기
pdfjs-editor-edit-comment-close-button =
.title = 닫기
pdfjs-editor-edit-comment-actions-edit-button-label = 편집
pdfjs-editor-edit-comment-actions-delete-button-label = 삭제
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = 주석을 입력하세요
pdfjs-editor-edit-comment-manager-cancel-button = 취소
pdfjs-editor-edit-comment-manager-save-button = 저장
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = 주석 편집 pdfjs-editor-edit-comment-dialog-title-when-editing = 주석 편집
pdfjs-editor-edit-comment-dialog-save-button-when-editing = 업데이트 pdfjs-editor-edit-comment-dialog-save-button-when-editing = 업데이트

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Handlinger
pdfjs-editor-edit-comment-actions-button =
.title = Handlinger
pdfjs-editor-edit-comment-close-button-label = Lukk
pdfjs-editor-edit-comment-close-button =
.title = Lukk
pdfjs-editor-edit-comment-actions-edit-button-label = Rediger
pdfjs-editor-edit-comment-actions-delete-button-label = Slett
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Skriv inn kommentaren din
pdfjs-editor-edit-comment-manager-cancel-button = Avbryt
pdfjs-editor-edit-comment-manager-save-button = Lagre
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Oppdater pdfjs-editor-edit-comment-dialog-save-button-when-editing = Oppdater
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Avbryt
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Rediger kommentar .title = Rediger kommentar
pdfjs-editor-add-comment-button =
.title = Legg til kommentar
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acties
pdfjs-editor-edit-comment-actions-button =
.title = Acties
pdfjs-editor-edit-comment-close-button-label = Sluiten
pdfjs-editor-edit-comment-close-button =
.title = Sluiten
pdfjs-editor-edit-comment-actions-edit-button-label = Bewerken
pdfjs-editor-edit-comment-actions-delete-button-label = Verwijderen
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Voer uw opmerking in
pdfjs-editor-edit-comment-manager-cancel-button = Annuleren
pdfjs-editor-edit-comment-manager-save-button = Opslaan
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Opmerking bewerken pdfjs-editor-edit-comment-dialog-title-when-editing = Opmerking bewerken
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Bijwerken pdfjs-editor-edit-comment-dialog-save-button-when-editing = Bijwerken

View File

@ -616,18 +616,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Handlingar
pdfjs-editor-edit-comment-actions-button =
.title = Handlingar
pdfjs-editor-edit-comment-close-button-label = Lat att
pdfjs-editor-edit-comment-close-button =
.title = Lat att
pdfjs-editor-edit-comment-actions-edit-button-label = Rediger
pdfjs-editor-edit-comment-actions-delete-button-label = Slett
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Skriv inn kommentaren din
pdfjs-editor-edit-comment-manager-cancel-button = Avbryt
pdfjs-editor-edit-comment-manager-save-button = Lagre
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar pdfjs-editor-edit-comment-dialog-title-when-editing = Rediger kommentar
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Oppdater pdfjs-editor-edit-comment-dialog-save-button-when-editing = Oppdater

View File

@ -386,6 +386,8 @@ pdfjs-editor-comments-sidebar-close-button =
.title = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ .title = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ
.aria-label = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ .aria-label = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ
pdfjs-editor-comments-sidebar-close-button-label = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ pdfjs-editor-comments-sidebar-close-button-label = ਬਾਹੀ ਨੂੰ ਬੰਦ ਕਰੋ
# Instructional copy to add a comment by selecting text or an annotations.
pdfjs-editor-comments-sidebar-no-comments1 = ਕੀ ਕੁਝ ਧਿਆਨ ਦੇਣ ਯੋਗ ਵੇਖਿਆ ਹੈ? ਇਸ ਨੂੰ ਉਘਾੜੋ ਅਤੇ ਟਿੱਪਣੀ ਦਿਓ।
pdfjs-editor-comments-sidebar-no-comments-link = ਹੋਰ ਜਾਣੋ pdfjs-editor-comments-sidebar-no-comments-link = ਹੋਰ ਜਾਣੋ
## Alt-text dialog ## Alt-text dialog
@ -616,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = ਕਾਰਵਾਈਆਂ
pdfjs-editor-edit-comment-actions-button =
.title = ਕਾਰਵਾਈਆਂ
pdfjs-editor-edit-comment-close-button-label = ਬੰਦ ਕਰੋ
pdfjs-editor-edit-comment-close-button =
.title = ਬੰਦ ਕਰੋ
pdfjs-editor-edit-comment-actions-edit-button-label = ਸੋਧੋ
pdfjs-editor-edit-comment-actions-delete-button-label = ਹਟਾਓ
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = ਆਪਣੀ ਟਿੱਪਣੀ ਦਿਓ
pdfjs-editor-edit-comment-manager-cancel-button = ਰੱਦ ਕਰੋ
pdfjs-editor-edit-comment-manager-save-button = ਸੰਭਾਲੋ
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = ਟਿੱਪਣੀ ਨੂੰ ਸੋਧੋ pdfjs-editor-edit-comment-dialog-title-when-editing = ਟਿੱਪਣੀ ਨੂੰ ਸੋਧੋ
pdfjs-editor-edit-comment-dialog-save-button-when-editing = ਅੱਪਡੇਟ ਕਰੋ pdfjs-editor-edit-comment-dialog-save-button-when-editing = ਅੱਪਡੇਟ ਕਰੋ
@ -642,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = ਰੱਦ ਕਰੋ
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = ਟਿੱਪਣੀ ਨੂੰ ਸੋਧੋ .title = ਟਿੱਪਣੀ ਨੂੰ ਸੋਧੋ
pdfjs-editor-add-comment-button =
.title = ਟਿੱਪਣੀ ਜੋੜੋ
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -621,18 +621,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Działania
pdfjs-editor-edit-comment-actions-button =
.title = Działania
pdfjs-editor-edit-comment-close-button-label = Zamknij
pdfjs-editor-edit-comment-close-button =
.title = Zamknij
pdfjs-editor-edit-comment-actions-edit-button-label = Edytuj
pdfjs-editor-edit-comment-actions-delete-button-label = Usuń
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Napisz komentarz
pdfjs-editor-edit-comment-manager-cancel-button = Anuluj
pdfjs-editor-edit-comment-manager-save-button = Zapisz
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Edytuj komentarz pdfjs-editor-edit-comment-dialog-title-when-editing = Edytuj komentarz
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizuj pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizuj
@ -647,6 +635,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Anuluj
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Edytuj komentarz .title = Edytuj komentarz
pdfjs-editor-add-comment-button =
.title = Dodaj komentarz
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Ações
pdfjs-editor-edit-comment-actions-button =
.title = Ações
pdfjs-editor-edit-comment-close-button-label = Fechar
pdfjs-editor-edit-comment-close-button =
.title = Fechar
pdfjs-editor-edit-comment-actions-edit-button-label = Editar
pdfjs-editor-edit-comment-actions-delete-button-label = Excluir
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Digite seu comentário
pdfjs-editor-edit-comment-manager-cancel-button = Cancelar
pdfjs-editor-edit-comment-manager-save-button = Salvar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentário pdfjs-editor-edit-comment-dialog-title-when-editing = Editar comentário
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Atualizar pdfjs-editor-edit-comment-dialog-save-button-when-editing = Atualizar
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Cancelar
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Editar comentário .title = Editar comentário
pdfjs-editor-add-comment-button =
.title = Adicionar comentário
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -616,18 +616,6 @@ pdfjs-editor-delete-comment-popup-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acziuns
pdfjs-editor-edit-comment-actions-button =
.title = Acziuns
pdfjs-editor-edit-comment-close-button-label = Serrar
pdfjs-editor-edit-comment-close-button =
.title = Serrar
pdfjs-editor-edit-comment-actions-edit-button-label = Modifitgar
pdfjs-editor-edit-comment-actions-delete-button-label = Stizzar
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Endatar in commentari
pdfjs-editor-edit-comment-manager-cancel-button = Interrumper
pdfjs-editor-edit-comment-manager-save-button = Memorisar
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Modifitgar il commentari pdfjs-editor-edit-comment-dialog-title-when-editing = Modifitgar il commentari
# No existing comment # No existing comment

View File

@ -37,8 +37,8 @@ pdfjs-open-file-button =
.title = Deschide un fișier .title = Deschide un fișier
pdfjs-open-file-button-label = Deschide pdfjs-open-file-button-label = Deschide
pdfjs-print-button = pdfjs-print-button =
.title = Listează .title = Printează
pdfjs-print-button-label = Listează pdfjs-print-button-label = Printează
pdfjs-save-button = pdfjs-save-button =
.title = Salvează .title = Salvează
pdfjs-save-button-label = Salvează pdfjs-save-button-label = Salvează
@ -621,18 +621,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Acțiuni
pdfjs-editor-edit-comment-actions-button =
.title = Acțiuni
pdfjs-editor-edit-comment-close-button-label = Închide
pdfjs-editor-edit-comment-close-button =
.title = Închide
pdfjs-editor-edit-comment-actions-edit-button-label = Editează
pdfjs-editor-edit-comment-actions-delete-button-label = Șterge
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Introdu comentariul
pdfjs-editor-edit-comment-manager-cancel-button = Anulează
pdfjs-editor-edit-comment-manager-save-button = Salvează
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Editează comentariul pdfjs-editor-edit-comment-dialog-title-when-editing = Editează comentariul
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizează pdfjs-editor-edit-comment-dialog-save-button-when-editing = Actualizează

View File

@ -622,18 +622,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Действия
pdfjs-editor-edit-comment-actions-button =
.title = Действия
pdfjs-editor-edit-comment-close-button-label = Закрыть
pdfjs-editor-edit-comment-close-button =
.title = Закрыть
pdfjs-editor-edit-comment-actions-edit-button-label = Изменить
pdfjs-editor-edit-comment-actions-delete-button-label = Удалить
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Введите ваш комментарий
pdfjs-editor-edit-comment-manager-cancel-button = Отмена
pdfjs-editor-edit-comment-manager-save-button = Сохранить
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Редактировать комментарий pdfjs-editor-edit-comment-dialog-title-when-editing = Редактировать комментарий
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Обновить pdfjs-editor-edit-comment-dialog-save-button-when-editing = Обновить

View File

@ -338,6 +338,5 @@ pdfjs-editor-add-signature-cancel-button = Annulla
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-manager-cancel-button = Annulla
pdfjs-editor-edit-comment-dialog-text-input = pdfjs-editor-edit-comment-dialog-text-input =
.placeholder = Cumintza a iscrìere… .placeholder = Cumintza a iscrìere…

View File

@ -626,18 +626,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Akcie
pdfjs-editor-edit-comment-actions-button =
.title = Akcie
pdfjs-editor-edit-comment-close-button-label = Zavrieť
pdfjs-editor-edit-comment-close-button =
.title = Zavrieť
pdfjs-editor-edit-comment-actions-edit-button-label = Upraviť
pdfjs-editor-edit-comment-actions-delete-button-label = Odstrániť
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Zadajte svoj komentár
pdfjs-editor-edit-comment-manager-cancel-button = Zrušiť
pdfjs-editor-edit-comment-manager-save-button = Uložiť
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Upraviť komentár pdfjs-editor-edit-comment-dialog-title-when-editing = Upraviť komentár
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizovať pdfjs-editor-edit-comment-dialog-save-button-when-editing = Aktualizovať

View File

@ -626,18 +626,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Dejanja
pdfjs-editor-edit-comment-actions-button =
.title = Dejanja
pdfjs-editor-edit-comment-close-button-label = Zapri
pdfjs-editor-edit-comment-close-button =
.title = Zapri
pdfjs-editor-edit-comment-actions-edit-button-label = Uredi
pdfjs-editor-edit-comment-actions-delete-button-label = Izbriši
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Vnesite komentar
pdfjs-editor-edit-comment-manager-cancel-button = Prekliči
pdfjs-editor-edit-comment-manager-save-button = Shrani
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Uredi komentar pdfjs-editor-edit-comment-dialog-title-when-editing = Uredi komentar
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Spremeni pdfjs-editor-edit-comment-dialog-save-button-when-editing = Spremeni
@ -652,6 +640,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Prekliči
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Uredi komentar .title = Uredi komentar
pdfjs-editor-add-comment-button =
.title = Dodaj komentar
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -609,18 +609,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Veprime
pdfjs-editor-edit-comment-actions-button =
.title = Veprime
pdfjs-editor-edit-comment-close-button-label = Mbylle
pdfjs-editor-edit-comment-close-button =
.title = Mbylle
pdfjs-editor-edit-comment-actions-edit-button-label = Përpunoni
pdfjs-editor-edit-comment-actions-delete-button-label = Fshije
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Jepni komentin tuaj
pdfjs-editor-edit-comment-manager-cancel-button = Anuloje
pdfjs-editor-edit-comment-manager-save-button = Ruaje
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Përpunoni koment pdfjs-editor-edit-comment-dialog-title-when-editing = Përpunoni koment
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Përditësojeni pdfjs-editor-edit-comment-dialog-save-button-when-editing = Përditësojeni
@ -635,6 +623,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Anuloje
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Përpunoni koment .title = Përpunoni koment
pdfjs-editor-add-comment-button =
.title = Shtoni koment
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Åtgärder
pdfjs-editor-edit-comment-actions-button =
.title = Åtgärder
pdfjs-editor-edit-comment-close-button-label = Stäng
pdfjs-editor-edit-comment-close-button =
.title = Stäng
pdfjs-editor-edit-comment-actions-edit-button-label = Redigera
pdfjs-editor-edit-comment-actions-delete-button-label = Ta bort
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Ange din kommentar
pdfjs-editor-edit-comment-manager-cancel-button = Avbryt
pdfjs-editor-edit-comment-manager-save-button = Spara
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Redigera kommentar pdfjs-editor-edit-comment-dialog-title-when-editing = Redigera kommentar
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Uppdatera pdfjs-editor-edit-comment-dialog-save-button-when-editing = Uppdatera

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Амалҳо
pdfjs-editor-edit-comment-actions-button =
.title = Амалҳо
pdfjs-editor-edit-comment-close-button-label = Пӯшидан
pdfjs-editor-edit-comment-close-button =
.title = Пӯшидан
pdfjs-editor-edit-comment-actions-edit-button-label = Таҳрир кардан
pdfjs-editor-edit-comment-actions-delete-button-label = Нест кардан
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Шарҳи худро ворид кунед
pdfjs-editor-edit-comment-manager-cancel-button = Бекор кардан
pdfjs-editor-edit-comment-manager-save-button = Нигоҳ доштан
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Таҳрир кардани шарҳ pdfjs-editor-edit-comment-dialog-title-when-editing = Таҳрир кардани шарҳ
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Навсозӣ кардан pdfjs-editor-edit-comment-dialog-save-button-when-editing = Навсозӣ кардан
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Бекор кардан
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Таҳрир кардани шарҳ .title = Таҳрир кардани шарҳ
pdfjs-editor-add-comment-button =
.title = Илова кардани шарҳ
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -602,18 +602,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = การกระทำ
pdfjs-editor-edit-comment-actions-button =
.title = การกระทำ
pdfjs-editor-edit-comment-close-button-label = ปิด
pdfjs-editor-edit-comment-close-button =
.title = ปิด
pdfjs-editor-edit-comment-actions-edit-button-label = แก้ไข
pdfjs-editor-edit-comment-actions-delete-button-label = ลบ
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = ป้อนความคิดเห็นของคุณ
pdfjs-editor-edit-comment-manager-cancel-button = ยกเลิก
pdfjs-editor-edit-comment-manager-save-button = บันทึก
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = แก้ไขความคิดเห็น pdfjs-editor-edit-comment-dialog-title-when-editing = แก้ไขความคิดเห็น
pdfjs-editor-edit-comment-dialog-save-button-when-editing = อัปเดต pdfjs-editor-edit-comment-dialog-save-button-when-editing = อัปเดต

View File

@ -618,18 +618,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Eylemler
pdfjs-editor-edit-comment-actions-button =
.title = Eylemler
pdfjs-editor-edit-comment-close-button-label = Kapat
pdfjs-editor-edit-comment-close-button =
.title = Kapat
pdfjs-editor-edit-comment-actions-edit-button-label = Düzenle
pdfjs-editor-edit-comment-actions-delete-button-label = Sil
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Yorumunuzu yazın
pdfjs-editor-edit-comment-manager-cancel-button = Vazgeç
pdfjs-editor-edit-comment-manager-save-button = Kaydet
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Yorumu düzenle pdfjs-editor-edit-comment-dialog-title-when-editing = Yorumu düzenle
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Güncelle pdfjs-editor-edit-comment-dialog-save-button-when-editing = Güncelle
@ -644,6 +632,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = Vazgeç
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = Yorumu düzenle .title = Yorumu düzenle
pdfjs-editor-add-comment-button =
.title = Yorum ekle
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -602,18 +602,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = Hành động
pdfjs-editor-edit-comment-actions-button =
.title = Hành động
pdfjs-editor-edit-comment-close-button-label = Đóng
pdfjs-editor-edit-comment-close-button =
.title = Đóng
pdfjs-editor-edit-comment-actions-edit-button-label = Chỉnh sửa
pdfjs-editor-edit-comment-actions-delete-button-label = Xóa
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = Nhập chú thích của bạn
pdfjs-editor-edit-comment-manager-cancel-button = Hủy bỏ
pdfjs-editor-edit-comment-manager-save-button = Lưu
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = Chỉnh sửa chú thích pdfjs-editor-edit-comment-dialog-title-when-editing = Chỉnh sửa chú thích
pdfjs-editor-edit-comment-dialog-save-button-when-editing = Cập nhật pdfjs-editor-edit-comment-dialog-save-button-when-editing = Cập nhật

View File

@ -602,18 +602,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = 操作
pdfjs-editor-edit-comment-actions-button =
.title = 操作
pdfjs-editor-edit-comment-close-button-label = 关闭
pdfjs-editor-edit-comment-close-button =
.title = 关闭
pdfjs-editor-edit-comment-actions-edit-button-label = 编辑
pdfjs-editor-edit-comment-actions-delete-button-label = 删除
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = 输入批注
pdfjs-editor-edit-comment-manager-cancel-button = 取消
pdfjs-editor-edit-comment-manager-save-button = 保存
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = 编辑批注 pdfjs-editor-edit-comment-dialog-title-when-editing = 编辑批注
pdfjs-editor-edit-comment-dialog-save-button-when-editing = 更新 pdfjs-editor-edit-comment-dialog-save-button-when-editing = 更新
@ -628,6 +616,8 @@ pdfjs-editor-edit-comment-dialog-cancel-button = 取消
pdfjs-editor-edit-comment-button = pdfjs-editor-edit-comment-button =
.title = 编辑批注 .title = 编辑批注
pdfjs-editor-add-comment-button =
.title = 添加批注
## Main menu for adding/removing signatures ## Main menu for adding/removing signatures

View File

@ -602,18 +602,6 @@ pdfjs-show-comment-button =
## Edit a comment dialog ## Edit a comment dialog
pdfjs-editor-edit-comment-actions-button-label = 動作
pdfjs-editor-edit-comment-actions-button =
.title = 動作
pdfjs-editor-edit-comment-close-button-label = 關閉
pdfjs-editor-edit-comment-close-button =
.title = 關閉
pdfjs-editor-edit-comment-actions-edit-button-label = 編輯
pdfjs-editor-edit-comment-actions-delete-button-label = 刪除
pdfjs-editor-edit-comment-manager-text-input =
.placeholder = 輸入您的註解
pdfjs-editor-edit-comment-manager-cancel-button = 取消
pdfjs-editor-edit-comment-manager-save-button = 儲存
# An existing comment is edited # An existing comment is edited
pdfjs-editor-edit-comment-dialog-title-when-editing = 編輯註解 pdfjs-editor-edit-comment-dialog-title-when-editing = 編輯註解
pdfjs-editor-edit-comment-dialog-save-button-when-editing = 更新 pdfjs-editor-edit-comment-dialog-save-button-when-editing = 更新

196
package-lock.json generated
View File

@ -16,12 +16,12 @@
"@metalsmith/layouts": "^3.0.0", "@metalsmith/layouts": "^3.0.0",
"@metalsmith/markdown": "^1.10.0", "@metalsmith/markdown": "^1.10.0",
"@napi-rs/canvas": "^0.1.81", "@napi-rs/canvas": "^0.1.81",
"@types/node": "^24.9.1", "@types/node": "^24.10.0",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.21",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"caniuse-lite": "^1.0.30001751", "caniuse-lite": "^1.0.30001754",
"core-js": "^3.46.0", "core-js": "^3.46.0",
"eslint": "^9.38.0", "eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0", "eslint-plugin-import": "^2.32.0",
"eslint-plugin-jasmine": "^4.2.2", "eslint-plugin-jasmine": "^4.2.2",
@ -30,7 +30,7 @@
"eslint-plugin-perfectionist": "^4.15.1", "eslint-plugin-perfectionist": "^4.15.1",
"eslint-plugin-prettier": "^5.5.4", "eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-unicorn": "^62.0.0", "eslint-plugin-unicorn": "^62.0.0",
"globals": "^16.4.0", "globals": "^16.5.0",
"gulp": "^5.0.1", "gulp": "^5.0.1",
"gulp-cli": "^3.1.0", "gulp-cli": "^3.1.0",
"gulp-postcss": "^10.0.0", "gulp-postcss": "^10.0.0",
@ -42,15 +42,15 @@
"jsdoc": "^4.0.5", "jsdoc": "^4.0.5",
"jstransformer-nunjucks": "^1.2.0", "jstransformer-nunjucks": "^1.2.0",
"metalsmith": "^2.6.3", "metalsmith": "^2.6.3",
"metalsmith-html-relative": "^2.0.8", "metalsmith-html-relative": "^2.0.9",
"ordered-read-streams": "^2.0.0", "ordered-read-streams": "^2.0.0",
"pngjs": "^7.0.0", "pngjs": "^7.0.0",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"postcss-dir-pseudo-class": "^9.0.1", "postcss-dir-pseudo-class": "^9.0.1",
"postcss-discard-comments": "^7.0.4", "postcss-discard-comments": "^7.0.5",
"postcss-nesting": "^13.0.2", "postcss-nesting": "^13.0.2",
"prettier": "^3.6.2", "prettier": "^3.6.2",
"puppeteer": "^24.26.1", "puppeteer": "^24.29.1",
"stylelint": "^16.25.0", "stylelint": "^16.25.0",
"stylelint-prettier": "^5.0.3", "stylelint-prettier": "^5.0.3",
"svglint": "^4.1.2", "svglint": "^4.1.2",
@ -98,7 +98,6 @@
"integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@babel/code-frame": "^7.27.1", "@babel/code-frame": "^7.27.1",
"@babel/generator": "^7.28.5", "@babel/generator": "^7.28.5",
@ -1649,7 +1648,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },
@ -1673,7 +1671,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"engines": { "engines": {
"node": ">=18" "node": ">=18"
} }
@ -1895,22 +1892,22 @@
} }
}, },
"node_modules/@eslint/config-helpers": { "node_modules/@eslint/config-helpers": {
"version": "0.4.1", "version": "0.4.2",
"resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.1.tgz", "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
"integrity": "sha512-csZAzkNhsgwb0I/UAV6/RGFTbiakPCf0ZrGmrIxQpYvGZ00PhTkSnyKNolphgIvmnJeGw6rcGVEXfTzUnFuEvw==", "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/core": "^0.16.0" "@eslint/core": "^0.17.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
} }
}, },
"node_modules/@eslint/core": { "node_modules/@eslint/core": {
"version": "0.16.0", "version": "0.17.0",
"resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.16.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
"integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==", "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
@ -1958,9 +1955,9 @@
} }
}, },
"node_modules/@eslint/js": { "node_modules/@eslint/js": {
"version": "9.38.0", "version": "9.39.1",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.38.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz",
"integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A==", "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -1981,13 +1978,13 @@
} }
}, },
"node_modules/@eslint/plugin-kit": { "node_modules/@eslint/plugin-kit": {
"version": "0.4.0", "version": "0.4.1",
"resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.0.tgz", "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
"integrity": "sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==", "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@eslint/core": "^0.16.0", "@eslint/core": "^0.17.0",
"levn": "^0.4.1" "levn": "^0.4.1"
}, },
"engines": { "engines": {
@ -2547,9 +2544,9 @@
} }
}, },
"node_modules/@puppeteer/browsers": { "node_modules/@puppeteer/browsers": {
"version": "2.10.12", "version": "2.10.13",
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.12.tgz", "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.10.13.tgz",
"integrity": "sha512-mP9iLFZwH+FapKJLeA7/fLqOlSUwYpMwjR1P5J23qd4e7qGJwecJccJqHYrjw33jmIZYV4dtiTHPD/J+1e7cEw==", "integrity": "sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
@ -2693,7 +2690,6 @@
"integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/estree": "*", "@types/estree": "*",
"@types/json-schema": "*" "@types/json-schema": "*"
@ -2751,7 +2747,6 @@
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/linkify-it": "^5", "@types/linkify-it": "^5",
"@types/mdurl": "^2" "@types/mdurl": "^2"
@ -2765,9 +2760,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": { "node_modules/@types/node": {
"version": "24.9.1", "version": "24.10.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.1.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.0.tgz",
"integrity": "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg==", "integrity": "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -3165,7 +3160,6 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"acorn": "bin/acorn" "acorn": "bin/acorn"
}, },
@ -3772,8 +3766,7 @@
"resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz", "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.7.0.tgz",
"integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==", "integrity": "sha512-b3N5eTW1g7vXkw+0CXh/HazGTcO5KYuu/RCNaJbDMPI6LHDi+7qe8EmxKUVe1sUbY2KZOVZFyj62x0OEz9qyAA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0"
"peer": true
}, },
"node_modules/bare-fs": { "node_modules/bare-fs": {
"version": "4.5.0", "version": "4.5.0",
@ -3847,9 +3840,9 @@
} }
}, },
"node_modules/bare-url": { "node_modules/bare-url": {
"version": "2.3.1", "version": "2.3.2",
"resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.1.tgz", "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz",
"integrity": "sha512-v2yl0TnaZTdEnelkKtXZGnotiV6qATBlnNuUMrHl6v9Lmmrh9mw9RYyImPU7/4RahumSwQS1k2oKXcRfXcbjJw==", "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"optional": true, "optional": true,
@ -4009,7 +4002,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"baseline-browser-mapping": "^2.8.9", "baseline-browser-mapping": "^2.8.9",
"caniuse-lite": "^1.0.30001746", "caniuse-lite": "^1.0.30001746",
@ -4174,9 +4166,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001751", "version": "1.0.30001754",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001754.tgz",
"integrity": "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==", "integrity": "sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==",
"dev": true, "dev": true,
"funding": [ "funding": [
{ {
@ -4894,12 +4886,11 @@
} }
}, },
"node_modules/devtools-protocol": { "node_modules/devtools-protocol": {
"version": "0.0.1508733", "version": "0.0.1521046",
"resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1508733.tgz", "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz",
"integrity": "sha512-QJ1R5gtck6nDcdM+nlsaJXcelPEI7ZxSMw1ujHpO1c4+9l+Nue5qlebi9xO1Z2MGr92bFOQTW7/rrheh5hHxDg==", "integrity": "sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w==",
"dev": true, "dev": true,
"license": "BSD-3-Clause", "license": "BSD-3-Clause"
"peer": true
}, },
"node_modules/dir-glob": { "node_modules/dir-glob": {
"version": "3.0.1", "version": "3.0.1",
@ -5375,21 +5366,20 @@
} }
}, },
"node_modules/eslint": { "node_modules/eslint": {
"version": "9.38.0", "version": "9.39.1",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.38.0.tgz", "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.1.tgz",
"integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==", "integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1", "@eslint-community/regexpp": "^4.12.1",
"@eslint/config-array": "^0.21.1", "@eslint/config-array": "^0.21.1",
"@eslint/config-helpers": "^0.4.1", "@eslint/config-helpers": "^0.4.2",
"@eslint/core": "^0.16.0", "@eslint/core": "^0.17.0",
"@eslint/eslintrc": "^3.3.1", "@eslint/eslintrc": "^3.3.1",
"@eslint/js": "9.38.0", "@eslint/js": "9.39.1",
"@eslint/plugin-kit": "^0.4.0", "@eslint/plugin-kit": "^0.4.1",
"@humanfs/node": "^0.16.6", "@humanfs/node": "^0.16.6",
"@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/module-importer": "^1.0.1",
"@humanwhocodes/retry": "^0.4.2", "@humanwhocodes/retry": "^0.4.2",
@ -5441,7 +5431,6 @@
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==", "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"eslint-config-prettier": "bin/cli.js" "eslint-config-prettier": "bin/cli.js"
}, },
@ -6417,9 +6406,9 @@
} }
}, },
"node_modules/glob": { "node_modules/glob": {
"version": "10.4.5", "version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"dev": true, "dev": true,
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
@ -6563,9 +6552,9 @@
} }
}, },
"node_modules/globals": { "node_modules/globals": {
"version": "16.4.0", "version": "16.5.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-16.4.0.tgz", "resolved": "https://registry.npmjs.org/globals/-/globals-16.5.0.tgz",
"integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==", "integrity": "sha512-c/c15i26VrJ4IRt5Z89DnIzCGDn9EcebibhAOjw5ibqEHsE1wLUgkPn9RDmNcUKyU87GeaL633nyJ+pplFR2ZQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@ -6680,9 +6669,9 @@
} }
}, },
"node_modules/gray-matter/node_modules/js-yaml": { "node_modules/gray-matter/node_modules/js-yaml": {
"version": "3.14.1", "version": "3.14.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz",
"integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -6699,7 +6688,6 @@
"integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==", "integrity": "sha512-PErok3DZSA5WGMd6XXV3IRNO0mlB+wW3OzhFJLEec1jSERg2j1bxJ6e5Fh6N6fn3FH2T9AP4UYNb/pYlADB9sA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"glob-watcher": "^6.0.0", "glob-watcher": "^6.0.0",
"gulp-cli": "^3.1.0", "gulp-cli": "^3.1.0",
@ -7941,9 +7929,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/js-yaml": { "node_modules/js-yaml": {
"version": "4.1.0", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -8386,7 +8374,6 @@
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"argparse": "^2.0.1", "argparse": "^2.0.1",
"entities": "^4.4.0", "entities": "^4.4.0",
@ -8509,7 +8496,6 @@
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"chokidar": "^3.6.0", "chokidar": "^3.6.0",
"commander": "^10.0.1", "commander": "^10.0.1",
@ -8529,15 +8515,15 @@
} }
}, },
"node_modules/metalsmith-html-relative": { "node_modules/metalsmith-html-relative": {
"version": "2.0.8", "version": "2.0.9",
"resolved": "https://registry.npmjs.org/metalsmith-html-relative/-/metalsmith-html-relative-2.0.8.tgz", "resolved": "https://registry.npmjs.org/metalsmith-html-relative/-/metalsmith-html-relative-2.0.9.tgz",
"integrity": "sha512-mxaKo5KRon23iEJqHF2UhCQedZI1dTPwWSe2gnYbHuoMbkczd5eJK9GYmO40ji7EYnnda6p6CGe6twteGO60Wg==", "integrity": "sha512-r5QnNNtoNoLuxCcfGeqxGgxrmzeIdnt+ikUbRXtVD6EGqYG78f9fpjqAjvh1y8ao4NUgUJAJiQWdTFIl03D78w==",
"dev": true, "dev": true,
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {
"cheerio": "^1.1.2", "cheerio": "^1.1.2",
"deepmerge": "^4.3.1", "deepmerge": "^4.3.1",
"minimatch": "^10.0.3" "minimatch": "^10.1.1"
}, },
"engines": { "engines": {
"node": ">=20.18.1" "node": ">=20.18.1"
@ -8547,11 +8533,11 @@
} }
}, },
"node_modules/metalsmith-html-relative/node_modules/minimatch": { "node_modules/metalsmith-html-relative/node_modules/minimatch": {
"version": "10.0.3", "version": "10.1.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dev": true, "dev": true,
"license": "ISC", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"@isaacs/brace-expansion": "^5.0.0" "@isaacs/brace-expansion": "^5.0.0"
}, },
@ -9429,7 +9415,6 @@
} }
], ],
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"nanoid": "^3.3.11", "nanoid": "^3.3.11",
"picocolors": "^1.1.1", "picocolors": "^1.1.1",
@ -9466,9 +9451,9 @@
} }
}, },
"node_modules/postcss-discard-comments": { "node_modules/postcss-discard-comments": {
"version": "7.0.4", "version": "7.0.5",
"resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.4.tgz", "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-7.0.5.tgz",
"integrity": "sha512-6tCUoql/ipWwKtVP/xYiFf1U9QgJ0PUvxN7pTcsQ8Ns3Fnwq1pU5D5s1MhT/XySeLq6GXNvn37U46Ded0TckWg==", "integrity": "sha512-IR2Eja8WfYgN5n32vEGSctVQ1+JARfu4UH8M7bgGh1bC+xI/obsPJXaBpQF7MAByvgwZinhpHpdrmXtvVVlKcQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -9589,7 +9574,6 @@
"integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"cssesc": "^3.0.0", "cssesc": "^3.0.0",
"util-deprecate": "^1.0.2" "util-deprecate": "^1.0.2"
@ -9621,7 +9605,6 @@
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"bin": { "bin": {
"prettier": "bin/prettier.cjs" "prettier": "bin/prettier.cjs"
}, },
@ -9748,18 +9731,18 @@
} }
}, },
"node_modules/puppeteer": { "node_modules/puppeteer": {
"version": "24.26.1", "version": "24.29.1",
"resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.26.1.tgz", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.29.1.tgz",
"integrity": "sha512-3RG2UqclzMFolM2fS4bN8t5/EjZ0VwEoAGVxG8PMGeprjLzj+x0U4auH7MQ4B6ftW+u1JUnTTN8ab4ABPdl4mA==", "integrity": "sha512-pX05JV1mMP+1N0vP3I4DOVwjMdpihv2LxQTtSfw6CUm5F0ZFLUFE/LSZ4yUWHYaM3C11Hdu+sgn7uY7teq5MYw==",
"dev": true, "dev": true,
"hasInstallScript": true, "hasInstallScript": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@puppeteer/browsers": "2.10.12", "@puppeteer/browsers": "2.10.13",
"chromium-bidi": "10.5.1", "chromium-bidi": "10.5.1",
"cosmiconfig": "^9.0.0", "cosmiconfig": "^9.0.0",
"devtools-protocol": "0.0.1508733", "devtools-protocol": "0.0.1521046",
"puppeteer-core": "24.26.1", "puppeteer-core": "24.29.1",
"typed-query-selector": "^2.12.0" "typed-query-selector": "^2.12.0"
}, },
"bin": { "bin": {
@ -9770,16 +9753,16 @@
} }
}, },
"node_modules/puppeteer-core": { "node_modules/puppeteer-core": {
"version": "24.26.1", "version": "24.29.1",
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.26.1.tgz", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.29.1.tgz",
"integrity": "sha512-YHZdo3chJ5b9pTYVnuDuoI3UX/tWJFJyRZvkLbThGy6XeHWC+0KI8iN0UMCkvde5l/YOk3huiVZ/PvwgSbwdrA==", "integrity": "sha512-ErJ9qKCK+bdLvBa7QVSQTBSPm8KZbl1yC/WvhrZ0ut27hDf2QBzjDsn1IukzE1i1KtZ7NYGETOV4W1beoo9izA==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"dependencies": { "dependencies": {
"@puppeteer/browsers": "2.10.12", "@puppeteer/browsers": "2.10.13",
"chromium-bidi": "10.5.1", "chromium-bidi": "10.5.1",
"debug": "^4.4.3", "debug": "^4.4.3",
"devtools-protocol": "0.0.1508733", "devtools-protocol": "0.0.1521046",
"typed-query-selector": "^2.12.0", "typed-query-selector": "^2.12.0",
"webdriver-bidi-protocol": "0.3.8", "webdriver-bidi-protocol": "0.3.8",
"ws": "^8.18.3" "ws": "^8.18.3"
@ -10291,7 +10274,6 @@
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"fast-deep-equal": "^3.1.3", "fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1", "fast-uri": "^3.0.1",
@ -11317,15 +11299,15 @@
"license": "BSD-2-Clause" "license": "BSD-2-Clause"
}, },
"node_modules/svglint/node_modules/glob": { "node_modules/svglint/node_modules/glob": {
"version": "11.0.3", "version": "11.1.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
"integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", "integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
"dev": true, "dev": true,
"license": "ISC", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"foreground-child": "^3.3.1", "foreground-child": "^3.3.1",
"jackspeak": "^4.1.1", "jackspeak": "^4.1.1",
"minimatch": "^10.0.3", "minimatch": "^10.1.1",
"minipass": "^7.1.2", "minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0", "package-json-from-dist": "^1.0.0",
"path-scurry": "^2.0.0" "path-scurry": "^2.0.0"
@ -11382,11 +11364,11 @@
} }
}, },
"node_modules/svglint/node_modules/minimatch": { "node_modules/svglint/node_modules/minimatch": {
"version": "10.0.3", "version": "10.1.1",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
"integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
"dev": true, "dev": true,
"license": "ISC", "license": "BlueOak-1.0.0",
"dependencies": { "dependencies": {
"@isaacs/brace-expansion": "^5.0.0" "@isaacs/brace-expansion": "^5.0.0"
}, },
@ -11898,7 +11880,6 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"dev": true, "dev": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"peer": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@ -12288,7 +12269,6 @@
"integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==", "integrity": "sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true,
"dependencies": { "dependencies": {
"@types/eslint-scope": "^3.7.7", "@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8", "@types/estree": "^1.0.8",

View File

@ -11,12 +11,12 @@
"@metalsmith/layouts": "^3.0.0", "@metalsmith/layouts": "^3.0.0",
"@metalsmith/markdown": "^1.10.0", "@metalsmith/markdown": "^1.10.0",
"@napi-rs/canvas": "^0.1.81", "@napi-rs/canvas": "^0.1.81",
"@types/node": "^24.9.1", "@types/node": "^24.10.0",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.21",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"caniuse-lite": "^1.0.30001751", "caniuse-lite": "^1.0.30001754",
"core-js": "^3.46.0", "core-js": "^3.46.0",
"eslint": "^9.38.0", "eslint": "^9.39.1",
"eslint-config-prettier": "^10.1.8", "eslint-config-prettier": "^10.1.8",
"eslint-plugin-import": "^2.32.0", "eslint-plugin-import": "^2.32.0",
"eslint-plugin-jasmine": "^4.2.2", "eslint-plugin-jasmine": "^4.2.2",
@ -25,7 +25,7 @@
"eslint-plugin-perfectionist": "^4.15.1", "eslint-plugin-perfectionist": "^4.15.1",
"eslint-plugin-prettier": "^5.5.4", "eslint-plugin-prettier": "^5.5.4",
"eslint-plugin-unicorn": "^62.0.0", "eslint-plugin-unicorn": "^62.0.0",
"globals": "^16.4.0", "globals": "^16.5.0",
"gulp": "^5.0.1", "gulp": "^5.0.1",
"gulp-cli": "^3.1.0", "gulp-cli": "^3.1.0",
"gulp-postcss": "^10.0.0", "gulp-postcss": "^10.0.0",
@ -37,15 +37,15 @@
"jsdoc": "^4.0.5", "jsdoc": "^4.0.5",
"jstransformer-nunjucks": "^1.2.0", "jstransformer-nunjucks": "^1.2.0",
"metalsmith": "^2.6.3", "metalsmith": "^2.6.3",
"metalsmith-html-relative": "^2.0.8", "metalsmith-html-relative": "^2.0.9",
"ordered-read-streams": "^2.0.0", "ordered-read-streams": "^2.0.0",
"pngjs": "^7.0.0", "pngjs": "^7.0.0",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"postcss-dir-pseudo-class": "^9.0.1", "postcss-dir-pseudo-class": "^9.0.1",
"postcss-discard-comments": "^7.0.4", "postcss-discard-comments": "^7.0.5",
"postcss-nesting": "^13.0.2", "postcss-nesting": "^13.0.2",
"prettier": "^3.6.2", "prettier": "^3.6.2",
"puppeteer": "^24.26.1", "puppeteer": "^24.29.1",
"stylelint": "^16.25.0", "stylelint": "^16.25.0",
"stylelint-prettier": "^5.0.3", "stylelint-prettier": "^5.0.3",
"svglint": "^4.1.2", "svglint": "^4.1.2",

View File

@ -1,5 +1,5 @@
{ {
"stableVersion": "5.4.296", "stableVersion": "5.4.394",
"baseVersion": "1b427a3af5e0a40c296a3cafb08edbd36d973ff1", "baseVersion": "1b427a3af5e0a40c296a3cafb08edbd36d973ff1",
"versionPrefix": "5.4." "versionPrefix": "5.4."
} }

View File

@ -267,6 +267,10 @@ class Catalog {
return markInfo; return markInfo;
} }
get hasStructTree() {
return this.#catDict.has("StructTreeRoot");
}
get structTreeRoot() { get structTreeRoot() {
let structTree = null; let structTree = null;
try { try {
@ -735,6 +739,16 @@ class Catalog {
return rawDests; return rawDests;
} }
get rawPageLabels() {
const obj = this.#catDict.getRaw("PageLabels");
if (!obj) {
return null;
}
const numberTree = new NumberTree(obj, this.xref);
return numberTree.getAll();
}
get pageLabels() { get pageLabels() {
let obj = null; let obj = null;
try { try {
@ -749,8 +763,8 @@ class Catalog {
} }
#readPageLabels() { #readPageLabels() {
const obj = this.#catDict.getRaw("PageLabels"); const nums = this.rawPageLabels;
if (!obj) { if (!nums) {
return null; return null;
} }
@ -758,8 +772,6 @@ class Catalog {
let style = null, let style = null,
prefix = ""; prefix = "";
const numberTree = new NumberTree(obj, this.xref);
const nums = numberTree.getAll();
let currentLabel = "", let currentLabel = "",
currentIndex = 1; currentIndex = 1;

View File

@ -131,6 +131,19 @@ class DecodeStream extends BaseStream {
getBaseStreams() { getBaseStreams() {
return this.stream ? this.stream.getBaseStreams() : null; return this.stream ? this.stream.getBaseStreams() : null;
} }
clone() {
// Make sure it has been fully read.
while (!this.eof) {
this.readBlock();
}
return new Stream(
this.buffer,
this.start,
this.end - this.start,
this.dict.clone()
);
}
} }
class StreamsSequenceStream extends DecodeStream { class StreamsSequenceStream extends DecodeStream {

View File

@ -52,6 +52,10 @@ class DecryptStream extends DecodeStream {
buffer.set(chunk, bufferLength); buffer.set(chunk, bufferLength);
this.bufferLength = newLength; this.bufferLength = newLength;
} }
getOriginalStream() {
return this;
}
} }
export { DecryptStream }; export { DecryptStream };

View File

@ -178,7 +178,7 @@ class Page {
); );
} }
#getBoundingBox(name) { getBoundingBox(name) {
if (this.xfaData) { if (this.xfaData) {
return this.xfaData.bbox; return this.xfaData.bbox;
} }
@ -201,7 +201,7 @@ class Page {
return shadow( return shadow(
this, this,
"mediaBox", "mediaBox",
this.#getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX this.getBoundingBox("MediaBox") || LETTER_SIZE_MEDIABOX
); );
} }
@ -210,7 +210,7 @@ class Page {
return shadow( return shadow(
this, this,
"cropBox", "cropBox",
this.#getBoundingBox("CropBox") || this.mediaBox this.getBoundingBox("CropBox") || this.mediaBox
); );
} }
@ -1167,49 +1167,6 @@ class PDFDocument {
}); });
} }
#collectSignatureCertificates(
fields,
collectedSignatureCertificates,
visited = new RefSet()
) {
if (!Array.isArray(fields)) {
return;
}
for (let field of fields) {
if (field instanceof Ref) {
if (visited.has(field)) {
continue;
}
visited.put(field);
}
field = this.xref.fetchIfRef(field);
if (!(field instanceof Dict)) {
continue;
}
if (field.has("Kids")) {
this.#collectSignatureCertificates(
field.get("Kids"),
collectedSignatureCertificates,
visited
);
continue;
}
const isSignature = isName(field.get("FT"), "Sig");
if (!isSignature) {
continue;
}
const value = field.get("V");
if (!(value instanceof Dict)) {
continue;
}
const subFilter = value.get("SubFilter");
if (!(subFilter instanceof Name)) {
continue;
}
collectedSignatureCertificates.add(subFilter.name);
}
}
get _xfaStreams() { get _xfaStreams() {
const { acroForm } = this.catalog; const { acroForm } = this.catalog;
if (!acroForm) { if (!acroForm) {
@ -1525,20 +1482,6 @@ class PDFDocument {
// specification). // specification).
const sigFlags = acroForm.get("SigFlags"); const sigFlags = acroForm.get("SigFlags");
const hasSignatures = !!(sigFlags & 0x1); const hasSignatures = !!(sigFlags & 0x1);
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
if (hasSignatures) {
const collectedSignatureCertificates = new Set();
this.#collectSignatureCertificates(
fields,
collectedSignatureCertificates
);
if (collectedSignatureCertificates.size > 0) {
formInfo.collectedSignatureCertificates = Array.from(
collectedSignatureCertificates
);
}
}
}
const hasOnlyDocumentSignatures = const hasOnlyDocumentSignatures =
hasSignatures && this.#hasOnlyDocumentSignatures(fields); hasSignatures && this.#hasOnlyDocumentSignatures(fields);
formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures; formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures;
@ -1566,11 +1509,6 @@ class PDFDocument {
IsSignaturesPresent: formInfo.hasSignatures, IsSignaturesPresent: formInfo.hasSignatures,
}; };
if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("MOZCENTRAL")) {
docInfo.collectedSignatureCertificates =
formInfo.collectedSignatureCertificates ?? null;
}
let infoDict; let infoDict;
try { try {
infoDict = xref.trailer.get("Info"); infoDict = xref.trailer.get("Info");

File diff suppressed because it is too large Load Diff

View File

@ -34,7 +34,7 @@ class NameOrNumberTree {
this._type = type; this._type = type;
} }
getAll() { getAll(isRaw = false) {
const map = new Map(); const map = new Map();
if (!this.root) { if (!this.root) {
return map; return map;
@ -68,7 +68,10 @@ class NameOrNumberTree {
continue; continue;
} }
for (let i = 0, ii = entries.length; i < ii; i += 2) { for (let i = 0, ii = entries.length; i < ii; i += 2) {
map.set(xref.fetchIfRef(entries[i]), xref.fetchIfRef(entries[i + 1])); map.set(
xref.fetchIfRef(entries[i]),
isRaw ? entries[i + 1] : xref.fetchIfRef(entries[i + 1])
);
} }
} }
return map; return map;

View File

@ -188,6 +188,10 @@ class Dict {
return [...this._map.values()]; return [...this._map.values()];
} }
getRawEntries() {
return this._map.entries();
}
set(key, value) { set(key, value) {
if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) { if (typeof PDFJSDev === "undefined" || PDFJSDev.test("TESTING")) {
if (typeof key !== "string") { if (typeof key !== "string") {
@ -231,6 +235,12 @@ class Dict {
} }
} }
setIfDict(key, value) {
if (value instanceof Dict) {
this.set(key, value);
}
}
has(key) { has(key) {
return this._map.has(key); return this._map.has(key);
} }
@ -429,6 +439,12 @@ class RefSetCache {
yield [Ref.fromString(ref), value]; yield [Ref.fromString(ref), value];
} }
} }
*keys() {
for (const ref of this._map.keys()) {
yield Ref.fromString(ref);
}
}
} }
function isName(v, name) { function isName(v, name) {

View File

@ -82,6 +82,15 @@ class Stream extends BaseStream {
makeSubStream(start, length, dict = null) { makeSubStream(start, length, dict = null) {
return new Stream(this.bytes.buffer, start, length, dict); return new Stream(this.bytes.buffer, start, length, dict);
} }
clone() {
return new Stream(
this.bytes.buffer,
this.start,
this.end - this.start,
this.dict.clone()
);
}
} }
class StringStream extends Stream { class StringStream extends Stream {

View File

@ -13,7 +13,12 @@
* limitations under the License. * limitations under the License.
*/ */
import { AnnotationPrefix, stringToPDFString, warn } from "../shared/util.js"; import {
AnnotationPrefix,
stringToPDFString,
stringToUTF8String,
warn,
} from "../shared/util.js";
import { Dict, isName, Name, Ref, RefSetCache } from "./primitives.js"; import { Dict, isName, Name, Ref, RefSetCache } from "./primitives.js";
import { lookupNormalRect, stringToAsciiOrUTF16BE } from "./core_utils.js"; import { lookupNormalRect, stringToAsciiOrUTF16BE } from "./core_utils.js";
import { BaseStream } from "./base_stream.js"; import { BaseStream } from "./base_stream.js";
@ -37,6 +42,7 @@ class StructTreeRoot {
this.roleMap = new Map(); this.roleMap = new Map();
this.structParentIds = null; this.structParentIds = null;
this.kidRefToPosition = undefined; this.kidRefToPosition = undefined;
this.parentTree = null;
} }
getKidPosition(kidRef) { getKidPosition(kidRef) {
@ -65,6 +71,11 @@ class StructTreeRoot {
init() { init() {
this.readRoleMap(); this.readRoleMap();
const parentTree = this.dict.get("ParentTree");
if (!parentTree) {
return;
}
this.parentTree = new NumberTree(parentTree, this.xref);
} }
#addIdToPage(pageRef, id, type) { #addIdToPage(pageRef, id, type) {
@ -610,7 +621,8 @@ class StructElementNode {
if (!isName(fileStream.dict.get("Subtype"), "application/mathml+xml")) { if (!isName(fileStream.dict.get("Subtype"), "application/mathml+xml")) {
continue; continue;
} }
return fileStream.getString(); // The default encoding for xml files is UTF-8.
return stringToUTF8String(fileStream.getString());
} }
const A = this.dict.get("A"); const A = this.dict.get("A");
if (A instanceof Dict) { if (A instanceof Dict) {
@ -765,7 +777,7 @@ class StructTreePage {
return; return;
} }
const parentTree = this.rootDict.get("ParentTree"); const { parentTree } = this.root;
if (!parentTree) { if (!parentTree) {
return; return;
} }
@ -776,10 +788,9 @@ class StructTreePage {
} }
const map = new Map(); const map = new Map();
const numberTree = new NumberTree(parentTree, this.xref);
if (Number.isInteger(id)) { if (Number.isInteger(id)) {
const parentArray = numberTree.get(id); const parentArray = parentTree.get(id);
if (Array.isArray(parentArray)) { if (Array.isArray(parentArray)) {
for (const ref of parentArray) { for (const ref of parentArray) {
if (ref instanceof Ref) { if (ref instanceof Ref) {
@ -793,7 +804,7 @@ class StructTreePage {
return; return;
} }
for (const [elemId, type] of ids) { for (const [elemId, type] of ids) {
const obj = numberTree.get(elemId); const obj = parentTree.get(elemId);
if (obj) { if (obj) {
const elem = this.addNode(this.xref.fetchIfRef(obj), map); const elem = this.addNode(this.xref.fetchIfRef(obj), map);
if ( if (
@ -824,6 +835,23 @@ class StructTreePage {
const element = new StructElementNode(this, dict); const element = new StructElementNode(this, dict);
map.set(dict, element); map.set(dict, element);
switch (element.role) {
case "L":
case "LBody":
case "LI":
case "Table":
case "THead":
case "TBody":
case "TFoot":
case "TR": {
// Always collect all child nodes of lists and tables, even empty ones
for (const kid of element.kids) {
if (kid.type === StructElementType.ELEMENT) {
this.addNode(kid.dict, map, level - 1);
}
}
}
}
const parent = dict.get("P"); const parent = dict.get("P");

View File

@ -36,6 +36,7 @@ import { MessageHandler, wrapReason } from "../shared/message_handler.js";
import { AnnotationFactory } from "./annotation.js"; import { AnnotationFactory } from "./annotation.js";
import { clearGlobalCaches } from "./cleanup_helper.js"; import { clearGlobalCaches } from "./cleanup_helper.js";
import { incrementalUpdate } from "./writer.js"; import { incrementalUpdate } from "./writer.js";
import { PDFEditor } from "./editor/pdf_editor.js";
import { PDFWorkerStream } from "./worker_stream.js"; import { PDFWorkerStream } from "./worker_stream.js";
import { StructTreeRoot } from "./struct_tree.js"; import { StructTreeRoot } from "./struct_tree.js";
@ -514,6 +515,7 @@ class WorkerMessageHandler {
return Promise.all([ return Promise.all([
pdfManager.ensureDoc("documentInfo"), pdfManager.ensureDoc("documentInfo"),
pdfManager.ensureCatalog("metadata"), pdfManager.ensureCatalog("metadata"),
pdfManager.ensureCatalog("hasStructTree"),
]); ]);
}); });
@ -557,6 +559,97 @@ class WorkerMessageHandler {
return pdfManager.ensureDoc("calculationOrderIds"); return pdfManager.ensureDoc("calculationOrderIds");
}); });
handler.on("ExtractPages", async function ({ pageInfos }) {
if (!pageInfos) {
warn("extractPages: nothing to extract.");
return null;
}
if (!Array.isArray(pageInfos)) {
pageInfos = [pageInfos];
}
let newDocumentId = 0;
for (const pageInfo of pageInfos) {
if (pageInfo.document === null) {
pageInfo.document = pdfManager.pdfDocument;
} else if (ArrayBuffer.isView(pageInfo.document)) {
const manager = new LocalPdfManager({
source: pageInfo.document,
docId: `${docId}_extractPages_${newDocumentId++}`,
handler,
password: pageInfo.password ?? null,
evaluatorOptions: Object.assign({}, pdfManager.evaluatorOptions),
});
let recoveryMode = false;
let isValid = true;
while (true) {
try {
await manager.requestLoadedStream();
await manager.ensureDoc("checkHeader");
await manager.ensureDoc("parseStartXRef");
await manager.ensureDoc("parse", [recoveryMode]);
break;
} catch (e) {
if (e instanceof XRefParseException) {
if (recoveryMode === false) {
recoveryMode = true;
continue;
} else {
isValid = false;
warn("extractPages: XRefParseException.");
}
} else if (e instanceof PasswordException) {
const task = new WorkerTask(
`PasswordException: response ${e.code}`
);
startWorkerTask(task);
try {
const { password } = await handler.sendWithPromise(
"PasswordRequest",
e
);
manager.updatePassword(password);
} catch {
isValid = false;
warn("extractPages: invalid password.");
} finally {
finishWorkerTask(task);
}
} else {
isValid = false;
warn("extractPages: invalid document.");
}
if (!isValid) {
break;
}
}
}
if (!isValid) {
pageInfo.document = null;
}
const isPureXfa = await manager.ensureDoc("isPureXfa");
if (isPureXfa) {
pageInfo.document = null;
warn("extractPages does not support pure XFA documents.");
} else {
pageInfo.document = manager.pdfDocument;
}
} else {
warn("extractPages: invalid document.");
}
}
try {
const pdfEditor = new PDFEditor();
const buffer = await pdfEditor.extractPages(pageInfos);
return buffer;
} catch (reason) {
// eslint-disable-next-line no-console
console.error(reason);
return null;
}
});
handler.on( handler.on(
"SaveDocument", "SaveDocument",
async function ({ isPureXfa, numPages, annotationStorage, filename }) { async function ({ isPureXfa, numPages, annotationStorage, filename }) {

View File

@ -19,7 +19,6 @@ import {
escapePDFName, escapePDFName,
escapeString, escapeString,
getSizeInBytes, getSizeInBytes,
numberToString,
parseXFAPath, parseXFAPath,
} from "./core_utils.js"; } from "./core_utils.js";
import { SimpleDOMNode, SimpleXMLParser } from "./xml_parser.js"; import { SimpleDOMNode, SimpleXMLParser } from "./xml_parser.js";
@ -27,29 +26,34 @@ import { Stream, StringStream } from "./stream.js";
import { BaseStream } from "./base_stream.js"; import { BaseStream } from "./base_stream.js";
import { calculateMD5 } from "./calculate_md5.js"; import { calculateMD5 } from "./calculate_md5.js";
async function writeObject(ref, obj, buffer, { encrypt = null }) { async function writeObject(
const transform = encrypt?.createCipherTransform(ref.num, ref.gen); ref,
obj,
buffer,
{ encrypt = null, encryptRef = null }
) {
// Avoid to encrypt the encrypt dictionary.
const transform =
encrypt && encryptRef !== ref
? encrypt.createCipherTransform(ref.num, ref.gen)
: null;
buffer.push(`${ref.num} ${ref.gen} obj\n`); buffer.push(`${ref.num} ${ref.gen} obj\n`);
if (obj instanceof Dict) { await writeValue(obj, buffer, transform);
await writeDict(obj, buffer, transform);
} else if (obj instanceof BaseStream) {
await writeStream(obj, buffer, transform);
} else if (Array.isArray(obj) || ArrayBuffer.isView(obj)) {
await writeArray(obj, buffer, transform);
}
buffer.push("\nendobj\n"); buffer.push("\nendobj\n");
} }
async function writeDict(dict, buffer, transform) { async function writeDict(dict, buffer, transform) {
buffer.push("<<"); buffer.push("<<");
for (const key of dict.getKeys()) { for (const [key, rawObj] of dict.getRawEntries()) {
buffer.push(` /${escapePDFName(key)} `); buffer.push(` /${escapePDFName(key)} `);
await writeValue(dict.getRaw(key), buffer, transform); await writeValue(rawObj, buffer, transform);
} }
buffer.push(">>"); buffer.push(">>");
} }
async function writeStream(stream, buffer, transform) { async function writeStream(stream, buffer, transform) {
stream = stream.getOriginalStream();
stream.reset();
let bytes = stream.getBytes(); let bytes = stream.getBytes();
const { dict } = stream; const { dict } = stream;
@ -67,7 +71,7 @@ async function writeStream(stream, buffer, transform) {
// The number 256 is arbitrary, but it should be reasonable. // The number 256 is arbitrary, but it should be reasonable.
const MIN_LENGTH_FOR_COMPRESSING = 256; const MIN_LENGTH_FOR_COMPRESSING = 256;
if (bytes.length >= MIN_LENGTH_FOR_COMPRESSING || isFilterZeroFlateDecode) { if (bytes.length >= MIN_LENGTH_FOR_COMPRESSING && !isFilterZeroFlateDecode) {
try { try {
const cs = new CompressionStream("deflate"); const cs = new CompressionStream("deflate");
const writer = cs.writable.getWriter(); const writer = cs.writable.getWriter();
@ -120,14 +124,11 @@ async function writeStream(stream, buffer, transform) {
async function writeArray(array, buffer, transform) { async function writeArray(array, buffer, transform) {
buffer.push("["); buffer.push("[");
let first = true; for (let i = 0, ii = array.length; i < ii; i++) {
for (const val of array) { await writeValue(array[i], buffer, transform);
if (!first) { if (i < ii - 1) {
buffer.push(" "); buffer.push(" ");
} else {
first = false;
} }
await writeValue(val, buffer, transform);
} }
buffer.push("]"); buffer.push("]");
} }
@ -145,7 +146,11 @@ async function writeValue(value, buffer, transform) {
} }
buffer.push(`(${escapeString(value)})`); buffer.push(`(${escapeString(value)})`);
} else if (typeof value === "number") { } else if (typeof value === "number") {
buffer.push(numberToString(value)); // Don't try to round numbers in general, it could lead to have degenerate
// matrices (e.g. [0.000008 0 0 0.000008 0 0]).
// The numbers must be "rounded" only when pdf.js is producing them and the
// current transformation matrix is well known.
buffer.push(value.toString());
} else if (typeof value === "boolean") { } else if (typeof value === "boolean") {
buffer.push(value.toString()); buffer.push(value.toString());
} else if (value instanceof Dict) { } else if (value instanceof Dict) {
@ -306,7 +311,7 @@ async function getXRefTable(xrefInfo, baseOffset, newRefs, newXref, buffer) {
} }
computeIDs(baseOffset, xrefInfo, newXref); computeIDs(baseOffset, xrefInfo, newXref);
buffer.push("trailer\n"); buffer.push("trailer\n");
await writeDict(newXref, buffer); await writeDict(newXref, buffer, null);
buffer.push("\nstartxref\n", baseOffset.toString(), "\n%%EOF\n"); buffer.push("\nstartxref\n", baseOffset.toString(), "\n%%EOF\n");
} }
@ -332,10 +337,17 @@ async function getXRefStreamTable(
const xrefTableData = []; const xrefTableData = [];
let maxOffset = 0; let maxOffset = 0;
let maxGen = 0; let maxGen = 0;
for (const { ref, data } of newRefs) { for (const { ref, data, objStreamRef, index } of newRefs) {
let gen; let gen;
maxOffset = Math.max(maxOffset, baseOffset); maxOffset = Math.max(maxOffset, baseOffset);
if (data !== null) { // The first number in each entry is the type (see 7.5.8.3):
// 0: free object
// 1: in-use object
// 2: compressed object
if (objStreamRef) {
gen = index;
xrefTableData.push([2, objStreamRef.num, gen]);
} else if (data !== null) {
gen = Math.min(ref.gen, 0xffff); gen = Math.min(ref.gen, 0xffff);
xrefTableData.push([1, baseOffset, gen]); xrefTableData.push([1, baseOffset, gen]);
baseOffset += data.length; baseOffset += data.length;
@ -371,13 +383,13 @@ async function getXRefStreamTable(
function computeIDs(baseOffset, xrefInfo, newXref) { function computeIDs(baseOffset, xrefInfo, newXref) {
if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) { if (Array.isArray(xrefInfo.fileIds) && xrefInfo.fileIds.length > 0) {
const md5 = computeMD5(baseOffset, xrefInfo); const md5 = computeMD5(baseOffset, xrefInfo);
newXref.set("ID", [xrefInfo.fileIds[0], md5]); newXref.set("ID", [xrefInfo.fileIds[0] || md5, md5]);
} }
} }
function getTrailerDict(xrefInfo, changes, useXrefStream) { function getTrailerDict(xrefInfo, changes, useXrefStream) {
const newXref = new Dict(null); const newXref = new Dict(null);
newXref.set("Prev", xrefInfo.startXRef); newXref.setIfDefined("Prev", xrefInfo?.startXRef);
const refForXrefTable = xrefInfo.newRef; const refForXrefTable = xrefInfo.newRef;
if (useXrefStream) { if (useXrefStream) {
changes.put(refForXrefTable, { data: "" }); changes.put(refForXrefTable, { data: "" });
@ -386,21 +398,20 @@ function getTrailerDict(xrefInfo, changes, useXrefStream) {
} else { } else {
newXref.set("Size", refForXrefTable.num); newXref.set("Size", refForXrefTable.num);
} }
if (xrefInfo.rootRef !== null) { newXref.setIfDefined("Root", xrefInfo?.rootRef);
newXref.set("Root", xrefInfo.rootRef); newXref.setIfDefined("Info", xrefInfo?.infoRef);
} newXref.setIfDefined("Encrypt", xrefInfo?.encryptRef);
if (xrefInfo.infoRef !== null) {
newXref.set("Info", xrefInfo.infoRef);
}
if (xrefInfo.encryptRef !== null) {
newXref.set("Encrypt", xrefInfo.encryptRef);
}
return newXref; return newXref;
} }
async function writeChanges(changes, xref, buffer = []) { async function writeChanges(changes, xref, buffer = []) {
const newRefs = []; const newRefs = [];
for (const [ref, { data }] of changes.items()) { for (const [ref, { data, objStreamRef, index }] of changes.items()) {
if (objStreamRef) {
newRefs.push({ ref, data, objStreamRef, index });
continue;
}
if (data === null || typeof data === "string") { if (data === null || typeof data === "string") {
newRefs.push({ ref, data }); newRefs.push({ ref, data });
continue; continue;
@ -483,4 +494,4 @@ async function incrementalUpdate({
return array; return array;
} }
export { incrementalUpdate, writeChanges, writeDict, writeObject }; export { incrementalUpdate, writeChanges, writeDict, writeObject, writeValue };

View File

@ -1025,6 +1025,24 @@ class PDFDocumentProxy {
return this._transport.saveDocument(); return this._transport.saveDocument();
} }
/**
* @typedef {Object} PageInfo
* @property {null|Uint8Array} document
* @property {Array<Array<number>|number>} [includePages]
* included ranges or indices.
* @property {Array<Array<number>|number>} [excludePages]
* excluded ranges or indices.
*/
/**
* @param {Array<PageInfo>} pageInfos - The pages to extract.
* @returns {Promise<Uint8Array>} A promise that is resolved with a
* {Uint8Array} containing the full data of the saved document.
*/
extractPages(pageInfos) {
return this._transport.extractPages(pageInfos);
}
/** /**
* @returns {Promise<{ length: number }>} A promise that is resolved when the * @returns {Promise<{ length: number }>} A promise that is resolved when the
* document's data is loaded. It is resolved with an {Object} that contains * document's data is loaded. It is resolved with an {Object} that contains
@ -2902,6 +2920,10 @@ class WorkerTransport {
}); });
} }
extractPages(pageInfos) {
return this.messageHandler.sendWithPromise("ExtractPages", { pageInfos });
}
getPage(pageNumber) { getPage(pageNumber) {
if ( if (
!Number.isInteger(pageNumber) || !Number.isInteger(pageNumber) ||
@ -3057,6 +3079,7 @@ class WorkerTransport {
metadata: results[1] ? new Metadata(results[1]) : null, metadata: results[1] ? new Metadata(results[1]) : null,
contentDispositionFilename: this._fullReader?.filename ?? null, contentDispositionFilename: this._fullReader?.filename ?? null,
contentLength: this._fullReader?.contentLength ?? null, contentLength: this._fullReader?.contentLength ?? null,
hasStructTree: results[2],
})); }));
this.#methodPromises.set(name, promise); this.#methodPromises.set(name, promise);
return promise; return promise;

View File

@ -16,6 +16,7 @@
import { AnnotationEditorParamsType, unreachable } from "../../shared/util.js"; import { AnnotationEditorParamsType, unreachable } from "../../shared/util.js";
import { noContextMenu, stopEvent } from "../display_utils.js"; import { noContextMenu, stopEvent } from "../display_utils.js";
import { AnnotationEditor } from "./editor.js"; import { AnnotationEditor } from "./editor.js";
import { CurrentPointers } from "./tools.js";
class DrawingOptions { class DrawingOptions {
#svgProperties = Object.create(null); #svgProperties = Object.create(null);
@ -81,14 +82,6 @@ class DrawingEditor extends AnnotationEditor {
static #currentDrawingOptions = null; static #currentDrawingOptions = null;
static #currentPointerId = NaN;
static #currentPointerType = null;
static #currentPointerIds = null;
static #currentMoveTimestamp = NaN;
static _INNER_MARGIN = 3; static _INNER_MARGIN = 3;
constructor(params) { constructor(params) {
@ -678,20 +671,15 @@ class DrawingEditor extends AnnotationEditor {
} }
static startDrawing(parent, uiManager, _isLTR, event) { static startDrawing(parent, uiManager, _isLTR, event) {
// The _currentPointerType is set when the user starts an empty drawing // The pointerType of CurrentPointer is set when the user starts an empty
// session. If, in the same drawing session, the user starts using a // drawing session. If, in the same drawing session, the user starts using a
// different type of pointer (e.g. a pen and then a finger), we just return. // different type of pointer (e.g. a pen and then a finger), we just return.
// //
// The _currentPointerId and _currentPointerIds are used to keep track of // If the user starts to draw with a finger and then uses a second finger,
// the pointers with a same type (e.g. two fingers). If the user starts to // we just stop the current drawing and let the user zoom the document.
// draw with a finger and then uses a second finger, we just stop the
// current drawing and let the user zoom the document.
const { target, offsetX: x, offsetY: y, pointerId, pointerType } = event; const { target, offsetX: x, offsetY: y, pointerId, pointerType } = event;
if ( if (CurrentPointers.isInitializedAndDifferentPointerType(pointerType)) {
DrawingEditor.#currentPointerType &&
DrawingEditor.#currentPointerType !== pointerType
) {
return; return;
} }
@ -704,16 +692,13 @@ class DrawingEditor extends AnnotationEditor {
const ac = (DrawingEditor.#currentDrawingAC = new AbortController()); const ac = (DrawingEditor.#currentDrawingAC = new AbortController());
const signal = parent.combinedSignal(ac); const signal = parent.combinedSignal(ac);
DrawingEditor.#currentPointerId ||= pointerId; CurrentPointers.setPointer(pointerType, pointerId);
DrawingEditor.#currentPointerType ??= pointerType;
window.addEventListener( window.addEventListener(
"pointerup", "pointerup",
e => { e => {
if (DrawingEditor.#currentPointerId === e.pointerId) { if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) {
this._endDraw(e); this._endDraw(e);
} else {
DrawingEditor.#currentPointerIds?.delete(e.pointerId);
} }
}, },
{ signal } { signal }
@ -721,10 +706,8 @@ class DrawingEditor extends AnnotationEditor {
window.addEventListener( window.addEventListener(
"pointercancel", "pointercancel",
e => { e => {
if (DrawingEditor.#currentPointerId === e.pointerId) { if (CurrentPointers.isSamePointerIdOrRemove(e.pointerId)) {
this._currentParent.endDrawingSession(); this._currentParent.endDrawingSession();
} else {
DrawingEditor.#currentPointerIds?.delete(e.pointerId);
} }
}, },
{ signal } { signal }
@ -732,14 +715,14 @@ class DrawingEditor extends AnnotationEditor {
window.addEventListener( window.addEventListener(
"pointerdown", "pointerdown",
e => { e => {
if (DrawingEditor.#currentPointerType !== e.pointerType) { if (!CurrentPointers.isSamePointerType(e.pointerType)) {
// For example, we started with a pen and the user // For example, we started with a pen and the user
// is now using a finger. // is now using a finger.
return; return;
} }
// For example, the user is using a second finger. // For example, the user is using a second finger.
(DrawingEditor.#currentPointerIds ||= new Set()).add(e.pointerId); CurrentPointers.initializeAndAddPointerId(e.pointerId);
// The first finger created a first point and a second finger just // The first finger created a first point and a second finger just
// started, so we stop the drawing and remove this only point. // started, so we stop the drawing and remove this only point.
@ -765,7 +748,7 @@ class DrawingEditor extends AnnotationEditor {
target.addEventListener( target.addEventListener(
"touchmove", "touchmove",
e => { e => {
if (e.timeStamp === DrawingEditor.#currentMoveTimestamp) { if (CurrentPointers.isSameTimeStamp(e.timeStamp)) {
// This move event is used to draw so we don't want to scroll. // This move event is used to draw so we don't want to scroll.
stopEvent(e); stopEvent(e);
} }
@ -812,16 +795,16 @@ class DrawingEditor extends AnnotationEditor {
} }
static _drawMove(event) { static _drawMove(event) {
DrawingEditor.#currentMoveTimestamp = -1; CurrentPointers.isSameTimeStamp(event.timeStamp);
if (!DrawingEditor.#currentDraw) { if (!DrawingEditor.#currentDraw) {
return; return;
} }
const { offsetX, offsetY, pointerId } = event; const { offsetX, offsetY, pointerId } = event;
if (DrawingEditor.#currentPointerId !== pointerId) { if (!CurrentPointers.isSamePointerId(pointerId)) {
return; return;
} }
if (DrawingEditor.#currentPointerIds?.size >= 1) { if (CurrentPointers.isUsingMultiplePointers()) {
// The user is using multiple fingers and the first one is moving. // The user is using multiple fingers and the first one is moving.
this._endDraw(event); this._endDraw(event);
return; return;
@ -831,7 +814,7 @@ class DrawingEditor extends AnnotationEditor {
DrawingEditor.#currentDraw.add(offsetX, offsetY) DrawingEditor.#currentDraw.add(offsetX, offsetY)
); );
// We track the timestamp to know if the touchmove event is used to draw. // We track the timestamp to know if the touchmove event is used to draw.
DrawingEditor.#currentMoveTimestamp = event.timeStamp; CurrentPointers.setTimeStamp(event.timeStamp);
stopEvent(event); stopEvent(event);
} }
@ -841,15 +824,14 @@ class DrawingEditor extends AnnotationEditor {
this._currentParent = null; this._currentParent = null;
DrawingEditor.#currentDraw = null; DrawingEditor.#currentDraw = null;
DrawingEditor.#currentDrawingOptions = null; DrawingEditor.#currentDrawingOptions = null;
DrawingEditor.#currentPointerType = null; CurrentPointers.clearPointerType();
DrawingEditor.#currentMoveTimestamp = NaN; CurrentPointers.clearTimeStamp();
} }
if (DrawingEditor.#currentDrawingAC) { if (DrawingEditor.#currentDrawingAC) {
DrawingEditor.#currentDrawingAC.abort(); DrawingEditor.#currentDrawingAC.abort();
DrawingEditor.#currentDrawingAC = null; DrawingEditor.#currentDrawingAC = null;
DrawingEditor.#currentPointerId = NaN; CurrentPointers.clearPointerIds();
DrawingEditor.#currentPointerIds = null;
} }
} }

View File

@ -42,6 +42,87 @@ function bindEvents(obj, element, names) {
} }
} }
/**
* Class to store current pointers used by the editor to be able to handle
* multiple pointers (e.g. two fingers, a pen, a mouse, ...).
*/
class CurrentPointers {
// To manage the pointer events.
// The pointerId and pointerIds are used to keep track of
// the pointers with a same type (e.g. two fingers).
static #pointerId = NaN;
static #pointerIds = null;
// Track the timestamp to know if the touchmove event is used.
static #moveTimestamp = NaN;
// The pointerType is used to know if we are using a mouse, a pen or a touch.
static #pointerType = null;
static initializeAndAddPointerId(pointerId) {
// Store pointer ids. For example, the user is using a second finger.
(CurrentPointers.#pointerIds ||= new Set()).add(pointerId);
}
static setPointer(pointerType, pointerId) {
CurrentPointers.#pointerId ||= pointerId;
CurrentPointers.#pointerType ??= pointerType;
}
static setTimeStamp(timeStamp) {
CurrentPointers.#moveTimestamp = timeStamp;
}
static isSamePointerId(pointerId) {
return CurrentPointers.#pointerId === pointerId;
}
// Check if it's the same pointer id, otherwise remove it from the set.
static isSamePointerIdOrRemove(pointerId) {
if (CurrentPointers.#pointerId === pointerId) {
return true;
}
CurrentPointers.#pointerIds?.delete(pointerId);
return false;
}
static isSamePointerType(pointerType) {
return CurrentPointers.#pointerType === pointerType;
}
static isInitializedAndDifferentPointerType(pointerType) {
return (
CurrentPointers.#pointerType !== null &&
!CurrentPointers.isSamePointerType(pointerType)
);
}
static isSameTimeStamp(timeStamp) {
return CurrentPointers.#moveTimestamp === timeStamp;
}
static isUsingMultiplePointers() {
// Check if the user is using multiple fingers
return CurrentPointers.#pointerIds?.size >= 1;
}
static clearPointerType() {
CurrentPointers.#pointerType = null;
}
static clearPointerIds() {
CurrentPointers.#pointerId = NaN;
CurrentPointers.#pointerIds = null;
}
static clearTimeStamp() {
CurrentPointers.#moveTimestamp = NaN;
}
}
/** /**
* Class to create some unique ids for the different editors. * Class to create some unique ids for the different editors.
*/ */
@ -2801,5 +2882,6 @@ export {
bindEvents, bindEvents,
ColorManager, ColorManager,
CommandManager, CommandManager,
CurrentPointers,
KeyboardManager, KeyboardManager,
}; };

View File

@ -457,6 +457,10 @@ class FontFaceObject {
return this.#fontData.disableFontFace ?? false; return this.#fontData.disableFontFace ?? false;
} }
set disableFontFace(value) {
shadow(this, "disableFontFace", !!value);
}
get fontExtraProperties() { get fontExtraProperties() {
return this.#fontData.fontExtraProperties ?? false; return this.#fontData.fontExtraProperties ?? false;
} }
@ -501,6 +505,10 @@ class FontFaceObject {
return this.#fontData.bbox; return this.#fontData.bbox;
} }
set bbox(bbox) {
shadow(this, "bbox", bbox);
}
get fontMatrix() { get fontMatrix() {
return this.#fontData.fontMatrix; return this.#fontData.fontMatrix;
} }

View File

@ -506,6 +506,7 @@ class Driver {
this.inFlightRequests = 0; this.inFlightRequests = 0;
this.testFilter = JSON.parse(params.get("testfilter") || "[]"); this.testFilter = JSON.parse(params.get("testfilter") || "[]");
this.xfaOnly = params.get("xfaonly") === "true"; this.xfaOnly = params.get("xfaonly") === "true";
this.masterMode = params.get("mastermode") === "true";
// Create a working canvas // Create a working canvas
this.canvas = document.createElement("canvas"); this.canvas = document.createElement("canvas");
@ -591,6 +592,25 @@ class Driver {
task.stats = { times: [] }; task.stats = { times: [] };
task.enableXfa = task.enableXfa === true; task.enableXfa = task.enableXfa === true;
if (task.includePages && task.type === "extract") {
if (this.masterMode) {
const includePages = [];
for (const page of task.includePages) {
if (Array.isArray(page)) {
for (let i = page[0]; i <= page[1]; i++) {
includePages.push(i);
}
} else {
includePages.push(page);
}
}
task.numberOfTasks = includePages.length;
task.includePages = includePages;
} else {
delete task.pageMapping;
}
}
const prevFile = md5FileMap.get(task.md5); const prevFile = md5FileMap.get(task.md5);
if (prevFile) { if (prevFile) {
if (task.file !== prevFile) { if (task.file !== prevFile) {
@ -658,6 +678,20 @@ class Driver {
}); });
let promise = loadingTask.promise; let promise = loadingTask.promise;
if (!this.masterMode && task.type === "extract") {
promise = promise.then(async doc => {
const data = await doc.extractPages([
{
document: null,
includePages: task.includePages,
},
]);
await loadingTask.destroy();
delete task.includePages;
return getDocument(data).promise;
});
}
if (task.annotationStorage) { if (task.annotationStorage) {
for (const annotation of Object.values(task.annotationStorage)) { for (const annotation of Object.values(task.annotationStorage)) {
const { bitmapName, quadPoints, paths, outlines } = annotation; const { bitmapName, quadPoints, paths, outlines } = annotation;
@ -862,7 +896,12 @@ class Driver {
} }
} }
if (task.skipPages?.includes(task.pageNum)) { if (
task.skipPages?.includes(task.pageNum) ||
(this.masterMode &&
task.includePages &&
!task.includePages.includes(task.pageNum - 1))
) {
this._log( this._log(
` Skipping page ${task.pageNum}/${task.pdfDoc.numPages}...\n` ` Skipping page ${task.pageNum}/${task.pdfDoc.numPages}...\n`
); );
@ -1274,10 +1313,11 @@ class Driver {
id: task.id, id: task.id,
numPages: task.pdfDoc ? task.lastPage || task.pdfDoc.numPages : 0, numPages: task.pdfDoc ? task.lastPage || task.pdfDoc.numPages : 0,
lastPageNum: this._getLastPageNumber(task), lastPageNum: this._getLastPageNumber(task),
numberOfTasks: task.numberOfTasks ?? -1,
failure, failure,
file: task.file, file: task.file,
round: task.round, round: task.round,
page: task.pageNum, page: task.pageMapping?.[task.pageNum] ?? task.pageNum,
snapshot, snapshot,
baselineSnapshot, baselineSnapshot,
stats: task.stats.times, stats: task.stats.times,

View File

@ -1,25 +1,24 @@
<!DOCTYPE html> <!doctype html>
<html> <html>
<head> <head>
<title>PDF.js font tests</title> <title>PDF.js font tests</title>
<link rel="stylesheet" type="text/css" href="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.css"> <link rel="stylesheet" type="text/css" href="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.css" />
<script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script> <script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
<script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script> <script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {
"pdfjs/": "../../src/", "pdfjs/": "../../src/",
"pdfjs-lib": "../../src/pdf.js", "pdfjs-lib": "../../src/pdf.js",
"pdfjs-web/": "../../web/", "pdfjs-web/": "../../web/",
"pdfjs-test/": "../" "pdfjs-test/": "../"
}
} }
} </script>
</script> <script src="jasmine-boot.js" type="module"></script>
<script src="jasmine-boot.js" type="module"></script> </head>
</head> <body></body>
<body>
</body>
</html> </html>

View File

@ -346,6 +346,46 @@ describe("accessibility", () => {
}); });
}); });
describe("MathML with some attributes in AF entry from LaTeX", () => {
let pages;
beforeEach(async () => {
pages = await loadAndWait("bug1997343.pdf", ".textLayer");
});
afterEach(async () => {
await closePages(pages);
});
it("must check that the MathML is correctly inserted", async () => {
await Promise.all(
pages.map(async ([browserName, page]) => {
const isSanitizerSupported = await page.evaluate(() => {
try {
// eslint-disable-next-line no-undef
return typeof Sanitizer !== "undefined";
} catch {
return false;
}
});
if (isSanitizerSupported) {
const mathML = await page.$eval(
"span.structTree span[aria-owns='p21R_mc64']",
el => el?.innerHTML ?? ""
);
expect(mathML)
.withContext(`In ${browserName}`)
.toEqual(
'<math display="block"> <msup> <mi>𝑛</mi> <mi>𝑝</mi> </msup> <mo lspace="0.278em" rspace="0.278em">=</mo> <mi>𝑛</mi> <mspace width="1.000em"></mspace> <mi> mod </mi> <mspace width="0.167em"></mspace> <mspace width="0.167em"></mspace> <mi>𝑝</mi> </math>'
);
} else {
pending(`Sanitizer API (in ${browserName}) is not supported`);
}
})
);
});
});
describe("MathML tags in the struct tree", () => { describe("MathML tags in the struct tree", () => {
let pages; let pages;

View File

@ -19,6 +19,8 @@ import {
closePages, closePages,
copy, copy,
copyToClipboard, copyToClipboard,
countSerialized,
countStorageEntries,
createPromise, createPromise,
dragAndDrop, dragAndDrop,
firstPageOnTop, firstPageOnTop,
@ -26,6 +28,7 @@ import {
getEditors, getEditors,
getEditorSelector, getEditorSelector,
getFirstSerialized, getFirstSerialized,
getNextEditorId,
getRect, getRect,
getSerialized, getSerialized,
isCanvasMonochrome, isCanvasMonochrome,
@ -85,6 +88,34 @@ const cancelFocusIn = async (page, selector) => {
}, selector); }, selector);
}; };
const createFreeTextEditor = async ({
page,
x,
y,
data = null,
noFocusIn = false,
}) => {
const editorSelector = getEditorSelector(await getNextEditorId(page));
const serializedCount = await countSerialized(page);
const storageEntriesCount = await countStorageEntries(page);
await page.mouse.click(x, y);
await page.waitForSelector(editorSelector, { visible: true });
if (data) {
await page.type(`${editorSelector} .internal`, data);
}
if (noFocusIn) {
await cancelFocusIn(page, editorSelector);
}
await commit(page);
await waitForSelectedEditor(page, editorSelector);
await waitForStorageEntries(page, storageEntriesCount + 1);
await waitForSerialized(page, serializedCount + 1);
return editorSelector;
};
describe("FreeText Editor", () => { describe("FreeText Editor", () => {
describe("FreeText", () => { describe("FreeText", () => {
let pages; let pages;
@ -103,15 +134,13 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0);
const data = "Hello PDF.js World !!"; const data = "Hello PDF.js World !!";
await page.mouse.click(rect.x + 100, rect.y + 100); const editorSelector = await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
await page.type(`${editorSelector} .internal`, data); x: rect.x + 100,
await commit(page); y: rect.y + 100,
data,
await waitForSelectedEditor(page, editorSelector); });
await waitForStorageEntries(page, 1);
await page.waitForFunction( await page.waitForFunction(
`document.getElementById("viewer-alert").textContent === "Text added"` `document.getElementById("viewer-alert").textContent === "Text added"`
@ -143,13 +172,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const firstEditorSelector = getEditorSelector(0); const firstEditorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(firstEditorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${firstEditorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await waitForStorageEntries(page, 1);
await selectEditor(page, firstEditorSelector); await selectEditor(page, firstEditorSelector);
await copy(page); await copy(page);
@ -187,13 +215,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const firstEditorSelector = getEditorSelector(0); const firstEditorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(firstEditorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${firstEditorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await waitForStorageEntries(page, 1);
await page.evaluate(() => { await page.evaluate(() => {
window.PDFViewerApplication.eventBus.dispatch( window.PDFViewerApplication.eventBus.dispatch(
@ -240,12 +267,12 @@ describe("FreeText Editor", () => {
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
for (const n of [0, 1, 2]) { for (const n of [0, 1, 2]) {
const editorSelector = getEditorSelector(n); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100 * n, rect.y + 100 * n); x: rect.x + 100 * n,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100 * n,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
const hasEditor = await page.evaluate( const hasEditor = await page.evaluate(
sel => !!document.querySelector(sel), sel => !!document.querySelector(sel),
@ -275,12 +302,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
let editorSelector = getEditorSelector(0); let editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await selectEditor(page, editorSelector); await selectEditor(page, editorSelector);
await copy(page); await copy(page);
@ -317,12 +344,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
expect(await getEditors(page, "selected")) expect(await getEditors(page, "selected"))
.withContext(`In ${browserName}`) .withContext(`In ${browserName}`)
@ -460,12 +487,12 @@ describe("FreeText Editor", () => {
const editorCenters = []; const editorCenters = [];
let lastX = rect.x + rect.width / 10; let lastX = rect.x + rect.width / 10;
for (let i = 0; i < 4; i++) { for (let i = 0; i < 4; i++) {
const editorSelector = getEditorSelector(i); const editorSelector = await createFreeTextEditor({
const data = `FreeText ${i}`; page,
await page.mouse.click(lastX, rect.y + rect.height / 10); x: lastX,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + rect.height / 10,
await page.type(`${editorSelector} .internal`, data); data: `FreeText ${i}`,
await commit(page); });
const editorRect = await getRect(page, editorSelector); const editorRect = await getRect(page, editorSelector);
lastX = editorRect.x + editorRect.width + 10; lastX = editorRect.x + editorRect.width + 10;
@ -627,16 +654,13 @@ describe("FreeText Editor", () => {
); );
expect(oldAriaOwns).withContext(`In ${browserName}`).toEqual(null); expect(oldAriaOwns).withContext(`In ${browserName}`).toEqual(null);
const editorSelector = getEditorSelector(0);
const rect = await getRect(page, `span[pdfjs="true"]`); const rect = await getRect(page, `span[pdfjs="true"]`);
const data = "Hello PDF.js World !!"; await createFreeTextEditor({
await page.mouse.click( page,
rect.x + rect.width / 2, x: rect.x + rect.width / 2,
rect.y + rect.height / 2 y: rect.y + rect.height / 2,
); data: "Hello PDF.js World !!",
await page.waitForSelector(editorSelector, { visible: true }); });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
const newAriaOwns = await page.$eval(`span[pdfjs="true"]`, el => const newAriaOwns = await page.$eval(`span[pdfjs="true"]`, el =>
el.getAttribute("aria-owns") el.getAttribute("aria-owns")
@ -664,7 +688,6 @@ describe("FreeText Editor", () => {
await Promise.all( await Promise.all(
pages.map(async ([browserName, page]) => { pages.map(async ([browserName, page]) => {
await switchToFreeText(page); await switchToFreeText(page);
let currentId = 0;
const expected = []; const expected = [];
const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1);
@ -682,23 +705,19 @@ describe("FreeText Editor", () => {
} }
const rect = await getRect(page, annotationLayerSelector); const rect = await getRect(page, annotationLayerSelector);
const editorSelector = getEditorSelector(currentId);
const data = `Hello PDF.js World !! on page ${pageNumber}`; const data = `Hello PDF.js World !! on page ${pageNumber}`;
expected.push(data); expected.push(data);
await page.mouse.click(rect.x + 100, rect.y + 100); const editorSelector = await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
await page.type(`${editorSelector} .internal`, data); x: rect.x + 100,
await commit(page); y: rect.y + 100,
data,
await waitForSelectedEditor(page, editorSelector); });
await waitForStorageEntries(page, currentId + 1);
const content = await page.$eval(editorSelector, el => const content = await page.$eval(editorSelector, el =>
el.innerText.trimEnd() el.innerText.trimEnd()
); );
expect(content).withContext(`In ${browserName}`).toEqual(data); expect(content).withContext(`In ${browserName}`).toEqual(data);
currentId += 1;
} }
const serialize = proprName => const serialize = proprName =>
@ -808,19 +827,16 @@ describe("FreeText Editor", () => {
await Promise.all( await Promise.all(
pages.map(async ([browserName, page]) => { pages.map(async ([browserName, page]) => {
await switchToFreeText(page); await switchToFreeText(page);
let currentId = 0;
for (let step = 0; step < 3; step++) { for (let step = 0; step < 3; step++) {
await firstPageOnTop(page); await firstPageOnTop(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(currentId); await createFreeTextEditor({
const data = `Hello ${step}`; page,
const x = Math.max(rect.x + 0.1 * rect.width, 10); x: Math.max(rect.x + 0.1 * rect.width, 10),
const y = Math.max(rect.y + 0.1 * rect.height, 10); y: Math.max(rect.y + 0.1 * rect.height, 10),
await page.mouse.click(x, y); data: `Hello ${step}`,
await page.waitForSelector(editorSelector, { visible: true }); });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
const promise = await waitForAnnotationEditorLayer(page); const promise = await waitForAnnotationEditorLayer(page);
await page.evaluate(() => { await page.evaluate(() => {
@ -828,7 +844,6 @@ describe("FreeText Editor", () => {
}); });
await awaitPromise(promise); await awaitPromise(promise);
currentId += 1;
await page.waitForSelector( await page.waitForSelector(
".page[data-page-number='1'] .canvasWrapper", ".page[data-page-number='1'] .canvasWrapper",
{ {
@ -1353,12 +1368,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
// Make Chrome happy. // Make Chrome happy.
await page.waitForFunction(() => { await page.waitForFunction(() => {
@ -1445,9 +1460,8 @@ describe("FreeText Editor", () => {
await Promise.all( await Promise.all(
pages.map(async ([browserName, page]) => { pages.map(async ([browserName, page]) => {
await switchToFreeText(page); await switchToFreeText(page);
let currentId = 0;
const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1);
const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1);
for (const pageNumber of oneToFourteen) { for (const pageNumber of oneToFourteen) {
const pageSelector = `.page[data-page-number = "${pageNumber}"]`; const pageSelector = `.page[data-page-number = "${pageNumber}"]`;
@ -1462,14 +1476,12 @@ describe("FreeText Editor", () => {
} }
const rect = await getRect(page, annotationLayerSelector); const rect = await getRect(page, annotationLayerSelector);
const editorSelector = getEditorSelector(currentId); await createFreeTextEditor({
const data = `Hello PDF.js World !! on page ${pageNumber}`; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: `Hello PDF.js World !! on page ${pageNumber}`,
await commit(page); });
currentId += 1;
} }
await selectAll(page); await selectAll(page);
@ -1804,12 +1816,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await page.focus("#editorFreeTextColor"); await page.focus("#editorFreeTextColor");
await kbUndo(page); await kbUndo(page);
@ -1848,13 +1860,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
const editorSelector = getEditorSelector(0); x: rect.x + 200,
await page.mouse.click(rect.x + 200, rect.y + 200); y: rect.y + 200,
await page.waitForSelector(editorSelector, { visible: true }); data: "Hello PDF.js World !!",
await page.type(`${editorSelector} .internal`, data); });
await commit(page);
const [pageX, pageY] = await getFirstSerialized(page, x => x.rect); const [pageX, pageY] = await getFirstSerialized(page, x => x.rect);
@ -1911,12 +1922,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const data = "Hello PDF.js World !!"; const editorSelector = await createFreeTextEditor({
const editorSelector = getEditorSelector(0); page,
await page.mouse.click(rect.x + 200, rect.y + 200); x: rect.x + 200,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 200,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await selectAll(page); await selectAll(page);
await page.focus("#editorFreeTextFontSize"); await page.focus("#editorFreeTextFontSize");
@ -1950,16 +1961,17 @@ describe("FreeText Editor", () => {
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const data = "Hello PDF.js World !!"; const data = "Hello PDF.js World !!";
let editorSelector = getEditorSelector(0); await createFreeTextEditor({
await page.mouse.click(rect.x + 100, rect.y + 100); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 100,
await page.type(`${editorSelector} .internal`, data); y: rect.y + 100,
await commit(page); data,
});
const [pageX, pageY] = await getFirstSerialized(page, x => x.rect); const [pageX, pageY] = await getFirstSerialized(page, x => x.rect);
await clearAll(page); await clearAll(page);
editorSelector = getEditorSelector(1); const editorSelector = getEditorSelector(1);
await page.mouse.click(rect.x + 100, rect.y + 100); await page.mouse.click(rect.x + 100, rect.y + 100);
await page.waitForSelector(editorSelector, { visible: true }); await page.waitForSelector(editorSelector, { visible: true });
@ -2023,13 +2035,13 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await cancelFocusIn(page, editorSelector); noFocusIn: true,
await commit(page); });
const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1); const oneToFourteen = Array.from(new Array(14).keys(), x => x + 1);
@ -2076,23 +2088,21 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
let rect = await getRect(page, ".annotationEditorLayer"); let rect = await getRect(page, ".annotationEditorLayer");
const firstEditorSelector = await createFreeTextEditor({
const firstEditorSelector = getEditorSelector(0); page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(firstEditorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${firstEditorSelector} .internal`, "A"); data: "A",
await commit(page); });
// Create a new editor. // Create a new editor.
rect = await getRect(page, firstEditorSelector); rect = await getRect(page, firstEditorSelector);
const secondEditorSelector = getEditorSelector(1); const secondEditorSelector = await createFreeTextEditor({
await page.mouse.click( page,
rect.x + 5 * rect.width, x: rect.x + 5 * rect.width,
rect.y + 5 * rect.height y: rect.y + 5 * rect.height,
); data: "B",
await page.waitForSelector(secondEditorSelector, { visible: true }); });
await page.type(`${secondEditorSelector} .internal`, "B");
await commit(page);
// Select the second editor. // Select the second editor.
await selectEditor(page, secondEditorSelector); await selectEditor(page, secondEditorSelector);
@ -2155,15 +2165,12 @@ describe("FreeText Editor", () => {
const allPositions = []; const allPositions = [];
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
const editorSelector = getEditorSelector(i); const editorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 10 + 30 * i, rect.y + 100 + 5 * i); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 10 + 30 * i,
await page.type( y: rect.y + 100 + 5 * i,
`${editorSelector} .internal`, data: String.fromCharCode(65 + i),
String.fromCharCode(65 + i) });
);
await commit(page);
allPositions.push(await getRect(page, editorSelector)); allPositions.push(await getRect(page, editorSelector));
} }
@ -2214,13 +2221,13 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await cancelFocusIn(page, editorSelector); noFocusIn: true,
await commit(page); });
await page.evaluate(() => { await page.evaluate(() => {
window.editingEvents = []; window.editingEvents = [];
@ -2267,12 +2274,13 @@ describe("FreeText Editor", () => {
const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`;
let rect = await getRect(page, page1Selector); let rect = await getRect(page, page1Selector);
const firstEditorSelector = getEditorSelector(0); const firstEditorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 10, rect.y + 10); page,
await page.waitForSelector(firstEditorSelector, { visible: true }); x: rect.x + 10,
await page.type(`${firstEditorSelector} .internal`, "Hello"); y: rect.y + 10,
await cancelFocusIn(page, firstEditorSelector); data: "Hello",
await commit(page); noFocusIn: true,
});
// Unselect. // Unselect.
await unselectEditor(page, firstEditorSelector); await unselectEditor(page, firstEditorSelector);
@ -2290,11 +2298,12 @@ describe("FreeText Editor", () => {
}); });
rect = await getRect(page, page14Selector); rect = await getRect(page, page14Selector);
const secondEditorSelector = getEditorSelector(1); await createFreeTextEditor({
await page.mouse.click(rect.x + 10, rect.y + 10); page,
await page.waitForSelector(secondEditorSelector, { visible: true }); x: rect.x + 10,
await page.type(`${secondEditorSelector} .internal`, "World"); y: rect.y + 10,
await commit(page); data: "World",
});
for (let i = 0; i < 13; i++) { for (let i = 0; i < 13; i++) {
await page.keyboard.press("P"); await page.keyboard.press("P");
@ -2336,12 +2345,13 @@ describe("FreeText Editor", () => {
const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`; const page1Selector = `.page[data-page-number = "1"] > .annotationEditorLayer.freetextEditing`;
const rect = await getRect(page, page1Selector); const rect = await getRect(page, page1Selector);
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 10, rect.y + 10); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 10,
await page.type(`${editorSelector} .internal`, "Hello"); y: rect.y + 10,
await cancelFocusIn(page, editorSelector); data: "Hello",
await commit(page); noFocusIn: true,
});
// Unselect. // Unselect.
await unselectEditor(page, editorSelector); await unselectEditor(page, editorSelector);
@ -2394,7 +2404,6 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const parentId = "p3R_mc8"; const parentId = "p3R_mc8";
const editorSelector = getEditorSelector(0);
const rect = await page.evaluate(id => { const rect = await page.evaluate(id => {
const parent = document.getElementById(id); const parent = document.getElementById(id);
let span = null; let span = null;
@ -2407,15 +2416,13 @@ describe("FreeText Editor", () => {
const { x, y, width, height } = span.getBoundingClientRect(); const { x, y, width, height } = span.getBoundingClientRect();
return { x, y, width, height }; return { x, y, width, height };
}, parentId); }, parentId);
await page.mouse.click(
rect.x + rect.width + 5,
rect.y + rect.height / 2
);
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, "Hello Wolrd");
await commit(page);
await waitForStorageEntries(page, 1); await createFreeTextEditor({
page,
x: rect.x + rect.width + 5,
y: rect.y + rect.height / 2,
data: "Hello World",
});
const id = await getFirstSerialized(page, x => x.structTreeParentId); const id = await getFirstSerialized(page, x => x.structTreeParentId);
expect(id).withContext(`In ${browserName}`).toEqual(parentId); expect(id).withContext(`In ${browserName}`).toEqual(parentId);
@ -2441,21 +2448,19 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0);
const data = "Hello PDF.js World !!"; const data = "Hello PDF.js World !!";
await page.mouse.click(rect.x + 100, rect.y + 100); const editorSelector = await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
const internalEditorSelector = `${editorSelector} .internal`; x: rect.x + 100,
await page.type(internalEditorSelector, data); y: rect.y + 100,
await commit(page); data,
});
await page.click(editorSelector, { count: 2 }); await page.click(editorSelector, { count: 2 });
await page.waitForSelector( await page.waitForSelector(
`${editorSelector} .overlay:not(.enabled)` `${editorSelector} .overlay:not(.enabled)`
); );
await page.click(internalEditorSelector, { await page.click(`${editorSelector} .internal`, { count: 3 });
count: 3,
});
const selection = await page.evaluate(() => const selection = await page.evaluate(() =>
document.getSelection().toString() document.getSelection().toString()
); );
@ -2588,12 +2593,13 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0);
const data = "Hello PDF.js World !!"; const data = "Hello PDF.js World !!";
await page.mouse.click(rect.x + 100, rect.y + 100); const editorSelector = await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
await page.type(`${editorSelector} .internal`, data); x: rect.x + 100,
await commit(page); y: rect.y + 100,
data,
});
let handle = await createPromise(page, resolve => { let handle = await createPromise(page, resolve => {
document.addEventListener("selectionchange", resolve, { document.addEventListener("selectionchange", resolve, {
@ -2642,12 +2648,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
// Delete it in using the button. // Delete it in using the button.
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -2685,38 +2691,39 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const firstEditorSelector = await createFreeTextEditor({
page,
x: rect.x + 100,
y: rect.y + 100,
data: "Hello PDF.js World !!",
});
const secondEditorSelector = await createFreeTextEditor({
page,
x: rect.x + 200,
y: rect.y + 200,
data: "Hello PDF.js World !!",
});
const data = "Hello PDF.js World !!"; // Select the first editor.
await selectEditor(page, firstEditorSelector);
for (let i = 1; i <= 2; i++) {
const editorSelector = getEditorSelector(i - 1);
await page.mouse.click(rect.x + i * 100, rect.y + i * 100);
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
}
// Select the editor created previously.
const editorSelector = getEditorSelector(0);
await selectEditor(page, editorSelector);
await selectAll(page); await selectAll(page);
// Delete it in using the button. // Delete it in using the button.
await page.focus(`${editorSelector} button.deleteButton`); await page.focus(`${firstEditorSelector} button.deleteButton`);
await page.keyboard.press("Enter"); await page.keyboard.press("Enter");
await page.waitForFunction( await page.waitForFunction(
sel => !document.querySelector(sel), sel => !document.querySelector(sel),
{}, {},
editorSelector firstEditorSelector
); );
await waitForStorageEntries(page, 0); await waitForStorageEntries(page, 0);
// Undo. // Undo.
await kbUndo(page); await kbUndo(page);
await waitForSerialized(page, 2); await waitForSerialized(page, 2);
await page.waitForSelector(editorSelector, { visible: true }); await page.waitForSelector(firstEditorSelector, { visible: true });
await page.waitForSelector(getEditorSelector(1), { visible: true }); await page.waitForSelector(secondEditorSelector, { visible: true });
}) })
); );
}); });
@ -2801,14 +2808,14 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0);
const data = "Hello\nPDF.js\nWorld\n!!"; const data = "Hello\nPDF.js\nWorld\n!!";
await page.mouse.click(rect.x + 100, rect.y + 100); await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
await page.type(`${editorSelector} .internal`, data); x: rect.x + 100,
await commit(page); y: rect.y + 100,
data,
});
await waitForSerialized(page, 1);
const serialized = (await getSerialized(page))[0]; const serialized = (await getSerialized(page))[0];
expect(serialized.value) expect(serialized.value)
.withContext(`In ${browserName}`) .withContext(`In ${browserName}`)
@ -2835,12 +2842,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await page.evaluate(() => { await page.evaluate(() => {
window.PDFViewerApplication.eventBus.dispatch( window.PDFViewerApplication.eventBus.dispatch(
@ -2936,13 +2943,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await waitForSerialized(page, 1);
await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.waitForSelector(`${editorSelector} button.deleteButton`);
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -2986,13 +2992,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click(rect.x + 100, rect.y + 100); x: rect.x + 100,
await page.waitForSelector(editorSelector, { visible: true }); y: rect.y + 100,
await page.type(`${editorSelector} .internal`, data); data: "Hello PDF.js World !!",
await commit(page); });
await waitForSerialized(page, 1);
await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.waitForSelector(`${editorSelector} button.deleteButton`);
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -3031,13 +3036,13 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
let editorSelector = getEditorSelector(0);
const data = "Hello PDF.js World !!"; const data = "Hello PDF.js World !!";
await page.mouse.click(rect.x + 100, rect.y + 100); let editorSelector = await createFreeTextEditor({
await page.waitForSelector(editorSelector, { visible: true }); page,
await page.type(`${editorSelector} .internal`, data); x: rect.x + 100,
await commit(page); y: rect.y + 100,
data,
});
const waitForTextChange = (previous, edSelector) => const waitForTextChange = (previous, edSelector) =>
page.waitForFunction( page.waitForFunction(
@ -3300,7 +3305,6 @@ describe("FreeText Editor", () => {
describe("Undo deletion popup has the expected behaviour", () => { describe("Undo deletion popup has the expected behaviour", () => {
let pages; let pages;
const editorSelector = getEditorSelector(0);
beforeEach(async () => { beforeEach(async () => {
pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer"); pages = await loadAndWait("tracemonkey.pdf", ".annotationEditorLayer");
@ -3316,12 +3320,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const data = "Hello PDF.js World !!"; const editorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 100, rect.y + 100); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 100,
await page.type(`${editorSelector} .internal`, data); y: rect.y + 100,
await commit(page); data: "Hello PDF.js World !!",
await waitForSerialized(page, 1); });
await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.waitForSelector(`${editorSelector} button.deleteButton`);
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -3344,12 +3348,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const data = "Hello PDF.js World !!"; const editorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 100, rect.y + 100); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 100,
await page.type(`${editorSelector} .internal`, data); y: rect.y + 100,
await commit(page); data: "Hello PDF.js World !!",
await waitForSerialized(page, 1); });
await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.waitForSelector(`${editorSelector} button.deleteButton`);
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -3377,12 +3381,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
let rect = await getRect(page, ".annotationEditorLayer"); let rect = await getRect(page, ".annotationEditorLayer");
const data = "Hello PDF.js World !!"; const editorSelector = await createFreeTextEditor({
await page.mouse.click(rect.x + 100, rect.y + 100); page,
await page.waitForSelector(editorSelector, { visible: true }); x: rect.x + 100,
await page.type(`${editorSelector} .internal`, data); y: rect.y + 100,
await commit(page); data: "Hello PDF.js World !!",
await waitForSerialized(page, 1); });
await page.waitForSelector(`${editorSelector} button.deleteButton`); await page.waitForSelector(`${editorSelector} button.deleteButton`);
await page.click(`${editorSelector} button.deleteButton`); await page.click(`${editorSelector} button.deleteButton`);
@ -3390,13 +3394,12 @@ describe("FreeText Editor", () => {
await page.waitForSelector("#editorUndoBar", { visible: true }); await page.waitForSelector("#editorUndoBar", { visible: true });
rect = await getRect(page, ".annotationEditorLayer"); rect = await getRect(page, ".annotationEditorLayer");
const secondEditorSelector = getEditorSelector(1); await createFreeTextEditor({
const newData = "This is a new text box!"; page,
await page.mouse.click(rect.x + 150, rect.y + 150); x: rect.x + 150,
await page.waitForSelector(secondEditorSelector, { visible: true }); y: rect.y + 150,
await page.type(`${secondEditorSelector} .internal`, newData); data: "This is a new text box!",
await commit(page); });
await waitForSerialized(page, 1);
await page.waitForSelector("#editorUndoBar", { hidden: true }); await page.waitForSelector("#editorUndoBar", { hidden: true });
}) })
); );
@ -3420,14 +3423,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
page,
const data = "Hello PDF.js World !!"; x: rect.x + 100,
await page.mouse.click(rect.x + 100, rect.y + 100); y: rect.y + 100,
await page.waitForSelector(editorSelector, { visible: true }); data: "Hello PDF.js World !!",
await page.type(`${editorSelector} .internal`, data); });
await commit(page);
await waitForSerialized(page, 1);
let alignment = await page.$eval( let alignment = await page.$eval(
`${editorSelector} .internal`, `${editorSelector} .internal`,
@ -3468,17 +3469,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
page,
const data = "Hello PDF.js World !!"; x: rect.x + rect.width / 2,
await page.mouse.click( y: rect.y + rect.height / 2,
rect.x + rect.width / 2, data: "Hello PDF.js World !!",
rect.y + rect.height / 2 });
);
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
await waitForSerialized(page, 1);
await switchToFreeText(page, /* disable */ true); await switchToFreeText(page, /* disable */ true);
@ -3508,17 +3504,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
page,
const data = "Hello PDF.js World !!"; x: rect.x + rect.width / 2,
await page.mouse.click( y: rect.y + rect.height / 2,
rect.x + rect.width / 2, data: "Hello PDF.js World !!",
rect.y + rect.height / 2 });
);
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
await waitForSerialized(page, 1);
await switchToFreeText(page, /* disable */ true); await switchToFreeText(page, /* disable */ true);
await switchToEditor("Ink", page); await switchToEditor("Ink", page);
@ -3573,15 +3564,12 @@ describe("FreeText Editor", () => {
await switchToFreeText(page); await switchToFreeText(page);
const rect = await getRect(page, ".annotationEditorLayer"); const rect = await getRect(page, ".annotationEditorLayer");
const editorSelector = getEditorSelector(0); const editorSelector = await createFreeTextEditor({
const data = "Hello PDF.js World !!"; page,
await page.mouse.click( x: rect.x + rect.width / 2,
rect.x + rect.width / 2, y: rect.y + rect.height / 2,
rect.y + rect.height / 2 data: "Hello PDF.js World !!",
); });
await page.waitForSelector(editorSelector, { visible: true });
await page.type(`${editorSelector} .internal`, data);
await commit(page);
const colorPickerSelector = `${editorSelector} input.basicColorPicker`; const colorPickerSelector = `${editorSelector} input.basicColorPicker`;
await page.waitForSelector(colorPickerSelector, { visible: true }); await page.waitForSelector(colorPickerSelector, { visible: true });

View File

@ -310,6 +310,12 @@ async function waitForEvent({
} }
} }
async function countStorageEntries(page) {
return page.evaluate(
() => window.PDFViewerApplication.pdfDocument.annotationStorage.size
);
}
async function waitForStorageEntries(page, nEntries) { async function waitForStorageEntries(page, nEntries) {
return page.waitForFunction( return page.waitForFunction(
n => window.PDFViewerApplication.pdfDocument.annotationStorage.size === n, n => window.PDFViewerApplication.pdfDocument.annotationStorage.size === n,
@ -318,6 +324,14 @@ async function waitForStorageEntries(page, nEntries) {
); );
} }
async function countSerialized(page) {
return page.evaluate(
() =>
window.PDFViewerApplication.pdfDocument.annotationStorage.serializable.map
?.size ?? 0
);
}
async function waitForSerialized(page, nEntries) { async function waitForSerialized(page, nEntries) {
return page.waitForFunction( return page.waitForFunction(
n => { n => {
@ -924,6 +938,8 @@ export {
closeSinglePage, closeSinglePage,
copy, copy,
copyToClipboard, copyToClipboard,
countSerialized,
countStorageEntries,
createPromise, createPromise,
dragAndDrop, dragAndDrop,
firstPageOnTop, firstPageOnTop,
@ -935,6 +951,7 @@ export {
getEditors, getEditors,
getEditorSelector, getEditorSelector,
getFirstSerialized, getFirstSerialized,
getNextEditorId,
getQuerySelector, getQuerySelector,
getRect, getRect,
getSelector, getSelector,

11
test/pdfs/.gitignore vendored
View File

@ -620,6 +620,7 @@
!autoprint.pdf !autoprint.pdf
!bug1811694.pdf !bug1811694.pdf
!bug1811510.pdf !bug1811510.pdf
!issue20324.pdf
!bug1815476.pdf !bug1815476.pdf
!issue16021.pdf !issue16021.pdf
!bug1770750.pdf !bug1770750.pdf
@ -752,4 +753,12 @@
!bug1937438_af_from_latex.pdf !bug1937438_af_from_latex.pdf
!bug1937438_from_word.pdf !bug1937438_from_word.pdf
!bug1937438_mml_from_latex.pdf !bug1937438_mml_from_latex.pdf
!marked_content_lang.pdf !marked_content_lang.pdf
!bug1997343.pdf
!doc_1_3_pages.pdf
!doc_2_3_pages.pdf
!doc_3_3_pages.pdf
!labelled_pages.pdf
!extract_link.pdf
!two_paragraphs.pdf
!paragraph_and_link.pdf

BIN
test/pdfs/bug1997343.pdf Executable file

Binary file not shown.

BIN
test/pdfs/doc_1_3_pages.pdf Executable file

Binary file not shown.

BIN
test/pdfs/doc_2_3_pages.pdf Executable file

Binary file not shown.

BIN
test/pdfs/doc_3_3_pages.pdf Executable file

Binary file not shown.

BIN
test/pdfs/extract_link.pdf Executable file

Binary file not shown.

BIN
test/pdfs/issue20324.pdf Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More