-
Joe Haddad authored
* Browser sort is not stable * Fix ordering of final message * Register the warning capture * Display only createElement warnings * Use different method name * Fix regression * Ignore errors with only node_module files * Ignore null files, too * Revise count * Revise warning * Update overlay.js * Add support for https://github.com/facebook/react/pull/9679 * Use absolute paths * Trim path if it's absolute * Make sure it's an absolute path * Oops * Tweak for new behavior * Make it safer * More resilient warnings * Prettier output * Fix flow
76d2d848
/* @flow */
import { enableTabClick } from '../utils/dom/enableTabClick';
import { createCode } from './code';
import { isInternalFile } from '../utils/isInternalFile';
import type { StackFrame } from '../utils/stack-frame';
import type { FrameSetting, OmitsObject } from './frames';
import { applyStyles } from '../utils/dom/css';
import {
omittedFramesStyle,
functionNameStyle,
depStyle,
linkStyle,
anchorStyle,
hiddenStyle,
} from '../styles';
function getGroupToggle(
document: Document,
omitsCount: number,
omitBundle: number
) {
const omittedFrames = document.createElement('div');
enableTabClick(omittedFrames);
const text1 = document.createTextNode(
'\u25B6 ' + omitsCount + ' stack frames were collapsed.'
);
omittedFrames.appendChild(text1);
omittedFrames.addEventListener('click', function() {
const hide = text1.textContent.match(/▲/);
const list = document.getElementsByName('bundle-' + omitBundle);
for (let index = 0; index < list.length; ++index) {
const n = list[index];
if (hide) {
n.style.display = 'none';
} else {
n.style.display = '';
}
}
if (hide) {
text1.textContent = text1.textContent.replace(/▲/, '▶');
text1.textContent = text1.textContent.replace(/expanded/, 'collapsed');
} else {
text1.textContent = text1.textContent.replace(/▶/, '▲');
text1.textContent = text1.textContent.replace(/collapsed/, 'expanded');
}
});
applyStyles(omittedFrames, omittedFramesStyle);
return omittedFrames;
}
function insertBeforeBundle(
document: Document,
parent: Node,
omitsCount: number,
omitBundle: number,
actionElement
) {
const children = document.getElementsByName('bundle-' + omitBundle);
if (children.length < 1) {
return;
}
let first: ?Node = children[0];
while (first != null && first.parentNode !== parent) {
first = first.parentNode;
}
const div = document.createElement('div');
enableTabClick(div);
div.setAttribute('name', 'bundle-' + omitBundle);
const text = document.createTextNode(
'\u25BC ' + omitsCount + ' stack frames were expanded.'
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
);
div.appendChild(text);
div.addEventListener('click', function() {
return actionElement.click();
});
applyStyles(div, omittedFramesStyle);
div.style.display = 'none';
parent.insertBefore(div, first);
}
function frameDiv(document: Document, functionName, url, internalUrl) {
const frame = document.createElement('div');
const frameFunctionName = document.createElement('div');
let cleanedFunctionName;
if (!functionName || functionName === 'Object.<anonymous>') {
cleanedFunctionName = '(anonymous function)';
} else {
cleanedFunctionName = functionName;
}
const cleanedUrl = url.replace('webpack://', '.');
if (internalUrl) {
applyStyles(
frameFunctionName,
Object.assign({}, functionNameStyle, depStyle)
);
} else {
applyStyles(frameFunctionName, functionNameStyle);
}
frameFunctionName.appendChild(document.createTextNode(cleanedFunctionName));
frame.appendChild(frameFunctionName);
const frameLink = document.createElement('div');
applyStyles(frameLink, linkStyle);
const frameAnchor = document.createElement('a');
applyStyles(frameAnchor, anchorStyle);
frameAnchor.appendChild(document.createTextNode(cleanedUrl));
frameLink.appendChild(frameAnchor);
frame.appendChild(frameLink);
return frame;
}
function createFrame(
document: Document,
frameSetting: FrameSetting,
frame: StackFrame,
contextSize: number,
critical: boolean,
omits: OmitsObject,
omitBundle: number,
parentContainer: HTMLDivElement,
lastElement: boolean
) {
const { compiled } = frameSetting;
let { functionName, _originalFileName: sourceFileName } = frame;
const {
fileName,
lineNumber,
columnNumber,
_scriptCode: scriptLines,
_originalLineNumber: sourceLineNumber,
_originalColumnNumber: sourceColumnNumber,
_originalScriptCode: sourceLines,
} = frame;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
// TODO: find a better place for this.
// Chrome has a bug with inferring function.name:
// https://github.com/facebookincubator/create-react-app/issues/2097
// Let's ignore a meaningless name we get for top-level modules.
if (functionName === 'Object.friendlySyntaxErrorLabel') {
functionName = '(anonymous function)';
}
let url;
if (!compiled && sourceFileName && sourceLineNumber) {
// Remove everything up to the first /src/
const trimMatch = /^[/|\\].*?[/|\\](src[/|\\].*)/.exec(sourceFileName);
if (trimMatch && trimMatch[1]) {
sourceFileName = trimMatch[1];
}
url = sourceFileName + ':' + sourceLineNumber;
if (sourceColumnNumber) {
url += ':' + sourceColumnNumber;
}
} else if (fileName && lineNumber) {
url = fileName + ':' + lineNumber;
if (columnNumber) {
url += ':' + columnNumber;
}
} else {
url = 'unknown';
}
let needsHidden = false;
const internalUrl = isInternalFile(url, sourceFileName);
if (internalUrl) {
++omits.value;
needsHidden = true;
}
let collapseElement = null;
if (!internalUrl || lastElement) {
if (omits.value > 0) {
const capV = omits.value;
const omittedFrames = getGroupToggle(document, capV, omitBundle);
window.requestAnimationFrame(() => {
insertBeforeBundle(
document,
parentContainer,
capV,
omitBundle,
omittedFrames
);
});
if (lastElement && internalUrl) {
collapseElement = omittedFrames;
} else {
parentContainer.appendChild(omittedFrames);
}
++omits.bundle;
}
omits.value = 0;
}
const elem = frameDiv(document, functionName, url, internalUrl);
if (needsHidden) {
applyStyles(elem, hiddenStyle);
elem.setAttribute('name', 'bundle-' + omitBundle);
}
let hasSource = false;
if (!internalUrl) {
if (
compiled && scriptLines && scriptLines.length !== 0 && lineNumber != null
) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
elem.appendChild(
createCode(
document,
scriptLines,
lineNumber,
columnNumber,
contextSize,
critical
)
);
hasSource = true;
} else if (
!compiled &&
sourceLines &&
sourceLines.length !== 0 &&
sourceLineNumber != null
) {
elem.appendChild(
createCode(
document,
sourceLines,
sourceLineNumber,
sourceColumnNumber,
contextSize,
critical
)
);
hasSource = true;
}
}
return { elem: elem, hasSource: hasSource, collapseElement: collapseElement };
}
export { createFrame };