1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-10-02 17:00:45 +00:00

Introduced new Dependency() class to encapsulate dependency handling logic

Note that the format is now slightly different; see js/Dependencies.js
for details
This commit is contained in:
Jeremy Ruston 2012-02-17 14:11:25 +00:00
parent 8d4d168432
commit 103a9a4d7f
11 changed files with 87 additions and 80 deletions

57
js/Dependencies.js Normal file
View File

@ -0,0 +1,57 @@
/*\
title: js/Dependencies.js
Represents the dependencies of a tiddler or a parser node as two fields:
tiddlers: A hashmap of explicitly tiddler titles, with the value `false` if the dependency is skinny, and `true` if it is fat
dependentAll: True if there is an implicit skinny dependency on all available tiddlers
\*/
(function(){
/*jslint node: true */
"use strict";
var utils = require("./Utils.js");
var Dependencies = function(tiddlers,dependentAll) {
this.tiddlers = tiddlers || {};
this.dependentAll = dependentAll;
};
/*
Adds a dependency to a given tiddler. Note how setting a dependency of fat=false on a tiddler that already has
a dependency of fat=true will leave the fat setting as true
*/
Dependencies.prototype.addDependency = function(tiddlerTitle,fat) {
if(!this.tiddlers[tiddlerTitle]) {
this.tiddlers[tiddlerTitle] = fat;
}
};
Dependencies.prototype.mergeDependencies = function(dep) {
this.dependentAll = dep.dependentAll || this.dependentAll;
for(var t in dep.tiddlers) {
this.addDependency(t,dep.tiddlers[t]);
}
};
/*
Determine if these dependencies are impacted by the specified array of changes
changes: Hashmap of {title: "created|modified|deleted"}
*/
Dependencies.prototype.hasChanged = function(changes) {
if(this.dependentAll) {
return true;
}
for(var c in changes) {
if(this.tiddlers.hasOwnProperty(c)) {
return true;
}
}
return false;
};
exports.Dependencies = Dependencies;
})();

View File

@ -11,6 +11,7 @@ Compiles images into JavaScript functions that render them in HTML
var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
Renderer = require("./Renderer.js").Renderer,
Dependencies = require("./Dependencies.js").Dependencies,
utils = require("./Utils.js");
var ImageParser = function(options) {
@ -24,7 +25,7 @@ ImageParser.prototype.parse = function(type,text) {
} else {
src = "data:" + type + ";base64," + text;
}
return new WikiTextParseTree([Renderer.ElementNode("img",{src: src})],{},this.store);
return new WikiTextParseTree([Renderer.ElementNode("img",{src: src})],new Dependencies(),this.store);
};
exports.ImageParser = ImageParser;

View File

