1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-11-27 03:57:21 +00:00

Fixes issue with #4504 and importvariable copying (#4518)

* Fixes issue with #4504 and importvariable copying

ImportVariables widget was using $tw.utils.extend to copy the
variables from temporary set widgets into itself. However,
$tw.utils.extend does NOT behave like Object.assign. It not only
copies all self-owned variables over, but also all variables
in that object's prototype chain. This led to some redundant copying,
and a problem where some variables might show up more than once
(like transclusion).

Fixed now. importvariables widget does its own copying, since it
can't rely on $tw.utils.extend to do the right job, and it can't
count on Object.assign to be there.

* Added test to prevent reversion of #4504

* Slight corrections to new importvariables test
This commit is contained in:
Cameron Fischer 2020-03-19 16:32:51 -04:00 committed by GitHub
parent 33fb4f5c0d
commit 561662782e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 1 deletions

View File

@ -61,7 +61,14 @@ ImportVariablesWidget.prototype.execute = function(tiddlerList) {
var widget = widgetPointer.makeChildWidget(node); var widget = widgetPointer.makeChildWidget(node);
widget.computeAttributes(); widget.computeAttributes();
widget.execute(); widget.execute();
$tw.utils.extend(widgetPointer.variables,widget.variables); // We SHALLOW copy over all variables
// in widget. We can't use
// $tw.utils.assign, because that copies
// up the prototype chain, which we
// don't want.
$tw.utils.each(Object.keys(widget.variables), function(key) {
widgetPointer.variables[key] = widget.variables[key];
});
} else { } else {
widgetPointer.makeChildWidgets([node]); widgetPointer.makeChildWidgets([node]);
widgetPointer = widgetPointer.children[0]; widgetPointer = widgetPointer.children[0];

View File

@ -517,6 +517,38 @@ describe("Widget module", function() {
// Test the rendering // Test the rendering
expect(wrapper.innerHTML).toBe("<p>Don't forget me.</p>"); expect(wrapper.innerHTML).toBe("<p>Don't forget me.</p>");
}); });
/** This test reproduces issue #4504.
*
* The importvariable widget was creating redundant copies into
* itself of variables in widgets higher up in the tree. Normally,
* this caused no errors, but it would mess up qualify-macros.
* They would find multiple instances of the same transclusion
* variable if a transclusion occured higher up in the widget tree
* than an importvariables AND that importvariables was importing
* at least ONE variable.
*/
it("adding imported variables doesn't change qualifyers", function() {
var wiki = new $tw.Wiki();
function wikiparse(text) {
var tree = parseText(text,wiki);
var widgetNode = createWidgetNode(tree,wiki);
var wrapper = renderWidgetNode(widgetNode);
return wrapper.innerHTML;
};
wiki.addTiddlers([
{title: "body", text: "\\import A\n<<qualify this>>"},
{title: "A", text: "\\define unused() ignored"}
]);
// This transclude wraps "body", which has an
// importvariable widget in it.
var withA = wikiparse("{{body}}");
wiki.addTiddler({title: "A", text: ""});
var withoutA = wikiparse("{{body}}");
// Importing two different version of "A" shouldn't cause
// the <<qualify>> widget to spit out something different.
expect(withA).toBe(withoutA);
});
}); });
})(); })();