From 663c220eaf37a14e599e6468be97fe57df5203f7 Mon Sep 17 00:00:00 2001 From: Phoenix Eliot Date: Tue, 23 Aug 2016 16:53:54 -0700 Subject: [PATCH] Show wev-dev iFrame error messages like Aether's This heavily refactors SpellView and adds infrastructure for receiving and reporting Errors raised by the web-dev iFrame. The web-dev error system, the Aether error system, and the Ace html-worker avoid disturbing each others' errors/annotations (though currently Aether+web-dev errors won't coexist), and they clear/update their own asynchronously. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Show web-dev iFrame errors as Ace annotations Add functional error banners (with poor messages) Improve error banners, don't allow duplicate Problems Refactor setAnnotations override Convert all constructor calls for Problems Add comments, clean up Clean up Don't clear things unnecessarily Clean up error message sending from iFrame Add web-dev:error schema Clarify error message attributes Refactor displaying AetherProblems Refactor displaying user problem banners Refactor onWebDevError Set ace styles on updating @problems Clean up, fix off-by-1 error Add comment Show stale web-dev errors differently Some web-dev errors are generated by "stale" code — code that's still running in the iFrame but doesn't have the player's recent changes. This shows those errors differently than if they weren't "stale", and suggests they re-run their code. Hook up web-dev event schema Destroy ignored duplicate problems Functionalize a bit of stuff Fix ProblemAlertView never loading --- app/assets/javascripts/web-dev-listener.js | 17 ++- app/core/initialize.coffee | 1 + app/schemas/subscriptions/tome.coffee | 2 +- app/schemas/subscriptions/web-dev.coffee | 9 ++ app/styles/play/level/tome/spell.sass | 4 - app/views/play/level/WebSurfaceView.coffee | 5 +- app/views/play/level/tome/Problem.coffee | 93 ++++++++++--- .../play/level/tome/ProblemAlertView.coffee | 18 +-- app/views/play/level/tome/Spell.coffee | 1 + app/views/play/level/tome/SpellView.coffee | 130 +++++++++++++----- server/commons/database.coffee | 1 - .../views/play/level/tome/Problem.spec.coffee | 6 +- 12 files changed, 203 insertions(+), 84 deletions(-) create mode 100644 app/schemas/subscriptions/web-dev.coffee diff --git a/app/assets/javascripts/web-dev-listener.js b/app/assets/javascripts/web-dev-listener.js index a1802604b..dc0e5f67d 100644 --- a/app/assets/javascripts/web-dev-listener.js +++ b/app/assets/javascripts/web-dev-listener.js @@ -1,5 +1,11 @@ // TODO: don't serve this script from codecombat.com; serve it from a harmless extra domain we don't have yet. +var lastSource = null; +var lastOrigin = null; +window.onerror = function(message, url, line, column, error){ + console.log("User script error on line " + line + ", column " + column + ": ", error); + lastSource.postMessage({ type: 'error', message: message, url: url, line: line, column: column }, lastOrigin); +} window.addEventListener('message', receiveMessage, false); var concreteDom; @@ -30,8 +36,9 @@ function receiveMessage(event) { console.log('Ignoring message from bad origin:', origin); return; } + lastOrigin = origin; var data = event.data; - var source = event.source; + var source = lastSource = event.source; switch (data.type) { case 'create': create(_.pick(data, 'dom', 'styles', 'scripts')); @@ -79,12 +86,8 @@ function replaceNodes(selector, newNodes){ $newNodes.attr('for', firstNode.attr('for')); newFirstNode = $newNodes[0]; - try { - firstNode.replaceWith(newFirstNode); // Removes newFirstNode from its array (!!) - } catch (e) { - console.log('Failed to update some nodes:', e); - } - + firstNode.replaceWith(newFirstNode); // Removes newFirstNode from its array (!!) + $(newFirstNode).after($newNodes); } diff --git a/app/core/initialize.coffee b/app/core/initialize.coffee index b81841a6b..cab60e5c2 100644 --- a/app/core/initialize.coffee +++ b/app/core/initialize.coffee @@ -13,6 +13,7 @@ channelSchemas = 'tome': require 'schemas/subscriptions/tome' 'god': require 'schemas/subscriptions/god' 'scripts': require 'schemas/subscriptions/scripts' + 'web-dev': require 'schemas/subscriptions/web-dev' 'world': require 'schemas/subscriptions/world' definitionSchemas = diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee index cff846e0c..d9d5f10d3 100644 --- a/app/schemas/subscriptions/tome.coffee +++ b/app/schemas/subscriptions/tome.coffee @@ -89,7 +89,7 @@ module.exports = 'tome:problems-updated': c.object {title: 'Problems Updated', description: 'Published when problems have been updated', required: ['spell', 'problems', 'isCast']}, spell: {type: 'object'} problems: {type: 'array'} - isCast: {type: 'boolean'} + isCast: {type: 'boolean', description: 'Whether the code has been Run yet. Sometimes determines if error displays as just annotation or as full banner.'} 'tome:change-language': c.object {title: 'Tome Change Language', description: 'Published when the Tome should update its programming language', required: ['language']}, language: {type: 'string'} diff --git a/app/schemas/subscriptions/web-dev.coffee b/app/schemas/subscriptions/web-dev.coffee new file mode 100644 index 000000000..4bd8c07b7 --- /dev/null +++ b/app/schemas/subscriptions/web-dev.coffee @@ -0,0 +1,9 @@ +c = require 'schemas/schemas' + +module.exports = + 'web-dev:error': c.object {title: 'Web Dev Error', description: 'Published when an uncaught error occurs in the web-dev iFrame', required: []}, + message: { type: 'string' } + url: { type: 'string', description: 'URL of the host iFrame' } + line: { type: 'integer', description: 'Line number of the start of the code that threw the exception (relative to its