diff --git a/lib/components/term.js b/lib/components/term.js index 3441b375..7780ab55 100644 --- a/lib/components/term.js +++ b/lib/components/term.js @@ -298,6 +298,65 @@ export default class Term extends React.PureComponent { return !e.catched; } + componentDidUpdate(prevProps) { + if (!prevProps.cleared && this.props.cleared) { + this.clear(); + } + + const nextTermOptions = getTermOptions(this.props); + + // Use bellSound in nextProps if it exists + // otherwise use the default sound found in xterm. + nextTermOptions.bellSound = this.props.bellSound || this.termDefaultBellSound; + + if (!prevProps.search && this.props.search) { + this.search(); + } + + // Update only options that have changed. + Object.keys(nextTermOptions) + .filter(option => option !== 'theme' && nextTermOptions[option] !== this.termOptions[option]) + .forEach(option => { + try { + this.term.setOption(option, nextTermOptions[option]); + } catch (e) { + if (/The webgl renderer only works with the webgl char atlas/i.test(e.message)) { + // Ignore this because the char atlas will also be changed + } else { + throw e; + } + } + }); + + // Do we need to update theme? + const shouldUpdateTheme = + !this.termOptions.theme || + nextTermOptions.rendererType !== this.termOptions.rendererType || + Object.keys(nextTermOptions.theme).some( + option => nextTermOptions.theme[option] !== this.termOptions.theme[option] + ); + if (shouldUpdateTheme) { + this.term.setOption('theme', nextTermOptions.theme); + } + + this.termOptions = nextTermOptions; + + if ( + this.props.fontSize !== prevProps.fontSize || + this.props.fontFamily !== prevProps.fontFamily || + this.props.lineHeight !== prevProps.lineHeight || + this.props.letterSpacing !== prevProps.letterSpacing + ) { + // resize to fit the container + this.fitResize(); + } + + if (prevProps.rows !== this.props.rows || prevProps.cols !== this.props.cols) { + this.resize(this.props.cols, this.props.rows); + } + } + + //TODO: Remove usage of legacy and soon deprecated lifecycle methods UNSAFE_componentWillReceiveProps(nextProps) { if (!this.props.cleared && nextProps.cleared) { this.clear(); diff --git a/lib/index.js b/lib/index.js index 7fa161a8..de53c0f9 100644 --- a/lib/index.js +++ b/lib/index.js @@ -33,14 +33,14 @@ window.__defineGetter__('plugins', () => plugins); const fetchFileData = configData => { const configInfo = Object.assign({}, configData, {bellSound: null}); - if (configInfo.bell.toUpperCase() !== 'SOUND' || !configInfo.bellSoundURL) { + if (!configInfo.bell || configInfo.bell.toUpperCase() !== 'SOUND' || !configInfo.bellSoundURL) { store_.dispatch(reloadConfig(configInfo)); return; } getBase64FileData(configInfo.bellSoundURL).then(base64FileData => { // prepend "base64," to the result of this method in order for this to work properly within xterm.js - const bellSound = 'base64,' + base64FileData; + const bellSound = !base64FileData ? null : 'base64,' + base64FileData; configInfo.bellSound = bellSound; store_.dispatch(reloadConfig(configInfo)); }); diff --git a/lib/utils/file.ts b/lib/utils/file.ts index 710aa730..247c7e7f 100644 --- a/lib/utils/file.ts +++ b/lib/utils/file.ts @@ -21,7 +21,7 @@ export function isExecutable(fileStat: Stats): boolean { } export function getBase64FileData(filePath: string): Promise { - return new Promise(resolve => { + return new Promise((resolve): void => { return fs.readFile(filePath, (err, data) => { if (err) { // Gracefully fail with a warning