diff options
author | Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> | 2023-06-18 10:46:03 -0400 |
---|---|---|
committer | Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> | 2023-06-18 10:46:03 -0400 |
commit | cd6ba2eecb6ea7599b0dc24863d406c8079e6ff0 (patch) | |
tree | 63734cb958db6ce544aa367428ced4bc3001625b | |
parent | b301dd1a72aa507c3d0f75eacd029913d8b5f723 (diff) | |
download | compiler-explorer-gh-7832.tar.gz compiler-explorer-gh-7832.zip |
Syntax highlighting for the print viewgh-7832
-rw-r--r-- | static/main.ts | 14 | ||||
-rw-r--r-- | static/print-view.ts | 87 | ||||
-rw-r--r-- | static/print.ts | 50 | ||||
-rw-r--r-- | static/themes.ts | 4 |
4 files changed, 98 insertions, 57 deletions
diff --git a/static/main.ts b/static/main.ts index 0e34b8d1a..9d961697b 100644 --- a/static/main.ts +++ b/static/main.ts @@ -46,7 +46,7 @@ import {Hub} from './hub.js'; import {Settings, SiteSettings} from './settings.js'; import * as local from './local.js'; import {Alert} from './widgets/alert.js'; -import * as themer from './themes.js'; +import {Themer} from './themes.js'; import * as motd from './motd.js'; import {SimpleCook} from './widgets/simplecook.js'; import {HistoryWidget} from './widgets/history-widget.js'; @@ -62,7 +62,7 @@ import {ComponentConfig, EmptyCompilerState, StateWithId, StateWithLanguage} fro import * as utils from '../lib/common-utils.js'; import {SentryCapture} from './sentry.js'; -import {Printerinator} from './print.js'; +import {Printerinator} from './print-view.js'; const logos = require.context('../views/resources/logos', false, /\.(png|svg)$/); @@ -90,7 +90,7 @@ const policyDocuments = { privacy: require('./generated/privacy.pug').default, }; -function setupSettings(hub: Hub) { +function setupSettings(hub: Hub): [Themer, SiteSettings] { const eventHub = hub.layout.eventHub; const defaultSettings = { defaultLanguage: hub.defaultLangId, @@ -118,7 +118,7 @@ function setupSettings(hub: Hub) { eventHub.emit('settingsChange', newSettings); } - new themer.Themer(eventHub, currentSettings); + const themer = new Themer(eventHub, currentSettings); eventHub.on('requestSettings', () => { eventHub.emit('settingsChange', currentSettings); @@ -128,7 +128,7 @@ function setupSettings(hub: Hub) { eventHub.on('modifySettings', (newSettings: Partial<SiteSettings>) => { SettingsObject.setSettings(_.extend(currentSettings, newSettings)); }); - return currentSettings; + return [themer, currentSettings]; } function hasCookieConsented(options: CompilerExplorerOptions) { @@ -627,7 +627,7 @@ function start() { new clipboard('.btn.clippy'); - const settings = setupSettings(hub); + const [themer, settings] = setupSettings(hub); // We assume no consent for embed users if (!options.embedded) { @@ -738,7 +738,7 @@ function start() { History.trackHistory(layout); new Sharing(layout); - new Printerinator(hub); + new Printerinator(hub, themer); } $(start); diff --git a/static/print-view.ts b/static/print-view.ts new file mode 100644 index 000000000..aacc7d5eb --- /dev/null +++ b/static/print-view.ts @@ -0,0 +1,87 @@ +// Copyright (c) 2023, Compiler Explorer Authors +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +import $ from 'jquery'; + +import * as monaco from 'monaco-editor'; + +import {Hub} from './hub'; +import {Themer, themes} from './themes'; +import {unwrap} from './assert'; +import {EventHub} from './event-hub'; + +export class Printerinator { + printview: JQuery; + eventHub: EventHub; + itemsAdded: number; + css: string | null = null; + + constructor(hub: Hub, private readonly themer: Themer) { + this.eventHub = hub.createEventHub(); + this.printview = $('#printview'); + + window.addEventListener('beforeprint', this.setupPrintView.bind(this)); + this.eventHub.on('printdata', this.addPrintData.bind(this)); + } + + getThemeStyles() { + if (this.css === null) { + // Awful hacky stuff to get the theme declarations from monaco + const container = document.createElement('div'); + const editor = monaco.editor.create(container); + const theme = this.themer.getCurrentTheme(); + this.themer.setTheme(themes.default); + const css = (editor as any)._codeEditorService._themeService._themeCSS; + this.css = css + .slice(css.indexOf('.mtk1')) + .trim() + .split('\n') + .map(line => '#printview ' + line) + .join('\n'); + this.themer.setTheme(unwrap(theme)); + } + return this.css; + } + + setupPrintView() { + this.printview.empty(); + this.printview[0].innerHTML = `<style>${this.getThemeStyles()}</style>`; + this.itemsAdded = 0; + // It's important that any highlighting is done under the default theme (simply applying the default css + // to tokens from another theme doesn't quite work) + const theme = this.themer.getCurrentTheme(); + this.themer.setTheme(themes.default); + // Request print data from everyone + this.eventHub.emit('printrequest'); + // Restore theme + this.themer.setTheme(unwrap(theme)); + } + + addPrintData(data: any) { + if (this.itemsAdded++ !== 0) { + this.printview[0].innerHTML += `<div class="pagebreak"></div>`; + } + this.printview[0].innerHTML += data; + } +} diff --git a/static/print.ts b/static/print.ts deleted file mode 100644 index 2605ba22a..000000000 --- a/static/print.ts +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2023, Compiler Explorer Authors -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -import $ from 'jquery'; - -import {Hub} from './hub'; - -export class Printerinator { - root: JQuery; - printview: JQuery; - itemsAdded: number; - - constructor(hub: Hub) { - const eventHub = hub.createEventHub(); - this.root = $('#root'); - this.printview = $('#printview'); - window.addEventListener('beforeprint', () => { - this.printview.empty(); - this.itemsAdded = 0; - eventHub.emit('printrequest'); - }); - eventHub.on('printdata', (data: any) => { - if (this.itemsAdded++ !== 0) { - this.printview[0].innerHTML += `<div class="pagebreak"></div>`; - } - this.printview[0].innerHTML += data; - }); - } -} diff --git a/static/themes.ts b/static/themes.ts index a13c8368b..d6bd637ed 100644 --- a/static/themes.ts +++ b/static/themes.ts @@ -434,6 +434,10 @@ export class Themer { this.currentTheme = theme; } + public getCurrentTheme() { + return this.currentTheme; + } + private onSettingsChange(newSettings: SiteSettings) { const newTheme = newSettings.theme && newSettings.theme in themes ? themes[newSettings.theme] : themes.default; if (!newTheme.monaco) newTheme.monaco = 'vs'; |