diff --git a/package-lock.json b/package-lock.json index cb0f52cb0..80cc62539 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "mime-types": "^2.1.35", "nanoid": "^5.0.8", "node-fetch": "^3.3.2", - "pdf.js": "github:edrlab/pdf.js#master", + "pdf.js": "github:edrlab/pdf.js#master2", "proxy-agent": "^6.4.0", "r2-lcp-js": "^1.0.41", "r2-navigator-js": "^1.16.5", @@ -20914,7 +20914,7 @@ "license": "MIT" }, "node_modules/pdf.js": { - "resolved": "git+ssh://git@github.com/edrlab/pdf.js.git#138f983a4a6943790e617827e1d55cada80b3b34", + "resolved": "git+ssh://git@github.com/edrlab/pdf.js.git#4ed465d7357fcdcc068b68772422c4fdc03e8617", "license": "Apache-2.0", "engines": { "node": ">=20" diff --git a/package.json b/package.json index a2b00c8ac..fe72a3faf 100644 --- a/package.json +++ b/package.json @@ -293,7 +293,7 @@ "mime-types": "^2.1.35", "nanoid": "^5.0.8", "node-fetch": "^3.3.2", - "pdf.js": "github:edrlab/pdf.js#master", + "pdf.js": "github:edrlab/pdf.js#master2", "proxy-agent": "^6.4.0", "r2-lcp-js": "^1.0.41", "r2-navigator-js": "^1.16.5", diff --git a/src/common/streamerProtocol.ts b/src/common/streamerProtocol.ts new file mode 100644 index 000000000..1908b1ef8 --- /dev/null +++ b/src/common/streamerProtocol.ts @@ -0,0 +1,8 @@ +// ==LICENSE-BEGIN== +// Copyright 2017 European Digital Reading Lab. All rights reserved. +// Licensed to the Readium Foundation under one or more contributor license agreements. +// Use of this source code is governed by a BSD-style license +// that can be found in the LICENSE file exposed on Github (readium) in the project repository. +// ==LICENSE-END== + +export const THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL = "thoriumhttps"; diff --git a/src/main/pdf/extract.ts b/src/main/pdf/extract.ts index 2fc18805d..e9adc080b 100644 --- a/src/main/pdf/extract.ts +++ b/src/main/pdf/extract.ts @@ -12,6 +12,7 @@ import { BrowserWindow } from "electron"; import { encodeURIComponent_RFC3986 } from "@r2-utils-js/_utils/http/UrlUtils"; import { IInfo } from "./extract.type"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; const debug = debug_("readium-desktop:main/pdf/extract/index.ts"); debug("_"); @@ -60,7 +61,7 @@ export const extractPDFData = }); // win.hide(); // doesn't works on linux - await win.loadURL(`pdfjs://local/web/viewer.html?file=${pdfPath}`); + await win.loadURL(`${THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL}://0.0.0.0/pdfjs/web/viewer.html?file=${pdfPath}`); const content = win.webContents; diff --git a/src/main/redux/sagas/app.ts b/src/main/redux/sagas/app.ts index 1d5eeaf04..6524055ec 100644 --- a/src/main/redux/sagas/app.ts +++ b/src/main/redux/sagas/app.ts @@ -158,22 +158,6 @@ export function* init() { debug("#####"); }); - // const sessionPDFWebview = session.fromPartition("persist:pdfjsreader"); - // const protocolFromPDFWebview = sessionPDFWebview.protocol; - protocol.registerFileProtocol("pdfjs", async (request, callback) => { - - const url = (new URL(request.url)).pathname; - debug("PDFJS request this file:", url); - - const pdfjsFolder = "assets/lib/pdfjs"; - let folderPath: string = path.join(__dirname, pdfjsFolder); - if (_PACKAGING === "0") { - folderPath = path.join(process.cwd(), "dist", pdfjsFolder); - } - const pathname = path.normalize(`${folderPath}/${url}`); - - callback(pathname); - }); protocol.registerFileProtocol("pdfjs-extract", async (request, callback) => { diff --git a/src/main/redux/sagas/publication/openPublication.ts b/src/main/redux/sagas/publication/openPublication.ts index c429d6292..ac67820d4 100644 --- a/src/main/redux/sagas/publication/openPublication.ts +++ b/src/main/redux/sagas/publication/openPublication.ts @@ -15,7 +15,6 @@ import { streamerActions } from "readium-desktop/main/redux/actions"; import { RootState } from "readium-desktop/main/redux/states"; import { streamerAddPublications, streamerLoadOrGetCachedPublication, - THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL, } from "readium-desktop/main/streamer/streamerNoHttp"; // eslint-disable-next-line local-rules/typed-redux-saga-use-typed-effects import { put, take } from "redux-saga/effects"; @@ -25,6 +24,7 @@ import { StatusEnum } from "@r2-lcp-js/parser/epub/lsd"; import { Publication as R2Publication } from "@r2-shared-js/models/publication"; import { PublicationViewConverter } from "readium-desktop/main/converter/publication"; import { getTranslator } from "readium-desktop/common/services/translator"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; // import { _USE_HTTP_STREAMER } from "readium-desktop/preprocessor-directives"; diff --git a/src/main/redux/sagas/streamer.ts b/src/main/redux/sagas/streamer.ts index 45aa3dc5e..f155911e7 100644 --- a/src/main/redux/sagas/streamer.ts +++ b/src/main/redux/sagas/streamer.ts @@ -13,12 +13,13 @@ import { error } from "readium-desktop/main/tools/error"; import { streamerActions } from "readium-desktop/main/redux/actions"; import { RootState } from "readium-desktop/main/redux/states"; import { - streamerRemovePublications, THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL, + streamerRemovePublications, } from "readium-desktop/main/streamer/streamerNoHttp"; import { SagaIterator } from "redux-saga"; // eslint-disable-next-line local-rules/typed-redux-saga-use-typed-effects import { all, put } from "redux-saga/effects"; import { call as callTyped, select as selectTyped } from "typed-redux-saga/macro"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; // import * as portfinder from "portfinder"; // import { Server } from "@r2-streamer-js/http/server"; diff --git a/src/main/streamer/streamerNoHttp.ts b/src/main/streamer/streamerNoHttp.ts index b9f58629d..3266e1361 100644 --- a/src/main/streamer/streamerNoHttp.ts +++ b/src/main/streamer/streamerNoHttp.ts @@ -11,7 +11,7 @@ import { app, protocol, ProtocolRequest, ProtocolResponse, session } from "elect import * as fs from "fs"; import * as mime from "mime-types"; import * as path from "path"; -import { IS_DEV } from "readium-desktop/preprocessor-directives"; +import { _PACKAGING, IS_DEV } from "readium-desktop/preprocessor-directives"; import { TaJsonSerialize } from "@r2-lcp-js/serializable"; import { parseDOM, serializeDOM } from "@r2-navigator-js/electron/common/dom"; @@ -45,10 +45,17 @@ import { READIUMCSS_FILE_PATH, setupMathJaxTransformer, } from "./streamerCommon"; import { OPDS_MEDIA_SCHEME } from "readium-desktop/main/redux/sagas/getEventChannel"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; +import { mimeTypes } from "readium-desktop/utils/mimeTypes"; // import { _USE_HTTP_STREAMER } from "readium-desktop/preprocessor-directives"; const debug = debug_("readium-desktop:main#streamerNoHttp"); +debug("_"); + +// !!!!!! +/// BE CAREFUL DEBUG HAS BEED DISABLED IN package.json +// !!!!!! const URL_PARAM_SESSION_INFO = "r2_SESSION_INFO"; @@ -56,7 +63,6 @@ const URL_PARAM_SESSION_INFO = "r2_SESSION_INFO"; // ... based on what metric, any particular HTTP server or client implementation? export const MAX_PREFETCH_LINKS = 10; -export const THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL = "thoriumhttps"; const READIUM_CSS_URL_PATH = "readium-css"; @@ -209,6 +215,9 @@ const streamProtocolHandler = async ( } } + const pdfjsAssetsPrefix = "/pdfjs/"; + const isPdfjsAssets = uPathname.startsWith(pdfjsAssetsPrefix); + const publicationAssetsPrefix = "/pub/"; const isPublicationAssets = uPathname.startsWith(publicationAssetsPrefix); @@ -222,6 +231,7 @@ const streamProtocolHandler = async ( const isMediaOverlays = uPathname.endsWith(mediaOverlaysPrefix); debug("streamProtocolHandler uPathname", uPathname); + debug("streamProtocolHandler isPdfjsAssets", isPdfjsAssets); debug("streamProtocolHandler isPublicationAssets", isPublicationAssets); debug("streamProtocolHandler isMathJax", isMathJax); debug("streamProtocolHandler isReadiumCSS", isReadiumCSS); @@ -266,7 +276,33 @@ const streamProtocolHandler = async ( // tslint:disable-next-line:max-line-length headers["Access-Control-Expose-Headers"] = "Content-Type, Content-Length, Accept-Ranges, Content-Range, Range, Link, Transfer-Encoding, X-Requested-With, Authorization, Accept, Origin, User-Agent, DNT, Cache-Control, Keep-Alive, If-Modified-Since"; - if (isPublicationAssets || isMediaOverlays) { + if (isPdfjsAssets) { + + const pdfjsUrlPathname = uPathname.substr(pdfjsAssetsPrefix.length); + debug("PDFJS request this file:", pdfjsUrlPathname); + + const pdfjsFolder = "assets/lib/pdfjs"; + let folderPath: string = path.join(__dirname, pdfjsFolder); + if (_PACKAGING === "0") { + folderPath = path.join(process.cwd(), "dist", pdfjsFolder); + } + const pdfjsFullPathname = path.normalize(`${folderPath}/${pdfjsUrlPathname}`); + debug("PDFJS full path name :", pdfjsFullPathname); + + const contentLength = `${fs.statSync(pdfjsFullPathname)?.size || 0}`; + headers["Content-Length"] = contentLength; + const contentType = `${mimeTypes[path.extname(pdfjsFullPathname).slice(1) as keyof typeof mimeTypes] || ""}; charset=utf-8`; + headers["Content-Type"] = contentType; + debug("PDFJS content-type:", contentType, contentLength); + const obj = { + // NodeJS.ReadableStream + data: fs.createReadStream(pdfjsFullPathname), + headers, + statusCode: 200, + }; + callback(obj); + return; + } else if (isPublicationAssets || isMediaOverlays) { let b64Path = uPathname.substr(publicationAssetsPrefix.length); const i = b64Path.indexOf("/"); let pathInZip = ""; diff --git a/src/renderer/reader/components/Reader.tsx b/src/renderer/reader/components/Reader.tsx index e53ce046a..797ccc8c1 100644 --- a/src/renderer/reader/components/Reader.tsx +++ b/src/renderer/reader/components/Reader.tsx @@ -103,10 +103,7 @@ import { apiDispatch } from "readium-desktop/renderer/common/redux/api/api"; import { MiniLocatorExtended, minimizeLocatorExtended } from "readium-desktop/common/redux/states/locatorInitialState"; import { translateContentFieldHelper } from "readium-desktop/common/services/translator"; import { getStore } from "../createStore"; - -// main process code! -// thoriumhttps -// import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/main/streamer/streamerNoHttp"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; // TODO: key not used but translation kept for potential future use // discard some not used key from i18n-scan cmd @@ -158,7 +155,7 @@ const handleLinkUrl_UpdateHistoryState = (url: string, isFromOnPopState = false) // if (/https?:\/\//.test(url_)) { if (!url_.startsWith(READIUM2_ELECTRON_HTTP_PROTOCOL + "://") && - !url_.startsWith("thoriumhttps://")) { + !url_.startsWith(THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL + "://")) { console.log(">> HISTORY POP STATE SKIP URL (1)", url_); return; } @@ -1755,7 +1752,7 @@ class Reader extends React.Component { } else if (typeof popState.state.data === "string") { // if (!/https?:\/\//.test(popState.state.data)) { if (popState.state.data.startsWith(READIUM2_ELECTRON_HTTP_PROTOCOL + "://") || - popState.state.data.startsWith("thoriumhttps://")) { + popState.state.data.startsWith(THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL + "://")) { this.handleLinkClick(undefined, popState.state.data, !isDocked, true); } else { console.log(">> HISTORY POP STATE SKIP URL (2)", popState.state.data); diff --git a/src/renderer/reader/pdf/driver.ts b/src/renderer/reader/pdf/driver.ts index 39bfa11fa..a3060d72a 100644 --- a/src/renderer/reader/pdf/driver.ts +++ b/src/renderer/reader/pdf/driver.ts @@ -19,6 +19,7 @@ import { encodeURIComponent_RFC3986 } from "@r2-utils-js/_utils/http/UrlUtils"; import { eventBus } from "./common/eventBus"; import { IEventBusPdfPlayer } from "./common/pdfReader.type"; +import { THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL } from "readium-desktop/common/streamerProtocol"; // bridge between webview tx-rx communication and reader.tsx @@ -145,7 +146,7 @@ export function pdfMount( // webview.setAttribute("disablewebsecurity", ""); webview.setAttribute("preload", preloadPath); - webview.setAttribute("src", "pdfjs://local/web/viewer.html?file=" + encodeURIComponent_RFC3986(pdfPath)); + webview.setAttribute("src", `${THORIUM_READIUM2_ELECTRON_HTTP_PROTOCOL}://0.0.0.0/pdfjs/web/viewer.html?file=` + encodeURIComponent_RFC3986(pdfPath)); publicationViewport.append(webview); } diff --git a/src/renderer/reader/pdf/webview/index_pdf.ts b/src/renderer/reader/pdf/webview/index_pdf.ts index 12118680a..707ea2c7a 100644 --- a/src/renderer/reader/pdf/webview/index_pdf.ts +++ b/src/renderer/reader/pdf/webview/index_pdf.ts @@ -7,7 +7,7 @@ import debounce from "debounce"; import { ipcRenderer } from "electron"; -import { PDFDocumentProxy } from "readium-desktop/typings/pdf.js/display/api"; +import { PDFDocumentProxy } from "pdf.js/types/src/pdf"; import { IEventPayload_R2_EVENT_WEBVIEW_KEYDOWN, IEventPayload_R2_EVENT_WEBVIEW_KEYUP, diff --git a/src/renderer/reader/pdf/webview/toc.ts b/src/renderer/reader/pdf/webview/toc.ts index 0732684fe..7eb0b5ade 100644 --- a/src/renderer/reader/pdf/webview/toc.ts +++ b/src/renderer/reader/pdf/webview/toc.ts @@ -5,7 +5,7 @@ // that can be found in the LICENSE file exposed on Github (readium) in the project repository. // ==LICENSE-END -import { PDFDocumentProxy } from "readium-desktop/typings/pdf.js/display/api"; +import { PDFDocumentProxy } from "pdf.js/types/src/pdf"; import { tryCatch } from "readium-desktop/utils/tryCatch"; import { ILink, TToc } from "../common/pdfReader.type";