Commit a65ff6b8 authored by Leon Arnott's avatar Leon Arnott
Browse files

Fixed a bug where attempting to generate certain error messages would instead...

Fixed a bug where attempting to generate certain error messages would instead cause an unrelated Javascript error to occur.

Also fixed the Chrome performance hack added in 7766c886e09a.
parent cc878663df6c
......@@ -8,6 +8,7 @@ Documentation is at http://twine2.neocities.org/. See below for compilation inst
* Fixed a bug where `(click:?page)` would suppress a gradient background applied to ?Page via `(enchant:)` or `(change:)`.
* Fixed an incorrectly-worded error message resulting from a data name containing an error (such as `$a's (a: 1 to 2)`, which is invalid syntax).
* Fixed a bug where attempting to generate certain error messages would instead cause an unrelated Javascript error to occur.
* Debug Mode: fixed a bug where values in the Variables pane would sometimes be truncated incorrectly, causing partial HTML entities like "&am…" to appear.
#### Alterations
......
......@@ -2270,7 +2270,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
/*d:
(hide: ...HookName) -> Command
Hides a hook that was already visible, without fully erasing it or its contained macro calls.
Hides a hook, or hooks, that were already visible, without fully erasing them or their contained macro calls.
Example usage:
```
......@@ -2287,7 +2287,7 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
as they are until you use (show:) to reveal them again.
Details:
(hide:) will hide every hook with the given name. To only hide a specific hook, you can use the
(hide:) will hide every hook with the given names. To only hide a specific hook, you can use the
possessive syntax, as usual: `(hide: ?1's 1st)`.
If you want to remove the hook's contents all together, and re-create it anew later, consider using (replace:) and (rerun:)
......@@ -2504,9 +2504,8 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
(dialog: [Bind], String, ...String) -> Command
Also known as: (alert:)
A command that, when used, displays a pop-up dialog box with the given string displayed, and a number of links labeled with
the remaining other strings. When one of the links is clicked to dismiss the dialog, it evaluates to the string text of that clicked
link. If an optional bound variable is provided, that variable is updated to match the pressed button.
A command that, when used, displays a pop-up dialog box with the given string displayed, and a number of button-shaped links labeled with
the remaining other strings. If an optional bound variable is provided, that variable is updated to match the pressed button.
Example usage:
* `(dialog: "Beyond this point, things get serious. Grab a snack and buckle up.", "Sure.")`
......
......@@ -232,6 +232,13 @@ define(['utils'], ({impossible}) => {
*/
const comparisonOpTypes = ['inequality','is','isNot','isIn','contains','doesNotContain',
'isNotIn','isA','typifies','isNotA','untypifies','matches','doesNotMatch'];
/*
A helper that creates a TwineError.create() call, stringifying all arguments.
*/
function emitTwineError(type, message, explanation) {
return "TwineError.create(" + stringify(type) + "," + stringify(message) + "," + stringify(explanation) + ")";
}
/*
This takes an array from TwineMarkup, rooted at an expression,
......@@ -269,7 +276,7 @@ define(['utils'], ({impossible}) => {
should be abided.
*/
if (isVarRef && whitespaceError) {
return "TwineError" + dotCreate + "'operation'," + stringify(whitespaceError) + ")";
return emitTwineError('operation', whitespaceError);
}
return "";
}
......@@ -338,7 +345,7 @@ define(['utils'], ({impossible}) => {
*/
else if (type === "whitespace") {
if (isVarRef && whitespaceError) {
return "TwineError" + dotCreate + "'operation'," + stringify(whitespaceError) + ")";
return emitTwineError('operation', whitespaceError);
}
}
}
......@@ -525,9 +532,8 @@ define(['utils'], ({impossible}) => {
leftIsComparison = isComparisonOp(before),
rightIsComparison = isComparisonOp(after),
// This error message is used for elided "is not" comparisons.
ambiguityError = "TwineError.create('operation', 'This use of \"is not\" and \""
+ type + "\" is grammatically ambiguous',"
+ "'Maybe try rewriting this as \"__ is not __ " + type + " __ is not __\"') ";
ambiguityError = emitTwineError('operation', "This use of \"is not\" and \"" + type + "\" is grammatically ambiguous.",
"Maybe try rewriting this as \"__ is not __ " + type + " __ is not __\"");
openString = Operations + "." + type + "(";
midString = ",";
......@@ -687,7 +693,7 @@ define(['utils'], ({impossible}) => {
right = compile(after, varRefArgs("right"));
closeString = ","
/*
Utils.stringify() is used to both escape the name
stringify() is used to both escape the name
string and wrap it in quotes.
*/
+ stringify(token.name) + ")"
......@@ -724,7 +730,7 @@ define(['utils'], ({impossible}) => {
left = compile(before, varRefArgs("left"));
closeString = ","
/*
Utils.stringify() is used to both escape the name
stringify() is used to both escape the name
string and wrap it in quotes.
*/
+ stringify(token.name) + ")"
......@@ -740,7 +746,7 @@ define(['utils'], ({impossible}) => {
left = It;
closeString = ","
/*
Utils.stringify() is used to both escape the name
stringify() is used to both escape the name
string and wrap it in quotes.
*/
+ stringify(token.name) + ")"
......@@ -821,9 +827,7 @@ define(['utils'], ({impossible}) => {
needsLeft = needsRight = MUSTNT;
}
else if (type === "error") {
return "TwineError" + dotCreate + "'syntax'," + stringify(token.message)
+ (token.explanation ? ", " + stringify(token.explanation) : "")
+ ")";
return emitTwineError('syntax', stringify(token.message), token.explanation ? stringify(token.explanation) : '');
}
/*
If a token was found, we can recursively
......@@ -861,22 +865,26 @@ define(['utils'], ({impossible}) => {
/*
Otherwise, create the error object for end-user examination.
*/
return "TwineError" + dotCreate + "'operation','I need usable code to be "
return emitTwineError('operation', "I need usable code to be "
+ (needsLeft === MUST ? "left " : "")
+ (needsLeft === MUST && needsRight === MUST ? "and " : "")
+ (needsRight === MUST ? "right " : "")
+ 'of "' + token.text + '"' + "')";
+ 'of ' + token.text + '.');
}
/*
Conversely, if a value is present at the left or right, and it MUSTN'T be there,
produce an error message.
*/
if ((needsLeft === MUSTNT && left) || (needsRight === MUSTNT && right)) {
return "TwineError" + dotCreate + "'operation','There can't be code to the "
return emitTwineError('operation', "There can't be a "
+ ((left && needsLeft === MUSTNT && right && needsRight === MUSTNT) ? left + ' or ' + right
: (left && needsLeft === MUSTNT ? left : right))
+ " to the "
+ (needsLeft === MUSTNT ? "left " : "")
+ (needsLeft === MUSTNT && needsRight === MUSTNT ? "or " : "")
+ (needsRight === MUSTNT ? "right " : "")
+ 'of "' + token.text + '"' + "')";
+ 'of ' + token.text + ".",
"There could be a comma missing between them, or there could be a ");
}
return openString + left + midString + right + closeString;
}
......
......@@ -259,7 +259,7 @@ $('pre > code').append("<div class='previewButton' title='Run this Harlowe code.
}
/* Chrome performance hack */
if (!navigator.userAgent.includes("Firefox")) {
console.log("Removed animated elements for performance reasons:", $('[style*=animation:]').remove());
console.log("Removed animated elements for performance reasons:", $('[style*="animation:"]').remove());
}
</script>
`;
......
......@@ -217,7 +217,8 @@ describe("enchantment macros", function () {
runPassage("(enchant:?Page,(color:'#800000')+(background:white))");
setTimeout(function() {
expect($('tw-story').css('color')).toMatch(/(?:#800000|rgb\(\s*128,\s*0,\s*0\s*\))/);
expect($('tw-story').css('background-color')).toMatch(/(?:#ffffff|rgb\(\s*255,\s*255,\s*255\s*\))/);
// ?Page enchantments affecting the background cause <tw-story> to gain a transparent background.
expect($('tw-story').css('background-color')).toMatch(/(?:transparent|rgba?\(\s*0,\s*0,\s*0,\s*0\))/);
done();
});
});
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment