redux-devtools/packages/redux-devtools-trace-monitor/src/openFile.js
2018-12-18 01:03:08 +02:00

93 lines
4.2 KiB
JavaScript

const isFF = navigator.userAgent.indexOf('Firefox') !== -1;
function openResource(fileName, lineNumber, stackFrame) {
const adjustedLineNumber = Math.max(lineNumber - 1, 0);
chrome.devtools.panels.openResource(fileName, adjustedLineNumber, (result) => {
//console.log("openResource callback args: ", callbackArgs);
if(result.isError) {
const {fileName: finalFileName, lineNumber: finalLineNumber} = stackFrame;
const adjustedLineNumber = Math.max(finalLineNumber - 1, 0);
chrome.devtools.panels.openResource(finalFileName, adjustedLineNumber, (result) => {
// console.log("openResource result: ", result);
});
}
});
}
function openAndCloseTab(url) {
chrome.tabs.create({ url }, tab => {
const removeTab = () => {
chrome.windows.onFocusChanged.removeListener(removeTab);
if (tab && tab.id) {
chrome.tabs.remove(tab.id, () => {
if(chrome.runtime.lastError) console.log(chrome.runtime.lastError); // eslint-disable-line no-console
else if (chrome.devtools && chrome.devtools.inspectedWindow) {
chrome.tabs.update(chrome.devtools.inspectedWindow.tabId, {active: true});
}
});
}
};
if (chrome.windows) chrome.windows.onFocusChanged.addListener(removeTab);
});
}
function openInIframe(url) {
const iframe = document.createElement('iframe');
iframe.src = url;
iframe.style = 'display:none';
document.body.appendChild(iframe);
setTimeout(() => iframe.parentNode.removeChild(iframe), 3000);
}
function openInEditor(editor, path, stackFrame) {
const projectPath = path.replace(/\/$/, '');
const file = stackFrame._originalFileName || stackFrame.finalFileName || stackFrame.fileName || '';
let filePath = /^https?:\/\//.test(file) ? file.replace(/^https?:\/\/[^\/]*/, '') : file.replace(/^\w+:\/\//, '');
filePath = filePath.replace(/^\/~\//, '/node_modules/');
const line = stackFrame._originalLineNumber || stackFrame.lineNumber || '0';
const column = stackFrame._originalColumnNumber || stackFrame.columnNumber || '0';
let url;
switch (editor) {
case 'vscode': case 'code':
url = `vscode://file/${projectPath}${filePath}:${line}:${column}`; break;
case 'atom':
url = `atom://core/open/file?filename=${projectPath}${filePath}&line=${line}&column=${column}`; break;
case 'webstorm': case 'phpstorm': case 'idea':
url = `${editor}://open?file=${projectPath}${filePath}&line=${line}&column=${column}`; break;
default: // sublime, emacs, macvim, textmate + custom like https://github.com/eclemens/atom-url-handler
url = `${editor}://open/?url=file://${projectPath}${filePath}&line=${line}&column=${column}`;
}
if (process.env.NODE_ENV === 'development') console.log(url); // eslint-disable-line no-console
if (chrome.devtools && !isFF) {
if (chrome.tabs) openAndCloseTab(url);
else window.open(url);
} else {
openInIframe(url);
}
}
export default function openFile(fileName, lineNumber, stackFrame) {
if (process.env.NODE_ENV === 'development') console.log(fileName, lineNumber, stackFrame); // eslint-disable-line no-console
if (!chrome || !chrome.storage) return; // TODO: Pass editor settings for using outside of browser extension
const storage = isFF ? chrome.storage.local : chrome.storage.sync || chrome.storage.local;
storage.get(['useEditor', 'editor', 'projectPath'], function({ useEditor, editor, projectPath }) {
if (useEditor && projectPath && typeof editor === 'string' && /^\w{1,30}$/.test(editor)) {
openInEditor(editor.toLowerCase(), projectPath, stackFrame);
} else {
if (chrome.devtools && chrome.devtools.panels && chrome.devtools.panels.openResource) {
openResource(fileName, lineNumber, stackFrame);
} else if (chrome.runtime && (chrome.runtime.openOptionsPage || isFF)) {
if (chrome.devtools && isFF) {
chrome.devtools.inspectedWindow.eval('confirm("Set the editor to open the file in?")', result => {
if (!result) return;
chrome.runtime.sendMessage({ type: 'OPEN_OPTIONS' });
});
} else if (confirm('Set the editor to open the file in?')) {
chrome.runtime.openOptionsPage();
}
}
}
});
}