@jupyterlab/pdf-extension
Advanced tools
Comparing version 1.0.0-alpha.6 to 1.0.0-alpha.7
@@ -0,11 +1,5 @@ | ||
import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; | ||
import { Widget } from '@phosphor/widgets'; | ||
import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; | ||
import '../style/index.css'; | ||
/** | ||
* The MIME type for PDF. | ||
*/ | ||
export declare const MIME_TYPE = "application/pdf"; | ||
export declare const PDF_CLASS = "jp-PDFViewer"; | ||
export declare const PDF_CONTAINER_CLASS = "jp-PDFContainer"; | ||
/** | ||
* A class for rendering a PDF document. | ||
@@ -20,6 +14,13 @@ */ | ||
/** | ||
* Handle a `before-hide` message. | ||
*/ | ||
protected onBeforeHide(): void; | ||
/** | ||
* Dispose of the resources held by the pdf widget. | ||
*/ | ||
dispose(): void; | ||
private _objectUrl; | ||
private _base64; | ||
private _disposable; | ||
private _object; | ||
private _ready; | ||
} | ||
@@ -26,0 +27,0 @@ /** |
128
lib/index.js
@@ -1,20 +0,37 @@ | ||
"use strict"; | ||
// Copyright (c) Jupyter Development Team. | ||
// Distributed under the terms of the Modified BSD License. | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const widgets_1 = require("@phosphor/widgets"); | ||
require("../style/index.css"); | ||
import { PromiseDelegate } from '@phosphor/coreutils'; | ||
import { DisposableDelegate } from '@phosphor/disposable'; | ||
import { Widget } from '@phosphor/widgets'; | ||
import '../style/index.css'; | ||
/** | ||
* The MIME type for PDF. | ||
*/ | ||
exports.MIME_TYPE = 'application/pdf'; | ||
exports.PDF_CLASS = 'jp-PDFViewer'; | ||
exports.PDF_CONTAINER_CLASS = 'jp-PDFContainer'; | ||
const MIME_TYPE = 'application/pdf'; | ||
/** | ||
* A class for rendering a PDF document. | ||
*/ | ||
class RenderedPDF extends widgets_1.Widget { | ||
export class RenderedPDF extends Widget { | ||
constructor() { | ||
super({ node: Private.createNode() }); | ||
this._objectUrl = ''; | ||
super(); | ||
this._base64 = ''; | ||
this._disposable = null; | ||
this._ready = new PromiseDelegate(); | ||
this.addClass('jp-PDFContainer'); | ||
// We put the object in an iframe, which seems to have a better chance | ||
// of retaining its scroll position upon tab focusing, moving around etc. | ||
const iframe = document.createElement('iframe'); | ||
this.node.appendChild(iframe); | ||
// The iframe content window is not available until the onload event. | ||
iframe.onload = () => { | ||
const body = iframe.contentWindow.document.createElement('body'); | ||
body.style.margin = '0px'; | ||
iframe.contentWindow.document.body = body; | ||
this._object = iframe.contentWindow.document.createElement('object'); | ||
this._object.type = MIME_TYPE; | ||
this._object.width = '100%'; | ||
this._object.height = '100%'; | ||
body.appendChild(this._object); | ||
this._ready.resolve(void 0); | ||
}; | ||
} | ||
@@ -24,19 +41,37 @@ /** | ||
*/ | ||
renderModel(model) { | ||
let data = model.data[exports.MIME_TYPE]; | ||
// If there is no data, do nothing. | ||
if (!data) { | ||
async renderModel(model) { | ||
await this._ready.promise; | ||
let data = model.data[MIME_TYPE]; | ||
if (!data || | ||
(data.length === this._base64.length && data === this._base64)) { | ||
// If there is no data, or if the string has not changed, we do not | ||
// need to re-parse the data and rerender. We do, however, check | ||
// for a fragment if the user wants to scroll the output. | ||
if (model.metadata.fragment && this._object.data) { | ||
const url = this._object.data; | ||
this._object.data = `${url.split('#')[0]}${model.metadata.fragment}`; | ||
} | ||
// For some opaque reason, Firefox seems to loose its scroll position | ||
// upon unhiding a PDF. But triggering a refresh of the URL makes it | ||
// find it again. No idea what the reason for this is. | ||
if (Private.IS_FIREFOX) { | ||
this._object.data = this._object.data; | ||
} | ||
return Promise.resolve(void 0); | ||
} | ||
const blob = Private.b64toBlob(data, exports.MIME_TYPE); | ||
let oldUrl = this._objectUrl; | ||
this._objectUrl = URL.createObjectURL(blob); | ||
this._base64 = data; | ||
const blob = Private.b64toBlob(data, MIME_TYPE); | ||
// Release reference to any previous object url. | ||
if (this._disposable) { | ||
this._disposable.dispose(); | ||
} | ||
let objectUrl = URL.createObjectURL(blob); | ||
if (model.metadata.fragment) { | ||
this._objectUrl += model.metadata.fragment; | ||
objectUrl += model.metadata.fragment; | ||
} | ||
this.node.querySelector('embed').setAttribute('src', this._objectUrl); | ||
// Release reference to any previous object url. | ||
if (oldUrl) { | ||
this._object.data = objectUrl; | ||
// Set the disposable release the object URL. | ||
this._disposable = new DisposableDelegate(() => { | ||
try { | ||
URL.revokeObjectURL(oldUrl); | ||
URL.revokeObjectURL(objectUrl); | ||
} | ||
@@ -46,4 +81,15 @@ catch (error) { | ||
} | ||
}); | ||
return; | ||
} | ||
/** | ||
* Handle a `before-hide` message. | ||
*/ | ||
onBeforeHide() { | ||
// Dispose of any URL fragment before hiding the widget | ||
// so that it is not remembered upon show. Only Firefox | ||
// seems to have a problem with this. | ||
if (Private.IS_FIREFOX) { | ||
this._object.data = this._object.data.split('#')[0]; | ||
} | ||
return Promise.resolve(void 0); | ||
} | ||
@@ -54,19 +100,15 @@ /** | ||
dispose() { | ||
try { | ||
URL.revokeObjectURL(this._objectUrl); | ||
if (this._disposable) { | ||
this._disposable.dispose(); | ||
} | ||
catch (error) { | ||
/* no-op */ | ||
} | ||
super.dispose(); | ||
} | ||
} | ||
exports.RenderedPDF = RenderedPDF; | ||
/** | ||
* A mime renderer factory for PDF data. | ||
*/ | ||
exports.rendererFactory = { | ||
export const rendererFactory = { | ||
safe: false, | ||
mimeTypes: [exports.MIME_TYPE], | ||
defaultRank: 75, | ||
mimeTypes: [MIME_TYPE], | ||
defaultRank: 100, | ||
createRenderer: options => new RenderedPDF() | ||
@@ -77,3 +119,3 @@ }; | ||
id: '@jupyterlab/pdf-extension:factory', | ||
rendererFactory: exports.rendererFactory, | ||
rendererFactory, | ||
dataType: 'string', | ||
@@ -85,3 +127,3 @@ fileTypes: [ | ||
fileFormat: 'base64', | ||
mimeTypes: [exports.MIME_TYPE], | ||
mimeTypes: [MIME_TYPE], | ||
extensions: ['.pdf'] | ||
@@ -99,3 +141,3 @@ } | ||
]; | ||
exports.default = extensions; | ||
export default extensions; | ||
/** | ||
@@ -107,14 +149,8 @@ * A namespace for PDF widget private data. | ||
/** | ||
* Create the node for the PDF widget. | ||
* A flag for determining whether the user is using Firefox. | ||
* There are some different PDF viewer behaviors on Firefox, | ||
* and we try to address them with this. User agent string parsing | ||
* is *not* reliable, so this should be considered a best-effort test. | ||
*/ | ||
function createNode() { | ||
let node = document.createElement('div'); | ||
node.className = exports.PDF_CONTAINER_CLASS; | ||
let pdf = document.createElement('embed'); | ||
pdf.className = exports.PDF_CLASS; | ||
pdf.setAttribute('type', exports.MIME_TYPE); | ||
node.appendChild(pdf); | ||
return node; | ||
} | ||
Private.createNode = createNode; | ||
Private.IS_FIREFOX = /Firefox/.test(navigator.userAgent); | ||
/** | ||
@@ -121,0 +157,0 @@ * Convert a base64 encoded string to a Blob object. |
{ | ||
"name": "@jupyterlab/pdf-extension", | ||
"version": "1.0.0-alpha.6", | ||
"version": "1.0.0-alpha.7", | ||
"description": "JupyterLab - PDF Viewer", | ||
@@ -9,2 +9,6 @@ "homepage": "https://github.com/jupyterlab/jupyterlab", | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/jupyterlab/jupyterlab.git" | ||
}, | ||
"license": "BSD-3-Clause", | ||
@@ -23,6 +27,2 @@ "author": "Project Jupyter", | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/jupyterlab/jupyterlab.git" | ||
}, | ||
"scripts": { | ||
@@ -36,3 +36,5 @@ "build": "tsc -b", | ||
"dependencies": { | ||
"@jupyterlab/rendermime-interfaces": "^1.3.0-alpha.6", | ||
"@jupyterlab/rendermime-interfaces": "^1.3.0-alpha.7", | ||
"@phosphor/coreutils": "^1.3.0", | ||
"@phosphor/disposable": "^1.1.2", | ||
"@phosphor/widgets": "^1.6.0" | ||
@@ -51,3 +53,3 @@ }, | ||
}, | ||
"gitHead": "25152cd7c0a2d2d3d020dcd59451c236e9ecc6ab" | ||
"gitHead": "f8e210a027f6545b426caf4ab64c75a1e1619a44" | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11183
241
4