@ -11,6 +11,7 @@ Compiles JSON objects into JavaScript functions that render them in HTML and pla
var WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
Renderer = require("./Renderer.js").Renderer,
Dependencies = require("./Dependencies.js").Dependencies,
utils = require("./Utils.js");
var renderObject = function(obj) {
@ -43,7 +44,7 @@ var JSONParser = function(options) {
};
JSONParser.prototype.parse = function(type,text) {
return new WikiTextParseTree([renderObject(JSON.parse(text))],{},this.store);
return new WikiTextParseTree([renderObject(JSON.parse(text))],new Dependencies(),this.store);
};
exports.JSONParser = JSONParser;

View File

@ -87,24 +87,9 @@ MacroNode.prototype.renderInDom = function(domNode,insertBefore) {
MacroNode.prototype.refresh = function(changes) {
var t,
self = this,
hasDependencyChanged = function() {
if(self.dependencies.dependentAll) {
return true;
}
for(var rel in self.dependencies) {
if(rel !== "dependentAll") {
for(var t in self.dependencies[rel]) {
if(changes.hasOwnProperty(t)) {
return true;
}
}
}
}
return false;
};
self = this;
// Check if any of the dependencies of this macro node have changed
if(hasDependencyChanged()) {
if(this.dependencies.hasChanged(changes)) {
// Re-execute the macro if so
var tiddler = this.store.getTiddler(this.tiddlerTitle);
this.execute(tiddler);
@ -118,24 +103,9 @@ MacroNode.prototype.refresh = function(changes) {
MacroNode.prototype.refreshInDom = function(changes) {
var t,
self = this,
hasDependencyChanged = function() {
if(self.dependencies.dependentAll) {
return true;
}
for(var rel in self.dependencies) {
if(rel !== "dependentAll") {
for(var t in self.dependencies[rel]) {
if(changes.hasOwnProperty(t)) {
return true;
}
}
}
}
return false;
};
self = this;
// Check if any of the dependencies of this macro node have changed
if(hasDependencyChanged()) {
if(this.dependencies.hasChanged(changes)) {
// Ask the macro to rerender itself if it can
var tiddler = this.store.getTiddler(this.tiddlerTitle);
if(this.macro.refresh) {

View File

@ -33,6 +33,7 @@ HTML nodes look like this:
var WikiTextRules = require("./WikiTextRules.js"),
WikiTextParseTree = require("./WikiTextParseTree.js").WikiTextParseTree,
Dependencies = require("./Dependencies.js").Dependencies,
Renderer = require("./Renderer.js").Renderer,
utils = require("./Utils.js"),
util = require("util");
@ -67,7 +68,7 @@ WikiTextParser.prototype.parse = function(type,text) {
this.source = text;
this.nextMatch = 0;
this.children = [];
this.dependencies = {};
this.dependencies = new Dependencies();
this.output = null;
this.subWikify(this.children);
var tree = new WikiTextParseTree(this.children,this.dependencies,this.store);
@ -76,25 +77,6 @@ WikiTextParser.prototype.parse = function(type,text) {
return tree;
};
WikiTextParser.prototype.mergeDependencies = function(newDependencies) {
for(var rel in newDependencies) {
if(rel === "dependentAll") {
this.dependencies.dependentAll = newDependencies.dependentAll;
} else {
if(!(rel in this.dependencies)) {
this.dependencies[rel] = {};
}
for(var t in newDependencies[rel]) {
if(this.dependencies[rel][t]) {
this.dependencies[rel][t]++;
} else {
this.dependencies[rel][t] = 1;
}
}
}
}
};
WikiTextParser.prototype.outputText = function(place,startPos,endPos) {
if(startPos < endPos) {
place.push(Renderer.TextNode(this.source.substring(startPos,endPos)));

View File

@ -9,6 +9,7 @@ title: js/WikiTextRules.js
var ArgParser = require("./ArgParser.js").ArgParser,
Renderer = require("./Renderer.js").Renderer,
Dependencies = require("./Dependencies.js").Dependencies,
util = require("util");
var textPrimitives = {
@ -131,7 +132,7 @@ var compileMacroParams = function(w,params) {
var insertMacroCall = function(w,output,name,params,children) {
var macro = w.store.macros[name],
dependencies = {};
dependencies = new Dependencies();
if(macro) {
if(macro.dependentAll) {
dependencies.dependentAll = true;
@ -143,21 +144,12 @@ var insertMacroCall = function(w,output,name,params,children) {
if(params[m].type === "eval") {
dependencies.dependentAll = true;
} else {
var rel = param.rel || "include",
target = params[m].value;
if(!(rel in dependencies)) {
dependencies[rel] = {};
}
if(dependencies[rel][target]) {
dependencies[rel][target]++;
} else {
dependencies[rel][target] = 1;
}
dependencies.addDependency(params[m].value,param.skinny);
}
}
}
}
w.mergeDependencies(dependencies);
w.dependencies.mergeDependencies(dependencies);
output.push(Renderer.MacroNode(name,compileMacroParams(w,params),children,dependencies,w.store));
}
};

View File

@ -18,7 +18,7 @@ exports.macro = {
name: "link",
types: ["text/html","text/plain"],
params: {
target: {byName: "default", type: "tiddler", rel: "link", optional: false}
target: {byName: "default", type: "tiddler", skinny: true, optional: false}
},
events: {
click: function(event,macroNode) {

View File

@ -8,6 +8,7 @@ title: js/macros/slider.js
"use strict";
var Renderer = require("../Renderer.js").Renderer,
Dependencies = require("../Dependencies.js").Dependencies,
Tiddler = require("../Tiddler.js").Tiddler,
utils = require("../Utils.js");
@ -35,8 +36,8 @@ exports.macro = {
var stateTiddler = macroNode.params.state ? store.getTiddler(macroNode.params.state) : {text: ""},
isOpen = stateTiddler.text.trim() === "open",
target = macroNode.params.targetTiddler,
dependencies = {include: {}};
dependencies.include[target] = 1;
dependencies = new Dependencies();
dependencies.addDependency(target,true);
var content = Renderer.SliderNode(macroNode.params.state,
macroNode.params.label,
macroNode.params.tooltip,

View File

@ -9,6 +9,7 @@ title: js/macros/story.js
var Tiddler = require("../Tiddler.js").Tiddler,
Renderer = require("../Renderer.js").Renderer,
Dependencies = require("../Dependencies.js").Dependencies,
utils = require("../Utils.js");
// Parse the text of a story tiddler into an array of tiddler titles
@ -47,10 +48,10 @@ exports.macro = {
content = [];
for(var t=0; t<tiddlers.length; t++) {
var paramFn = {target: tiddlers[t],template: macroNode.params.template},
dependencies = {include: {}};
dependencies.include[tiddlers[t]] = 1;
dependencies = new Dependencies();
dependencies.addDependency(tiddlers[t],true);
if(macroNode.params.template) {
dependencies.include[macroNode.params.template] = 1;
dependencies.addDependency(macroNode.params.template,true);
}
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
m.execute(tiddler);
@ -82,10 +83,10 @@ exports.macro = {
if(tiddlerNode === null) {
// If not, render the tiddler
var paramFn = {target: targetTiddlers[t],template: template},
dependencies = {include: {}};
dependencies.include[targetTiddlers[t]] = 1;
dependencies = new Dependencies();
dependencies.addDependency(targetTiddlers[t],true);
if(template) {
dependencies.include[template] = 1;
dependencies.addDependency(template,true);
}
var m = Renderer.MacroNode("tiddler",paramFn,null,dependencies,store);
m.execute(store.getTiddler(targetTiddlers[t]));

View File

@ -8,6 +8,7 @@ title: js/macros/view.js
"use strict";
var Renderer = require("../Renderer.js").Renderer,
Dependencies = require("../Dependencies.js").Dependencies,
utils = require("../Utils.js");
exports.macro = {
@ -29,8 +30,8 @@ exports.macro = {
if(v !== undefined) {
switch(macroNode.params.format) {
case "link":
var dependencies = {link: {}};
dependencies.link[v] = 1;
var dependencies = new Dependencies();
dependencies.addDependency(v,false);
var link = Renderer.MacroNode("link",
{target: v},
[Renderer.TextNode(v)],
@ -59,7 +60,7 @@ exports.macro = {
}
}
}
return "";
return [];
}
};

View File

@ -9,6 +9,7 @@ Some useful tiddlers for feature testing:
* ImageTests showing different ways of embedding images
* SampleData showing how JSON tiddlers are handled
* VideoTests showing how different online video formats can be embedded
* SliderTests showing how sliders work
Technical documentation includes:
* [[Testing]] regimen