merge upstream
This commit is contained in:
commit
9597efb3f4
3
extensions/firefox/chrome-mozcentral.manifest
Normal file
3
extensions/firefox/chrome-mozcentral.manifest
Normal file
@ -0,0 +1,3 @@
|
||||
resource pdf.js content/
|
||||
component {d0c5195d-e798-49d4-b1d3-9324328b2291} components/PdfStreamConverter.js
|
||||
contract @mozilla.org/streamconv;1?from=application/pdf&to=*/* {d0c5195d-e798-49d4-b1d3-9324328b2291}
|
@ -11,7 +11,7 @@ const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
const PDFJS_EVENT_ID = 'pdf.js.message';
|
||||
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
const EXT_PREFIX = 'extensions.uriloader@pdf.js';
|
||||
const PREF_PREFIX = 'PDFJSSCRIPT_PREF_PREFIX';
|
||||
const MAX_DATABASE_LENGTH = 4096;
|
||||
const FIREFOX_ID = '{ec8030f7-c20a-464f-9b0e-13a3a9e97384}';
|
||||
const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
||||
@ -19,6 +19,7 @@ const SEAMONKEY_ID = '{92650c4d-4b8e-4d2a-b7eb-24ecf4f6b63a}';
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
Cu.import('resource://gre/modules/NetUtil.jsm');
|
||||
Cu.import('resource://gre/modules/AddonManager.jsm');
|
||||
|
||||
let appInfo = Cc['@mozilla.org/xre/app-info;1']
|
||||
.getService(Ci.nsIXULAppInfo);
|
||||
@ -57,7 +58,7 @@ function getStringPref(pref, def) {
|
||||
}
|
||||
|
||||
function log(aMsg) {
|
||||
if (!getBoolPref(EXT_PREFIX + '.pdfBugEnabled', false))
|
||||
if (!getBoolPref(PREF_PREFIX + '.pdfBugEnabled', false))
|
||||
return;
|
||||
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Services.console.logStringMessage(msg);
|
||||
@ -91,9 +92,15 @@ function getLocalizedStrings(path) {
|
||||
}
|
||||
return map;
|
||||
}
|
||||
function getLocalizedString(strings, id) {
|
||||
if (id in strings)
|
||||
return strings[id]['textContent'];
|
||||
return id;
|
||||
}
|
||||
|
||||
// All the priviledged actions.
|
||||
function ChromeActions() {
|
||||
function ChromeActions(domWindow) {
|
||||
this.domWindow = domWindow;
|
||||
}
|
||||
|
||||
ChromeActions.prototype = {
|
||||
@ -136,12 +143,12 @@ ChromeActions.prototype = {
|
||||
// Protect against something sending tons of data to setDatabase.
|
||||
if (data.length > MAX_DATABASE_LENGTH)
|
||||
return;
|
||||
setStringPref(EXT_PREFIX + '.database', data);
|
||||
setStringPref(PREF_PREFIX + '.database', data);
|
||||
},
|
||||
getDatabase: function() {
|
||||
if (inPrivateBrowsing)
|
||||
return '{}';
|
||||
return getStringPref(EXT_PREFIX + '.database', '{}');
|
||||
return getStringPref(PREF_PREFIX + '.database', '{}');
|
||||
},
|
||||
getLocale: function() {
|
||||
return getStringPref('general.useragent.locale', 'en-US');
|
||||
@ -164,10 +171,30 @@ ChromeActions.prototype = {
|
||||
},
|
||||
searchEnabled: function() {
|
||||
return getBoolPref(EXT_PREFIX + '.searchEnabled', false);
|
||||
},
|
||||
fallback: function(url) {
|
||||
var self = this;
|
||||
var domWindow = this.domWindow;
|
||||
var strings = getLocalizedStrings('chrome.properties');
|
||||
var message = getLocalizedString(strings, 'unsupported_feature');
|
||||
|
||||
var win = Services.wm.getMostRecentWindow('navigator:browser');
|
||||
var browser = win.gBrowser.getBrowserForDocument(domWindow.top.document);
|
||||
var notificationBox = win.gBrowser.getNotificationBox(browser);
|
||||
|
||||
var buttons = [{
|
||||
label: getLocalizedString(strings, 'open_with_different_viewer'),
|
||||
accessKey: null,
|
||||
callback: function() {
|
||||
self.download(url);
|
||||
}
|
||||
}];
|
||||
notificationBox.appendNotification(message, 'pdfjs-fallback', null,
|
||||
notificationBox.PRIORITY_WARNING_LOW,
|
||||
buttons);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Event listener to trigger chrome privedged code.
|
||||
function RequestListener(actions) {
|
||||
this.actions = actions;
|
||||
@ -193,7 +220,7 @@ function PdfStreamConverter() {
|
||||
PdfStreamConverter.prototype = {
|
||||
|
||||
// properties required for XPCOM registration:
|
||||
classID: Components.ID('{6457a96b-2d68-439a-bcfa-44465fbcdbb1}'),
|
||||
classID: Components.ID('{PDFJSSCRIPT_STREAM_CONVERTER_ID}'),
|
||||
classDescription: 'pdf.js Component',
|
||||
contractID: '@mozilla.org/streamconv;1?from=application/pdf&to=*/*',
|
||||
|
||||
@ -270,7 +297,8 @@ PdfStreamConverter.prototype = {
|
||||
var domWindow = getDOMWindow(channel);
|
||||
// Double check the url is still the correct one.
|
||||
if (domWindow.document.documentURIObject.equals(aRequest.URI)) {
|
||||
let requestListener = new RequestListener(new ChromeActions);
|
||||
let requestListener = new RequestListener(
|
||||
new ChromeActions(domWindow));
|
||||
domWindow.addEventListener(PDFJS_EVENT_ID, function(event) {
|
||||
requestListener.receive(event);
|
||||
}, false, true);
|
||||
|
@ -1,27 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
|
||||
#filter substitution
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>uriloader@pdf.js</em:id>
|
||||
<!-- PDFJS_LOCALIZED_METADATA -->
|
||||
<em:name>PDF Viewer</em:name>
|
||||
<em:version>PDFJSSCRIPT_VERSION</em:version>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>@FIREFOX_VERSION@</em:minVersion>
|
||||
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
<em:strictCompatibility>true</em:strictCompatibility>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:creator>Mozilla</em:creator>
|
||||
<em:description>Uses HTML5 to display PDF files directly in Firefox.</em:description>
|
||||
<em:homepageURL>https://support.mozilla.org/kb/Opening%20PDF%20files%20within%20Firefox</em:homepageURL>
|
||||
<em:type>2</em:type>
|
||||
</Description>
|
||||
</RDF>
|
8
l10n/cs/metadata.inc
Normal file
8
l10n/cs/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>cs</em:locale>
|
||||
<em:name>PDF Viewer</em:name>
|
||||
<em:description>Používá HTML5 pro zobrazení PDF souborů přímo ve Firefoxu.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
45
l10n/cs/viewer.properties
Normal file
45
l10n/cs/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=Aktuální zobrazení(zkopírovat nebo otevřít v novém okně)
|
||||
previous.title=Předchozí stránka
|
||||
next.title=Další stránka
|
||||
print.title=Tisk
|
||||
download.title=Stáhnout
|
||||
zoom_out.title=Zmenšit
|
||||
zoom_in.title=Zvětšit
|
||||
error_more_info=Více informací
|
||||
error_less_info=Méně informací
|
||||
error_close=Zavřít
|
||||
error_build=PDF.JS Build: {{build}}
|
||||
error_message=Zpráva:{{message}}
|
||||
error_stack=Stack:{{stack}}
|
||||
error_file=Soubor:{{file}}
|
||||
error_line=Řádek:{{line}}
|
||||
page_scale_width=Šířka stránky
|
||||
page_scale_fit=Stránka
|
||||
page_scale_auto=Automatické přibližení
|
||||
page_scale_actual=Skutečná velikost
|
||||
toggle_slider.title=Přepnout posuvník
|
||||
thumbs.title=Zobrazit náhledy
|
||||
outline.title=Zobrazit osnovu dokumentu
|
||||
loading=Načítám... {{percent}}%
|
||||
loading_error_indicator=Chyba
|
||||
loading_error=Došlo k chybě při načítání PDF.
|
||||
rendering_error=Došlo k chybě při vykreslování stránky.
|
||||
page_label=Stránka:
|
||||
page_of=z{{pageCount}}
|
||||
no_outline=Žádné osnovy k dispozici
|
||||
open_file.title=Otevřít soubor
|
||||
text_annotation_type=[{{type}}Anotace]
|
||||
toggle_slider_label=Přepnout posuvník
|
||||
thumbs_label=Náhledy
|
||||
outline_label=Přehled dokumentu
|
||||
bookmark_label=Aktuální zobrazení
|
||||
previous_label=Předchozí
|
||||
next_label=Další
|
||||
print_label=Tisk
|
||||
download_label=Stáhnout
|
||||
zoom_out_label=Zmenšit
|
||||
zoom_in_label=Přiblížit
|
||||
zoom.title=Zvětšit
|
||||
thumb_page_title=Stránka{{page}}
|
||||
thumb_page_canvas=Náhled stránky {{page}}
|
||||
request_password=PDF je chráněn heslem:
|
@ -17,7 +17,7 @@ page_scale_width=Sidebredde
|
||||
page_scale_fit=Helside
|
||||
page_scale_auto=Automatisk zoom
|
||||
page_scale_actual=Faktisk størrelse
|
||||
toggle_slider.title=Skift Slider
|
||||
toggle_slider.title=Skift slider
|
||||
thumbs.title=Vis thumbnails
|
||||
outline.title=Vis dokumentoversigt
|
||||
loading=Indlæser... {{percent}}%
|
||||
@ -29,3 +29,17 @@ page_of=af {{pageCount}}
|
||||
no_outline=Ingen dokumentoversigt tilgængelig
|
||||
open_file.title=Åbn fil
|
||||
text_annotation_type=[{{type}} Kommentar]
|
||||
toggle_slider_label=Skift slider
|
||||
thumbs_label=Thumbnails
|
||||
outline_label=Dokumentoversigt
|
||||
bookmark_label=Aktuel visning
|
||||
previous_label=Forrige
|
||||
next_label=Næste
|
||||
print_label=Udskriv
|
||||
download_label=Hent
|
||||
zoom_out_label=Zoom ud
|
||||
zoom_in_label=Zoom ind
|
||||
zoom.title=Zoom
|
||||
thumb_page_title=Side {{page}}
|
||||
thumb_page_canvas=Thumbnail af side {{page}}
|
||||
request_password=PDF filen er beskyttet med et kodeord:
|
||||
|
2
l10n/en-US/chrome.properties
Normal file
2
l10n/en-US/chrome.properties
Normal file
@ -0,0 +1,2 @@
|
||||
unsupported_feature=This PDF document might not be displayed correctly.
|
||||
open_with_different_viewer=Open With Different Viewer
|
@ -42,3 +42,5 @@ zoom_in_label=Zoom In
|
||||
zoom.title=Zoom
|
||||
thumb_page_title=Page {{page}}
|
||||
thumb_page_canvas=Thumbnail of Page {{page}}
|
||||
request_password=PDF is protected by a password:
|
||||
open_file_label=Open
|
||||
|
7
l10n/fr/metadata.inc
Normal file
7
l10n/fr/metadata.inc
Normal file
@ -0,0 +1,7 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>fr</em:locale>
|
||||
<em:name>PDF Viewer</em:name>
|
||||
<em:description>Utilise HTML5 pour afficher les documents PDF directement dans Firefox.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
45
l10n/fr/viewer.properties
Normal file
45
l10n/fr/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=Vue courante (copier ou ouvrir dans une nouvelle fenêtre)
|
||||
previous.title=Précédente
|
||||
next.title=Suivante
|
||||
print.title=Imprimer
|
||||
download.title=Télécharger
|
||||
zoom_out.title=Zoom arrière
|
||||
zoom_in.title=Zoom avant
|
||||
error_more_info=Plus d'informations
|
||||
error_less_info=Moins d'informations
|
||||
error_close=Fermer
|
||||
error_build=Version de PDF.JS : {{build}}
|
||||
error_message=Message : {{message}}
|
||||
error_stack=Pile : {{stack}}
|
||||
error_file=Fichier : {{file}}
|
||||
error_line=Ligne : {{line}}
|
||||
page_scale_width=Largeur de la page
|
||||
page_scale_fit=Ajuster à la page
|
||||
page_scale_auto=Zoom automatique
|
||||
page_scale_actual=Taille réelle
|
||||
toggle_slider.title=Afficher/Masquer la barre latérale
|
||||
thumbs.title=Afficher/masquer les vignettes
|
||||
outline.title=Afficher/masquer la structure
|
||||
loading=Chargement… {{percent}}%
|
||||
loading_error_indicator=Erreur
|
||||
loading_error=Une erreur est survenue lors du chargement du PDF.
|
||||
rendering_error=Une erreur est survenue lors de l'affichage de la page.
|
||||
page_label=Page :
|
||||
page_of=sur {{pageCount}}
|
||||
no_outline=Pas de structure disponible
|
||||
open_file.title=Ouvrir un fichier
|
||||
text_annotation_type=[Annotation {{type}}]
|
||||
toggle_slider_label=Afficher/Masquer la barre latérale
|
||||
thumbs_label=Vignettes
|
||||
outline_label=Structure du document
|
||||
bookmark_label=Vue courante
|
||||
previous_label=Précédente
|
||||
next_label=Suivante
|
||||
print_label=Imprimer
|
||||
download_label=Télécharger
|
||||
zoom_out_label=Zoom arrière
|
||||
zoom_in_label=Zoom avant
|
||||
zoom.title=Zoom
|
||||
thumb_page_title=Page {{page}}
|
||||
thumb_page_canvas=Aperçu de la page {{page}}
|
||||
request_password=Ce PDF est protégé par un mot de passe :
|
8
l10n/he/metadata.inc
Normal file
8
l10n/he/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>he</em:locale>
|
||||
<em:name>קורא PDF</em:name>
|
||||
<em:description>הצגת קבצי PDF ישירות ב־Firefox באמצעות HTML5.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
46
l10n/he/viewer.properties
Normal file
46
l10n/he/viewer.properties
Normal file
@ -0,0 +1,46 @@
|
||||
bookmark.title=דף נוכחי (העתקה או פתיחה בחלון חדש)
|
||||
previous.title=דף קודם
|
||||
next.title=דף הבא
|
||||
print.title=הדפסה
|
||||
download.title=הורדה
|
||||
zoom_out.title=התרחקות
|
||||
zoom_in.title=התקרבות
|
||||
error_more_info=יותר מידע
|
||||
error_less_info=פחות מידע
|
||||
error_close=סגירה
|
||||
error_build=בניית PDF.JS: {{build}}
|
||||
error_message=הודעה: {{message}}
|
||||
error_stack=מחסנית: {{stack}}
|
||||
error_file=קובץ: {{file}}
|
||||
error_line=שורה: {{line}}
|
||||
page_scale_width=רוחב דף
|
||||
page_scale_fit=גודל דף
|
||||
page_scale_auto=התקרבות אוטומטית
|
||||
page_scale_actual=גודל אמיתי
|
||||
toggle_slider.title=מתג החלקה
|
||||
thumbs.title=הצגת תמונות ממוזערות
|
||||
outline.title=הצגת מתאר מסמך
|
||||
loading=בטעינה... {{percent}}%
|
||||
loading_error_indicator=שגיאה
|
||||
loading_error=אירעה שגיאה בעת טעינת קובץ PDF.
|
||||
rendering_error=אירעה שגיאה בעת עיבוד הדף.
|
||||
page_label=דף:
|
||||
page_of=מתוך {{pageCount}}
|
||||
no_outline=אין מתאר זמין
|
||||
open_file.title=פתיחת קובץ
|
||||
text_annotation_type=[{{type}} Annotation]
|
||||
toggle_slider_label=מתג החלקה
|
||||
thumbs_label=תמונות ממוזערות
|
||||
outline_label=מתאר מסמך
|
||||
bookmark_label=תצוגה נוכחית
|
||||
previous_label=קודם
|
||||
next_label=הבא
|
||||
print_label=הדפסה
|
||||
download_label=הורדה
|
||||
zoom_out_label=התרחקות
|
||||
zoom_in_label=התקרבות
|
||||
zoom.title=מרחק מתצוגה
|
||||
thumb_page_title=דף {{page}}
|
||||
thumb_page_canvas=תמונה ממוזערת של דף {{page}}
|
||||
request_password=קובץ PDF מוגן בססמה:
|
||||
open_file_label=פתיחה
|
8
l10n/ja/metadata.inc
Normal file
8
l10n/ja/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>ja</em:locale>
|
||||
<em:name>PDF Viewer</em:name>
|
||||
<em:description>HTML5を使用して、Firefoxで直接PDFファイルを表示します。</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
45
l10n/ja/viewer.properties
Normal file
45
l10n/ja/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=現在のビュー (コピーまたは新しいウインドウで開く)
|
||||
previous.title=前のページ
|
||||
next.title=次のページ
|
||||
print.title=印刷
|
||||
download.title=ダウンロード
|
||||
zoom_out.title=縮小
|
||||
zoom_in.title=拡大
|
||||
error_more_info=詳細情報
|
||||
error_less_info=詳細情報の非表示
|
||||
error_close=閉じる
|
||||
error_build=PDF.JS Build: {{build}}
|
||||
error_message=メッセージ: {{message}}
|
||||
error_stack=スタック: {{stack}}
|
||||
error_file=ファイル: {{file}}
|
||||
error_line=ライン: {{line}}
|
||||
page_scale_width=幅に合わせる
|
||||
page_scale_fit=ページのサイズに合わせる
|
||||
page_scale_auto=自動ズーム
|
||||
page_scale_actual=実際のサイズ
|
||||
toggle_slider.title=サイドバーの切り替え
|
||||
thumbs.title=縮小版を表示
|
||||
outline.title=文書の目次を表示
|
||||
loading=読み込み中... {{percent}}%
|
||||
loading_error_indicator=エラー
|
||||
loading_error=PDFの読み込み中にエラーが発生しました
|
||||
rendering_error=ページのレンダリング中にエラーが発生しました
|
||||
page_label=ページ:
|
||||
page_of=of {{pageCount}}
|
||||
no_outline=利用可能な目次はありません
|
||||
open_file.title=ファイルを開く
|
||||
text_annotation_type=[{{type}} 注釈]
|
||||
toggle_slider_label=サイドバーの切り替え
|
||||
thumbs_label=縮小版
|
||||
outline_label=文書の目次
|
||||
bookmark_label=現在のビュー
|
||||
previous_label=前へ
|
||||
next_label=次へ
|
||||
print_label=印刷
|
||||
download_label=ダウンロード
|
||||
zoom_out_label=縮小
|
||||
zoom_in_label=拡大
|
||||
zoom.title=ズーム
|
||||
thumb_page_title=ページ {{page}}
|
||||
thumb_page_canvas=ページの縮小版 {{page}}
|
||||
request_password=PDFはパスワードによって保護されています
|
@ -40,3 +40,6 @@ download_label=Загрузить
|
||||
zoom_out_label=Уменьшить
|
||||
zoom_in_label=Увеличить
|
||||
zoom.title=Масштаб
|
||||
thumb_page_title=Страница {{page}}
|
||||
thumb_page_canvas=Уменьшенное изображение страницы {{page}}
|
||||
request_password=PDF защищён паролем:
|
||||
|
8
l10n/sv/metadata.inc
Normal file
8
l10n/sv/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>sv</em:locale>
|
||||
<em:name>PDF Läsare</em:name>
|
||||
<em:description>Använder HTML5 för att visa PDF filer direkt i Firefox.</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
45
l10n/sv/viewer.properties
Normal file
45
l10n/sv/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=Aktuell vy (visa eller öppna i nytt fönster)
|
||||
previous.title=Föregående sida
|
||||
next.title=Nästa sida
|
||||
print.title=Skriv ut
|
||||
download.title=Ladda ner
|
||||
zoom_out.title=Zooma ut
|
||||
zoom_in.title=Zooma in
|
||||
error_more_info=Mer information
|
||||
error_less_info=Mindre information
|
||||
error_close=Stäng
|
||||
error_build=PDF.JS bygge: {{build}}
|
||||
error_message=Meddelande: {{message}}
|
||||
error_stack=Stack: {{stack}}
|
||||
error_file=Fil: {{file}}
|
||||
error_line=Rad: {{line}}
|
||||
page_scale_width=Sidbredd
|
||||
page_scale_fit=Passa sida
|
||||
page_scale_auto=Automatisk zoom
|
||||
page_scale_actual=Faktisk storlek
|
||||
toggle_slider.title=Visa/Dölj panel
|
||||
thumbs.title=Visa miniatyrer
|
||||
outline.title=Visa dokumentdisposition
|
||||
loading=Laddar... {{percent}}%
|
||||
loading_error_indicator=Fel
|
||||
loading_error=Ett fel inträffade när PDF dokumentet laddades.
|
||||
rendering_error=Ett fel inträffade när PDF dokumentet renderades.
|
||||
page_label=Sida:
|
||||
page_of=av {{pageCount}}
|
||||
no_outline=Ingen dokumentdisposition tillgänglig
|
||||
open_file.title=Öppna fil
|
||||
text_annotation_type=[{{type}} Annotering]
|
||||
toggle_slider_label=Visa/Dölj panel
|
||||
thumbs_label=Miniatyrer
|
||||
outline_label=Disposition
|
||||
bookmark_label=Aktuell vy
|
||||
previous_label=Föregående
|
||||
next_label=Nästa
|
||||
print_label=Skriv ut
|
||||
download_label=Ladda ner
|
||||
zoom_out_label=Zooma ut
|
||||
zoom_in_label=Zooma in
|
||||
zoom.title=Zooma
|
||||
thumb_page_title=Sida {{page}}
|
||||
thumb_page_canvas=Miniatyr av sida {{page}}
|
||||
request_password=PDF dokumentet är skyddat av ett lösenord:
|
8
l10n/zh-CN/metadata.inc
Normal file
8
l10n/zh-CN/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>zh-CN</em:locale>
|
||||
<em:name>PDF 查看器</em:name>
|
||||
<em:description>使用 HTML5 来支持在 Firefox 中直接显示 PDF 文件。</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
45
l10n/zh-CN/viewer.properties
Normal file
45
l10n/zh-CN/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=当前视图(复制或在新窗口中打开)
|
||||
previous.title=上一页
|
||||
next.title=下一页
|
||||
print.title=打印
|
||||
download.title=下载
|
||||
zoom_out.title=缩小
|
||||
zoom_in.title=放大
|
||||
error_more_info=更多信息
|
||||
error_less_info=更少信息
|
||||
error_close=关闭
|
||||
error_build=PDF.JS Build: {{build}}
|
||||
error_message=Message: {{message}}
|
||||
error_stack=Stack: {{stack}}
|
||||
error_file=File: {{file}}
|
||||
error_line=Line: {{line}}
|
||||
page_scale_width=适合页宽
|
||||
page_scale_fit=适合页面
|
||||
page_scale_auto=自动缩放
|
||||
page_scale_actual=实际大小
|
||||
toggle_slider.title=切换侧栏
|
||||
thumbs.title=显示缩略图
|
||||
outline.title=显示文档大纲
|
||||
loading=正在载入... {{percent}}%
|
||||
loading_error_indicator=错误
|
||||
loading_error=载入PDF时发生错误。
|
||||
rendering_error=呈现页面时发生错误。
|
||||
page_label=页:
|
||||
page_of=/ {{pageCount}}
|
||||
no_outline=无可用大纲
|
||||
open_file.title=打开文件
|
||||
text_annotation_type=[{{type}} 注解]
|
||||
toggle_slider_label=切换侧栏
|
||||
thumbs_label=缩略图
|
||||
outline_label=文档大纲
|
||||
bookmark_label=当前视图
|
||||
previous_label=向上
|
||||
next_label=向下
|
||||
print_label=打印
|
||||
download_label=下载
|
||||
zoom_out_label=缩小
|
||||
zoom_in_label=放大
|
||||
zoom.title=缩放
|
||||
thumb_page_title=页码 {{page}}
|
||||
thumb_page_canvas=页面 {{page}} 的缩略图
|
||||
request_password=PDF 被密码保护:
|
8
l10n/zh-TW/metadata.inc
Normal file
8
l10n/zh-TW/metadata.inc
Normal file
@ -0,0 +1,8 @@
|
||||
<em:localized>
|
||||
<Description>
|
||||
<em:locale>zh-TW</em:locale>
|
||||
<em:name>PDF 瀏覽器</em:name>
|
||||
<em:description>利用 HTML5 技術在 Firefox 中直接顯示 PDF 格式檔案。</em:description>
|
||||
</Description>
|
||||
</em:localized>
|
||||
|
45
l10n/zh-TW/viewer.properties
Normal file
45
l10n/zh-TW/viewer.properties
Normal file
@ -0,0 +1,45 @@
|
||||
bookmark.title=目前檢視(複製或在新視窗中開啟)
|
||||
previous.title=上一頁
|
||||
next.title=下一頁
|
||||
print.title=列印
|
||||
download.title=下載
|
||||
zoom_out.title=縮小
|
||||
zoom_in.title=放大
|
||||
error_more_info=更多資訊
|
||||
error_less_info=更少資訊
|
||||
error_close=關閉
|
||||
error_build=PDF.JS 版本號: {{build}}
|
||||
error_message=錯誤信息: {{message}}
|
||||
error_stack=堆疊: {{stack}}
|
||||
error_file=檔案: {{file}}
|
||||
error_line=行數: {{line}}
|
||||
page_scale_width=符合頁寬
|
||||
page_scale_fit=符合頁面
|
||||
page_scale_auto=自動縮放
|
||||
page_scale_actual=實際大小
|
||||
toggle_slider.title=切換側邊欄
|
||||
thumbs.title=顯示縮圖
|
||||
outline.title=顯示文件綱要
|
||||
loading=正在載入... {{percent}}%
|
||||
loading_error_indicator=錯誤
|
||||
loading_error=載入PDF檔案時發生錯誤。
|
||||
rendering_error=渲染頁面時發生錯誤。
|
||||
page_label=頁次:
|
||||
page_of=, 共 {{pageCount}} 頁
|
||||
no_outline=無可用的綱要
|
||||
open_file.title=開啟檔案
|
||||
text_annotation_type=[{{type}} 註解]
|
||||
toggle_slider_label=切換側邊欄
|
||||
thumbs_label=縮圖
|
||||
outline_label=文件綱要
|
||||
bookmark_label=目前檢視
|
||||
previous_label=上一頁
|
||||
next_label=下一頁
|
||||
print_label=列印
|
||||
download_label=下載
|
||||
zoom_out_label=縮小
|
||||
zoom_in_label=放大
|
||||
zoom.title=縮放
|
||||
thumb_page_title=第 {{page}} 頁
|
||||
thumb_page_canvas=第 {{page}} 頁的縮圖
|
||||
request_password=PDF 檔案受密碼保護:
|
41
make.js
41
make.js
@ -9,7 +9,11 @@ var ROOT_DIR = __dirname + '/', // absolute path to project's root
|
||||
LOCALE_SRC_DIR = 'l10n/',
|
||||
GH_PAGES_DIR = BUILD_DIR + 'gh-pages/',
|
||||
REPO = 'git@github.com:mozilla/pdf.js.git',
|
||||
PYTHON_BIN = 'python2.7';
|
||||
PYTHON_BIN = 'python2.7',
|
||||
MOZCENTRAL_PREF_PREFIX = 'pdfjs',
|
||||
FIREFOX_PREF_PREFIX = 'extensions.uriloader@pdf.js',
|
||||
MOZCENTRAL_STREAM_CONVERTER_ID = 'd0c5195d-e798-49d4-b1d3-9324328b2291',
|
||||
FIREFOX_STREAM_CONVERTER_ID = '6457a96b-2d68-439a-bcfa-44465fbcdbb1';
|
||||
|
||||
//
|
||||
// make all
|
||||
@ -106,6 +110,10 @@ target.locale = function() {
|
||||
cp(path + '/viewer.properties', EXTENSION_LOCALE_OUTPUT + '/' + locale);
|
||||
}
|
||||
|
||||
if (test('-f', path + '/chrome.properties')) {
|
||||
cp(path + '/chrome.properties', EXTENSION_LOCALE_OUTPUT + '/' + locale);
|
||||
}
|
||||
|
||||
if (test('-f', path + '/metadata.inc')) {
|
||||
var metadata = cat(path + '/metadata.inc');
|
||||
metadataContent += metadata;
|
||||
@ -348,6 +356,9 @@ target.firefox = function() {
|
||||
sed('-i', /PDFJSSCRIPT_VERSION/, EXTENSION_VERSION, FIREFOX_BUILD_DIR + '/install.rdf');
|
||||
sed('-i', /PDFJSSCRIPT_VERSION/, EXTENSION_VERSION, FIREFOX_BUILD_DIR + '/update.rdf');
|
||||
|
||||
sed('-i', /PDFJSSCRIPT_STREAM_CONVERTER_ID/, FIREFOX_STREAM_CONVERTER_ID, FIREFOX_BUILD_DIR + 'components/PdfStreamConverter.js');
|
||||
sed('-i', /PDFJSSCRIPT_PREF_PREFIX/, FIREFOX_PREF_PREFIX, FIREFOX_BUILD_DIR + 'components/PdfStreamConverter.js');
|
||||
|
||||
// Update localized metadata
|
||||
var localizedMetadata = cat(EXTENSION_SRC_DIR + '/firefox/metadata.inc');
|
||||
sed('-i', /.*PDFJS_LOCALIZED_METADATA.*\n/, localizedMetadata, FIREFOX_BUILD_DIR + '/install.rdf');
|
||||
@ -377,26 +388,24 @@ target.mozcentral = function() {
|
||||
echo('### Building mozilla-central extension');
|
||||
|
||||
var MOZCENTRAL_DIR = BUILD_DIR + 'mozcentral/',
|
||||
MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/app/profile/extensions/uriloader@pdf.js/',
|
||||
MOZCENTRAL_EXTENSION_DIR = MOZCENTRAL_DIR + 'browser/extensions/pdfjs/',
|
||||
MOZCENTRAL_CONTENT_DIR = MOZCENTRAL_EXTENSION_DIR + 'content/',
|
||||
MOZCENTRAL_L10N_DIR = MOZCENTRAL_DIR + 'browser/locales/en-US/pdfviewer/',
|
||||
MOZCENTRAL_TEST_DIR = MOZCENTRAL_EXTENSION_DIR + 'test/',
|
||||
FIREFOX_CONTENT_DIR = EXTENSION_SRC_DIR + '/firefox/content/',
|
||||
FIREFOX_EXTENSION_FILES_TO_COPY =
|
||||
['*.js',
|
||||
['components/*.js',
|
||||
'*.svg',
|
||||
'*.png',
|
||||
'*.manifest',
|
||||
'install.rdf.in',
|
||||
'README.mozilla',
|
||||
'components',
|
||||
'../../LICENSE'],
|
||||
DEFAULT_LOCALE_FILES =
|
||||
[LOCALE_SRC_DIR + 'en-US/viewer.properties'],
|
||||
[LOCALE_SRC_DIR + 'en-US/viewer.properties',
|
||||
LOCALE_SRC_DIR + 'en-US/chrome.properties'],
|
||||
FIREFOX_MC_EXTENSION_FILES =
|
||||
['bootstrap.js',
|
||||
'icon.png',
|
||||
'icon64.png',
|
||||
'chrome.manifest',
|
||||
['chrome.manifest',
|
||||
'components',
|
||||
'content',
|
||||
'LICENSE'];
|
||||
@ -415,6 +424,8 @@ target.mozcentral = function() {
|
||||
// Copy extension files
|
||||
cd('extensions/firefox');
|
||||
cp('-R', FIREFOX_EXTENSION_FILES_TO_COPY, ROOT_DIR + MOZCENTRAL_EXTENSION_DIR);
|
||||
mv('-f', ROOT_DIR + MOZCENTRAL_EXTENSION_DIR + '/chrome-mozcentral.manifest',
|
||||
ROOT_DIR + MOZCENTRAL_EXTENSION_DIR + '/chrome.manifest')
|
||||
cd(ROOT_DIR);
|
||||
|
||||
// Copy a standalone version of pdf.js inside the content directory
|
||||
@ -446,9 +457,11 @@ target.mozcentral = function() {
|
||||
cp(DEFAULT_LOCALE_FILES, MOZCENTRAL_L10N_DIR);
|
||||
|
||||
// Update the build version number
|
||||
sed('-i', /PDFJSSCRIPT_VERSION/, EXTENSION_VERSION, MOZCENTRAL_EXTENSION_DIR + 'install.rdf.in');
|
||||
sed('-i', /PDFJSSCRIPT_VERSION/, EXTENSION_VERSION, MOZCENTRAL_EXTENSION_DIR + 'README.mozilla');
|
||||
|
||||
sed('-i', /PDFJSSCRIPT_STREAM_CONVERTER_ID/, MOZCENTRAL_STREAM_CONVERTER_ID, MOZCENTRAL_EXTENSION_DIR + 'components/PdfStreamConverter.js');
|
||||
sed('-i', /PDFJSSCRIPT_PREF_PREFIX/, MOZCENTRAL_PREF_PREFIX, MOZCENTRAL_EXTENSION_DIR + 'components/PdfStreamConverter.js');
|
||||
|
||||
// List all files for mozilla-central
|
||||
cd(MOZCENTRAL_EXTENSION_DIR);
|
||||
var extensionFiles = '';
|
||||
@ -457,6 +470,11 @@ target.mozcentral = function() {
|
||||
extensionFiles += file+'\n';
|
||||
});
|
||||
extensionFiles.to('extension-files');
|
||||
cd(ROOT_DIR);
|
||||
|
||||
// Copy test files
|
||||
mkdir('-p', MOZCENTRAL_TEST_DIR);
|
||||
cp('-Rf', 'test/mozcentral/*', MOZCENTRAL_TEST_DIR);
|
||||
};
|
||||
|
||||
//
|
||||
@ -490,6 +508,9 @@ target.chrome = function() {
|
||||
// Copy a standalone version of pdf.js inside the content directory
|
||||
cp(BUILD_TARGET, CHROME_BUILD_CONTENT_DIR + BUILD_DIR);
|
||||
cp('-R', EXTENSION_WEB_FILES, CHROME_BUILD_CONTENT_DIR + '/web');
|
||||
// Replacing the l10n.js file with regular gh-pages one
|
||||
rm(CHROME_BUILD_CONTENT_DIR + '/web/l10n.js');
|
||||
cp('external/webL10n/l10n.js', CHROME_BUILD_CONTENT_DIR + '/web');
|
||||
cp('web/locale.properties', CHROME_BUILD_CONTENT_DIR + '/web');
|
||||
mv('-f', CHROME_BUILD_CONTENT_DIR + '/web/viewer-production.html',
|
||||
CHROME_BUILD_CONTENT_DIR + '/web/viewer.html');
|
||||
|
65
src/api.js
65
src/api.js
@ -7,20 +7,46 @@
|
||||
* is used, which means it must follow the same origin rules that any XHR does
|
||||
* e.g. No cross domain requests without CORS.
|
||||
*
|
||||
* @param {string|TypedAray} source Either a url to a PDF is located or a
|
||||
* typed array (Uint8Array) already populated with data.
|
||||
* @param {Object} headers An object containing the http headers like this:
|
||||
* { Authorization: "BASIC XXX" }.
|
||||
* @param {string|TypedAray|object} source Can be an url to where a PDF is
|
||||
* located, a typed array (Uint8Array) already populated with data or
|
||||
* and parameter object with the following possible fields:
|
||||
* - url - The URL of the PDF.
|
||||
* - data - A typed array with PDF data.
|
||||
* - httpHeaders - Basic authentication headers.
|
||||
* - password - For decrypting password-protected PDFs.
|
||||
*
|
||||
* @return {Promise} A promise that is resolved with {PDFDocumentProxy} object.
|
||||
*/
|
||||
PDFJS.getDocument = function getDocument(source, headers) {
|
||||
PDFJS.getDocument = function getDocument(source) {
|
||||
var url, data, headers, password, parameters = {};
|
||||
if (typeof source === 'string') {
|
||||
url = source;
|
||||
} else if (isArrayBuffer(source)) {
|
||||
data = source;
|
||||
} else if (typeof source === 'object') {
|
||||
url = source.url;
|
||||
data = source.data;
|
||||
headers = source.httpHeaders;
|
||||
password = source.password;
|
||||
parameters.password = password || null;
|
||||
|
||||
if (!url && !data)
|
||||
error('Invalid parameter array, need either .data or .url');
|
||||
} else {
|
||||
error('Invalid parameter in getDocument, need either Uint8Array, ' +
|
||||
'string or a parameter object');
|
||||
}
|
||||
|
||||
var promise = new PDFJS.Promise();
|
||||
var transport = new WorkerTransport(promise);
|
||||
if (typeof source === 'string') {
|
||||
if (data) {
|
||||
// assuming the data is array, instantiating directly from it
|
||||
transport.sendData(data, parameters);
|
||||
} else if (url) {
|
||||
// fetch url
|
||||
PDFJS.getPdf(
|
||||
{
|
||||
url: source,
|
||||
url: url,
|
||||
progress: function getPDFProgress(evt) {
|
||||
if (evt.lengthComputable)
|
||||
promise.progress({
|
||||
@ -35,12 +61,10 @@ PDFJS.getDocument = function getDocument(source, headers) {
|
||||
headers: headers
|
||||
},
|
||||
function getPDFLoad(data) {
|
||||
transport.sendData(data);
|
||||
transport.sendData(data, parameters);
|
||||
});
|
||||
} else {
|
||||
// assuming the source is array, instantiating directly from it
|
||||
transport.sendData(source);
|
||||
}
|
||||
|
||||
return promise;
|
||||
};
|
||||
|
||||
@ -122,6 +146,11 @@ var PDFDocumentProxy = (function PDFDocumentProxyClosure() {
|
||||
});
|
||||
return promise;
|
||||
},
|
||||
isEncrypted: function PDFDocumentProxy_isEncrypted() {
|
||||
var promise = new PDFJS.Promise();
|
||||
promise.resolve(this.pdfInfo.encrypted);
|
||||
return promise;
|
||||
},
|
||||
destroy: function PDFDocumentProxy_destroy() {
|
||||
this.transport.destroy();
|
||||
}
|
||||
@ -429,7 +458,7 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
messageHandler.send('test', testObj);
|
||||
return;
|
||||
} catch (e) {
|
||||
warn('The worker has been disabled.');
|
||||
info('The worker has been disabled.');
|
||||
}
|
||||
}
|
||||
// Either workers are disabled, not supported or have thrown an exception.
|
||||
@ -473,6 +502,14 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
this.workerReadyPromise.resolve(pdfDocument);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('NeedPassword', function transportPassword(data) {
|
||||
this.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('IncorrectPassword', function transportBadPass(data) {
|
||||
this.workerReadyPromise.reject(data.exception.message, data.exception);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('GetPage', function transportPage(data) {
|
||||
var pageInfo = data.pageInfo;
|
||||
var page = new PDFPageProxy(pageInfo, this);
|
||||
@ -575,8 +612,8 @@ var WorkerTransport = (function WorkerTransportClosure() {
|
||||
});
|
||||
},
|
||||
|
||||
sendData: function WorkerTransport_sendData(data) {
|
||||
this.messageHandler.send('GetDocRequest', data);
|
||||
sendData: function WorkerTransport_sendData(data, params) {
|
||||
this.messageHandler.send('GetDocRequest', {data: data, params: params});
|
||||
},
|
||||
|
||||
getPage: function WorkerTransport_getPage(pageNumber, promise) {
|
||||
|
@ -343,10 +343,13 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.ctx.webkitLineDashOffset = dashPhase;
|
||||
},
|
||||
setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) {
|
||||
TODO('set rendering intent: ' + intent);
|
||||
// Maybe if we one day fully support color spaces this will be important
|
||||
// for now we can ignore.
|
||||
// TODO set rendering intent?
|
||||
},
|
||||
setFlatness: function CanvasGraphics_setFlatness(flatness) {
|
||||
TODO('set flatness: ' + flatness);
|
||||
// There's no way to control this with canvas, but we can safely ignore.
|
||||
// TODO set flatness?
|
||||
},
|
||||
setGState: function CanvasGraphics_setGState(states) {
|
||||
for (var i = 0, ii = states.length; i < ii; i++) {
|
||||
@ -841,7 +844,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
text.length += shownText.length;
|
||||
}
|
||||
} else {
|
||||
malformed('TJ array element ' + e + ' is not string or num');
|
||||
error('TJ array element ' + e + ' is not string or num');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,12 +451,12 @@ var LabCS = (function LabCSClosure() {
|
||||
error('Invalid WhitePoint components, no fallback available');
|
||||
|
||||
if (this.XB < 0 || this.YB < 0 || this.ZB < 0) {
|
||||
warn('Invalid BlackPoint, falling back to default');
|
||||
info('Invalid BlackPoint, falling back to default');
|
||||
this.XB = this.YB = this.ZB = 0;
|
||||
}
|
||||
|
||||
if (this.amin > this.amax || this.bmin > this.bmax) {
|
||||
warn('Invalid Range, falling back to defaults');
|
||||
info('Invalid Range, falling back to defaults');
|
||||
this.amin = -100;
|
||||
this.amax = 100;
|
||||
this.bmin = -100;
|
||||
|
17
src/core.js
17
src/core.js
@ -7,7 +7,7 @@ var globalScope = (typeof window === 'undefined') ? this : window;
|
||||
|
||||
var isWorker = (typeof window == 'undefined');
|
||||
|
||||
var ERRORS = 0, WARNINGS = 1, TODOS = 5;
|
||||
var ERRORS = 0, WARNINGS = 1, INFOS = 5;
|
||||
var verbosity = WARNINGS;
|
||||
|
||||
// The global PDFJS object exposes the API
|
||||
@ -362,19 +362,19 @@ var Page = (function PageClosure() {
|
||||
* `PDFDocument` objects on the main thread created.
|
||||
*/
|
||||
var PDFDocument = (function PDFDocumentClosure() {
|
||||
function PDFDocument(arg, callback) {
|
||||
function PDFDocument(arg, password) {
|
||||
if (isStream(arg))
|
||||
init.call(this, arg);
|
||||
init.call(this, arg, password);
|
||||
else if (isArrayBuffer(arg))
|
||||
init.call(this, new Stream(arg));
|
||||
init.call(this, new Stream(arg), password);
|
||||
else
|
||||
error('PDFDocument: Unknown argument type');
|
||||
}
|
||||
|
||||
function init(stream) {
|
||||
function init(stream, password) {
|
||||
assertWellFormed(stream.length > 0, 'stream must have data');
|
||||
this.stream = stream;
|
||||
this.setup();
|
||||
this.setup(password);
|
||||
this.acroForm = this.catalog.catDict.get('AcroForm');
|
||||
}
|
||||
|
||||
@ -465,11 +465,12 @@ var PDFDocument = (function PDFDocumentClosure() {
|
||||
}
|
||||
// May not be a PDF file, continue anyway.
|
||||
},
|
||||
setup: function PDFDocument_setup(ownerPassword, userPassword) {
|
||||
setup: function PDFDocument_setup(password) {
|
||||
this.checkHeader();
|
||||
var xref = new XRef(this.stream,
|
||||
this.startXRef,
|
||||
this.mainXRefEntriesOffset);
|
||||
this.mainXRefEntriesOffset,
|
||||
password);
|
||||
this.xref = xref;
|
||||
this.catalog = new Catalog(xref);
|
||||
},
|
||||
|
@ -556,7 +556,9 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
var encryptionKey = prepareKeyData(fileIdBytes, passwordBytes,
|
||||
ownerPassword, userPassword, flags,
|
||||
revision, keyLength, encryptMetadata);
|
||||
if (!encryptionKey && password) {
|
||||
if (!encryptionKey && !password) {
|
||||
throw new PasswordException('No password given', 'needpassword');
|
||||
} else if (!encryptionKey && password) {
|
||||
// Attempting use the password as an owner password
|
||||
var decodedPassword = decodeUserPassword(passwordBytes, ownerPassword,
|
||||
revision, keyLength);
|
||||
@ -566,7 +568,7 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
||||
}
|
||||
|
||||
if (!encryptionKey)
|
||||
error('incorrect password or encryption data');
|
||||
throw new PasswordException('Incorrect Password', 'incorrectpassword');
|
||||
|
||||
this.encryptionKey = encryptionKey;
|
||||
|
||||
|
@ -108,39 +108,21 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
|
||||
// Compatibility
|
||||
BX: 'beginCompat',
|
||||
EX: 'endCompat'
|
||||
EX: 'endCompat',
|
||||
|
||||
// (reserved partial commands for the lexer)
|
||||
BM: null,
|
||||
BD: null,
|
||||
'true': null,
|
||||
fa: null,
|
||||
fal: null,
|
||||
fals: null,
|
||||
'false': null,
|
||||
nu: null,
|
||||
nul: null,
|
||||
'null': null
|
||||
};
|
||||
|
||||
function splitCombinedOperations(operations) {
|
||||
// Two or more operations can be combined together, trying to find which
|
||||
// operations were concatenated.
|
||||
var result = [];
|
||||
var opIndex = 0;
|
||||
|
||||
if (!operations) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (opIndex < operations.length) {
|
||||
var currentOp = '';
|
||||
for (var op in OP_MAP) {
|
||||
if (op == operations.substr(opIndex, op.length) &&
|
||||
op.length > currentOp.length) {
|
||||
currentOp = op;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentOp.length > 0) {
|
||||
result.push(operations.substr(opIndex, currentOp.length));
|
||||
opIndex += currentOp.length;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PartialEvaluator.prototype = {
|
||||
getOperatorList: function PartialEvaluator_getOperatorList(stream,
|
||||
resources,
|
||||
@ -285,39 +267,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
resources = resources || new Dict();
|
||||
var xobjs = resources.get('XObject') || new Dict();
|
||||
var patterns = resources.get('Pattern') || new Dict();
|
||||
var parser = new Parser(new Lexer(stream), false, xref);
|
||||
var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
|
||||
var res = resources;
|
||||
var hasNextObj = false, nextObjs;
|
||||
var args = [], obj;
|
||||
var TILING_PATTERN = 1, SHADING_PATTERN = 2;
|
||||
|
||||
while (true) {
|
||||
if (hasNextObj) {
|
||||
obj = nextObjs.pop();
|
||||
hasNextObj = (nextObjs.length > 0);
|
||||
} else {
|
||||
obj = parser.getObj();
|
||||
if (isEOF(obj))
|
||||
break;
|
||||
}
|
||||
obj = parser.getObj();
|
||||
if (isEOF(obj))
|
||||
break;
|
||||
|
||||
if (isCmd(obj)) {
|
||||
var cmd = obj.cmd;
|
||||
var fn = OP_MAP[cmd];
|
||||
if (!fn) {
|
||||
// invalid content command, trying to recover
|
||||
var cmds = splitCombinedOperations(cmd);
|
||||
if (cmds) {
|
||||
cmd = cmds[0];
|
||||
fn = OP_MAP[cmd];
|
||||
// feeding other command on the next iteration
|
||||
hasNextObj = true;
|
||||
nextObjs = [];
|
||||
for (var idx = 1; idx < cmds.length; idx++) {
|
||||
nextObjs.push(Cmd.get(cmds[idx]));
|
||||
}
|
||||
}
|
||||
}
|
||||
assertWellFormed(fn, 'Unknown command "' + cmd + '"');
|
||||
// TODO figure out how to type-check vararg functions
|
||||
|
||||
@ -457,6 +419,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
value[1]
|
||||
]);
|
||||
break;
|
||||
case 'BM':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'Normal')
|
||||
TODO('graphic state operator ' + key);
|
||||
break;
|
||||
case 'SMask':
|
||||
// We support the default so don't trigger the TODO.
|
||||
if (!isName(value) || value.name != 'None')
|
||||
TODO('graphic state operator ' + key);
|
||||
break;
|
||||
// Only generate info log messages for the following since
|
||||
// they are unlikey to have a big impact on the rendering.
|
||||
case 'OP':
|
||||
case 'op':
|
||||
case 'OPM':
|
||||
@ -469,14 +443,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
case 'HT':
|
||||
case 'SM':
|
||||
case 'SA':
|
||||
case 'BM':
|
||||
case 'SMask':
|
||||
case 'AIS':
|
||||
case 'TK':
|
||||
TODO('graphic state operator ' + key);
|
||||
// TODO implement these operators.
|
||||
info('graphic state operator ' + key);
|
||||
break;
|
||||
default:
|
||||
warn('Unknown graphic state operator ' + key);
|
||||
info('Unknown graphic state operator ' + key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -725,8 +698,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
||||
}
|
||||
} else if (octet == 0x3E) {
|
||||
if (token.length) {
|
||||
// XXX guessing chars size by checking number size in the CMap
|
||||
if (token.length <= 2 && properties.composite)
|
||||
// Heuristic: guessing chars size by checking numbers sizes
|
||||
// in the CMap entries.
|
||||
if (token.length == 2 && properties.composite)
|
||||
properties.wideChars = false;
|
||||
|
||||
if (token.length <= 4) {
|
||||
|
31
src/fonts.js
31
src/fonts.js
@ -2706,9 +2706,9 @@ var Font = (function FontClosure() {
|
||||
this.isSymbolicFont = false;
|
||||
}
|
||||
|
||||
// heuristics: if removed more than 2 glyphs encoding WinAnsiEncoding
|
||||
// does not set properly
|
||||
if (glyphsRemoved > 2) {
|
||||
// heuristics: if removed more than 10 glyphs encoding WinAnsiEncoding
|
||||
// does not set properly (broken PDFs have about 100 removed glyphs)
|
||||
if (glyphsRemoved > 10) {
|
||||
warn('Switching TrueType encoding to MacRomanEncoding for ' +
|
||||
this.name + ' font');
|
||||
encoding = Encodings.MacRomanEncoding;
|
||||
@ -4208,7 +4208,7 @@ var CFFFont = (function CFFFontClosure() {
|
||||
this.properties = properties;
|
||||
|
||||
var parser = new CFFParser(file, properties);
|
||||
var cff = parser.parse();
|
||||
var cff = parser.parse(true);
|
||||
var compiler = new CFFCompiler(cff);
|
||||
this.readExtra(cff);
|
||||
try {
|
||||
@ -4299,7 +4299,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
this.properties = properties;
|
||||
}
|
||||
CFFParser.prototype = {
|
||||
parse: function CFFParser_parse() {
|
||||
parse: function CFFParser_parse(normalizeCIDData) {
|
||||
var properties = this.properties;
|
||||
var cff = new CFF();
|
||||
this.cff = cff;
|
||||
@ -4354,6 +4354,21 @@ var CFFParser = (function CFFParserClosure() {
|
||||
cff.charset = charset;
|
||||
cff.encoding = encoding;
|
||||
|
||||
if (!cff.isCIDFont || !normalizeCIDData)
|
||||
return cff;
|
||||
|
||||
// DirectWrite does not like CID fonts data. Trying to convert/flatten
|
||||
// the font data and remove CID properties.
|
||||
if (cff.fdArray.length !== 1)
|
||||
error('Unable to normalize CID font in CFF data');
|
||||
|
||||
var fontDict = cff.fdArray[0];
|
||||
fontDict.setByKey(17, topDict.getByName('CharStrings'));
|
||||
cff.topDict = fontDict;
|
||||
cff.isCIDFont = false;
|
||||
delete cff.fdArray;
|
||||
delete cff.fdSelect;
|
||||
|
||||
return cff;
|
||||
},
|
||||
parseHeader: function CFFParser_parseHeader() {
|
||||
@ -4364,7 +4379,7 @@ var CFFParser = (function CFFParserClosure() {
|
||||
++offset;
|
||||
|
||||
if (offset != 0) {
|
||||
warn('cff data is shifted');
|
||||
info('cff data is shifted');
|
||||
bytes = bytes.subarray(offset);
|
||||
this.bytes = bytes;
|
||||
}
|
||||
@ -4952,9 +4967,9 @@ var CFFPrivateDict = (function CFFPrivateDictClosure() {
|
||||
[[12, 17], 'LanguageGroup', 'num', 0],
|
||||
[[12, 18], 'ExpansionFactor', 'num', 0.06],
|
||||
[[12, 19], 'initialRandomSeed', 'num', 0],
|
||||
[19, 'Subrs', 'offset', null],
|
||||
[20, 'defaultWidthX', 'num', 0],
|
||||
[21, 'nominalWidthX', 'num', 0]
|
||||
[21, 'nominalWidthX', 'num', 0],
|
||||
[19, 'Subrs', 'offset', null]
|
||||
];
|
||||
var tables = null;
|
||||
function CFFPrivateDict(strings) {
|
||||
|
@ -298,7 +298,7 @@ var Catalog = (function CatalogClosure() {
|
||||
})();
|
||||
|
||||
var XRef = (function XRefClosure() {
|
||||
function XRef(stream, startXRef, mainXRefEntriesOffset) {
|
||||
function XRef(stream, startXRef, mainXRefEntriesOffset, password) {
|
||||
this.stream = stream;
|
||||
this.entries = [];
|
||||
this.xrefstms = {};
|
||||
@ -311,8 +311,7 @@ var XRef = (function XRefClosure() {
|
||||
var encrypt = trailerDict.get('Encrypt');
|
||||
if (encrypt) {
|
||||
var fileId = trailerDict.get('ID');
|
||||
this.encrypt = new CipherTransformFactory(encrypt,
|
||||
fileId[0] /*, password */);
|
||||
this.encrypt = new CipherTransformFactory(encrypt, fileId[0], password);
|
||||
}
|
||||
|
||||
// get the root dictionary (catalog) object
|
||||
|
@ -264,8 +264,16 @@ var Parser = (function ParserClosure() {
|
||||
})();
|
||||
|
||||
var Lexer = (function LexerClosure() {
|
||||
function Lexer(stream) {
|
||||
function Lexer(stream, knownCommands) {
|
||||
this.stream = stream;
|
||||
// The PDFs might have "glued" commands with other commands, operands or
|
||||
// literals, e.g. "q1". The knownCommands is a dictionary of the valid
|
||||
// commands and their prefixes. The prefixes are built the following way:
|
||||
// if there a command that is a prefix of the other valid command or
|
||||
// literal (e.g. 'f' and 'false') the following prefixes must be included,
|
||||
// 'fa', 'fal', 'fals'. The prefixes are not needed, if the command has no
|
||||
// other commands or literals as a prefix. The knowCommands is optional.
|
||||
this.knownCommands = knownCommands;
|
||||
}
|
||||
|
||||
Lexer.isSpace = function Lexer_isSpace(ch) {
|
||||
@ -529,12 +537,18 @@ var Lexer = (function LexerClosure() {
|
||||
|
||||
// command
|
||||
var str = ch;
|
||||
var knownCommands = this.knownCommands;
|
||||
var knownCommandFound = knownCommands && (str in knownCommands);
|
||||
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
|
||||
// stop if known command is found and next character does not make
|
||||
// the str a command
|
||||
if (knownCommandFound && !((str + ch) in knownCommands))
|
||||
break;
|
||||
stream.skip();
|
||||
if (str.length == 128)
|
||||
error('Command token too long: ' + str.length);
|
||||
|
||||
str += ch;
|
||||
knownCommandFound = knownCommands && (str in knownCommands);
|
||||
}
|
||||
if (str == 'true')
|
||||
return true;
|
||||
|
@ -1687,7 +1687,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
|
||||
if (a1 > codingLine[codingPos]) {
|
||||
if (a1 > this.columns) {
|
||||
warn('row is wrong length');
|
||||
info('row is wrong length');
|
||||
this.err = true;
|
||||
a1 = this.columns;
|
||||
}
|
||||
@ -1707,7 +1707,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
|
||||
if (a1 > codingLine[codingPos]) {
|
||||
if (a1 > this.columns) {
|
||||
warn('row is wrong length');
|
||||
info('row is wrong length');
|
||||
this.err = true;
|
||||
a1 = this.columns;
|
||||
}
|
||||
@ -1717,7 +1717,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
codingLine[codingPos] = a1;
|
||||
} else if (a1 < codingLine[codingPos]) {
|
||||
if (a1 < 0) {
|
||||
warn('invalid code');
|
||||
info('invalid code');
|
||||
this.err = true;
|
||||
a1 = 0;
|
||||
}
|
||||
@ -1879,7 +1879,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
this.eof = true;
|
||||
break;
|
||||
default:
|
||||
warn('bad 2d code');
|
||||
info('bad 2d code');
|
||||
this.addPixels(columns, 0);
|
||||
this.err = true;
|
||||
}
|
||||
@ -1942,7 +1942,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
code1 = this.lookBits(12);
|
||||
if (code1 != 1)
|
||||
warn('bad rtc code: ' + code1);
|
||||
info('bad rtc code: ' + code1);
|
||||
this.eatBits(12);
|
||||
if (this.encoding > 0) {
|
||||
this.lookBits(1);
|
||||
@ -2065,7 +2065,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
if (result[0] && result[2])
|
||||
return result[1];
|
||||
}
|
||||
warn('Bad two dim code');
|
||||
info('Bad two dim code');
|
||||
return EOF;
|
||||
};
|
||||
|
||||
@ -2098,7 +2098,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
if (result[0])
|
||||
return result[1];
|
||||
}
|
||||
warn('bad white code');
|
||||
info('bad white code');
|
||||
this.eatBits(1);
|
||||
return 1;
|
||||
};
|
||||
@ -2135,7 +2135,7 @@ var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||
if (result[0])
|
||||
return result[1];
|
||||
}
|
||||
warn('bad black code');
|
||||
info('bad black code');
|
||||
this.eatBits(1);
|
||||
return 1;
|
||||
};
|
||||
|
83
src/util.js
83
src/util.js
@ -3,6 +3,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
// Use only for debugging purposes. This should not be used in any code that is
|
||||
// in mozilla master.
|
||||
function log(msg) {
|
||||
if (console && console.log)
|
||||
console.log(msg);
|
||||
@ -10,9 +12,36 @@ function log(msg) {
|
||||
print(msg);
|
||||
}
|
||||
|
||||
// A notice for devs that will not trigger the fallback UI. These are good
|
||||
// for things that are helpful to devs, such as warning that Workers were
|
||||
// disabled, which is important to devs but not end users.
|
||||
function info(msg) {
|
||||
if (verbosity >= INFOS) {
|
||||
log('Info: ' + msg);
|
||||
PDFJS.LogManager.notify('info', msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Non-fatal warnings that should trigger the fallback UI.
|
||||
function warn(msg) {
|
||||
if (verbosity >= WARNINGS)
|
||||
if (verbosity >= WARNINGS) {
|
||||
log('Warning: ' + msg);
|
||||
PDFJS.LogManager.notify('warn', msg);
|
||||
}
|
||||
}
|
||||
|
||||
// Fatal errors that should trigger the fallback UI and halt execution by
|
||||
// throwing an exception.
|
||||
function error(msg) {
|
||||
log('Error: ' + msg);
|
||||
log(backtrace());
|
||||
PDFJS.LogManager.notify('error', msg);
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
// Missing features that should trigger the fallback UI.
|
||||
function TODO(what) {
|
||||
warn('TODO: ' + what);
|
||||
}
|
||||
|
||||
function backtrace() {
|
||||
@ -23,21 +52,6 @@ function backtrace() {
|
||||
}
|
||||
}
|
||||
|
||||
function error(msg) {
|
||||
log('Error: ' + msg);
|
||||
log(backtrace());
|
||||
throw new Error(msg);
|
||||
}
|
||||
|
||||
function TODO(what) {
|
||||
if (verbosity >= TODOS)
|
||||
log('TODO: ' + what);
|
||||
}
|
||||
|
||||
function malformed(msg) {
|
||||
error('Malformed PDF: ' + msg);
|
||||
}
|
||||
|
||||
function assert(cond, msg) {
|
||||
if (!cond)
|
||||
error(msg);
|
||||
@ -47,9 +61,25 @@ function assert(cond, msg) {
|
||||
// behavior is undefined.
|
||||
function assertWellFormed(cond, msg) {
|
||||
if (!cond)
|
||||
malformed(msg);
|
||||
error(msg);
|
||||
}
|
||||
|
||||
var LogManager = PDFJS.LogManager = (function LogManagerClosure() {
|
||||
var loggers = [];
|
||||
return {
|
||||
addLogger: function logManager_addLogger(logger) {
|
||||
loggers.push(logger);
|
||||
},
|
||||
notify: function(type, message) {
|
||||
for (var i = 0, ii = loggers.length; i < ii; i++) {
|
||||
var logger = loggers[i];
|
||||
if (logger[type])
|
||||
logger[type](message);
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
function shadow(obj, prop, value) {
|
||||
Object.defineProperty(obj, prop, { value: value,
|
||||
enumerable: true,
|
||||
@ -58,6 +88,19 @@ function shadow(obj, prop, value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
var PasswordException = (function PasswordExceptionClosure() {
|
||||
function PasswordException(msg, code) {
|
||||
this.name = 'PasswordException';
|
||||
this.message = msg;
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
PasswordException.prototype = new Error();
|
||||
PasswordException.constructor = PasswordException;
|
||||
|
||||
return PasswordException;
|
||||
})();
|
||||
|
||||
function bytesToString(bytes) {
|
||||
var str = '';
|
||||
var length = bytes.length;
|
||||
@ -456,7 +499,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
|
||||
}
|
||||
|
||||
this.isResolved = true;
|
||||
this.data = data || null;
|
||||
this.data = (typeof data !== 'undefined') ? data : null;
|
||||
var callbacks = this.callbacks;
|
||||
|
||||
for (var i = 0, ii = callbacks.length; i < ii; i++) {
|
||||
@ -471,7 +514,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
|
||||
}
|
||||
},
|
||||
|
||||
reject: function Promise_reject(reason) {
|
||||
reject: function Promise_reject(reason, exception) {
|
||||
if (this.isRejected) {
|
||||
error('A Promise can be rejected only once ' + this.name);
|
||||
}
|
||||
@ -484,7 +527,7 @@ var Promise = PDFJS.Promise = (function PromiseClosure() {
|
||||
var errbacks = this.errbacks;
|
||||
|
||||
for (var i = 0, ii = errbacks.length; i < ii; i++) {
|
||||
errbacks[i].call(null, reason);
|
||||
errbacks[i].call(null, reason, exception);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -11,10 +11,13 @@ function MessageHandler(name, comObj) {
|
||||
var ah = this.actionHandler = {};
|
||||
|
||||
ah['console_log'] = [function ahConsoleLog(data) {
|
||||
console.log.apply(console, data);
|
||||
console.log.apply(console, data);
|
||||
}];
|
||||
ah['console_error'] = [function ahConsoleError(data) {
|
||||
console.error.apply(console, data);
|
||||
console.error.apply(console, data);
|
||||
}];
|
||||
ah['_warn'] = [function ah_Warn(data) {
|
||||
warn(data);
|
||||
}];
|
||||
|
||||
comObj.onmessage = function messageHandlerComObjOnMessage(event) {
|
||||
@ -88,14 +91,35 @@ var WorkerMessageHandler = {
|
||||
handler.on('GetDocRequest', function wphSetupDoc(data) {
|
||||
// Create only the model of the PDFDoc, which is enough for
|
||||
// processing the content of the pdf.
|
||||
pdfModel = new PDFDocument(new Stream(data));
|
||||
var pdfData = data.data;
|
||||
var pdfPassword = data.params.password;
|
||||
try {
|
||||
pdfModel = new PDFDocument(new Stream(pdfData), pdfPassword);
|
||||
} catch (e) {
|
||||
if (e instanceof PasswordException) {
|
||||
if (e.code === 'needpassword') {
|
||||
handler.send('NeedPassword', {
|
||||
exception: e
|
||||
});
|
||||
} else if (e.code === 'incorrectpassword') {
|
||||
handler.send('IncorrectPassword', {
|
||||
exception: e
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
var doc = {
|
||||
numPages: pdfModel.numPages,
|
||||
fingerprint: pdfModel.getFingerprint(),
|
||||
destinations: pdfModel.catalog.destinations,
|
||||
outline: pdfModel.catalog.documentOutline,
|
||||
info: pdfModel.getDocumentInfo(),
|
||||
metadata: pdfModel.catalog.metadata
|
||||
metadata: pdfModel.catalog.metadata,
|
||||
encrypted: !!pdfModel.xref.encrypt
|
||||
};
|
||||
handler.send('GetDoc', {pdfInfo: doc});
|
||||
});
|
||||
@ -240,6 +264,17 @@ var workerConsole = {
|
||||
if (typeof window === 'undefined') {
|
||||
globalScope.console = workerConsole;
|
||||
|
||||
// Add a logger so we can pass warnings on to the main thread, errors will
|
||||
// throw an exception which will be forwarded on automatically.
|
||||
PDFJS.LogManager.addLogger({
|
||||
warn: function(msg) {
|
||||
postMessage({
|
||||
action: '_warn',
|
||||
data: msg
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
var handler = new MessageHandler('worker_processor', this);
|
||||
WorkerMessageHandler.setup(handler);
|
||||
}
|
||||
|
21
test/mozcentral/Makefile.in
Normal file
21
test/mozcentral/Makefile.in
Normal file
@ -0,0 +1,21 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = browser/extensions/pdfjs/test
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_BROWSER_TEST_FILES = \
|
||||
head.js \
|
||||
browser_pdfjs_main.js \
|
||||
file_pdfjs_test.pdf \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
102
test/mozcentral/browser_pdfjs_main.js
Normal file
102
test/mozcentral/browser_pdfjs_main.js
Normal file
@ -0,0 +1,102 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
const RELATIVE_DIR = "browser/extensions/pdfjs/test/";
|
||||
const TESTROOT = "http://example.com/browser/" + RELATIVE_DIR;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var tab = gBrowser.addTab(TESTROOT + "file_pdfjs_test.pdf");
|
||||
var newTabBrowser = gBrowser.getBrowserForTab(tab);
|
||||
newTabBrowser.addEventListener("pagechange", function onPageChange() {
|
||||
newTabBrowser.removeEventListener("pagechange", onPageChange, true);
|
||||
|
||||
var document = newTabBrowser.contentDocument,
|
||||
window = newTabBrowser.contentWindow;
|
||||
|
||||
//
|
||||
// Overall sanity tests
|
||||
//
|
||||
ok(document.querySelector('div#viewer'), "document content has viewer UI");
|
||||
ok('PDFJS' in window.wrappedJSObject, "window content has PDFJS object");
|
||||
|
||||
//
|
||||
// Sidebar: open
|
||||
//
|
||||
var sidebar = document.querySelector('button#sidebarToggle'),
|
||||
outerContainer = document.querySelector('div#outerContainer');
|
||||
|
||||
sidebar.click();
|
||||
ok(outerContainer.classList.contains('sidebarOpen'), 'sidebar opens on click');
|
||||
|
||||
// Thumbnails are created asynchronously - wait for them
|
||||
waitForElement(document, 'canvas#thumbnail2', function(error) {
|
||||
if (error)
|
||||
finish();
|
||||
|
||||
//
|
||||
// Page change from thumbnail click
|
||||
//
|
||||
var pageNumber = document.querySelector('input#pageNumber');
|
||||
is(parseInt(pageNumber.value), 1, 'initial page is 1');
|
||||
|
||||
var thumbnail = document.querySelector('canvas#thumbnail2');
|
||||
ok(thumbnail, 'thumbnail2 is available');
|
||||
if (thumbnail) {
|
||||
thumbnail.click();
|
||||
is(parseInt(pageNumber.value), 2, 'clicking on thumbnail changes page');
|
||||
}
|
||||
|
||||
//
|
||||
// Sidebar: close
|
||||
//
|
||||
sidebar.click();
|
||||
ok(!outerContainer.classList.contains('sidebarOpen'), 'sidebar closes on click');
|
||||
|
||||
//
|
||||
// Page change from prev/next buttons
|
||||
//
|
||||
var prevPage = document.querySelector('button#previous'),
|
||||
nextPage = document.querySelector('button#next');
|
||||
|
||||
nextPage.click();
|
||||
is(parseInt(pageNumber.value), 2, 'page increases after clicking on next');
|
||||
|
||||
prevPage.click();
|
||||
is(parseInt(pageNumber.value), 1, 'page decreases after clicking on previous');
|
||||
|
||||
//
|
||||
// Bookmark button
|
||||
//
|
||||
var viewBookmark = document.querySelector('a#viewBookmark');
|
||||
viewBookmark.click();
|
||||
ok(viewBookmark.href.length > 0, 'viewBookmark button has href');
|
||||
|
||||
//
|
||||
// Zoom in/out
|
||||
//
|
||||
var zoomOut = document.querySelector('button.zoomOut'),
|
||||
zoomIn = document.querySelector('button.zoomIn');
|
||||
|
||||
// Zoom in
|
||||
var oldWidth = document.querySelector('canvas#page1').width;
|
||||
zoomIn.click();
|
||||
var newWidth = document.querySelector('canvas#page1').width;
|
||||
ok(oldWidth < newWidth, 'zooming in increases page width (old: '+oldWidth+', new: '+newWidth+')');
|
||||
|
||||
// Zoom out
|
||||
var oldWidth = document.querySelector('canvas#page1').width;
|
||||
zoomOut.click();
|
||||
var newWidth = document.querySelector('canvas#page1').width;
|
||||
ok(oldWidth > newWidth, 'zooming out decreases page width (old: '+oldWidth+', new: '+newWidth+')');
|
||||
|
||||
finish();
|
||||
});
|
||||
}, true, true);
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
}
|
BIN
test/mozcentral/file_pdfjs_test.pdf
Normal file
BIN
test/mozcentral/file_pdfjs_test.pdf
Normal file
Binary file not shown.
21
test/mozcentral/head.js
Normal file
21
test/mozcentral/head.js
Normal file
@ -0,0 +1,21 @@
|
||||
// Waits for element 'el' to exist in the DOM of 'doc' before executing 'callback'
|
||||
// Useful when elements are created asynchronously, e.g. after a Web Worker task
|
||||
function waitForElement(doc, el, callback) {
|
||||
var time = 0,
|
||||
interval = 10,
|
||||
timeout = 5000;
|
||||
|
||||
var checkEl = setInterval(function() {
|
||||
if (doc.querySelector(el)) {
|
||||
clearInterval(checkEl);
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
time += interval;
|
||||
if (time > timeout) {
|
||||
ok(false, 'waitForElement timed out on element: '+el);
|
||||
clearInterval(checkEl);
|
||||
if (callback) callback(true);
|
||||
}
|
||||
}, interval);
|
||||
}
|
1
test/pdfs/issue1629.pdf.link
Normal file
1
test/pdfs/issue1629.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://is.muni.cz/www/20544/noty/sbm/Taize/Adoramus_te_Christe.pdf
|
1
test/pdfs/issue1709.pdf.link
Normal file
1
test/pdfs/issue1709.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.mft-online.de/files/medizinerreport_2012.pdf
|
1
test/pdfs/issue1721.pdf.link
Normal file
1
test/pdfs/issue1721.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.lezarts.org/07oforhom/Faitsdivers/Hadopi/Le%20Rapport%20Hadopi,%20Intox.pdf
|
@ -402,6 +402,14 @@
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1709",
|
||||
"file": "pdfs/issue1709.pdf",
|
||||
"md5": "84497bd23b7c82d03d2681a1cb1d9ed0",
|
||||
"rounds": 1,
|
||||
"pageLimit": 10,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1015",
|
||||
"file": "pdfs/issue1015.pdf",
|
||||
"md5": "b61503d1b445742b665212866afb60e2",
|
||||
@ -451,6 +459,13 @@
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1629",
|
||||
"file": "pdfs/issue1629.pdf",
|
||||
"md5": "0f2cbbf268383a377e95e6bbe36c6a9a",
|
||||
"rounds": 1,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1169",
|
||||
"file": "pdfs/issue1169.pdf",
|
||||
"md5": "3df3ed21fd43ac7fdb21e2015c8a7809",
|
||||
@ -543,6 +558,14 @@
|
||||
"link": false,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1721",
|
||||
"file": "pdfs/issue1721.pdf",
|
||||
"md5": "b47177f9e5197a76ec498733ecab60e6",
|
||||
"rounds": 1,
|
||||
"pageLimit": 2,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1243",
|
||||
"file": "pdfs/issue1243.pdf",
|
||||
"md5": "130c849b83513d5ac5e03c6421fc7489",
|
||||
|
@ -78,6 +78,54 @@ describe('evaluator', function() {
|
||||
expect(result.fnArray[1]).toEqual('save');
|
||||
expect(result.fnArray[2]).toEqual('save');
|
||||
});
|
||||
|
||||
it('should handle three glued operations #2', function() {
|
||||
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||
'prefix');
|
||||
var resources = new ResourcesMock();
|
||||
resources.Res1 = {};
|
||||
var stream = new StringStream('B*BBMC');
|
||||
var result = evaluator.getOperatorList(stream, resources, []);
|
||||
|
||||
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||
expect(result.fnArray.length).toEqual(3);
|
||||
expect(result.fnArray[0]).toEqual('eoFillStroke');
|
||||
expect(result.fnArray[1]).toEqual('fillStroke');
|
||||
expect(result.fnArray[2]).toEqual('beginMarkedContent');
|
||||
});
|
||||
|
||||
it('should handle glued operations and operands', function() {
|
||||
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||
'prefix');
|
||||
var stream = new StringStream('q5 Ts');
|
||||
var result = evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
||||
|
||||
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||
expect(result.fnArray.length).toEqual(2);
|
||||
expect(result.fnArray[0]).toEqual('save');
|
||||
expect(result.fnArray[1]).toEqual('setTextRise');
|
||||
expect(result.argsArray.length).toEqual(2);
|
||||
expect(result.argsArray[1].length).toEqual(1);
|
||||
expect(result.argsArray[1][0]).toEqual(5);
|
||||
});
|
||||
|
||||
it('should handle glued operations and literals', function() {
|
||||
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||
'prefix');
|
||||
var stream = new StringStream('trueifalserinulli');
|
||||
var result = evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
||||
|
||||
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||
expect(result.fnArray.length).toEqual(3);
|
||||
expect(result.fnArray[0]).toEqual('setFlatness');
|
||||
expect(result.fnArray[1]).toEqual('setRenderingIntent');
|
||||
expect(result.fnArray[2]).toEqual('setFlatness');
|
||||
expect(result.argsArray.length).toEqual(3);
|
||||
expect(result.argsArray[0].length).toEqual(1);
|
||||
expect(result.argsArray[0][0]).toEqual(true);
|
||||
expect(result.argsArray[1].length).toEqual(1);
|
||||
expect(result.argsArray[1][0]).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -120,6 +120,9 @@
|
||||
return new Uint8Array(new VBArray(this.responseBody).toArray());
|
||||
}
|
||||
});
|
||||
Object.defineProperty(xhrPrototype, 'overrideMimeType', {
|
||||
value: function xmlHttpRequestOverrideMimeType(mimeType) {}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
@ -217,15 +220,84 @@
|
||||
var div = document.createElement('div');
|
||||
if ('dataset' in div)
|
||||
return; // dataset property exists
|
||||
var oldCreateElement = document.createElement;
|
||||
document.createElement = function newCreateElement() {
|
||||
var result = oldCreateElement.apply(document, arguments);
|
||||
if (arguments[0] === 'div') {
|
||||
// creating dataset property for the div elements
|
||||
result.dataset = {};
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'dataset', {
|
||||
get: function() {
|
||||
if (this._dataset)
|
||||
return this._dataset;
|
||||
|
||||
var dataset = {};
|
||||
for (var j = 0, jj = this.attributes.length; j < jj; j++) {
|
||||
var attribute = this.attributes[j];
|
||||
if (attribute.name.substring(0, 5) != 'data-')
|
||||
continue;
|
||||
var key = attribute.name.substring(5).replace(/\-([a-z])/g,
|
||||
function(all, ch) { return ch.toUpperCase(); });
|
||||
dataset[key] = attribute.value;
|
||||
}
|
||||
|
||||
Object.defineProperty(this, '_dataset', {
|
||||
value: dataset,
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
return dataset;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
})();
|
||||
|
||||
// HTMLElement classList property
|
||||
(function checkClassListProperty() {
|
||||
var div = document.createElement('div');
|
||||
if ('classList' in div)
|
||||
return; // classList property exists
|
||||
|
||||
function changeList(element, itemName, add, remove) {
|
||||
var s = element.className || '';
|
||||
var list = s.split(/\s+/g);
|
||||
if (list[0] == '') list.shift();
|
||||
var index = list.indexOf(itemName);
|
||||
if (index < 0 && add)
|
||||
list.push(itemName);
|
||||
if (index >= 0 && remove)
|
||||
list.splice(index, 1);
|
||||
element.className = list.join(' ');
|
||||
}
|
||||
|
||||
var classListPrototype = {
|
||||
add: function(name) {
|
||||
changeList(this.element, name, true, false);
|
||||
},
|
||||
remove: function(name) {
|
||||
changeList(this.element, name, false, true);
|
||||
},
|
||||
toggle: function(name) {
|
||||
changeList(this.element, name, true, true);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
Object.defineProperty(HTMLElement.prototype, 'classList', {
|
||||
get: function() {
|
||||
if (this._classList)
|
||||
return this._classList;
|
||||
|
||||
var classList = Object.create(classListPrototype, {
|
||||
element: {
|
||||
value: this,
|
||||
writable: false,
|
||||
enumerable: true
|
||||
}
|
||||
});
|
||||
Object.defineProperty(this, '_classList', {
|
||||
value: classList,
|
||||
writable: false,
|
||||
enumerable: false
|
||||
});
|
||||
return classList;
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
})();
|
||||
|
||||
// Check console compatability
|
||||
@ -252,3 +324,17 @@
|
||||
document.addEventListener('click', ignoreIfTargetDisabled, true);
|
||||
}
|
||||
})();
|
||||
|
||||
// Checks if navigator.language is supported
|
||||
(function checkNavigatorLanguage() {
|
||||
if ('language' in navigator)
|
||||
return;
|
||||
Object.defineProperty(navigator, 'language', {
|
||||
get: function navigatorLanguage() {
|
||||
var language = navigator.userLanguage || 'en-US';
|
||||
return language.substring(0, 2).toLowerCase() +
|
||||
language.substring(2).toUpperCase();
|
||||
},
|
||||
enumerable: true
|
||||
});
|
||||
})();
|
||||
|
BIN
web/images/toolbarButton-openFile.png
Normal file
BIN
web/images/toolbarButton-openFile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 708 B |
@ -428,6 +428,10 @@ html[dir='rtl'] .dropdownToolbarButton {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.dropdownToolbarButton > select > option {
|
||||
background: hsl(0,0%,24%);
|
||||
}
|
||||
|
||||
#customScaleOption {
|
||||
display: none;
|
||||
}
|
||||
@ -501,6 +505,11 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
|
||||
content: url(images/toolbarButton-print.png);
|
||||
}
|
||||
|
||||
.toolbarButton.openFile::before {
|
||||
display: inline-block;
|
||||
content: url(images/toolbarButton-openFile.png);
|
||||
}
|
||||
|
||||
.toolbarButton.download::before {
|
||||
display: inline-block;
|
||||
content: url(images/toolbarButton-download.png);
|
||||
@ -985,3 +994,76 @@ canvas {
|
||||
#PDFBug table {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
@media print {
|
||||
#sidebarContainer, .toolbar, #loadingBox, #errorWrapper, .textLayer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mainContainer, #viewerContainer, .page, .page canvas {
|
||||
position: static;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.page {
|
||||
float: left;
|
||||
display: none;
|
||||
box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
}
|
||||
|
||||
.page[data-loaded] {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 950px) {
|
||||
html[dir='ltr'] #outerContainer.sidebarMoving .outerCenter,
|
||||
html[dir='ltr'] #outerContainer.sidebarOpen .outerCenter {
|
||||
float: left;
|
||||
left: 180px;
|
||||
}
|
||||
html[dir='rtl'] #outerContainer.sidebarMoving .outerCenter,
|
||||
html[dir='rtl'] #outerContainer.sidebarOpen .outerCenter {
|
||||
float: right;
|
||||
right: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 770px) {
|
||||
#sidebarContainer {
|
||||
top: 33px;
|
||||
z-index: 100;
|
||||
}
|
||||
#sidebarContent {
|
||||
top: 32px;
|
||||
background-color: hsla(0,0%,0%,.7);
|
||||
}
|
||||
#thumbnailView, #outlineView {
|
||||
top: 66px;
|
||||
}
|
||||
|
||||
html[dir='ltr'] #outerContainer.sidebarOpen > #mainContainer {
|
||||
left: 0px;
|
||||
}
|
||||
html[dir='rtl'] #outerContainer.sidebarOpen > #mainContainer {
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
html[dir='ltr'] .outerCenter {
|
||||
float: left;
|
||||
left: 180px;
|
||||
}
|
||||
html[dir='rtl'] .outerCenter {
|
||||
float: right;
|
||||
right: 180px;
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 600px) {
|
||||
#toolbarViewerRight {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
@ -89,20 +89,16 @@
|
||||
<span data-l10n-id="next_label">Next</span>
|
||||
</button>
|
||||
</div>
|
||||
<label class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
|
||||
<label id="pageNumberLabel" class="toolbarLabel" for="pageNumber" data-l10n-id="page_label">Page: </label>
|
||||
<input type="number" id="pageNumber" class="toolbarField pageNumber" onchange="PDFView.page = this.value;" value="1" size="4" min="1" tabindex="6">
|
||||
</input>
|
||||
<span id="numPages" class="toolbarLabel"></span>
|
||||
</div>
|
||||
<div id="toolbarViewerRight">
|
||||
<input id="fileInput" class="fileInput" type="file" oncontextmenu="return false;" tabindex="10" />
|
||||
|
||||
<!--
|
||||
<input id="fileInput" class="fileInput" type="file" oncontextmenu="return false;" style="visibility: hidden; position: fixed; right: 0; top: 0" />
|
||||
<button id="openFile" class="toolbarButton print" title="Open File" tabindex="10" data-l10n-id="open_file" onclick="document.getElementById('fileInput').click()">
|
||||
<button id="openFile" class="toolbarButton openFile" title="Open File" tabindex="10" data-l10n-id="open_file" onclick="document.getElementById('fileInput').click()">
|
||||
<span data-l10n-id="open_file_label">Open</span>
|
||||
</button>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<button id="print" class="toolbarButton print" title="Print" tabindex="11" data-l10n-id="print" onclick="window.print()">
|
||||
@ -127,7 +123,7 @@
|
||||
<span data-l10n-id="zoom_in_label">Zoom In</span>
|
||||
</button>
|
||||
</div>
|
||||
<span class="dropdownToolbarButton">
|
||||
<span id="scaleSelectContainer" class="dropdownToolbarButton">
|
||||
<select id="scaleSelect" onchange="PDFView.parseScale(this.value);" title="Zoom" oncontextmenu="return false;" tabindex="9" data-l10n-id="zoom">
|
||||
<option id="pageAutoOption" value="auto" selected="selected" data-l10n-id="page_scale_auto">Automatic Zoom</option>
|
||||
<option id="pageActualOption" value="page-actual" data-l10n-id="page_scale_actual">Actual Size</option>
|
||||
|
112
web/viewer.js
112
web/viewer.js
@ -223,6 +223,7 @@ var PDFView = {
|
||||
pageText: [],
|
||||
container: null,
|
||||
initialized: false,
|
||||
fellback: false,
|
||||
// called once when the document is loaded
|
||||
initialize: function pdfViewInitialize() {
|
||||
this.container = document.getElementById('viewerContainer');
|
||||
@ -333,10 +334,15 @@ var PDFView = {
|
||||
return currentPageNumber;
|
||||
},
|
||||
|
||||
open: function pdfViewOpen(url, scale) {
|
||||
this.url = url;
|
||||
|
||||
document.title = decodeURIComponent(getFileName(url)) || url;
|
||||
open: function pdfViewOpen(url, scale, password) {
|
||||
var parameters = {password: password};
|
||||
if (typeof url === 'string') { // URL
|
||||
this.url = url;
|
||||
document.title = decodeURIComponent(getFileName(url)) || url;
|
||||
parameters.url = url;
|
||||
} else if (url && 'byteLength' in url) { // ArrayBuffer
|
||||
parameters.data = url;
|
||||
}
|
||||
|
||||
if (!PDFView.loadingBar) {
|
||||
PDFView.loadingBar = new ProgressBar('#loadingBar', {});
|
||||
@ -344,12 +350,23 @@ var PDFView = {
|
||||
|
||||
var self = this;
|
||||
self.loading = true;
|
||||
PDFJS.getDocument(url).then(
|
||||
PDFJS.getDocument(parameters).then(
|
||||
function getDocumentCallback(pdfDocument) {
|
||||
self.load(pdfDocument, scale);
|
||||
self.loading = false;
|
||||
},
|
||||
function getDocumentError(message, exception) {
|
||||
if (exception.name === 'PasswordException') {
|
||||
if (exception.code === 'needpassword') {
|
||||
var promptString = mozL10n.get('request_password', null,
|
||||
'PDF is protected by a password:');
|
||||
password = prompt(promptString);
|
||||
if (password && password.length > 0) {
|
||||
return PDFView.open(url, scale, password);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.textContent = mozL10n.get('loading_error_indicator',
|
||||
null, 'Error');
|
||||
@ -376,6 +393,18 @@ var PDFView = {
|
||||
}
|
||||
},
|
||||
|
||||
fallback: function pdfViewFallback() {
|
||||
if (!PDFJS.isFirefoxExtension)
|
||||
return;
|
||||
// Only trigger the fallback once so we don't spam the user with messages
|
||||
// for one PDF.
|
||||
if (this.fellback)
|
||||
return;
|
||||
this.fellback = true;
|
||||
var url = this.url.split('#')[0];
|
||||
FirefoxCom.request('fallback', url);
|
||||
},
|
||||
|
||||
navigateTo: function pdfViewNavigateTo(dest) {
|
||||
if (typeof dest === 'string')
|
||||
dest = this.destinations[dest];
|
||||
@ -438,6 +467,34 @@ var PDFView = {
|
||||
* and optionally a 'stack' property.
|
||||
*/
|
||||
error: function pdfViewError(message, moreInfo) {
|
||||
var moreInfoText = mozL10n.get('error_build', {build: PDFJS.build},
|
||||
'PDF.JS Build: {{build}}') + '\n';
|
||||
if (moreInfo) {
|
||||
moreInfoText +=
|
||||
mozL10n.get('error_message', {message: moreInfo.message},
|
||||
'Message: {{message}}');
|
||||
if (moreInfo.stack) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_stack', {stack: moreInfo.stack},
|
||||
'Stack: {{stack}}');
|
||||
} else {
|
||||
if (moreInfo.filename) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_file', {file: moreInfo.filename},
|
||||
'File: {{file}}');
|
||||
}
|
||||
if (moreInfo.lineNumber) {
|
||||
moreInfoText += '\n' +
|
||||
mozL10n.get('error_line', {line: moreInfo.lineNumber},
|
||||
'Line: {{line}}');
|
||||
}
|
||||
}
|
||||
}
|
||||
if (PDFJS.isFirefoxExtension) {
|
||||
console.error(message + '\n' + moreInfoText);
|
||||
this.fallback();
|
||||
return;
|
||||
}
|
||||
var errorWrapper = document.getElementById('errorWrapper');
|
||||
errorWrapper.removeAttribute('hidden');
|
||||
|
||||
@ -464,32 +521,9 @@ var PDFView = {
|
||||
};
|
||||
moreInfoButton.removeAttribute('hidden');
|
||||
lessInfoButton.setAttribute('hidden', 'true');
|
||||
errorMoreInfo.value =
|
||||
mozL10n.get('error_build', {build: PDFJS.build},
|
||||
'PDF.JS Build: {{build}}') + '\n';
|
||||
errorMoreInfo.value = moreInfoText;
|
||||
|
||||
if (moreInfo) {
|
||||
errorMoreInfo.value +=
|
||||
mozL10n.get('error_message', {message: moreInfo.message},
|
||||
'Message: {{message}}');
|
||||
if (moreInfo.stack) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_stack', {stack: moreInfo.stack},
|
||||
'Stack: {{stack}}');
|
||||
} else {
|
||||
if (moreInfo.filename) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_file', {file: moreInfo.filename},
|
||||
'File: {{file}}');
|
||||
}
|
||||
if (moreInfo.lineNumber) {
|
||||
errorMoreInfo.value += '\n' +
|
||||
mozL10n.get('error_line', {line: moreInfo.lineNumber},
|
||||
'Line: {{line}}');
|
||||
}
|
||||
}
|
||||
}
|
||||
errorMoreInfo.rows = errorMoreInfo.value.split('\n').length - 1;
|
||||
errorMoreInfo.rows = moreInfoText.split('\n').length - 1;
|
||||
},
|
||||
|
||||
progress: function pdfViewProgress(level) {
|
||||
@ -1009,6 +1043,9 @@ var PageView = function pageView(container, pdfPage, id, scale,
|
||||
if (comment)
|
||||
div.appendChild(comment);
|
||||
break;
|
||||
case 'Widget':
|
||||
TODO('support forms');
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1459,7 +1496,7 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
||||
|
||||
if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader ||
|
||||
!window.FileList || !window.Blob) {
|
||||
document.getElementById('fileInput').setAttribute('hidden', 'true');
|
||||
document.getElementById('openFile').setAttribute('hidden', 'true');
|
||||
} else {
|
||||
document.getElementById('fileInput').value = null;
|
||||
}
|
||||
@ -1495,6 +1532,14 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
||||
document.querySelector('#viewSearch').classList.remove('hidden');
|
||||
}
|
||||
|
||||
// Listen for warnings to trigger the fallback UI. Errors should be caught
|
||||
// and call PDFView.error() so we don't need to listen for those.
|
||||
PDFJS.LogManager.addLogger({
|
||||
warn: function() {
|
||||
PDFView.fallback();
|
||||
}
|
||||
});
|
||||
|
||||
var thumbsView = document.getElementById('thumbnailView');
|
||||
thumbsView.addEventListener('scroll', updateThumbViewArea, true);
|
||||
|
||||
@ -1645,10 +1690,7 @@ window.addEventListener('change', function webViewerChange(evt) {
|
||||
for (var i = 0; i < data.length; i++)
|
||||
uint8Array[i] = data.charCodeAt(i);
|
||||
|
||||
// TODO using blob instead?
|
||||
PDFJS.getDocument(uint8Array).then(function(pdfDocument) {
|
||||
PDFView.load(pdfDocument);
|
||||
});
|
||||
PDFView.open(uint8Array, 0);
|
||||
};
|
||||
|
||||
// Read as a binary string since "readAsArrayBuffer" is not yet
|
||||
|
Loading…
x
Reference in New Issue
Block a user