mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-10 05:35:05 +08:00
Move and rename files. NOAUTOREVERT=true NOPRESUBMIT=true NOTREECHECKS=true Bug: 768828 TBR=darin@chromium.org NOTRY=true Change-Id: I66d3b155808bc5bdbf237b80208e1e552bcf7f28 Reviewed-on: https://chromium-review.googlesource.com/1001153 Reviewed-by: Blink Reformat <blink-reformat@chromium.org> Commit-Queue: Blink Reformat <blink-reformat@chromium.org> Cr-Original-Commit-Position: refs/heads/master@{#549061} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: 0aee4434a4dba42a42abaea9bfbc0cd196a63bc1
150 lines
4.3 KiB
JavaScript
150 lines
4.3 KiB
JavaScript
// Copyright 2016 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
/**
|
|
* @unrestricted
|
|
*/
|
|
Terminal.TerminalWidget = class extends UI.VBox {
|
|
constructor() {
|
|
super(true);
|
|
this.registerRequiredCSS('terminal/xterm.js/build/xterm.css');
|
|
this.registerRequiredCSS('terminal/terminal.css');
|
|
this.element.classList.add('terminal-root');
|
|
this._init();
|
|
this._linkifier = new Components.Linkifier();
|
|
this._config = {attributes: true, childList: true, characterData: true, subtree: true};
|
|
}
|
|
|
|
async _init() {
|
|
const backend = await Services.serviceManager.createRemoteService('Terminal');
|
|
this._initialized(backend);
|
|
}
|
|
|
|
/**
|
|
* @param {?Services.ServiceManager.Service} backend
|
|
*/
|
|
_initialized(backend) {
|
|
if (!backend) {
|
|
if (!this._unavailableLabel) {
|
|
this._unavailableLabel = this.contentElement.createChild('div', 'terminal-error-message fill');
|
|
this._unavailableLabel.createChild('div').textContent = Common.UIString('Terminal service is not available');
|
|
}
|
|
setTimeout(this._init.bind(this), 2000);
|
|
return;
|
|
}
|
|
|
|
if (this._unavailableLabel) {
|
|
this._unavailableLabel.remove();
|
|
delete this._unavailableLabel;
|
|
}
|
|
|
|
this._backend = backend;
|
|
|
|
if (!this._term) {
|
|
this._term = new Terminal({cursorBlink: true});
|
|
this._term.open(this.contentElement);
|
|
this._mutationObserver = new MutationObserver(this._linkify.bind(this));
|
|
this._mutationObserver.observe(this.contentElement, this._config);
|
|
this._term.on('data', data => {
|
|
this._backend.send('write', {data: data});
|
|
});
|
|
this._term.fit();
|
|
this._term.on('resize', size => {
|
|
this._backend.send('resize', {cols: size.cols, rows: size.rows});
|
|
});
|
|
}
|
|
|
|
this._backend.send('init', {cols: this._term.cols, rows: this._term.rows});
|
|
this._backend.on('data', result => {
|
|
this._term.write(result.data);
|
|
});
|
|
this._backend.on('disposed', this._disposed.bind(this));
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
onResize() {
|
|
if (this._term)
|
|
this._term.fit();
|
|
}
|
|
|
|
_disposed() {
|
|
this._initialized(null);
|
|
}
|
|
|
|
/**
|
|
* @override
|
|
*/
|
|
ownerViewDisposed() {
|
|
if (this._backend)
|
|
this._backend.dispose();
|
|
}
|
|
|
|
_linkify() {
|
|
this._mutationObserver.takeRecords();
|
|
this._mutationObserver.disconnect();
|
|
this._linkifier.reset();
|
|
const rows = this._term['rowContainer'].children;
|
|
for (let i = 0; i < rows.length; i++)
|
|
this._linkifyTerminalLine(rows[i]);
|
|
this._mutationObserver.observe(this.contentElement, this._config);
|
|
}
|
|
|
|
/**
|
|
* @param {string} string
|
|
*/
|
|
_linkifyText(string) {
|
|
const regex1 = /([/\w\.-]*)+\:([\d]+)(?:\:([\d]+))?/;
|
|
const regex2 = /([/\w\.-]*)+\(([\d]+),([\d]+)\)/;
|
|
const container = createDocumentFragment();
|
|
|
|
while (string) {
|
|
const linkString = regex1.exec(string) || regex2.exec(string);
|
|
if (!linkString)
|
|
break;
|
|
|
|
const text = linkString[0];
|
|
const path = linkString[1];
|
|
const lineNumber = parseInt(linkString[2], 10) - 1 || 0;
|
|
const columnNumber = parseInt(linkString[3], 10) - 1 || 0;
|
|
|
|
const uiSourceCode = Workspace.workspace.uiSourceCodes().find(uisc => uisc.url().endsWith(path));
|
|
const linkIndex = string.indexOf(text);
|
|
const nonLink = string.substring(0, linkIndex);
|
|
container.appendChild(createTextNode(nonLink));
|
|
|
|
if (uiSourceCode) {
|
|
container.appendChild(Components.Linkifier.linkifyURL(
|
|
uiSourceCode.url(),
|
|
{text, lineNumber, columnNumber, maxLengh: Number.MAX_VALUE, className: 'terminal-link'}));
|
|
} else {
|
|
container.appendChild(createTextNode(text));
|
|
}
|
|
string = string.substring(linkIndex + text.length);
|
|
}
|
|
|
|
if (string)
|
|
container.appendChild(createTextNode(string));
|
|
return container;
|
|
}
|
|
|
|
/**
|
|
* @param {!Node} line
|
|
*/
|
|
_linkifyTerminalLine(line) {
|
|
let node = line.firstChild;
|
|
while (node) {
|
|
if (node.nodeType !== Node.TEXT_NODE) {
|
|
node = node.nextSibling;
|
|
continue;
|
|
}
|
|
const nextNode = node.nextSibling;
|
|
node.remove();
|
|
const linkified = this._linkifyText(node.textContent);
|
|
line.insertBefore(linkified, nextNode);
|
|
node = nextNode;
|
|
}
|
|
}
|
|
};
|