diff --git a/app/webpack.config.js b/app/webpack.config.js index 610ad172..1125fb57 100644 --- a/app/webpack.config.js +++ b/app/webpack.config.js @@ -9,6 +9,7 @@ module.exports = { 'preload': path.resolve(__dirname, 'src/entry.preload.ts'), 'bundle': path.resolve(__dirname, 'src/entry.ts'), }, + mode: process.env.DEV ? 'development' : 'production', context: __dirname, devtool: 'source-map', output: { diff --git a/package.json b/package.json index cc453f22..b1d43b14 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,7 @@ }, "scripts": { "build": "webpack --color --config app/webpack.config.js && webpack --color --config terminus-core/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-terminal/webpack.config.js && webpack --color --config terminus-settings/webpack.config.js && webpack --color --config terminus-plugin-manager/webpack.config.js && webpack --color --config terminus-community-color-schemes/webpack.config.js && webpack --color --config terminus-ssh/webpack.config.js", - "watch": "webpack --progress --color --watch", + "watch": "DEV=1 webpack --progress --color --watch", "start": "cross-env DEV=1 electron app --debug", "prod": "cross-env DEV=1 electron app", "lint": "tslint -c tslint.json -t stylish terminus-*/src/**/*.ts terminus-*/src/*.ts app/src/*.ts", diff --git a/terminus-community-color-schemes/webpack.config.js b/terminus-community-color-schemes/webpack.config.js index e1b447fb..40d4b57f 100644 --- a/terminus-community-color-schemes/webpack.config.js +++ b/terminus-community-color-schemes/webpack.config.js @@ -13,6 +13,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-community-color-schemes:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], diff --git a/terminus-core/webpack.config.js b/terminus-core/webpack.config.js index c95dac73..a26e7385 100644 --- a/terminus-core/webpack.config.js +++ b/terminus-core/webpack.config.js @@ -14,6 +14,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-core:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], diff --git a/terminus-plugin-manager/webpack.config.js b/terminus-plugin-manager/webpack.config.js index db17c178..78a3f8a3 100644 --- a/terminus-plugin-manager/webpack.config.js +++ b/terminus-plugin-manager/webpack.config.js @@ -13,6 +13,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-plugin-manager:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], diff --git a/terminus-settings/webpack.config.js b/terminus-settings/webpack.config.js index b4f90155..50ceecbf 100644 --- a/terminus-settings/webpack.config.js +++ b/terminus-settings/webpack.config.js @@ -13,6 +13,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-settings:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], diff --git a/terminus-ssh/webpack.config.js b/terminus-ssh/webpack.config.js index aacc6f78..5ed37d0d 100644 --- a/terminus-ssh/webpack.config.js +++ b/terminus-ssh/webpack.config.js @@ -12,6 +12,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-ssh:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], diff --git a/terminus-terminal/package.json b/terminus-terminal/package.json index 37fda145..a987e116 100644 --- a/terminus-terminal/package.json +++ b/terminus-terminal/package.json @@ -24,7 +24,8 @@ "@types/winreg": "^1.2.30", "dataurl": "0.1.0", "deep-equal": "1.0.1", - "file-loader": "^0.11.2" + "file-loader": "^0.11.2", + "xterm": "^3.6.0" }, "peerDependencies": { "@angular/common": "4.0.1", diff --git a/terminus-terminal/src/components/terminalSettingsTab.component.pug b/terminus-terminal/src/components/terminalSettingsTab.component.pug index 047a832e..a3f676e5 100644 --- a/terminus-terminal/src/components/terminalSettingsTab.component.pug +++ b/terminus-terminal/src/components/terminalSettingsTab.component.pug @@ -1,6 +1,18 @@ h3.mb-3 Appearance .row .col-md-6 + .form-line + .header + .title Frontend + .description Switches terminal frontend implementation (experimental) + + select.form-control( + [(ngModel)]='config.store.terminal.frontend', + (ngModelChange)='config.save()', + ) + option(value='hterm') hterm + option(value='xterm') xterm + .form-line .header .title Font diff --git a/terminus-terminal/src/components/terminalSettingsTab.component.ts b/terminus-terminal/src/components/terminalSettingsTab.component.ts index 51cb5aea..4e5f498d 100644 --- a/terminus-terminal/src/components/terminalSettingsTab.component.ts +++ b/terminus-terminal/src/components/terminalSettingsTab.component.ts @@ -1,7 +1,7 @@ import { Observable } from 'rxjs' import { debounceTime, distinctUntilChanged, map } from 'rxjs/operators' import { exec } from 'mz/child_process' -const equal = require('deep-equal') +import deepEqual = require('deep-equal') const fontManager = require('font-manager') import { Component, Inject } from '@angular/core' @@ -17,7 +17,7 @@ export class TerminalSettingsTabComponent { shells: IShell[] = [] persistenceProviders: SessionPersistenceProvider[] colorSchemes: ITerminalColorScheme[] = [] - equalComparator = equal + equalComparator = deepEqual editingColorScheme: ITerminalColorScheme schemeChanged = false @@ -88,7 +88,7 @@ export class TerminalSettingsTabComponent { } isCustomScheme (scheme: ITerminalColorScheme) { - return this.config.store.terminal.customColorSchemes.some(x => equal(x, scheme)) + return this.config.store.terminal.customColorSchemes.some(x => deepEqual(x, scheme)) } colorsTrackBy (index) { diff --git a/terminus-terminal/src/components/terminalTab.component.ts b/terminus-terminal/src/components/terminalTab.component.ts index 33436e7b..fd3aac84 100644 --- a/terminus-terminal/src/components/terminalTab.component.ts +++ b/terminus-terminal/src/components/terminalTab.component.ts @@ -7,10 +7,10 @@ import { AppService, ConfigService, BaseTabComponent, ElectronService, HostAppSe import { IShell } from '../api' import { Session, SessionsService } from '../services/sessions.service' import { TerminalService } from '../services/terminal.service' -import { TerminalContainersService } from '../services/terminalContainers.service' +import { TerminalFrontendService } from '../services/terminalFrontend.service' import { TerminalDecorator, ResizeEvent, SessionOptions } from '../api' -import { TermContainer } from '../terminalContainers/termContainer' +import { Frontend } from '../frontends/frontend' @Component({ selector: 'terminalTab', @@ -29,7 +29,7 @@ export class TerminalTabComponent extends BaseTabComponent { @Input() zoom = 0 @ViewChild('content') content @HostBinding('style.background-color') backgroundColor: string - termContainer: TermContainer + frontend: Frontend sessionCloseSubscription: Subscription hotkeysSubscription: Subscription htermVisible = false @@ -39,10 +39,10 @@ export class TerminalTabComponent extends BaseTabComponent { private contextMenu: any private termContainerSubscriptions: Subscription[] = [] - get input$ (): Observable { return this.termContainer.input$ } + get input$ (): Observable { return this.frontend.input$ } get output$ (): Observable { return this.output } - get resize$ (): Observable { return this.termContainer.resize$ } - get alternateScreenActive$ (): Observable { return this.termContainer.alternateScreenActive$ } + get resize$ (): Observable { return this.frontend.resize$ } + get alternateScreenActive$ (): Observable { return this.frontend.alternateScreenActive$ } constructor ( private zone: NgZone, @@ -52,7 +52,7 @@ export class TerminalTabComponent extends BaseTabComponent { private sessions: SessionsService, private electron: ElectronService, private terminalService: TerminalService, - private terminalContainersService: TerminalContainersService, + private terminalContainersService: TerminalFrontendService, public config: ConfigService, private toastr: ToastrService, @Optional() @Inject(TerminalDecorator) private decorators: TerminalDecorator[], @@ -69,23 +69,23 @@ export class TerminalTabComponent extends BaseTabComponent { } switch (hotkey) { case 'ctrl-c': - if (this.termContainer.getSelection()) { - this.termContainer.copySelection() - this.termContainer.clearSelection() + if (this.frontend.getSelection()) { + this.frontend.copySelection() + this.frontend.clearSelection() this.toastr.info('Copied') } else { this.sendInput('\x03') } break case 'copy': - this.termContainer.copySelection() + this.frontend.copySelection() this.toastr.info('Copied') break case 'paste': this.paste() break case 'clear': - this.termContainer.clear() + this.frontend.clear() break case 'zoom-in': this.zoomIn() @@ -138,7 +138,7 @@ export class TerminalTabComponent extends BaseTabComponent { }) this.sessionCloseSubscription = this.session.closed$.subscribe(() => { - this.termContainer.destroy() + this.frontend.destroy() this.app.closeTab(this) }) } @@ -153,16 +153,16 @@ export class TerminalTabComponent extends BaseTabComponent { ngOnInit () { this.focused$.subscribe(() => { this.configure() - this.termContainer.focus() + this.frontend.focus() }) - this.termContainer = this.terminalContainersService.getContainer(this.session) + this.frontend = this.terminalContainersService.getFrontend(this.session) - this.termContainer.ready$.subscribe(() => { + this.frontend.ready$.subscribe(() => { this.htermVisible = true }) - this.termContainer.resize$.pipe(first()).subscribe(async ({columns, rows}) => { + this.frontend.resize$.pipe(first()).subscribe(async ({columns, rows}) => { if (!this.session.open) { this.initializeSession(columns, rows) } @@ -174,7 +174,8 @@ export class TerminalTabComponent extends BaseTabComponent { this.session.releaseInitialDataBuffer() }) - this.termContainer.attach(this.content.nativeElement) + this.frontend.configure(this.config.store) + this.frontend.attach(this.content.nativeElement) this.attachTermContainerHandlers() this.configure() @@ -189,9 +190,9 @@ export class TerminalTabComponent extends BaseTabComponent { }) }, 1000) - this.termContainer.bell$.subscribe(() => { + this.frontend.bell$.subscribe(() => { if (this.config.store.terminal.bell === 'visual') { - this.termContainer.visualBell() + this.frontend.visualBell() } if (this.config.store.terminal.bell === 'audible') { this.bellPlayer.play() @@ -212,7 +213,7 @@ export class TerminalTabComponent extends BaseTabComponent { click: () => { this.zone.run(() => { setTimeout(() => { - this.termContainer.copySelection() + this.frontend.copySelection() this.toastr.info('Copied') }) }) @@ -239,12 +240,12 @@ export class TerminalTabComponent extends BaseTabComponent { attachTermContainerHandlers () { this.detachTermContainerHandlers() this.termContainerSubscriptions = [ - this.termContainer.title$.subscribe(title => this.zone.run(() => this.setTitle(title))), + this.frontend.title$.subscribe(title => this.zone.run(() => this.setTitle(title))), - this.focused$.subscribe(() => this.termContainer.enableResizing = true), - this.blurred$.subscribe(() => this.termContainer.enableResizing = false), + this.focused$.subscribe(() => this.frontend.enableResizing = true), + this.blurred$.subscribe(() => this.frontend.enableResizing = false), - this.termContainer.mouseEvent$.subscribe(event => { + this.frontend.mouseEvent$.subscribe(event => { if (event.type === 'mousedown') { if (event.which === 3) { if (this.config.store.terminal.rightClick === 'menu') { @@ -274,11 +275,11 @@ export class TerminalTabComponent extends BaseTabComponent { } }), - this.termContainer.input$.subscribe(data => { + this.frontend.input$.subscribe(data => { this.sendInput(data) }), - this.termContainer.resize$.subscribe(({columns, rows}) => { + this.frontend.resize$.subscribe(({columns, rows}) => { console.log(`Resizing to ${columns}x${rows}`) this.zone.run(() => { if (this.session.open) { @@ -302,7 +303,7 @@ export class TerminalTabComponent extends BaseTabComponent { } else { this.setProgress(null) } - this.termContainer.write(data) + this.frontend.write(data) } paste () { @@ -319,7 +320,7 @@ export class TerminalTabComponent extends BaseTabComponent { } configure (): void { - this.termContainer.configure(this.config.store) + this.frontend.configure(this.config.store) if (this.config.store.terminal.background === 'colorScheme') { if (this.config.store.terminal.colorScheme.background) { @@ -332,20 +333,21 @@ export class TerminalTabComponent extends BaseTabComponent { zoomIn () { this.zoom++ - this.termContainer.setZoom(this.zoom) + this.frontend.setZoom(this.zoom) } zoomOut () { this.zoom-- - this.termContainer.setZoom(this.zoom) + this.frontend.setZoom(this.zoom) } resetZoom () { this.zoom = 0 - this.termContainer.setZoom(this.zoom) + this.frontend.setZoom(this.zoom) } ngOnDestroy () { + this.frontend.detach(this.content.nativeElement) this.detachTermContainerHandlers() this.config.enabledServices(this.decorators).forEach(decorator => { decorator.detach(this) diff --git a/terminus-terminal/src/config.ts b/terminus-terminal/src/config.ts index a4f9fed9..a378b7d7 100644 --- a/terminus-terminal/src/config.ts +++ b/terminus-terminal/src/config.ts @@ -3,6 +3,7 @@ import { ConfigProvider, Platform } from 'terminus-core' export class TerminalConfigProvider extends ConfigProvider { defaults = { terminal: { + frontend: 'hterm', autoOpen: false, fontSize: 14, linePadding: 0, diff --git a/terminus-terminal/src/terminalContainers/termContainer.ts b/terminus-terminal/src/frontends/frontend.ts similarity index 95% rename from terminus-terminal/src/terminalContainers/termContainer.ts rename to terminus-terminal/src/frontends/frontend.ts index 0eba8e62..253a9d3c 100644 --- a/terminus-terminal/src/terminalContainers/termContainer.ts +++ b/terminus-terminal/src/frontends/frontend.ts @@ -1,7 +1,7 @@ import { Observable, Subject, AsyncSubject, ReplaySubject, BehaviorSubject } from 'rxjs' import { ResizeEvent } from '../api' -export abstract class TermContainer { +export abstract class Frontend { enableResizing = true protected ready = new AsyncSubject() protected title = new ReplaySubject(1) @@ -26,6 +26,7 @@ export abstract class TermContainer { get drop$ (): Observable { return this.drop } abstract attach (host: HTMLElement): void + detach (host: HTMLElement): void { } // tslint:disable-line destroy (): void { for (let o of [ diff --git a/terminus-terminal/src/terminalContainers/htermContainer.ts b/terminus-terminal/src/frontends/htermFrontend.ts similarity index 98% rename from terminus-terminal/src/terminalContainers/htermContainer.ts rename to terminus-terminal/src/frontends/htermFrontend.ts index d3f2fe66..5023cae2 100644 --- a/terminus-terminal/src/terminalContainers/htermContainer.ts +++ b/terminus-terminal/src/frontends/htermFrontend.ts @@ -1,7 +1,7 @@ -import { TermContainer } from './termContainer' +import { Frontend } from './frontend' import { hterm, preferenceManager } from '../hterm' -export class HTermContainer extends TermContainer { +export class HTermFrontend extends Frontend { term: any io: any private htermIframe: HTMLElement @@ -50,6 +50,9 @@ export class HTermContainer extends TermContainer { } configure (config: any): void { + if (!this.term) { + return + } this.configuredFontSize = config.terminal.fontSize this.configuredLinePadding = config.terminal.linePadding this.setFontSize() @@ -144,6 +147,7 @@ export class HTermContainer extends TermContainer { private init () { this.term = new hterm.hterm.Terminal() + this.term.colorPaletteOverrides = [] this.term.onTerminalReady = () => { this.term.installKeyboard() this.term.scrollPort_.setCtrlVPaste(true) @@ -225,7 +229,5 @@ export class HTermContainer extends TermContainer { size.height += this.configuredLinePadding return size } - - this.term.colorPaletteOverrides = [] } } diff --git a/terminus-terminal/src/frontends/xtermFrontend.ts b/terminus-terminal/src/frontends/xtermFrontend.ts new file mode 100644 index 00000000..6f6cf129 --- /dev/null +++ b/terminus-terminal/src/frontends/xtermFrontend.ts @@ -0,0 +1,121 @@ +import { Frontend } from './frontend' +import { Terminal, ITheme } from 'xterm' +import * as fit from 'xterm/lib/addons/fit/fit' +import 'xterm/dist/xterm.css' +import deepEqual = require('deep-equal') + +Terminal.applyAddon(fit) + +export class XTermFrontend extends Frontend { + enableResizing = true + xterm: Terminal + private configuredFontSize = 0 + private zoom = 0 + private resizeHandler: any + private configuredTheme: ITheme = {} + + constructor () { + super() + this.xterm = new Terminal({ + allowTransparency: true, + enableBold: true, + }) + this.xterm.on('data', data => { + this.input.next(data) + }) + this.xterm.on('resize', ({ cols, rows }) => { + this.resize.next({ rows, columns: cols }) + }) + this.xterm.on('title', title => { + this.title.next(title) + }) + } + + attach (host: HTMLElement): void { + this.xterm.open(host) + this.ready.next(null) + this.ready.complete() + + this.resizeHandler = () => (this.xterm as any).fit() + window.addEventListener('resize', this.resizeHandler) + + this.resizeHandler() + + host.addEventListener('dragOver', (event: any) => this.dragOver.next(event)) + host.addEventListener('drop', event => this.drop.next(event)) + } + + detach (host: HTMLElement): void { + window.removeEventListener('resize', this.resizeHandler) + } + + getSelection (): string { + return this.xterm.getSelection() + } + + copySelection (): void { + (navigator as any).clipboard.writeText(this.getSelection()) + } + + clearSelection (): void { + this.xterm.clearSelection() + } + + focus (): void { + setTimeout(() => this.xterm.focus()) + } + + write (data: string): void { + this.xterm.write(data) + } + + clear (): void { + this.xterm.clear() + } + + visualBell (): void { + (this.xterm as any).bell() + } + + configure (config: any): void { + this.xterm.setOption('fontFamily', `"${config.terminal.font}", "monospace-fallback", monospace`) + this.xterm.setOption('bellStyle', config.terminal.bell) + this.xterm.setOption('cursorStyle', { + beam: 'bar' + }[config.terminal.cuxrsor] || config.terminal.cursor) + this.xterm.setOption('cursorBlink', config.terminal.cursorBlink) + this.xterm.setOption('macOptionIsMeta', config.terminal.altIsMeta) + // this.xterm.setOption('colors', ) + this.configuredFontSize = config.terminal.fontSize + this.setFontSize() + + let theme: ITheme = { + foreground: config.terminal.colorScheme.foreground, + background: (config.terminal.background === 'colorScheme') ? config.terminal.colorScheme.background : 'transparent', + cursor: config.terminal.colorScheme.cursor, + } + + const colorNames = [ + 'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white', + 'brightBlack', 'brightRed', 'brightGreen', 'brightYellow', 'brightBlue', 'brightMagenta', 'brightCyan', 'brightWhite' + ] + + for (let i = 0; i < colorNames.length; i++) { + theme[colorNames[i]] = config.terminal.colorScheme.colors[i] + } + + if (!deepEqual(this.configuredTheme, theme)) { + this.xterm.setOption('theme', theme) + this.configuredTheme = theme + } + } + + setZoom (zoom: number): void { + this.zoom = zoom + this.setFontSize() + } + + private setFontSize () { + this.xterm.setOption('fontSize', this.configuredFontSize * Math.pow(1.1, this.zoom)) + } +} diff --git a/terminus-terminal/src/index.ts b/terminus-terminal/src/index.ts index e1fed22e..5f27c1fb 100644 --- a/terminus-terminal/src/index.ts +++ b/terminus-terminal/src/index.ts @@ -13,8 +13,8 @@ import { TerminalSettingsTabComponent } from './components/terminalSettingsTab.c import { ColorPickerComponent } from './components/colorPicker.component' import { SessionsService, BaseSession } from './services/sessions.service' +import { TerminalFrontendService } from './services/terminalFrontend.service' import { TerminalService } from './services/terminal.service' -import { TerminalContainersService } from './services/terminalContainers.service' import { ScreenPersistenceProvider } from './persistence/screen' import { TMuxPersistenceProvider } from './persistence/tmux' @@ -50,8 +50,8 @@ import { hterm } from './hterm' ], providers: [ SessionsService, + TerminalFrontendService, TerminalService, - TerminalContainersService, { provide: ToolbarButtonProvider, useClass: ButtonProvider, multi: true }, { provide: TabRecoveryProvider, useClass: RecoveryProvider, multi: true }, @@ -125,4 +125,4 @@ export default class TerminalModule { } export * from './api' -export { TerminalService, BaseSession, TerminalTabComponent, TerminalContainersService } +export { TerminalService, BaseSession, TerminalTabComponent, TerminalFrontendService } diff --git a/terminus-terminal/src/pathDrop.ts b/terminus-terminal/src/pathDrop.ts index c5d24b8b..88b98f49 100644 --- a/terminus-terminal/src/pathDrop.ts +++ b/terminus-terminal/src/pathDrop.ts @@ -10,10 +10,10 @@ export class PathDropDecorator extends TerminalDecorator { attach (terminal: TerminalTabComponent): void { setTimeout(() => { this.subscriptions = [ - terminal.termContainer.dragOver$.subscribe(event => { + terminal.frontend.dragOver$.subscribe(event => { event.preventDefault() }), - terminal.termContainer.drop$.subscribe(event => { + terminal.frontend.drop$.subscribe(event => { for (let file of event.dataTransfer.files as any) { this.injectPath(terminal, file.path) } diff --git a/terminus-terminal/src/persistence/tmux.ts b/terminus-terminal/src/persistence/tmux.ts index 6189cfed..2b55706f 100644 --- a/terminus-terminal/src/persistence/tmux.ts +++ b/terminus-terminal/src/persistence/tmux.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core' import { execFileSync } from 'child_process' -import * as AsyncLock from 'async-lock' +import AsyncLock = require('async-lock') import { ConnectableObservable, AsyncSubject, Subject } from 'rxjs' import { first, publish } from 'rxjs/operators' import * as childProcess from 'child_process' diff --git a/terminus-terminal/src/services/sessions.service.ts b/terminus-terminal/src/services/sessions.service.ts index 9bd1e4ec..67e5b0b0 100644 --- a/terminus-terminal/src/services/sessions.service.ts +++ b/terminus-terminal/src/services/sessions.service.ts @@ -1,10 +1,10 @@ -const psNode = require('ps-node') +import psNode = require('ps-node') let nodePTY import * as fs from 'mz/fs' import { Observable, Subject } from 'rxjs' import { first } from 'rxjs/operators' import { Injectable, Inject } from '@angular/core' -import { Logger, LogService, ElectronService, ConfigService } from 'terminus-core' +import { Logger, LogService, ConfigService } from 'terminus-core' import { exec } from 'mz/child_process' import { SessionOptions, SessionPersistenceProvider } from '../api' @@ -202,7 +202,6 @@ export class SessionsService { constructor ( @Inject(SessionPersistenceProvider) private persistenceProviders: SessionPersistenceProvider[], private config: ConfigService, - electron: ElectronService, log: LogService, ) { nodePTY = require('node-pty-tmp') diff --git a/terminus-terminal/src/services/terminalContainers.service.ts b/terminus-terminal/src/services/terminalContainers.service.ts deleted file mode 100644 index 12f4d603..00000000 --- a/terminus-terminal/src/services/terminalContainers.service.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Injectable } from '@angular/core' -import { TermContainer } from '../terminalContainers/termContainer' -import { HTermContainer } from '../terminalContainers/htermContainer' -import { BaseSession } from '../services/sessions.service' - -@Injectable() -export class TerminalContainersService { - private containers = new WeakMap() - - getContainer (session: BaseSession): TermContainer { - if (!this.containers.has(session)) { - this.containers.set(session, new HTermContainer()) - } - return this.containers.get(session) - } -} diff --git a/terminus-terminal/src/services/terminalFrontend.service.ts b/terminus-terminal/src/services/terminalFrontend.service.ts new file mode 100644 index 00000000..5978c30b --- /dev/null +++ b/terminus-terminal/src/services/terminalFrontend.service.ts @@ -0,0 +1,25 @@ +import { Injectable } from '@angular/core' +import { ConfigService } from 'terminus-core' +import { Frontend } from '../frontends/frontend' +import { HTermFrontend } from '../frontends/htermFrontend' +import { XTermFrontend } from '../frontends/xtermFrontend' +import { BaseSession } from '../services/sessions.service' + +@Injectable() +export class TerminalFrontendService { + private containers = new WeakMap() + + constructor (private config: ConfigService) { } + + getFrontend (session: BaseSession): Frontend { + if (!this.containers.has(session)) { + this.containers.set( + session, + (this.config.store.terminal.frontend === 'xterm') + ? new XTermFrontend() + : new HTermFrontend() + ) + } + return this.containers.get(session) + } +} diff --git a/terminus-terminal/webpack.config.js b/terminus-terminal/webpack.config.js index e556bf4a..fa749071 100644 --- a/terminus-terminal/webpack.config.js +++ b/terminus-terminal/webpack.config.js @@ -13,6 +13,7 @@ module.exports = { libraryTarget: 'umd', devtoolModuleFilenameTemplate: 'webpack-terminus-terminal:///[resource-path]', }, + mode: process.env.DEV ? 'development' : 'production', resolve: { modules: ['.', 'src', 'node_modules', '../app/node_modules'].map(x => path.join(__dirname, x)), extensions: ['.ts', '.js'], @@ -35,7 +36,7 @@ module.exports = { }, { test: /\.pug$/, use: ['apply-loader', 'pug-loader'] }, { test: /\.scss$/, use: ['to-string-loader', 'css-loader', 'sass-loader'] }, - { test: /\.css$/, use: ['to-string-loader', 'css-loader'] }, + { test: /\.css$/, use: ['style-loader', 'css-loader'] }, { test: /\.svg/, use: ['svg-inline-loader'] }, { test: /\.(ttf|eot|otf|woff|woff2|ogg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, diff --git a/terminus-terminal/yarn.lock b/terminus-terminal/yarn.lock index fcd04ab9..af7c6da1 100644 --- a/terminus-terminal/yarn.lock +++ b/terminus-terminal/yarn.lock @@ -137,3 +137,7 @@ thenify-all@^1.0.0: winreg@^1.2.3: version "1.2.4" resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b" + +xterm@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/xterm/-/xterm-3.6.0.tgz#9b95cd23a338e5842343aec1a104f094c5153e7c" diff --git a/tsconfig.json b/tsconfig.json index 3e0218b7..66f742a9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -13,6 +13,8 @@ "noUnusedLocals": true, "declaration": true, "skipLibCheck": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, "lib": [ "dom", "es5",