Skip to content

Commit 9fbda46

Browse files
committed
forward jshint syntax errors to the sketch console
1 parent 4cdace3 commit 9fbda46

2 files changed

Lines changed: 54 additions & 7 deletions

File tree

client/modules/Preview/EmbedFrame.jsx

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import resolvePathsForElementsWithAttribute from '../../../server/utils/resolveU
2121

2222
let objectUrls = {};
2323
let objectPaths = {};
24+
let jshintErrors = [];
25+
let jshintErrorKeys = new Set();
2426

2527
const Frame = styled.iframe`
2628
min-height: 100%;
@@ -56,7 +58,7 @@ function resolveCSSLinksInString(content, files) {
5658
return newContent;
5759
}
5860

59-
function jsPreprocess(jsText) {
61+
function jsPreprocess(jsText, fileName) {
6062
let newContent = jsText;
6163
// check the code for js errors before sending it to strip comments
6264
// or loops.
@@ -68,11 +70,26 @@ function jsPreprocess(jsText) {
6870
space: true
6971
});
7072
newContent = loopProtect(newContent);
73+
} else {
74+
JSHINT.errors.forEach((err) => {
75+
if (!err) return;
76+
const key = `${fileName}:${err.line}:${err.character}:${err.reason}`;
77+
if (jshintErrorKeys.has(key)) return;
78+
jshintErrorKeys.add(key);
79+
jshintErrors.push({
80+
file: fileName,
81+
line: err.line,
82+
character: err.character,
83+
reason: err.reason,
84+
evidence: err.evidence,
85+
code: err.code
86+
});
87+
});
7188
}
7289
return newContent;
7390
}
7491

75-
function resolveJSLinksInString(content, files) {
92+
function resolveJSLinksInString(content, files, fileName) {
7693
let newContent = content;
7794
let jsFileStrings = content.match(STRING_REGEX);
7895
jsFileStrings = jsFileStrings || [];
@@ -98,7 +115,7 @@ function resolveJSLinksInString(content, files) {
98115
}
99116
});
100117

101-
return jsPreprocess(newContent);
118+
return jsPreprocess(newContent, fileName);
102119
}
103120

104121
function resolveScripts(sketchDoc, files) {
@@ -136,7 +153,7 @@ function resolveScripts(sketchDoc, files) {
136153
) !== null
137154
) {
138155
script.setAttribute('crossorigin', '');
139-
script.innerHTML = resolveJSLinksInString(script.innerHTML, files); // eslint-disable-line
156+
script.innerHTML = resolveJSLinksInString(script.innerHTML, files, 'index.html'); // eslint-disable-line
140157
}
141158
});
142159
}
@@ -175,7 +192,11 @@ function resolveJSAndCSSLinks(files) {
175192
files.forEach((file) => {
176193
const newFile = { ...file };
177194
if (file.name.match(/.*\.js$/i)) {
178-
newFile.content = resolveJSLinksInString(newFile.content, files);
195+
newFile.content = resolveJSLinksInString(
196+
newFile.content,
197+
files,
198+
file.name
199+
);
179200
} else if (file.name.match(/.*\.css$/i)) {
180201
newFile.content = resolveCSSLinksInString(newFile.content, files);
181202
}
@@ -188,7 +209,7 @@ function addLoopProtect(sketchDoc) {
188209
const scriptsInHTML = sketchDoc.getElementsByTagName('script');
189210
const scriptsInHTMLArray = Array.prototype.slice.call(scriptsInHTML);
190211
scriptsInHTMLArray.forEach((script) => {
191-
script.innerHTML = jsPreprocess(script.innerHTML); // eslint-disable-line
212+
script.innerHTML = jsPreprocess(script.innerHTML, 'index.html'); // eslint-disable-line
192213
});
193214
}
194215

@@ -197,6 +218,8 @@ function injectLocalFiles(files, htmlFile, options) {
197218
let scriptOffs = [];
198219
objectUrls = {};
199220
objectPaths = {};
221+
jshintErrors = [];
222+
jshintErrorKeys = new Set();
200223
const resolvedFiles = resolveJSAndCSSLinks(files);
201224
const parser = new DOMParser();
202225
const sketchDoc = parser.parseFromString(htmlFile.content, 'text/html');
@@ -241,13 +264,14 @@ p5.prototype.registerMethod('afterSetup', p5.prototype.ensureAccessibleCanvas);`
241264
const sketchDocString = `<!DOCTYPE HTML>\n${sketchDoc.documentElement.outerHTML}`;
242265
scriptOffs = getAllScriptOffsets(sketchDocString);
243266
const consoleErrorsScript = sketchDoc.createElement('script');
267+
addLoopProtect(sketchDoc);
244268
consoleErrorsScript.innerHTML = `
245269
window.offs = ${JSON.stringify(scriptOffs)};
246270
window.objectUrls = ${JSON.stringify(objectUrls)};
247271
window.objectPaths = ${JSON.stringify(objectPaths)};
272+
window.__jshintErrors = ${JSON.stringify(jshintErrors)};
248273
window.editorOrigin = '${getConfig('EDITOR_URL')}';
249274
`;
250-
addLoopProtect(sketchDoc);
251275
sketchDoc.head.prepend(consoleErrorsScript);
252276

253277
return `<!DOCTYPE HTML>\n${sketchDoc.documentElement.outerHTML}`;

client/utils/previewEntry.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,29 @@ setInterval(() => {
3535
}
3636
}, LOGWAIT);
3737

38+
if (Array.isArray(window.__jshintErrors) && window.__jshintErrors.length > 0) {
39+
const errorLogs = window.__jshintErrors.map((err) => {
40+
const location = `${err.file}:${err.line}:${err.character}`;
41+
const data = `SyntaxError: ${err.reason}\n at ${location}`;
42+
return {
43+
log: [
44+
{
45+
method: 'error',
46+
data: [data],
47+
id: `${Date.now()}-${err.file}-${err.line}-${err.character}`
48+
}
49+
]
50+
};
51+
});
52+
editor.postMessage(
53+
{
54+
source: 'sketch',
55+
messages: errorLogs
56+
},
57+
editorOrigin
58+
);
59+
}
60+
3861
function handleMessageEvent(e) {
3962
// maybe don't need this?? idk!
4063
if (window.origin !== e.origin) return;

0 commit comments

Comments
 (0)