mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-26 18:10:27 +00:00
a1c8ac624f
There are still some whitespace and attribute ordering issues, but the result runs correctly.
174 lines
5.2 KiB
JavaScript
Executable File
174 lines
5.2 KiB
JavaScript
Executable File
// Returns true if path is a valid field name (path),
|
|
// i.e. a sequence of identifiers, separated by "."
|
|
TiddlyWiki.isValidFieldName = function(name)
|
|
{
|
|
var match = /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*/.exec(name);
|
|
return match && (match[0] == name);
|
|
};
|
|
|
|
// Throws an exception when name is not a valid field name.
|
|
TiddlyWiki.checkFieldName = function(name)
|
|
{
|
|
if(!TiddlyWiki.isValidFieldName(name))
|
|
throw config.messages.invalidFieldName.format([name]);
|
|
};
|
|
|
|
function StringFieldAccess(n,readOnly)
|
|
{
|
|
this.set = readOnly ?
|
|
function(t,v) {if(v != t[n]) throw config.messages.fieldCannotBeChanged.format([n]);} :
|
|
function(t,v) {if(v != t[n]) {t[n] = v; return true;}};
|
|
this.get = function(t) {return t[n];};
|
|
}
|
|
|
|
function DateFieldAccess(n)
|
|
{
|
|
this.set = function(t,v) {
|
|
var d = v instanceof Date ? v : Date.convertFromYYYYMMDDHHMM(v);
|
|
if(d != t[n]) {
|
|
t[n] = d; return true;
|
|
}
|
|
};
|
|
this.get = function(t) {return t[n].convertToYYYYMMDDHHMM();};
|
|
}
|
|
|
|
function LinksFieldAccess(n)
|
|
{
|
|
this.set = function(t,v) {
|
|
var s = (typeof v == "string") ? v.readBracketedList() : v;
|
|
if(s.toString() != t[n].toString()) {
|
|
t[n] = s; return true;
|
|
}
|
|
};
|
|
this.get = function(t) {return String.encodeTiddlyLinkList(t[n]);};
|
|
}
|
|
|
|
TiddlyWiki.standardFieldAccess = {
|
|
// The set functions return true when setting the data has changed the value.
|
|
"title": new StringFieldAccess("title",true),
|
|
// Handle the "tiddler" field name as the title
|
|
"tiddler": new StringFieldAccess("title",true),
|
|
"text": new StringFieldAccess("text"),
|
|
"modifier": new StringFieldAccess("modifier"),
|
|
"modified": new DateFieldAccess("modified"),
|
|
"creator": new StringFieldAccess("creator"),
|
|
"created": new DateFieldAccess("created"),
|
|
"tags": new LinksFieldAccess("tags")
|
|
};
|
|
|
|
TiddlyWiki.isStandardField = function(name)
|
|
{
|
|
return TiddlyWiki.standardFieldAccess[name] != undefined;
|
|
};
|
|
|
|
// Sets the value of the given field of the tiddler to the value.
|
|
// Setting an ExtendedField's value to null or undefined removes the field.
|
|
// Setting a namespace to undefined removes all fields of that namespace.
|
|
// The fieldName is case-insensitive.
|
|
// All values will be converted to a string value.
|
|
TiddlyWiki.prototype.setValue = function(tiddler,fieldName,value)
|
|
{
|
|
TiddlyWiki.checkFieldName(fieldName);
|
|
var t = this.resolveTiddler(tiddler);
|
|
if(!t)
|
|
return;
|
|
fieldName = fieldName.toLowerCase();
|
|
var isRemove = (value === undefined) || (value === null);
|
|
var accessor = TiddlyWiki.standardFieldAccess[fieldName];
|
|
if(accessor) {
|
|
if(isRemove)
|
|
// don't remove StandardFields
|
|
return;
|
|
var h = TiddlyWiki.standardFieldAccess[fieldName];
|
|
if(!h.set(t,value))
|
|
return;
|
|
} else {
|
|
var oldValue = t.fields[fieldName];
|
|
if(isRemove) {
|
|
if(oldValue !== undefined) {
|
|
// deletes a single field
|
|
delete t.fields[fieldName];
|
|
} else {
|
|
// no concrete value is defined for the fieldName
|
|
// so we guess this is a namespace path.
|
|
// delete all fields in a namespace
|
|
var re = new RegExp("^"+fieldName+"\\.");
|
|
var dirty = false;
|
|
var n;
|
|
for(n in t.fields) {
|
|
if(n.match(re)) {
|
|
delete t.fields[n];
|
|
dirty = true;
|
|
}
|
|
}
|
|
if(!dirty)
|
|
return;
|
|
}
|
|
} else {
|
|
// the "normal" set case. value is defined (not null/undefined)
|
|
// For convenience provide a nicer conversion Date->String
|
|
value = value instanceof Date ? value.convertToYYYYMMDDHHMMSSMMM() : String(value);
|
|
if(oldValue == value)
|
|
return;
|
|
t.fields[fieldName] = value;
|
|
}
|
|
}
|
|
// When we are here the tiddler/store really was changed.
|
|
this.notify(t.title,true);
|
|
if(!fieldName.match(/^temp\./))
|
|
this.setDirty(true);
|
|
};
|
|
|
|
// Returns the value of the given field of the tiddler.
|
|
// The fieldName is case-insensitive.
|
|
// Will only return String values (or undefined).
|
|
TiddlyWiki.prototype.getValue = function(tiddler,fieldName)
|
|
{
|
|
var t = this.resolveTiddler(tiddler);
|
|
if(!t)
|
|
return undefined;
|
|
if(fieldName.indexOf(config.textPrimitives.sectionSeparator) === 0 || fieldName.indexOf(config.textPrimitives.sliceSeparator) === 0) {
|
|
var sliceType = fieldName.substr(0, 2);
|
|
var sliceName = fieldName.substring(2);
|
|
return store.getTiddlerText("%0%1%2".format(t.title,sliceType,sliceName));
|
|
} else {
|
|
fieldName = fieldName.toLowerCase();
|
|
var accessor = TiddlyWiki.standardFieldAccess[fieldName];
|
|
if(accessor) {
|
|
return accessor.get(t);
|
|
}
|
|
}
|
|
return t.fields[fieldName];
|
|
};
|
|
|
|
// Calls the callback function for every field in the tiddler.
|
|
// When callback function returns a non-false value the iteration stops
|
|
// and that value is returned.
|
|
// The order of the fields is not defined.
|
|
// @param callback a function(tiddler,fieldName,value).
|
|
TiddlyWiki.prototype.forEachField = function(tiddler,callback,onlyExtendedFields)
|
|
{
|
|
var t = this.resolveTiddler(tiddler);
|
|
if(!t)
|
|
return undefined;
|
|
var n,result;
|
|
for(n in t.fields) {
|
|
result = callback(t,n,t.fields[n]);
|
|
if(result)
|
|
return result;
|
|
}
|
|
if(onlyExtendedFields)
|
|
return undefined;
|
|
for(n in TiddlyWiki.standardFieldAccess) {
|
|
if(n != "tiddler") {
|
|
// even though the "title" field can also be referenced through the name "tiddler"
|
|
// we only visit this field once.
|
|
result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
|
|
if(result)
|
|
return result;
|
|
}
|
|
}
|
|
return undefined;
|
|
};
|
|
|