Merge pull request #73 from lmccart/console
fixing line numbers in console
This commit is contained in:
commit
669a7d47e5
1 changed files with 95 additions and 46 deletions
|
@ -3,55 +3,100 @@ import ReactDOM from 'react-dom';
|
||||||
import escapeStringRegexp from 'escape-string-regexp';
|
import escapeStringRegexp from 'escape-string-regexp';
|
||||||
import srcDoc from 'srcdoc-polyfill';
|
import srcDoc from 'srcdoc-polyfill';
|
||||||
|
|
||||||
const hijackConsoleScript = `<script>
|
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
|
||||||
var iframeWindow = window;
|
|
||||||
var originalConsole = iframeWindow.console;
|
|
||||||
iframeWindow.console = {};
|
|
||||||
|
|
||||||
var methods = [
|
const startTag = 'filestart-';
|
||||||
'debug', 'clear', 'error', 'info', 'log', 'warn'
|
|
||||||
];
|
|
||||||
|
|
||||||
methods.forEach( function(method) {
|
function getAllScriptOffsets(htmlFile) {
|
||||||
iframeWindow.console[method] = function() {
|
const offs = [];
|
||||||
originalConsole[method].apply(originalConsole, arguments);
|
let found = true;
|
||||||
|
let lastInd = 0;
|
||||||
|
let ind = 0;
|
||||||
|
let endFilenameInd = 0;
|
||||||
|
let filename = '';
|
||||||
|
let lineOffset = 0;
|
||||||
|
while (found) {
|
||||||
|
ind = htmlFile.indexOf(startTag, lastInd);
|
||||||
|
if (ind === -1) {
|
||||||
|
found = false;
|
||||||
|
} else {
|
||||||
|
endFilenameInd = htmlFile.indexOf('.js', ind + startTag.length + 3);
|
||||||
|
filename = htmlFile.substring(ind + startTag.length, endFilenameInd);
|
||||||
|
lineOffset = htmlFile.substring(0, ind).split('\n').length;
|
||||||
|
offs.push([lineOffset, filename]);
|
||||||
|
lastInd = ind + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return offs;
|
||||||
|
}
|
||||||
|
|
||||||
var args = Array.from(arguments);
|
function hijackConsoleScript(offs) {
|
||||||
args = args.map(function(i) {
|
const s = `<script>
|
||||||
// catch objects
|
function getScriptOff(line) {
|
||||||
return (typeof i === 'string') ? i : JSON.stringify(i);
|
var offs = ${offs};
|
||||||
});
|
var l = 0;
|
||||||
|
var file = '';
|
||||||
|
for (var i=0; i<offs.length; i++) {
|
||||||
|
var n = offs[i][0];
|
||||||
|
if (n < line && n > l) {
|
||||||
|
l = n;
|
||||||
|
file = offs[i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [line - l, file];
|
||||||
|
}
|
||||||
|
|
||||||
// post message to parent window
|
|
||||||
window.parent.postMessage({
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
method: method,
|
var iframeWindow = window;
|
||||||
arguments: args,
|
var originalConsole = iframeWindow.console;
|
||||||
source: 'sketch'
|
iframeWindow.console = {};
|
||||||
}, '*');
|
|
||||||
|
var methods = [
|
||||||
|
'debug', 'clear', 'error', 'info', 'log', 'warn'
|
||||||
|
];
|
||||||
|
|
||||||
|
methods.forEach( function(method) {
|
||||||
|
iframeWindow.console[method] = function() {
|
||||||
|
originalConsole[method].apply(originalConsole, arguments);
|
||||||
|
|
||||||
|
var args = Array.from(arguments);
|
||||||
|
args = args.map(function(i) {
|
||||||
|
// catch objects
|
||||||
|
return (typeof i === 'undefined') ? 'undefined' : JSON.stringify(i);
|
||||||
|
});
|
||||||
|
|
||||||
|
// post message to parent window
|
||||||
|
window.parent.postMessage({
|
||||||
|
method: method,
|
||||||
|
arguments: args,
|
||||||
|
source: 'sketch'
|
||||||
|
}, '*');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// catch reference errors, via http://stackoverflow.com/a/12747364/2994108
|
||||||
|
window.onerror = function (msg, url, lineNumber, columnNo, error) {
|
||||||
|
var string = msg.toLowerCase();
|
||||||
|
var substring = "script error";
|
||||||
|
var data = {};
|
||||||
|
|
||||||
|
if (string.indexOf(substring) !== -1){
|
||||||
|
data = 'Script Error: See Browser Console for Detail';
|
||||||
|
} else {
|
||||||
|
var fileInfo = getScriptOff(lineNumber);
|
||||||
|
data = msg + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')';
|
||||||
|
}
|
||||||
|
window.parent.postMessage({
|
||||||
|
method: 'error',
|
||||||
|
arguments: data,
|
||||||
|
source: 'sketch'
|
||||||
|
}, '*');
|
||||||
|
return false;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
</script>`;
|
||||||
// catch reference errors, via http://stackoverflow.com/a/12747364/2994108
|
return s;
|
||||||
window.onerror = function (msg, url, lineNumber, columnNo, error) {
|
}
|
||||||
var string = msg.toLowerCase();
|
|
||||||
var substring = "script error";
|
|
||||||
var data = {};
|
|
||||||
|
|
||||||
if (string.indexOf(substring) > -1){
|
|
||||||
data = 'Script Error: See Browser Console for Detail';
|
|
||||||
} else {
|
|
||||||
data = msg + ' Line: ' + lineNumber + 'column: ' + columnNo;
|
|
||||||
}
|
|
||||||
window.parent.postMessage({
|
|
||||||
method: 'error',
|
|
||||||
arguments: data,
|
|
||||||
source: 'sketch'
|
|
||||||
}, '*');
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
</script>`;
|
|
||||||
|
|
||||||
class PreviewFrame extends React.Component {
|
class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
|
@ -95,6 +140,7 @@ class PreviewFrame extends React.Component {
|
||||||
|
|
||||||
injectLocalFiles() {
|
injectLocalFiles() {
|
||||||
let htmlFile = this.props.htmlFile.content;
|
let htmlFile = this.props.htmlFile.content;
|
||||||
|
let scriptOffs = [];
|
||||||
|
|
||||||
// have to build the array manually because the spread operator is only
|
// have to build the array manually because the spread operator is only
|
||||||
// one level down...
|
// one level down...
|
||||||
|
@ -102,9 +148,10 @@ class PreviewFrame extends React.Component {
|
||||||
this.props.jsFiles.forEach(jsFile => {
|
this.props.jsFiles.forEach(jsFile => {
|
||||||
const newJSFile = { ...jsFile };
|
const newJSFile = { ...jsFile };
|
||||||
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
let jsFileStrings = newJSFile.content.match(/(['"])((\\\1|.)*?)\1/gm);
|
||||||
|
const jsFileRegex = /^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i;
|
||||||
jsFileStrings = jsFileStrings || [];
|
jsFileStrings = jsFileStrings || [];
|
||||||
jsFileStrings.forEach(jsFileString => {
|
jsFileStrings.forEach(jsFileString => {
|
||||||
if (jsFileString.match(/^('|")(?!(http:\/\/|https:\/\/)).*\.(png|jpg|jpeg|gif|bmp|mp3|wav|aiff|ogg|json)('|")$/i)) {
|
if (jsFileString.match(jsFileRegex)) {
|
||||||
const filePath = jsFileString.substr(1, jsFileString.length - 2);
|
const filePath = jsFileString.substr(1, jsFileString.length - 2);
|
||||||
let fileName = filePath;
|
let fileName = filePath;
|
||||||
if (fileName.match(/^\.\//)) {
|
if (fileName.match(/^\.\//)) {
|
||||||
|
@ -125,7 +172,8 @@ class PreviewFrame extends React.Component {
|
||||||
jsFiles.forEach(jsFile => {
|
jsFiles.forEach(jsFile => {
|
||||||
const fileName = escapeStringRegexp(jsFile.name);
|
const fileName = escapeStringRegexp(jsFile.name);
|
||||||
const fileRegex = new RegExp(`<script.*?src=('|")((\.\/)|\/)?${fileName}('|").*?>([\s\S]*?)<\/script>`, 'gmi');
|
const fileRegex = new RegExp(`<script.*?src=('|")((\.\/)|\/)?${fileName}('|").*?>([\s\S]*?)<\/script>`, 'gmi');
|
||||||
htmlFile = htmlFile.replace(fileRegex, `<script>\n${jsFile.content}\n</script>`);
|
const replacementString = `<script data-tag="${startTag}${jsFile.name}">\n${jsFile.content}\n</script>`;
|
||||||
|
htmlFile = htmlFile.replace(fileRegex, replacementString);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.props.cssFiles.forEach(cssFile => {
|
this.props.cssFiles.forEach(cssFile => {
|
||||||
|
@ -146,7 +194,8 @@ class PreviewFrame extends React.Component {
|
||||||
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
|
htmlFile = htmlFile.replace(/(?:<head.*?>)([\s\S]*?)(?:<\/head>)/gmi, `<head>\n${htmlHeadContents}\n</head>`);
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlFile += hijackConsoleScript;
|
scriptOffs = getAllScriptOffsets(htmlFile);
|
||||||
|
htmlFile += hijackConsoleScript(JSON.stringify(scriptOffs));
|
||||||
|
|
||||||
return htmlFile;
|
return htmlFile;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue