Commit 5dacedb7 authored by Leon Arnott's avatar Leon Arnott
Browse files

Fixed two more bugs.

 * Fixed a long-standing bug where combined changers weren't being properly copied, and adding more changers to them would mutate variables that were storing that changer.
 * Fixed a bug where, upon supplying a label string to (meter:), any updates to the meter would cause that label to gain any styles, such as (border:) borders, that had been given to the meter itself.
parent 0502b84201d2
......@@ -7,11 +7,13 @@ Documentation is at http://twine2.neocities.org/. See below for compilation inst
#### Bugfixes
* Fixed a long-standing bug where line breaks couldn't be used as whitespace around operators. For instance, `(print: 2`, a line break, then `is > 1)` would cause an error instead of being treated as `(print: 2 is > 1)`.
* Fixed a long-standing bug where combined changers weren't being properly copied, and adding more changers to them would mutate variables that were storing that changer.
* Fixed a bug where `bind` and `2bind` wouldn't work properly when used to bind a data structure's data name (such as `bind $list's 1st`).
* Fixed a bug where error messages would incorrectly call custom macros' parameters "a number" even if that parameter was restricted to something else.
* Fixed a code generation bug in the "The passage ___ was visited" option of the "If" pane of the editor toolbar.
* Fixed a bug where custom macros couldn't call other custom macros if the other macro's `(output:)` or `(output-hook:)` was inside a nested hook, such as an `(if:)` hook.
* Fixed a bug where `(icon-restart:)` didn't restart the story when clicked.
* Fixed a bug where, upon supplying a label string to `(meter:)`, any updates to the meter would cause that label to gain any styles, such as `(border:)` borders, that had been given to the meter itself.
### 3.2.1 changes (Jan 18, 2021):
......
......@@ -105,7 +105,14 @@ define(['utils', 'utils/operationutils', 'internaltypes/changedescriptor', 'inte
},
TwineScript_Clone() {
return this.create(this.macroName, this.params, this.next);
/*
Each link in the chain needs to be cloned, not just the start.
*/
let clone = this.create(this.macroName, this.params, this.next), tail = clone;
while (tail.next) {
tail = tail.next = tail.next.TwineScript_Clone();
}
return clone;
},
/*
......
......@@ -1197,14 +1197,14 @@ define(['jquery', 'macros', 'utils', 'state', 'passages', 'renderer', 'engine',
if (bind.varRef.matches(obj,name)) {
const value = bind.varRef.get();
if (typeof value === "number") {
const icon = cd.target.children('tw-meter');
icon.attr('style', makeStyleString(value));
const meter = cd.target.children('tw-meter');
meter.attr('style', makeStyleString(value));
if (labelOrGradient) {
/*
Re-render the label, in the same manner as (cycling-link:).
Re-render the label. We do NOT reuse the same ChangeDescriptor here, because this renders into the <tw-meter> instead of the
wrapping <tw-expression>, and thus shouldn't have the same styles, borders, etc. as it.
*/
const cd2 = assign({}, cd, { source: labelOrGradient, target: icon, append: 'replace', transitionDeferred: false, });
cd.section.renderInto("", null, cd2, tempVariables);
cd.section.renderInto("", null, { source: labelOrGradient, target: meter, append: 'replace', transitionDeferred: false, }, tempVariables);
}
}
}
......
......@@ -123,8 +123,8 @@
or: producesBooleanTrueIf('or') + `the values on each side of it are both \`false\`.` + otherwiseFalse,
not: `The <b>"not" operator</b> inverts the boolean value to its right, turning \`true\` to \`false\` and vice-versa.`,
isNot: producesBooleanTrueIf('is not') + `the values on each sides of it are NOT exactly the same.` + otherwiseFalse,
contains: producesBooleanTrueIf('contains') + `the array, string, datamap or dataset on the left contains the data on the right.` + otherwiseFalse,
doesNotContain: producesBooleanTrueIf('does not contain') + `the array, string, datamap or dataset on the left does NOT contain the data on the right.` + otherwiseFalse,
contains: producesBooleanTrueIf('contains') + `the array, string, or dataset on the left contains the data on the right, or if the datamap on the left has the data name on the right.` + otherwiseFalse,
doesNotContain: producesBooleanTrueIf('does not contain') + `the array, string, or dataset on the left does NOT contain the data on the right, or if the datamap on the left does NOT have the data name on the right.` + otherwiseFalse,
isIn: producesBooleanTrueIf('is in') + `the data on the left is in the array, string, datamap or dataset on the right.` + otherwiseFalse,
isA: producesBooleanTrueIf('is a') + "the data on the left matches the datatype on the right." + otherwiseFalse,
isNotA: producesBooleanTrueIf('is not a') + "the data on the left does NOT match the datatype on the right." + otherwiseFalse,
......
......@@ -148,6 +148,9 @@ tw-sidebar {
@media (min-width: 576px) {
left: -5em;
width: 3em;
tw-enchantment[style*="width"] > & {
width: inherit;
}
position:absolute;
@include flex-direction(column);
}
......
......@@ -1098,6 +1098,10 @@ describe("style changer macros", function() {
done();
});
});
it("composition doesn't mutate", function() {
expect("(set: $a to (collapse:))(set:$b to $a + (text-color:red))(v6m-print:(source:$a))").markupToPrint("(collapse:)");
expect("(set:_b to (b4r-size:1)+(b4r:'solid'))(enchant:?passage,_b+(corner-radius: 12)+(size:7/8))(v6m-print:(source:_b))").markupToPrint("(border-size:1)+(border:\"solid\")");
});
it("errors if composed with non-changer objects", function() {
expect("(set: $a to (align:'==>')+?Foo)").markupToError();
expect("(set: $a to (align:'==>')+(goto:'Foo'))").markupToError();
......
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