forked from jupyter-server/jupyter_server
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add an html override extension (jupyter-server#218)
- Loading branch information
Steve Silvester
authored and
GitHub Enterprise
committed
Oct 18, 2021
1 parent
c6c9749
commit cb3a59a
Showing
3 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { | ||
JupyterFrontEnd, | ||
JupyterFrontEndPlugin | ||
} from '@jupyterlab/application'; | ||
|
||
import { ReadonlyPartialJSONObject } from '@lumino/coreutils'; | ||
|
||
import { | ||
IRenderMime, | ||
IRenderMimeRegistry, | ||
RenderedHTML | ||
} from '@jupyterlab/rendermime'; | ||
|
||
class CustomRenderedHTML extends RenderedHTML { | ||
/** | ||
* Render a mime model as html content, replacing unsupported output. | ||
*/ | ||
render(model: IRenderMime.IMimeModel): Promise<void> { | ||
const data = { ...model.data }; | ||
const html = data['text/html']; | ||
// Replace html as needed. | ||
if (html && typeof html === 'string') { | ||
// Look for PixieDust-related content | ||
if (html.indexOf('#twistie') !== -1 || html.indexOf('pd_save') !== -1) { | ||
data['text/html'] = | ||
'<h2>PixieDust is not yet supported in JupyterLab</h2>'; | ||
// Look for jQuery content | ||
} else if (html.indexOf('$(') !== -1) { | ||
data['text/html'] = '<h2>JQuery is not supported in JupyterLab</h2>'; | ||
} | ||
} | ||
return super.render({ ...model, data: data as ReadonlyPartialJSONObject }); | ||
} | ||
} | ||
|
||
/** | ||
* HTML Replacement plugin. | ||
*/ | ||
export const HTMLReplacementPlugin: JupyterFrontEndPlugin<void> = { | ||
id: 'data_studio:html_replacement_plugin', | ||
autoStart: true, | ||
requires: [IRenderMimeRegistry], | ||
activate: async (app: JupyterFrontEnd, registry: IRenderMimeRegistry) => { | ||
console.log('JupyterLab extension "HTML Replacement" is activated!'); | ||
|
||
const factory: IRenderMime.IRendererFactory = { | ||
safe: true, | ||
mimeTypes: ['text/html'], | ||
defaultRank: 50, | ||
createRenderer: options => new CustomRenderedHTML(options) | ||
}; | ||
registry.addFactory(factory, 50); | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
import { JupyterLab } from '@jupyterlab/application'; | ||
|
||
import { | ||
IRenderMimeRegistry, | ||
RenderMimeRegistry, | ||
standardRendererFactories | ||
} from '@jupyterlab/rendermime'; | ||
|
||
import { HTMLReplacementPlugin } from '../src/overridehtml'; | ||
|
||
import { defaultSanitizer } from '@jupyterlab/apputils'; | ||
|
||
describe('html override', () => { | ||
let app: JupyterLab; | ||
let registry: IRenderMimeRegistry; | ||
const sanitizer = defaultSanitizer; | ||
const options = { | ||
mimeType: 'text/html', | ||
sanitizer, | ||
resolver: null, | ||
linkHandler: null, | ||
latexTypesetter: null | ||
}; | ||
|
||
beforeEach(async () => { | ||
app = new JupyterLab(); | ||
registry = new RenderMimeRegistry({ | ||
initialFactories: standardRendererFactories | ||
}); | ||
}); | ||
|
||
it('should replace pixiedust content', async () => { | ||
await HTMLReplacementPlugin.activate(app, registry); | ||
const data = { 'text/html': '$("#twistie6a9330b3").click(function()' }; | ||
const factory = registry.getFactory('text/html'); | ||
const renderer = factory!.createRenderer(options); | ||
await renderer.renderModel(registry.createModel({ data })); | ||
expect(renderer.node.innerHTML).toBe( | ||
'<h2>PixieDust is not yet supported in JupyterLab</h2>' | ||
); | ||
|
||
data['text/html'] = '<div class="pd_save is-viewer-good" style="'; | ||
await renderer.renderModel(registry.createModel({ data })); | ||
expect(renderer.node.innerHTML).toBe( | ||
'<h2>PixieDust is not yet supported in JupyterLab</h2>' | ||
); | ||
}); | ||
|
||
it('should handle jQuery content', async () => { | ||
await HTMLReplacementPlugin.activate(app, registry); | ||
const data = { 'text/html': '$(foo)' }; | ||
const model = registry.createModel({ data }); | ||
const factory = registry.getFactory('text/html'); | ||
const renderer = factory!.createRenderer(options); | ||
await renderer.renderModel(model); | ||
expect(renderer.node.innerHTML).toBe( | ||
'<h2>JQuery is not supported in JupyterLab</h2>' | ||
); | ||
}); | ||
|
||
it('should pass other content throught', async () => { | ||
await HTMLReplacementPlugin.activate(app, registry); | ||
const data = { 'text/html': '<h1>hello,world!</h1>' }; | ||
const model = registry.createModel({ data }); | ||
const factory = registry.getFactory('text/html'); | ||
const renderer = factory!.createRenderer(options); | ||
await renderer.renderModel(model); | ||
expect(renderer.node.innerHTML).toBe('<h1>hello,world!</h1>'); | ||
}); | ||
}); |