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,7 +3,49 @@ 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>
 | 
 | ||||||
|  | const startTag = 'filestart-'; | ||||||
|  | 
 | ||||||
|  | function getAllScriptOffsets(htmlFile) { | ||||||
|  |   const offs = []; | ||||||
|  |   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; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function hijackConsoleScript(offs) { | ||||||
|  |   const s = `<script>
 | ||||||
|  |     function getScriptOff(line) { | ||||||
|  |       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]; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     document.addEventListener('DOMContentLoaded', function() { |     document.addEventListener('DOMContentLoaded', function() { | ||||||
|       var iframeWindow = window; |       var iframeWindow = window; | ||||||
|       var originalConsole = iframeWindow.console; |       var originalConsole = iframeWindow.console; | ||||||
|  | @ -20,7 +62,7 @@ const hijackConsoleScript = `<script> | ||||||
|           var args = Array.from(arguments); |           var args = Array.from(arguments); | ||||||
|           args = args.map(function(i) { |           args = args.map(function(i) { | ||||||
|             // catch objects
 |             // catch objects
 | ||||||
|           return (typeof i === 'string') ? i : JSON.stringify(i); |             return (typeof i === 'undefined') ? 'undefined' : JSON.stringify(i); | ||||||
|           }); |           }); | ||||||
| 
 | 
 | ||||||
|           // post message to parent window
 |           // post message to parent window
 | ||||||
|  | @ -38,10 +80,11 @@ const hijackConsoleScript = `<script> | ||||||
|           var substring = "script error"; |           var substring = "script error"; | ||||||
|           var data = {}; |           var data = {}; | ||||||
| 
 | 
 | ||||||
|         if (string.indexOf(substring) > -1){ |           if (string.indexOf(substring) !== -1){ | ||||||
|             data = 'Script Error: See Browser Console for Detail'; |             data = 'Script Error: See Browser Console for Detail'; | ||||||
|           } else { |           } else { | ||||||
|           data = msg + ' Line: ' + lineNumber + 'column: ' + columnNo; |             var fileInfo = getScriptOff(lineNumber); | ||||||
|  |             data = msg + ' (' + fileInfo[1] + ': line ' + fileInfo[0] + ')'; | ||||||
|           } |           } | ||||||
|           window.parent.postMessage({ |           window.parent.postMessage({ | ||||||
|             method: 'error', |             method: 'error', | ||||||
|  | @ -52,6 +95,8 @@ const hijackConsoleScript = `<script> | ||||||
|       }; |       }; | ||||||
|     }); |     }); | ||||||
|   </script>`; |   </script>`; | ||||||
|  |   return s; | ||||||
|  | } | ||||||
| 
 | 
 | ||||||
| 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
	
	 Cassie Tarakajian
						Cassie Tarakajian