1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-02-13 05:29:49 +00:00

Compare commits

..

7 Commits

Author SHA1 Message Date
jeremy@jermolene.com
162e4be9f2 Docs updates 2022-05-23 09:21:12 +01:00
jeremy@jermolene.com
1ef9d11ca3 Merge branch 'master' into json-ops 2022-05-23 09:16:44 +01:00
jeremy@jermolene.com
28f1d587b6 Rename JSON operators
See https://github.com/Jermolene/TiddlyWiki5/pull/6522#issuecomment-1111206619
2022-04-27 17:35:45 +01:00
jeremy@jermolene.com
096b30f43b WIP 2022-04-27 17:28:02 +01:00
jeremy@jermolene.com
1d4418a777 Merge branch 'master' into json-ops 2022-04-27 17:27:43 +01:00
jeremy@jermolene.com
093cda65fb Merge branch 'master' into json-ops 2022-04-06 17:37:21 +01:00
jeremy@jermolene.com
5f4dc2a5fe Initial Commit 2022-03-11 10:25:16 +00:00
639 changed files with 21438 additions and 8738 deletions

2
.gitignore vendored
View File

@@ -1,7 +1,5 @@
.DS_Store .DS_Store
.c9/ .c9/
.vscode/
tmp/ tmp/
output/ output/
node_modules/ node_modules/

View File

@@ -5,7 +5,7 @@
# Default to the current version number for building the plugin library # Default to the current version number for building the plugin library
if [ -z "$TW5_BUILD_VERSION" ]; then if [ -z "$TW5_BUILD_VERSION" ]; then
TW5_BUILD_VERSION=v5.2.4 TW5_BUILD_VERSION=v5.2.3
fi fi
echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]" echo "Using TW5_BUILD_VERSION as [$TW5_BUILD_VERSION]"
@@ -233,15 +233,6 @@ node $TW5_BUILD_TIDDLYWIKI \
--build index \ --build index \
|| exit 1 || exit 1
# /editions/twitter-archivist/index.html Twitter Archivist edition
node $TW5_BUILD_TIDDLYWIKI \
./editions/twitter-archivist \
--verbose \
--load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT/editions/twitter-archivist/ \
--build index \
|| exit 1
###################################################### ######################################################
# #
# Plugin demos # Plugin demos
@@ -459,7 +450,7 @@ node $TW5_BUILD_TIDDLYWIKI \
--verbose \ --verbose \
--load $TW5_BUILD_OUTPUT/build.tid \ --load $TW5_BUILD_OUTPUT/build.tid \
--output $TW5_BUILD_OUTPUT/library/$TW5_BUILD_VERSION \ --output $TW5_BUILD_OUTPUT/library/$TW5_BUILD_VERSION \
--build library\ --build \
|| exit 1 || exit 1
# Delete the temporary build tiddler # Delete the temporary build tiddler

View File

@@ -9,7 +9,6 @@ node ./tiddlywiki.js \
--verbose \ --verbose \
--version \ --version \
--rendertiddler $:/core/save/all test.html text/plain \ --rendertiddler $:/core/save/all test.html text/plain \
--test \
|| exit 1 || exit 1
echo To run the tests in a browser, open "editions/test/output/test.html" echo To run the tests in a browser, open "editions/test/output/test.html"

View File

@@ -1230,16 +1230,13 @@ $tw.Wiki = function(options) {
this.getTiddler = function(title) { this.getTiddler = function(title) {
if(title) { if(title) {
var t = tiddlers[title]; var t = tiddlers[title];
if(t !== undefined) { if(t instanceof $tw.Tiddler) {
return t; return t;
} else { } else if(title !== undefined && shadowTiddlers[title]) {
var s = shadowTiddlers[title]; return shadowTiddlers[title].tiddler;
if(s !== undefined) {
return s.tiddler;
}
} }
return undefined;
} }
return undefined;
}; };
// Get an array of all tiddler titles // Get an array of all tiddler titles
@@ -2403,11 +2400,11 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("application/x-font-ttf","base64",".woff"); $tw.utils.registerFileType("application/x-font-ttf","base64",".woff");
$tw.utils.registerFileType("application/font-woff2","base64",".woff2"); $tw.utils.registerFileType("application/font-woff2","base64",".woff2");
$tw.utils.registerFileType("audio/ogg","base64",".ogg"); $tw.utils.registerFileType("audio/ogg","base64",".ogg");
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
$tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]); $tw.utils.registerFileType("video/ogg","base64",[".ogm",".ogv",".ogg"]);
$tw.utils.registerFileType("video/webm","base64",".webm"); $tw.utils.registerFileType("video/webm","base64",".webm");
$tw.utils.registerFileType("video/mp4","base64",".mp4"); $tw.utils.registerFileType("video/mp4","base64",".mp4");
$tw.utils.registerFileType("audio/mp3","base64",".mp3"); $tw.utils.registerFileType("audio/mp3","base64",".mp3");
$tw.utils.registerFileType("audio/mp4","base64",[".mp4",".m4a"]);
$tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"}); $tw.utils.registerFileType("text/markdown","utf8",[".md",".markdown"],{deserializerType:"text/x-markdown"});
$tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]); $tw.utils.registerFileType("text/x-markdown","utf8",[".md",".markdown"]);
$tw.utils.registerFileType("application/enex+xml","utf8",".enex"); $tw.utils.registerFileType("application/enex+xml","utf8",".enex");
@@ -2419,7 +2416,7 @@ $tw.boot.initStartup = function(options) {
$tw.utils.registerFileType("application/epub+zip","base64",".epub"); $tw.utils.registerFileType("application/epub+zip","base64",".epub");
$tw.utils.registerFileType("application/octet-stream","base64",".octet-stream"); $tw.utils.registerFileType("application/octet-stream","base64",".octet-stream");
// Create the wiki store for the app // Create the wiki store for the app
$tw.wiki = new $tw.Wiki($tw.safeMode && {enableIndexers: []}); $tw.wiki = new $tw.Wiki();
// Install built in tiddler fields modules // Install built in tiddler fields modules
$tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield"); $tw.Tiddler.fieldModules = $tw.modules.getModulesByTypeAsHashmap("tiddlerfield");
// Install the tiddler deserializer modules // Install the tiddler deserializer modules

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +0,0 @@
title: $:/core/images/layout-button
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-layout-button tc-image-button" viewBox="0 0 24 24" stroke-width="1" stroke="none"><path d="M0 0h24v24H0z" fill="none"/><rect x="2" y="2" width="7" height="7" rx="2"/><rect x="2" y="13" width="7" height="9" rx="2"/><rect x="12" y="2" width="10" height="20" rx="2"/></svg>

View File

@@ -1,6 +0,0 @@
title: $:/core/images/mastodon
tags: $:/tags/Image
<svg width="22pt" height="22pt" class="tc-image-mastodon tc-image-button" viewBox="0 0 128 128">
<path d="M112.716,76.735C111.231,85.764 99.411,95.646 85.836,97.561C78.757,98.559 71.787,99.476 64.355,99.073C52.201,98.415 42.61,95.646 42.61,95.646C42.61,97.044 42.683,98.374 42.829,99.619C44.409,113.79 54.723,114.639 64.493,115.035C74.354,115.434 83.134,112.163 83.134,112.163L83.539,122.695C83.539,122.695 76.642,127.071 64.355,127.875C57.58,128.315 49.167,127.674 39.369,124.61C18.118,117.965 14.463,91.202 13.904,64.048C13.733,55.985 13.839,48.383 13.839,42.024C13.839,14.257 29.238,6.118 29.238,6.118C37.002,1.905 50.326,0.134 64.177,-0L64.517,-0C78.369,0.134 91.701,1.905 99.465,6.118C99.465,6.118 114.864,14.257 114.864,42.024C114.864,42.024 115.057,62.511 112.716,76.735ZM96.7,44.179C96.7,37.307 95.219,31.847 92.245,27.807C89.177,23.767 85.16,21.696 80.174,21.696C74.403,21.696 70.034,24.316 67.146,29.556L64.337,35.118L61.529,29.556C58.64,24.316 54.271,21.696 48.501,21.696C43.514,21.696 39.497,23.767 36.43,27.807C33.455,31.847 31.974,37.307 31.974,44.179L31.974,77.8L43.249,77.8L43.249,45.167C43.249,38.288 45.699,34.796 50.599,34.796C56.017,34.796 58.733,38.938 58.733,47.128L58.733,64.99L69.941,64.99L69.941,47.128C69.941,38.938 72.657,34.796 78.075,34.796C82.975,34.796 85.425,38.288 85.425,45.167L85.425,77.8L96.7,77.8L96.7,44.179Z"/>
</svg>

View File

@@ -18,8 +18,6 @@ CopyToClipboard/Caption: copy to clipboard
CopyToClipboard/Hint: Copy this text to the clipboard CopyToClipboard/Hint: Copy this text to the clipboard
Delete/Caption: delete Delete/Caption: delete
Delete/Hint: Delete this tiddler Delete/Hint: Delete this tiddler
DeleteTiddlers/Caption: delete tiddlers
DeleteTiddlers/Hint: Delete tiddlers
Edit/Caption: edit Edit/Caption: edit
Edit/Hint: Edit this tiddler Edit/Hint: Edit this tiddler
Encryption/Caption: encryption Encryption/Caption: encryption
@@ -59,8 +57,6 @@ Home/Caption: home
Home/Hint: Open the default tiddlers Home/Hint: Open the default tiddlers
Language/Caption: language Language/Caption: language
Language/Hint: Choose the user interface language Language/Hint: Choose the user interface language
LayoutSwitcher/Hint: Open layout switcher
LayoutSwitcher/Caption: layout
Manager/Caption: tiddler manager Manager/Caption: tiddler manager
Manager/Hint: Open tiddler manager Manager/Hint: Open tiddler manager
More/Caption: more More/Caption: more

View File

@@ -7,7 +7,7 @@ Appearance/Hint: Ways to customise the appearance of your TiddlyWiki.
Basics/AnimDuration/Prompt: Animation duration Basics/AnimDuration/Prompt: Animation duration
Basics/AutoFocus/Prompt: Default focus field for new tiddlers Basics/AutoFocus/Prompt: Default focus field for new tiddlers
Basics/Caption: Basics Basics/Caption: Basics
Basics/DefaultTiddlers/BottomHint: Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to {{retain story ordering||$:/snippets/retain-story-ordering-button}} Basics/DefaultTiddlers/BottomHint: Use &#91;&#91;double square brackets&#93;&#93; for titles with spaces. Or you can choose to <$button set="$:/DefaultTiddlers" setTo="[list[$:/StoryList]]">retain story ordering</$button>
Basics/DefaultTiddlers/Prompt: Default tiddlers Basics/DefaultTiddlers/Prompt: Default tiddlers
Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup Basics/DefaultTiddlers/TopHint: Choose which tiddlers are displayed at startup
Basics/Language/Prompt: Hello! Current language: Basics/Language/Prompt: Hello! Current language:
@@ -90,8 +90,8 @@ Plugins/Languages/Caption: Languages
Plugins/Languages/Hint: Language pack plugins Plugins/Languages/Hint: Language pack plugins
Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found Plugins/NoInfoFound/Hint: No ''"<$text text=<<currentTab>>/>"'' found
Plugins/NotInstalled/Hint: This plugin is not currently installed Plugins/NotInstalled/Hint: This plugin is not currently installed
Plugins/OpenPluginLibrary: Open plugin library Plugins/OpenPluginLibrary: open plugin library
Plugins/ClosePluginLibrary: Close plugin library Plugins/ClosePluginLibrary: close plugin library
Plugins/PluginWillRequireReload: (requires reload) Plugins/PluginWillRequireReload: (requires reload)
Plugins/Plugins/Caption: Plugins Plugins/Plugins/Caption: Plugins
Plugins/Plugins/Hint: Plugins Plugins/Plugins/Hint: Plugins

View File

@@ -1,6 +1,5 @@
title: $:/language/EditTemplate/ title: $:/language/EditTemplate/
Caption: Editor
Body/External/Hint: This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself Body/External/Hint: This tiddler shows content stored outside of the main TiddlyWiki file. You can edit the tags and fields but cannot directly edit the content itself
Body/Placeholder: Type the text for this tiddler Body/Placeholder: Type the text for this tiddler
Body/Preview/Type/Output: output Body/Preview/Type/Output: output

View File

@@ -13,7 +13,7 @@ dependents: For a plugin, lists the dependent plugin titles
description: The descriptive text for a plugin, or a modal dialogue description: The descriptive text for a plugin, or a modal dialogue
draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft draft.of: For draft tiddlers, contains the title of the tiddler of which this is a draft
draft.title: For draft tiddlers, contains the proposed new title of the tiddler draft.title: For draft tiddlers, contains the proposed new title of the tiddler
footer: The footer text for a modal footer: The footer text for a wizard
hide-body: The view template will hide bodies of tiddlers if set to ''yes'' hide-body: The view template will hide bodies of tiddlers if set to ''yes''
icon: The title of the tiddler containing the icon associated with a tiddler icon: The title of the tiddler containing the icon associated with a tiddler
library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes'' library: Indicates that a tiddler should be saved as a JavaScript library if set to ''yes''
@@ -28,7 +28,7 @@ plugin-type: The type of plugin in a plugin tiddler
revision: The revision of the tiddler held at the server revision: The revision of the tiddler held at the server
released: Date of a TiddlyWiki release released: Date of a TiddlyWiki release
source: The source URL associated with a tiddler source: The source URL associated with a tiddler
subtitle: The subtitle text for a modal subtitle: The subtitle text for a wizard
tags: A list of tags associated with a tiddler tags: A list of tags associated with a tiddler
text: The body text of a tiddler text: The body text of a tiddler
throttle.refresh: If present, throttles refreshes of this tiddler throttle.refresh: If present, throttles refreshes of this tiddler

View File

@@ -9,10 +9,9 @@ Before you start storing important information in ~TiddlyWiki it is vital to mak
<div class="tc-control-panel"> <div class="tc-control-panel">
|tc-table-no-border tc-first-col-min-width tc-first-link-nowrap|k |<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
| <$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link>|<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> | |<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
| <$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link>|<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> | |<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
|^ <$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link><br><<lingo DefaultTiddlers/TopHint>>|<$edit tag="textarea" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
</div> </div>
See the [[control panel|$:/ControlPanel]] for more options. See the [[control panel|$:/ControlPanel]] for more options.

View File

@@ -1,18 +0,0 @@
title: $:/language/Help/commands
description: Run commands returned from a filter
Sequentially run the command tokens returned from a filter
```
--commands <filter>
```
Examples
```
--commands "[enlist{$:/build-commands-as-text}]"
```
```
--commands "[{$:/build-commands-as-json}jsonindexes[]] :map[{$:/build-commands-as-json}jsonget<currentTiddler>]"
```

View File

@@ -31,5 +31,5 @@ Notes:
Examples: Examples:
* `--render '[!is[system]]' '[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]'` -- renders all non-system tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles and the extension HTML * `--render "[!is[system]]" "[encodeuricomponent[]addprefix[tiddlers/]addsuffix[.html]]"` -- renders all non-system tiddlers as files in the subdirectory "tiddlers" with URL-encoded titles and the extension HTML
* `--render '.' 'tiddlers.json' 'text/plain' '$:/core/templates/exporters/JsonFile' 'exportFilter' '[tag[HelloThere]]'` -- renders the tiddlers tagged "HelloThere" to a JSON file named "tiddlers.json"

View File

@@ -8,7 +8,6 @@ CloseAll/Button: close all
ColourPicker/Recent: Recent: ColourPicker/Recent: Recent:
ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text=<<title>>/>"? ConfirmCancelTiddler: Do you wish to discard changes to the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"? ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
ConfirmDeleteTiddlers: Are you sure you wish to delete <<resultCount>> tiddler(s)?
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"? ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"? ConfirmEditShadowTiddler: You are about to edit a ShadowTiddler. Any changes will override the default system making future upgrades non-trivial. Are you sure you want to edit "<$text text=<<title>>/>"?
ConfirmAction: Do you wish to proceed? ConfirmAction: Do you wish to proceed?

View File

@@ -1,6 +1,5 @@
title: $:/language/SideBar/ title: $:/language/SideBar/
Caption: Sidebar
All/Caption: All All/Caption: All
Contents/Caption: Contents Contents/Caption: Contents
Drafts/Caption: Drafts Drafts/Caption: Drafts

View File

@@ -1,42 +0,0 @@
/*\
title: $:/core/modules/commands/commands.js
type: application/javascript
module-type: command
Runs the commands returned from a filter
\*/
(function() {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "commands",
synchronous: true
};
var Command = function(params, commander) {
this.params = params;
this.commander = commander;
};
Command.prototype.execute = function() {
// Parse the filter
var filter = this.params[0];
if(!filter) {
return "No filter specified";
}
var commands = this.commander.wiki.filterTiddlers(filter)
if(commands.length === 0) {
return "No tiddlers found for filter '" + filter + "'";
}
this.commander.addCommandTokens(commands);
return null;
};
exports.Command = Command;
})();

View File

@@ -50,7 +50,7 @@ Render individual tiddlers and save the results to the specified files
console.log("Rendering \"" + title + "\" to \"" + filepath + "\""); console.log("Rendering \"" + title + "\" to \"" + filepath + "\"");
} }
var parser = wiki.parseTiddler(template || title), var parser = wiki.parseTiddler(template || title),
widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title,storyTiddler: title})}), widgetNode = wiki.makeWidget(parser,{variables: $tw.utils.extend({},variables,{currentTiddler: title})}),
container = $tw.fakeDocument.createElement("div"); container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null); widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent; var text = type === "text/html" ? container.innerHTML : container.textContent;

View File

@@ -40,7 +40,6 @@ Command.prototype.execute = function() {
$tw.utils.createFileDirectories(filename); $tw.utils.createFileDirectories(filename);
if(template) { if(template) {
variables.currentTiddler = title; variables.currentTiddler = title;
variables.storyTiddler = title;
title = template; title = template;
} }
if(name && value) { if(name && value) {

View File

@@ -46,7 +46,7 @@ Command.prototype.execute = function() {
} }
$tw.utils.each(tiddlers,function(title) { $tw.utils.each(tiddlers,function(title) {
var parser = wiki.parseTiddler(template), var parser = wiki.parseTiddler(template),
widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title, storyTiddler: title}}), widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}}),
container = $tw.fakeDocument.createElement("div"); container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null); widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent, var text = type === "text/html" ? container.innerHTML : container.textContent,

View File

@@ -35,7 +35,7 @@ function FramedEngine(options) {
this.iframeDoc = this.iframeNode.contentWindow.document; this.iframeDoc = this.iframeNode.contentWindow.document;
// (Firefox requires us to put some empty content in the iframe) // (Firefox requires us to put some empty content in the iframe)
var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette"); var paletteTitle = this.widget.wiki.getTiddlerText("$:/palette");
var colorScheme = (this.widget.wiki.getTiddler(paletteTitle) || {fields: {}}).fields["color-scheme"] || "light"; var colorScheme = this.widget.wiki.getTiddler(paletteTitle).fields["color-scheme"] || "light";
this.iframeDoc.open(); this.iframeDoc.open();
this.iframeDoc.write("<meta name='color-scheme' content='" + colorScheme + "'>"); this.iframeDoc.write("<meta name='color-scheme' content='" + colorScheme + "'>");
this.iframeDoc.close(); this.iframeDoc.close();
@@ -87,7 +87,7 @@ function FramedEngine(options) {
$tw.utils.addEventListeners(this.domNode,[ $tw.utils.addEventListeners(this.domNode,[
{name: "click",handlerObject: this,handlerMethod: "handleClickEvent"}, {name: "click",handlerObject: this,handlerMethod: "handleClickEvent"},
{name: "input",handlerObject: this,handlerMethod: "handleInputEvent"}, {name: "input",handlerObject: this,handlerMethod: "handleInputEvent"},
{name: "keydown",handlerObject: this,handlerMethod: "handleKeydownEvent"}, {name: "keydown",handlerObject: this.widget,handlerMethod: "handleKeydownEvent"},
{name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"} {name: "focus",handlerObject: this,handlerMethod: "handleFocusEvent"}
]); ]);
// Add drag and drop event listeners if fileDrop is enabled // Add drag and drop event listeners if fileDrop is enabled
@@ -192,17 +192,6 @@ FramedEngine.prototype.handleFocusEvent = function(event) {
} }
}; };
/*
Handle a keydown event
*/
FramedEngine.prototype.handleKeydownEvent = function(event) {
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
return true;
}
return this.widget.handleKeydownEvent(event);
};
/* /*
Handle a click Handle a click
*/ */

View File

@@ -115,7 +115,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
// Otherwise, we need to construct a default value for the editor // Otherwise, we need to construct a default value for the editor
switch(this.editField) { switch(this.editField) {
case "text": case "text":
value = ""; value = "Type the text for the tiddler '" + this.editTitle + "'";
type = "text/vnd.tiddlywiki"; type = "text/vnd.tiddlywiki";
break; break;
case "title": case "title":
@@ -298,7 +298,7 @@ function editTextWidgetFactory(toolbarEngine,nonToolbarEngine) {
Propogate keydown events to our container for the keyboard widgets benefit Propogate keydown events to our container for the keyboard widgets benefit
*/ */
EditTextWidget.prototype.propogateKeydownEvent = function(event) { EditTextWidget.prototype.propogateKeydownEvent = function(event) {
var newEvent = this.cloneEvent(event,["keyCode","code","which","key","metaKey","ctrlKey","altKey","shiftKey"]); var newEvent = this.cloneEvent(event,["keyCode","which","metaKey","ctrlKey","altKey","shiftKey"]);
return !this.parentDomNode.dispatchEvent(newEvent); return !this.parentDomNode.dispatchEvent(newEvent);
}; };

View File

@@ -16,9 +16,7 @@ exports.map = function(operationSubFunction,options) {
return function(results,source,widget) { return function(results,source,widget) {
if(results.length > 0) { if(results.length > 0) {
var inputTitles = results.toArray(), var inputTitles = results.toArray(),
index = 0, index = 0;
suffixes = options.suffixes,
flatten = (suffixes[0] && suffixes[0][0] === "flat") ? true : false;
results.clear(); results.clear();
$tw.utils.each(inputTitles,function(title) { $tw.utils.each(inputTitles,function(title) {
var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{ var filtered = operationSubFunction(options.wiki.makeTiddlerIterator([title]),{
@@ -38,13 +36,7 @@ exports.map = function(operationSubFunction,options) {
} }
} }
}); });
if(filtered.length && flatten) { results.push(filtered[0] || "");
$tw.utils.each(filtered,function(value) {
results.push(value);
})
} else {
results.push(filtered[0]||"");
}
++index; ++index;
}); });
} }

View File

@@ -12,9 +12,6 @@ Adds tiddler filtering methods to the $tw.Wiki object.
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
/* Maximum permitted filter recursion depth */
var MAX_FILTER_DEPTH = 300;
/* /*
Parses an operation (i.e. a run) within a filter string Parses an operation (i.e. a run) within a filter string
operators: Array of array of operator nodes into which results should be inserted operators: Array of array of operator nodes into which results should be inserted
@@ -223,18 +220,10 @@ source: an iterator function for the source tiddlers, called source(iterator), w
widget: an optional widget node for retrieving the current tiddler etc. widget: an optional widget node for retrieving the current tiddler etc.
*/ */
exports.compileFilter = function(filterString) { exports.compileFilter = function(filterString) {
if(!this.filterCache) {
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
if(this.filterCache[filterString] !== undefined) {
return this.filterCache[filterString];
}
var filterParseTree; var filterParseTree;
try { try {
filterParseTree = this.parseFilter(filterString); filterParseTree = this.parseFilter(filterString);
} catch(e) { } catch(e) {
// We do not cache this result, so it adjusts along with localization changes
return function(source,widget) { return function(source,widget) {
return [$tw.language.getString("Error/Filter") + ": " + e]; return [$tw.language.getString("Error/Filter") + ": " + e];
}; };
@@ -331,7 +320,7 @@ exports.compileFilter = function(filterString) {
})()); })());
}); });
// Return a function that applies the operations to a source iterator of tiddler titles // Return a function that applies the operations to a source iterator of tiddler titles
var fnMeasured = $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) { return $tw.perf.measure("filter: " + filterString,function filterFunction(source,widget) {
if(!source) { if(!source) {
source = self.each; source = self.each;
} else if(typeof source === "object") { // Array or hashmap } else if(typeof source === "object") { // Array or hashmap
@@ -341,27 +330,11 @@ exports.compileFilter = function(filterString) {
widget = $tw.rootWidget; widget = $tw.rootWidget;
} }
var results = new $tw.utils.LinkedList(); var results = new $tw.utils.LinkedList();
self.filterRecursionCount = (self.filterRecursionCount || 0) + 1; $tw.utils.each(operationFunctions,function(operationFunction) {
if(self.filterRecursionCount < MAX_FILTER_DEPTH) { operationFunction(results,source,widget);
$tw.utils.each(operationFunctions,function(operationFunction) { });
operationFunction(results,source,widget);
});
} else {
results.push("/**-- Excessive filter recursion --**/");
}
self.filterRecursionCount = self.filterRecursionCount - 1;
return results.toArray(); return results.toArray();
}); });
if(this.filterCacheCount >= 2000) {
// To prevent memory leak, we maintain an upper limit for cache size.
// Reset if exceeded. This should give us 95% of the benefit
// that no cache limit would give us.
this.filterCache = Object.create(null);
this.filterCacheCount = 0;
}
this.filterCache[filterString] = fnMeasured;
this.filterCacheCount++;
return fnMeasured;
}; };
})(); })();

View File

@@ -1,35 +0,0 @@
/*\
title: $:/core/modules/filters/format/json.js
type: application/javascript
module-type: formatfilteroperator
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.json = function(source,operand,options) {
var results = [],
spaces = null;
if(operand) {
spaces = /^\d+$/.test(operand) ? parseInt(operand,10) : operand;
}
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title);
try {
data = JSON.parse(title);
} catch(e) {
data = undefined;
}
if(data !== undefined) {
results.push(JSON.stringify(data,null,spaces));
}
});
return results;
};
})();

View File

@@ -1,46 +0,0 @@
/*\
title: $:/core/modules/filters/insertafter.js
type: application/javascript
module-type: filteroperator
Insert an item after another item in a list
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Order a list
*/
exports.insertafter = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
results.push(title);
});
var target = operator.operands[1] || (options.widget && options.widget.getVariable(operator.suffix || "currentTiddler"));
if(target !== operator.operand) {
// Remove the entry from the list if it is present
var pos = results.indexOf(operator.operand);
if(pos !== -1) {
results.splice(pos,1);
}
// Insert the entry after the target marker
pos = results.indexOf(target);
if(pos !== -1) {
results.splice(pos+1,0,operator.operand);
} else {
var suffix = operator.operands.length > 1 ? operator.suffix : "";
if(suffix === "start") {
results.splice(0,0,operator.operand);
} else {
results.push(operator.operand);
}
}
}
return results;
};
})();

View File

@@ -32,12 +32,7 @@ exports.insertbefore = function(source,operator,options) {
if(pos !== -1) { if(pos !== -1) {
results.splice(pos,0,operator.operand); results.splice(pos,0,operator.operand);
} else { } else {
var suffix = operator.operands.length > 1 ? operator.suffix : ""; results.push(operator.operand);
if(suffix == "start") {
results.splice(0,0,operator.operand);
} else {
results.push(operator.operand);
}
} }
} }
return results; return results;

View File

@@ -19,13 +19,13 @@ exports.variable = function(source,prefix,options) {
var results = []; var results = [];
if(prefix === "!") { if(prefix === "!") {
source(function(tiddler,title) { source(function(tiddler,title) {
if(options.widget.getVariable(title) === undefined) { if(!(title in options.widget.variables)) {
results.push(title); results.push(title);
} }
}); });
} else { } else {
source(function(tiddler,title) { source(function(tiddler,title) {
if(options.widget.getVariable(title) !== undefined) { if(title in options.widget.variables) {
results.push(title); results.push(title);
} }
}); });

View File

@@ -15,25 +15,11 @@ Filter operators for JSON operations
exports["jsonget"] = function(source,operator,options) { exports["jsonget"] = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title); var data = options.wiki.getTiddlerDataCached(title);
if(data) { if(data) {
var items = getDataItemValueAsStrings(data,operator.operands); var item = getDataItemValueAsStrings(data,operator.operands);
if(items !== undefined) {
results.push.apply(results,items);
}
}
});
return results;
};
exports["jsonextract"] = function(source,operator,options) {
var results = [];
source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title);
if(data) {
var item = getDataItem(data,operator.operands);
if(item !== undefined) { if(item !== undefined) {
results.push(JSON.stringify(item)); results.push.apply(results,item);
} }
} }
}); });
@@ -43,11 +29,11 @@ exports["jsonextract"] = function(source,operator,options) {
exports["jsonindexes"] = function(source,operator,options) { exports["jsonindexes"] = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title); var data = options.wiki.getTiddlerDataCached(title);
if(data) { if(data) {
var items = getDataItemKeysAsStrings(data,operator.operands); var item = getDataItemKeysAsStrings(data,operator.operands);
if(items !== undefined) { if(item !== undefined) {
results.push.apply(results,items); results.push.apply(results,item);
} }
} }
}); });
@@ -57,7 +43,7 @@ exports["jsonindexes"] = function(source,operator,options) {
exports["jsontype"] = function(source,operator,options) { exports["jsontype"] = function(source,operator,options) {
var results = []; var results = [];
source(function(tiddler,title) { source(function(tiddler,title) {
var data = $tw.utils.parseJSONSafe(title,title); var data = options.wiki.getTiddlerDataCached(title);
if(data) { if(data) {
var item = getDataItemType(data,operator.operands); var item = getDataItemType(data,operator.operands);
if(item !== undefined) { if(item !== undefined) {
@@ -74,7 +60,7 @@ Given a JSON data structure and an array of index strings, return an array of th
function getDataItemValueAsStrings(data,indexes) { function getDataItemValueAsStrings(data,indexes) {
// Get the item // Get the item
var item = getDataItem(data,indexes); var item = getDataItem(data,indexes);
// Return the item as a string list // Return the item as a string
return convertDataItemValueToStrings(item); return convertDataItemValueToStrings(item);
} }
@@ -94,29 +80,24 @@ Return an array of the string representation of the values of a data item, or "u
function convertDataItemValueToStrings(item) { function convertDataItemValueToStrings(item) {
// Return the item as a string // Return the item as a string
if(item === undefined) { if(item === undefined) {
return undefined; return item;
} else if(item === null) { }
return ["null"] if(typeof item === "object") {
} else if(typeof item === "object") { if(item === null) {
var results = [],i,t; return ["null"];
if($tw.utils.isArray(item)) { }
// Return all the items in arrays recursively var results = [];
for(i=0; i<item.length; i++) { if($tw.utils.isArray(item)) {
t = convertDataItemValueToStrings(item[i]) $tw.utils.each(item,function(value) {
if(t !== undefined) { results.push.apply(results,convertDataItemValueToStrings(value));
results.push.apply(results,t); });
} return results;
} } else {
} else { $tw.utils.each(Object.keys(item).sort(),function(key) {
// Return all the values in objects recursively results.push.apply(results,convertDataItemValueToStrings(item[key]));
$tw.utils.each(Object.keys(item).sort(),function(key) { });
t = convertDataItemValueToStrings(item[key]); return results;
if(t !== undefined) {
results.push.apply(results,t);
}
});
} }
return results;
} }
return [item.toString()]; return [item.toString()];
} }

View File

@@ -16,15 +16,9 @@ Filter operator for returning the names of the active variables
Export our filter function Export our filter function
*/ */
exports.variables = function(source,operator,options) { exports.variables = function(source,operator,options) {
var names = [], var names = [];
widget = options.widget; for(var variable in options.widget.variables) {
while(widget && !widget.hasOwnProperty("variables")) { names.push(variable);
widget = widget.parentWidget;
}
if(widget && widget.variables) {
for(var variable in widget.variables) {
names.push(variable);
}
} }
return names.sort(); return names.sort();
}; };

View File

@@ -141,7 +141,6 @@ function KeyboardManager(options) {
this.shortcutKeysList = [], // Stores the shortcut-key descriptors this.shortcutKeysList = [], // Stores the shortcut-key descriptors
this.shortcutActionList = [], // Stores the corresponding action strings this.shortcutActionList = [], // Stores the corresponding action strings
this.shortcutParsedList = []; // Stores the parsed key descriptors this.shortcutParsedList = []; // Stores the parsed key descriptors
this.shortcutPriorityList = []; // Stores the parsed shortcut priority
this.lookupNames = ["shortcuts"]; this.lookupNames = ["shortcuts"];
this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac") this.lookupNames.push($tw.platform.isMac ? "shortcuts-mac" : "shortcuts-not-mac")
this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows"); this.lookupNames.push($tw.platform.isWindows ? "shortcuts-windows" : "shortcuts-not-windows");
@@ -319,23 +318,12 @@ KeyboardManager.prototype.updateShortcutLists = function(tiddlerList) {
this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined; this.shortcutKeysList[i] = tiddlerFields.key !== undefined ? tiddlerFields.key : undefined;
this.shortcutActionList[i] = tiddlerFields.text; this.shortcutActionList[i] = tiddlerFields.text;
this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined; this.shortcutParsedList[i] = this.shortcutKeysList[i] !== undefined ? this.parseKeyDescriptors(this.shortcutKeysList[i]) : undefined;
this.shortcutPriorityList[i] = tiddlerFields.priority === "yes" ? true : false;
} }
}; };
/* KeyboardManager.prototype.handleKeydownEvent = function(event) {
event: the keyboard event object
options:
onlyPriority: true if only priority global shortcuts should be invoked
*/
KeyboardManager.prototype.handleKeydownEvent = function(event, options) {
options = options || {};
var key, action; var key, action;
for(var i=0; i<this.shortcutTiddlers.length; i++) { for(var i=0; i<this.shortcutTiddlers.length; i++) {
if(options.onlyPriority && this.shortcutPriorityList[i] !== true) {
continue;
}
if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) { if(this.shortcutParsedList[i] !== undefined && this.checkKeyDescriptors(event,this.shortcutParsedList[i])) {
key = this.shortcutParsedList[i]; key = this.shortcutParsedList[i];
action = this.shortcutActionList[i]; action = this.shortcutActionList[i];

View File

@@ -13,11 +13,6 @@ The CSV text parser processes CSV files into a table wrapped in a scrollable wid
"use strict"; "use strict";
var CsvParser = function(type,text,options) { var CsvParser = function(type,text,options) {
// Special handler for tab-delimited files
if (type === 'text/tab-delimited-values' && !options.separator) {
options.separator = "\t";
}
// Table framework // Table framework
this.tree = [{ this.tree = [{
"type": "scrollable", "children": [{ "type": "scrollable", "children": [{
@@ -29,33 +24,30 @@ var CsvParser = function(type,text,options) {
}] }]
}]; }];
// Split the text into lines // Split the text into lines
var lines = $tw.utils.parseCsvString(text, options), var lines = text.split(/\r?\n/mg),
tag = "th"; tag = "th";
var maxColumns = 0;
$tw.utils.each(lines, function(columns) {
maxColumns = Math.max(columns.length, maxColumns);
});
for(var line=0; line<lines.length; line++) { for(var line=0; line<lines.length; line++) {
var columns = lines[line]; var lineText = lines[line];
var row = { if(lineText) {
"type": "element", "tag": "tr", "children": [] var row = {
}; "type": "element", "tag": "tr", "children": []
for(var column=0; column<maxColumns; column++) { };
row.children.push({ var columns = lineText.split(",");
"type": "element", "tag": tag, "children": [{ for(var column=0; column<columns.length; column++) {
"type": "text", row.children.push({
"text": columns[column] || '' "type": "element", "tag": tag, "children": [{
}] "type": "text",
}); "text": columns[column]
}]
});
}
tag = "td";
this.tree[0].children[0].children[0].children.push(row);
} }
tag = "td";
this.tree[0].children[0].children[0].children.push(row);
} }
}; };
exports["text/csv"] = CsvParser; exports["text/csv"] = CsvParser;
exports["text/tab-delimited-values"] = CsvParser;
})(); })();

View File

@@ -58,7 +58,7 @@ exports.parse = function() {
var reEnd; var reEnd;
if(this.match[3]) { if(this.match[3]) {
// If so, the end of the body is marked with \end // If so, the end of the body is marked with \end
reEnd = new RegExp("(\\r?\\n\\\\end[^\\S\\n\\r]*(?:" + $tw.utils.escapeRegExp(this.match[1]) + ")?(?:$|\\r?\\n))","mg"); reEnd = /(\r?\n\\end[^\S\n\r]*(?:$|\r?\n))/mg;
} else { } else {
// Otherwise, the end of the definition is marked by the end of the line // Otherwise, the end of the definition is marked by the end of the line
reEnd = /($|\r?\n)/mg; reEnd = /($|\r?\n)/mg;

View File

@@ -1,68 +0,0 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/parsermode.js
type: application/javascript
module-type: wikirule
Wiki pragma rule for parser mode specifications
```
\parsermode block
\parsermode inline
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "parsermode";
exports.types = {pragma: true};
/*
Instantiate parse rule
*/
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /^\\parsermode[^\S\n]/mg;
};
/*
Parse the most recent match
*/
exports.parse = function() {
// Move past the pragma invocation
this.parser.pos = this.matchRegExp.lastIndex;
// Parse whitespace delimited tokens terminated by a line break
var reMatch = /[^\S\n]*(\S+)|(\r?\n)/mg,
parserMode = undefined;
reMatch.lastIndex = this.parser.pos;
var match = reMatch.exec(this.parser.source);
while(match && match.index === this.parser.pos) {
this.parser.pos = reMatch.lastIndex;
// Exit if we've got the line break
if(match[2]) {
break;
}
// Process the token
if(match[1]) {
parserMode = match[1];
}
// Match the next token
match = reMatch.exec(this.parser.source);
}
// Process the tokens
if(parserMode !== undefined) {
if(parserMode === "block") {
this.parser.parseAsInline = false;
} else if(parserMode === "inline") {
this.parser.parseAsInline = true;
}
}
// No parse tree nodes to return
return [];
};
})();

View File

@@ -41,6 +41,9 @@ exports.parse = function() {
var node = { var node = {
type: "element", type: "element",
tag: "span", tag: "span",
attributes: {
"class": {type: "string", value: "tc-inline-style"}
},
children: tree children: tree
}; };
if(classString) { if(classString) {
@@ -49,9 +52,6 @@ exports.parse = function() {
if(stylesString) { if(stylesString) {
$tw.utils.addAttributeToParseTreeNode(node,"style",stylesString); $tw.utils.addAttributeToParseTreeNode(node,"style",stylesString);
} }
if(!classString && !stylesString) {
$tw.utils.addClassToParseTreeNode(node,"tc-inline-style");
}
return [node]; return [node];
}; };

View File

@@ -47,8 +47,6 @@ var WikiParser = function(type,text,options) {
this.sourceLength = this.source.length; this.sourceLength = this.source.length;
// Flag for ignoring whitespace // Flag for ignoring whitespace
this.configTrimWhiteSpace = false; this.configTrimWhiteSpace = false;
// Parser mode
this.parseAsInline = options.parseAsInline;
// Set current parse position // Set current parse position
this.pos = 0; this.pos = 0;
// Start with empty output // Start with empty output
@@ -85,7 +83,7 @@ var WikiParser = function(type,text,options) {
// Parse any pragmas // Parse any pragmas
var topBranch = this.parsePragmas(); var topBranch = this.parsePragmas();
// Parse the text into inline runs or blocks // Parse the text into inline runs or blocks
if(this.parseAsInline) { if(options.parseAsInline) {
topBranch.push.apply(topBranch,this.parseInlineRun()); topBranch.push.apply(topBranch,this.parseInlineRun());
} else { } else {
topBranch.push.apply(topBranch,this.parseBlocks()); topBranch.push.apply(topBranch,this.parseBlocks());
@@ -118,7 +116,7 @@ WikiParser.prototype.loadRemoteTiddler = function(url) {
*/ */
WikiParser.prototype.setupRules = function(proto,configPrefix) { WikiParser.prototype.setupRules = function(proto,configPrefix) {
var self = this; var self = this;
if(!$tw.safeMode) { if(!$tw.safemode) {
$tw.utils.each(proto,function(object,name) { $tw.utils.each(proto,function(object,name) {
if(self.wiki.getTiddlerText(configPrefix + name,"enable") !== "enable") { if(self.wiki.getTiddlerText(configPrefix + name,"enable") !== "enable") {
delete proto[name]; delete proto[name];

View File

@@ -30,16 +30,6 @@ exports.handler = function(request,response,state) {
if(fields.revision) { if(fields.revision) {
delete fields.revision; delete fields.revision;
} }
// If this is a skinny tiddler, it means the client never got the full
// version of the tiddler to edit. So we must preserve whatever text
// already exists on the server, or else we'll inadvertently delete it.
if(fields._is_skinny !== undefined) {
var tiddler = state.wiki.getTiddler(title);
if(tiddler) {
fields.text = tiddler.fields.text;
}
delete fields._is_skinny;
}
state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title})); state.wiki.addTiddler(new $tw.Tiddler(fields,{title: title}));
var changeCount = state.wiki.getChangeCount(title).toString(); var changeCount = state.wiki.getChangeCount(title).toString();
response.writeHead(204, "OK",{ response.writeHead(204, "OK",{

View File

@@ -359,9 +359,8 @@ Server.prototype.listen = function(port,host,prefix) {
} }
// Display the port number after we've started listening (the port number might have been specified as zero, in which case we will get an assigned port) // Display the port number after we've started listening (the port number might have been specified as zero, in which case we will get an assigned port)
server.on("listening",function() { server.on("listening",function() {
var address = server.address(), var address = server.address();
url = self.protocol + "://" + (address.family === "IPv6" ? "[" + address.address + "]" : address.address) + ":" + address.port + prefix; $tw.utils.log("Serving on " + self.protocol + "://" + address.address + ":" + address.port + prefix,"brown/orange");
$tw.utils.log("Serving on " + url,"brown/orange");
$tw.utils.log("(press ctrl-C to exit)","red"); $tw.utils.log("(press ctrl-C to exit)","red");
}); });
// Listen // Listen

View File

@@ -62,14 +62,12 @@ function loadIFrame(url,callback) {
Unload library iframe for given url Unload library iframe for given url
*/ */
function unloadIFrame(url){ function unloadIFrame(url){
var iframes = document.getElementsByTagName('iframe'); $tw.utils.each(document.getElementsByTagName('iframe'), function(iframe) {
for(var t=iframes.length-1; t--; t>=0) {
var iframe = iframes[t];
if(iframe.getAttribute("library") === "true" && if(iframe.getAttribute("library") === "true" &&
iframe.getAttribute("src") === url) { iframe.getAttribute("src") === url) {
iframe.parentNode.removeChild(iframe); iframe.parentNode.removeChild(iframe);
} }
} });
} }
function saveIFrameInfoTiddler(iframeInfo) { function saveIFrameInfoTiddler(iframeInfo) {

View File

@@ -121,11 +121,7 @@ exports.startup = function() {
}); });
// Set up the syncer object if we've got a syncadaptor // Set up the syncer object if we've got a syncadaptor
if($tw.syncadaptor) { if($tw.syncadaptor) {
$tw.syncer = new $tw.Syncer({ $tw.syncer = new $tw.Syncer({wiki: $tw.wiki, syncadaptor: $tw.syncadaptor});
wiki: $tw.wiki,
syncadaptor: $tw.syncadaptor,
logging: $tw.wiki.getTiddlerText('$:/config/SyncLogging', "yes") === "yes"
});
} }
// Setup the saver handler // Setup the saver handler
$tw.saverHandler = new $tw.SaverHandler({ $tw.saverHandler = new $tw.SaverHandler({

View File

@@ -54,9 +54,7 @@ exports.startup = function() {
var hash = $tw.utils.getLocationHash(); var hash = $tw.utils.getLocationHash();
if(hash !== $tw.locationHash) { if(hash !== $tw.locationHash) {
$tw.locationHash = hash; $tw.locationHash = hash;
if(hash !== "#") { openStartupTiddlers({defaultToCurrentStory: true});
openStartupTiddlers({defaultToCurrentStory: true});
}
} }
},false); },false);
// Listen for the tm-browser-refresh message // Listen for the tm-browser-refresh message

View File

@@ -12,113 +12,35 @@ A barebones CSV parser
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
var QUOTE = '"';
var getCellInfo = function(text, start, length, SEPARATOR) {
var isCellQuoted = text.charAt(start) === QUOTE;
var cellStart = isCellQuoted ? start + 1 : start;
if (text.charAt(i) === SEPARATOR) {
return [cellStart, cellStart, false];
}
for (var i = cellStart; i < length; i++) {
var cellCharacter = text.charAt(i);
var isEOL = cellCharacter === "\n" || cellCharacter === "\r";
if (isEOL && !isCellQuoted) {
return [cellStart, i, false];
} else if (cellCharacter === SEPARATOR && !isCellQuoted) {
return [cellStart, i, false];
} else if (cellCharacter === QUOTE && isCellQuoted) {
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (nextCharacter !== QUOTE) {
return [cellStart, i, true];
} else {
i++;
}
}
}
return [cellStart, i, isCellQuoted];
}
exports.parseCsvString = function(text, options) {
if (!text) {
return [];
}
options = options || {};
var SEPARATOR = options.separator || ",",
length = text.length,
rows = [],
nextRow = [];
for (var i = 0; i < length; i++) {
var cellInfo = getCellInfo(text, i, length, SEPARATOR);
var cellText = text.substring(cellInfo[0], cellInfo[1]);
if (cellInfo[2]) {
cellText = cellText.replace(/""/g, '"');
cellInfo[1]++;
}
nextRow.push(cellText);
i = cellInfo[1];
var character = text.charAt(i);
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (character === "\r" || character === "\n") {
// Edge case for empty rows
if (nextRow.length === 1 && nextRow[0] === '') {
nextRow.length = 0;
}
rows.push(nextRow);
nextRow = [];
if (character === "\r") {
var nextCharacter = i + 1 < length ? text.charAt(i + 1) : '';
if (nextCharacter === "\n") {
i++;
}
}
}
}
// Special case if last cell in last row is an empty cell
if (text.charAt(length - 1) === SEPARATOR) {
nextRow.push("");
}
rows.push(nextRow);
return rows;
}
/* /*
Parse a CSV string with a header row and return an array of hashmaps. Parse a CSV string with a header row and return an array of hashmaps.
*/ */
exports.parseCsvStringWithHeader = function(text,options) { exports.parseCsvStringWithHeader = function(text,options) {
var csv = $tw.utils.parseCsvString(text, options); options = options || {};
var headers = csv[0]; var separator = options.separator || ",",
rows = text.split(/\r?\n/mg).map(function(row) {
csv = csv.slice(1); return $tw.utils.trim(row);
for (var i = 0; i < csv.length; i++) { }).filter(function(row) {
var row = csv[i]; return row !== "";
var rowObject = Object.create(null); });
if(rows.length < 1) {
for(var columnIndex=0; columnIndex<headers.length; columnIndex++) { return "Missing header row";
var columnName = headers[columnIndex];
if (columnName) {
rowObject[columnName] = $tw.utils.trim(row[columnIndex] || "");
}
}
csv[i] = rowObject;
} }
return csv; var headings = rows[0].split(separator),
results = [];
for(var row=1; row<rows.length; row++) {
var columns = rows[row].split(separator),
columnResult = Object.create(null);
if(columns.length !== headings.length) {
return "Malformed CSV row '" + rows[row] + "'";
}
for(var column=0; column<columns.length; column++) {
var columnName = headings[column];
columnResult[columnName] = $tw.utils.trim(columns[column] || "");
}
results.push(columnResult);
}
return results;
} }
})(); })();

View File

@@ -12,8 +12,6 @@ Various static DOM-related utility functions.
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
var Popup = require("$:/core/modules/utils/dom/popup.js");
/* /*
Determines whether element 'a' contains element 'b' Determines whether element 'a' contains element 'b'
Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/ Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/
@@ -296,21 +294,8 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
}); });
if(selectedNode.offsetLeft) { if(selectedNode.offsetLeft) {
// Add variables with a (relative and absolute) popup coordinate string for the selected node // Add a variable with a popup coordinate string for the selected node
var nodeRect = { variables["tv-popup-coords"] = "(" + selectedNode.offsetLeft + "," + selectedNode.offsetTop +"," + selectedNode.offsetWidth + "," + selectedNode.offsetHeight + ")";
left: selectedNode.offsetLeft,
top: selectedNode.offsetTop,
width: selectedNode.offsetWidth,
height: selectedNode.offsetHeight
};
variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);
var absRect = $tw.utils.extend({}, nodeRect);
for (var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
absRect.left += currentNode.offsetLeft;
absRect.top += currentNode.offsetTop;
}
variables["tv-popup-abs-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csAbsolute,absRect);
// Add variables for offset of selected node // Add variables for offset of selected node
variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString(); variables["tv-selectednode-posx"] = selectedNode.offsetLeft.toString();

View File

@@ -25,13 +25,14 @@ widget: widget to use as the context for the filter
exports.makeDraggable = function(options) { exports.makeDraggable = function(options) {
var dragImageType = options.dragImageType || "dom", var dragImageType = options.dragImageType || "dom",
dragImage, dragImage,
domNode = options.domNode; domNode = options.domNode,
dragHandle = options.selector && domNode.querySelector(options.selector) || domNode;
// Make the dom node draggable (not necessary for anchor tags) // Make the dom node draggable (not necessary for anchor tags)
if(!options.selector && ((domNode.tagName || "").toLowerCase() !== "a")) { if((domNode.tagName || "").toLowerCase() !== "a") {
domNode.setAttribute("draggable","true"); dragHandle.setAttribute("draggable","true");
} }
// Add event handlers // Add event handlers
$tw.utils.addEventListeners(domNode,[ $tw.utils.addEventListeners(dragHandle,[
{name: "dragstart", handlerFunction: function(event) { {name: "dragstart", handlerFunction: function(event) {
if(event.dataTransfer === undefined) { if(event.dataTransfer === undefined) {
return false; return false;
@@ -40,19 +41,19 @@ exports.makeDraggable = function(options) {
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(), var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
dragFilter = options.dragFilterFn && options.dragFilterFn(), dragFilter = options.dragFilterFn && options.dragFilterFn(),
titles = dragTiddler ? [dragTiddler] : [], titles = dragTiddler ? [dragTiddler] : [],
startActions = options.startActions, startActions = options.startActions,
variables, variables,
domNodeRect; domNodeRect;
if(dragFilter) { if(dragFilter) {
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget)); titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
} }
var titleString = $tw.utils.stringifyList(titles); var titleString = $tw.utils.stringifyList(titles);
// Check that we've something to drag // Check that we've something to drag
if(titles.length > 0 && (options.selector && $tw.utils.domMatchesSelector(event.target,options.selector) || event.target === domNode)) { if(titles.length > 0 && event.target === dragHandle) {
// Mark the drag in progress // Mark the drag in progress
$tw.dragInProgress = domNode; $tw.dragInProgress = domNode;
// Set the dragging class on the element being dragged // Set the dragging class on the element being dragged
$tw.utils.addClass(domNode,"tc-dragging"); $tw.utils.addClass(event.target,"tc-dragging");
// Invoke drag-start actions if given // Invoke drag-start actions if given
if(startActions !== undefined) { if(startActions !== undefined) {
// Collect our variables // Collect our variables
@@ -106,22 +107,21 @@ exports.makeDraggable = function(options) {
dataTransfer.setData("text/vnd.tiddler",jsonData); dataTransfer.setData("text/vnd.tiddler",jsonData);
dataTransfer.setData("text/plain",titleString); dataTransfer.setData("text/plain",titleString);
dataTransfer.setData("text/x-moz-url","data:text/vnd.tiddler," + encodeURIComponent(jsonData)); dataTransfer.setData("text/x-moz-url","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
} else {
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
} }
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURIComponent(jsonData));
dataTransfer.setData("Text",titleString); dataTransfer.setData("Text",titleString);
event.stopPropagation(); event.stopPropagation();
} }
return false; return false;
}}, }},
{name: "dragend", handlerFunction: function(event) { {name: "dragend", handlerFunction: function(event) {
if((options.selector && $tw.utils.domMatchesSelector(event.target,options.selector)) || event.target === domNode) { if(event.target === domNode) {
// Collect the tiddlers being dragged // Collect the tiddlers being dragged
var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(), var dragTiddler = options.dragTiddlerFn && options.dragTiddlerFn(),
dragFilter = options.dragFilterFn && options.dragFilterFn(), dragFilter = options.dragFilterFn && options.dragFilterFn(),
titles = dragTiddler ? [dragTiddler] : [], titles = dragTiddler ? [dragTiddler] : [],
endActions = options.endActions, endActions = options.endActions,
variables; variables;
if(dragFilter) { if(dragFilter) {
titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget)); titles.push.apply(titles,options.widget.wiki.filterTiddlers(dragFilter,options.widget));
} }
@@ -135,7 +135,7 @@ exports.makeDraggable = function(options) {
options.widget.invokeActionString(endActions,options.widget,event,variables); options.widget.invokeActionString(endActions,options.widget,event,variables);
} }
// Remove the dragging class on the element being dragged // Remove the dragging class on the element being dragged
$tw.utils.removeClass(domNode,"tc-dragging"); $tw.utils.removeClass(event.target,"tc-dragging");
// Delete the drag image element // Delete the drag image element
if(dragImage) { if(dragImage) {
dragImage.parentNode.removeChild(dragImage); dragImage.parentNode.removeChild(dragImage);

View File

@@ -26,8 +26,6 @@ Display a modal dialogue
options: see below options: see below
Options include: Options include:
downloadLink: Text of a big download link to include downloadLink: Text of a big download link to include
event: widget event
variables: from event.paramObject
*/ */
Modal.prototype.display = function(title,options) { Modal.prototype.display = function(title,options) {
options = options || {}; options = options || {};
@@ -211,10 +209,6 @@ Modal.prototype.display = function(title,options) {
headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false); headerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false); bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false); footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true")) {
modalBackdrop.addEventListener("click",closeHandler,false);
}
// Set the initial styles for the message // Set the initial styles for the message
$tw.utils.setStyle(modalBackdrop,[ $tw.utils.setStyle(modalBackdrop,[
{opacity: "0"} {opacity: "0"}

View File

@@ -36,9 +36,8 @@ Notifier.prototype.display = function(title,options) {
if(!tiddler) { if(!tiddler) {
return; return;
} }
// Add classes and roles // Add classes
$tw.utils.addClass(notification,"tc-notification"); $tw.utils.addClass(notification,"tc-notification");
notification.setAttribute("role","alert");
// Create the variables // Create the variables
var variables = $tw.utils.extend({currentTiddler: title},options.variables); var variables = $tw.utils.extend({currentTiddler: title},options.variables);
// Render the body of the notification // Render the body of the notification

View File

@@ -22,19 +22,6 @@ var Popup = function(options) {
this.popups = []; // Array of {title:,wiki:,domNode:} objects this.popups = []; // Array of {title:,wiki:,domNode:} objects
}; };
/*
Global regular expression for parsing the location of a popup.
This is also used by the Reveal widget.
*/
exports.popupLocationRegExp = /^(@?)\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/
/*
Objekt containing the available prefixes for coordinates build with the `buildCoordinates` function:
- csOffsetParent: Uses a coordinate system based on the offset parent (no prefix).
- csAbsolute: Use an absolute coordinate system (prefix "@").
*/
exports.coordinatePrefix = { csOffsetParent: "", csAbsolute: "@" }
/* /*
Trigger a popup open or closed. Parameters are in a hashmap: Trigger a popup open or closed. Parameters are in a hashmap:
title: title of the tiddler where the popup details are stored title: title of the tiddler where the popup details are stored
@@ -149,17 +136,8 @@ Popup.prototype.show = function(options) {
height: options.domNode.offsetHeight height: options.domNode.offsetHeight
}; };
} }
if(options.absolute && options.domNode) { var popupRect = "(" + rect.left + "," + rect.top + "," +
// Walk the offsetParent chain and add the position of the offsetParents to make rect.width + "," + rect.height + ")";
// the position absolute to the root node of the page.
var currentNode = options.domNode.offsetParent;
while(currentNode) {
rect.left += currentNode.offsetLeft;
rect.top += currentNode.offsetTop;
currentNode = currentNode.offsetParent;
}
}
var popupRect = exports.buildCoordinates(options.absolute?exports.coordinatePrefix.csAbsolute:exports.coordinatePrefix.csOffsetParent,rect);
if(options.noStateReference) { if(options.noStateReference) {
options.wiki.setText(options.title,"text",undefined,popupRect); options.wiki.setText(options.title,"text",undefined,popupRect);
} else { } else {
@@ -194,54 +172,13 @@ Popup.prototype.cancel = function(level) {
}; };
/* /*
Returns true if the specified title and text identifies an active popup. Returns true if the specified title and text identifies an active popup
This function is safe to call, even if the popup class was not initialized.
*/ */
exports.readPopupState = function(text) { Popup.prototype.readPopupState = function(text) {
return exports.popupLocationRegExp.test(text); var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/;
return popupLocationRegExp.test(text);
}; };
/*
Parses a coordinate string in the format `(x,y,w,h)` or `@(x,y,z,h)` and returns
an object containing the position, width and height. The absolute-Mark is boolean
value that indicates the coordinate system of the coordinates. If they start with
an `@`, `absolute` is set to true and the coordinates are relative to the root
element. If the initial `@` is missing, they are relative to the offset parent
element and `absoute` is false.
This function is safe to call, even if the popup class was not initialized.
*/
exports.parseCoordinates = function(coordinates) {
var match = exports.popupLocationRegExp.exec(coordinates);
if(match) {
return {
absolute: (match[1] === "@"),
left: parseFloat(match[2]),
top: parseFloat(match[3]),
width: parseFloat(match[4]),
height: parseFloat(match[5])
};
} else {
return false;
}
}
/*
Builds a coordinate string from a coordinate system identifier and an object
containing the left, top, width and height values.
Use constants defined in coordinatePrefix to specify a coordinate system.
If one of the parameters is invalid for building a coordinate string `(0,0,0,0)`
will be returned.
This function is safe to call, even if the popup class was not initialized.
*/
exports.buildCoordinates = function(prefix,position) {
var coord = prefix + "(" + position.left + "," + position.top + "," + position.width + "," + position.height + ")";
if (exports.popupLocationRegExp.test(coord)) {
return coord;
} else {
return "(0,0,0,0)";
}
}
exports.Popup = Popup; exports.Popup = Popup;
})(); })();

View File

@@ -42,7 +42,7 @@ var TW_TextNode = function(text) {
this.textContent = text + ""; this.textContent = text + "";
}; };
Object.setPrototypeOf(TW_TextNode,TW_Node.prototype); TW_TextNode.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_TextNode.prototype, "nodeType", { Object.defineProperty(TW_TextNode.prototype, "nodeType", {
get: function() { get: function() {
@@ -67,7 +67,7 @@ var TW_Element = function(tag,namespace) {
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml"; this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
}; };
Object.setPrototypeOf(TW_Element,TW_Node.prototype); TW_Element.prototype = Object.create(TW_Node.prototype);
Object.defineProperty(TW_Element.prototype, "style", { Object.defineProperty(TW_Element.prototype, "style", {
get: function() { get: function() {

View File

@@ -15,11 +15,10 @@ function LinkedList() {
LinkedList.prototype.clear = function() { LinkedList.prototype.clear = function() {
// LinkedList performs the duty of both the head and tail node // LinkedList performs the duty of both the head and tail node
this.next = new LLMap(); this.next = Object.create(null);
this.prev = new LLMap(); this.prev = Object.create(null);
// Linked list head initially points to itself this.first = undefined;
this.next.set(null, null); this.last = undefined;
this.prev.set(null, null);
this.length = 0; this.length = 0;
}; };
@@ -42,29 +41,28 @@ Push behaves like array.push and accepts multiple string arguments. But it also
accepts a single array argument too, to be consistent with its other methods. accepts a single array argument too, to be consistent with its other methods.
*/ */
LinkedList.prototype.push = function(/* values */) { LinkedList.prototype.push = function(/* values */) {
var i, values = arguments; var values = arguments;
if($tw.utils.isArray(values[0])) { if($tw.utils.isArray(values[0])) {
values = values[0]; values = values[0];
} }
for(i = 0; i < values.length; i++) { for(var i = 0; i < values.length; i++) {
_assertString(values[i]); _assertString(values[i]);
} }
for(i = 0; i < values.length; i++) { for(var i = 0; i < values.length; i++) {
_linkToEnd(this,values[i]); _linkToEnd(this,values[i]);
} }
return this.length; return this.length;
}; };
LinkedList.prototype.pushTop = function(value) { LinkedList.prototype.pushTop = function(value) {
var t;
if($tw.utils.isArray(value)) { if($tw.utils.isArray(value)) {
for (t=0; t<value.length; t++) { for (var t=0; t<value.length; t++) {
_assertString(value[t]); _assertString(value[t]);
} }
for(t=0; t<value.length; t++) { for(var t=0; t<value.length; t++) {
_removeOne(this,value[t]); _removeOne(this,value[t]);
} }
for(t=0; t<value.length; t++) { for(var t=0; t<value.length; t++) {
_linkToEnd(this,value[t]); _linkToEnd(this,value[t]);
} }
} else { } else {
@@ -76,11 +74,11 @@ LinkedList.prototype.pushTop = function(value) {
LinkedList.prototype.each = function(callback) { LinkedList.prototype.each = function(callback) {
var visits = Object.create(null), var visits = Object.create(null),
value = this.next.get(null); value = this.first;
while(value !== null) { while(value !== undefined) {
callback(value); callback(value);
var next = this.next.get(value); var next = this.next[value];
if(Array.isArray(next)) { if(typeof next === "object") {
var i = visits[value] || 0; var i = visits[value] || 0;
visits[value] = i+1; visits[value] = i+1;
value = next[i]; value = next[i];
@@ -107,79 +105,91 @@ LinkedList.prototype.makeTiddlerIterator = function(wiki) {
}; };
function _removeOne(list,value) { function _removeOne(list,value) {
var nextEntry = list.next.get(value); var prevEntry = list.prev[value],
if(nextEntry === undefined) { nextEntry = list.next[value],
return;
}
var prevEntry = list.prev.get(value),
prev = prevEntry, prev = prevEntry,
next = nextEntry, next = nextEntry;
ref; if(typeof nextEntry === "object") {
if(Array.isArray(nextEntry)) {
next = nextEntry[0]; next = nextEntry[0];
prev = prevEntry[0]; prev = prevEntry[0];
} }
// Relink preceding element. // Relink preceding element.
ref = list.next.get(prev); if(list.first === value) {
if(Array.isArray(ref)) { list.first = next
var i = ref.indexOf(value); } else if(prev !== undefined) {
ref[i] = next; if(typeof list.next[prev] === "object") {
if(next === undefined) {
// Must have been last, and 'i' would be last element.
list.next[prev].pop();
} else {
var i = list.next[prev].indexOf(value);
list.next[prev][i] = next;
}
} else {
list.next[prev] = next;
}
} else { } else {
list.next.set(prev,next); return;
} }
// Now relink following element // Now relink following element
ref = list.prev.get(next); // Check "next !== undefined" rather than "list.last === value" because
if(Array.isArray(ref)) { // we need to know if the FIRST value is the last in the list, not the last.
var i = ref.indexOf(value); if(next !== undefined) {
ref[i] = prev; if(typeof list.prev[next] === "object") {
if(prev === undefined) {
// Must have been first, and 'i' would be 0.
list.prev[next].shift();
} else {
var i = list.prev[next].indexOf(value);
list.prev[next][i] = prev;
}
} else {
list.prev[next] = prev;
}
} else { } else {
list.prev.set(next,prev); list.last = prev;
} }
// Delink actual value. If it uses arrays, just remove first entries. // Delink actual value. If it uses arrays, just remove first entries.
if(Array.isArray(nextEntry) && nextEntry.length > 1) { if(typeof nextEntry === "object") {
nextEntry.shift(); nextEntry.shift();
prevEntry.shift(); prevEntry.shift();
} else { } else {
list.next.set(value,undefined); list.next[value] = undefined;
list.prev.set(value,undefined); list.prev[value] = undefined;
} }
list.length -= 1; list.length -= 1;
}; };
// Sticks the given node onto the end of the list. // Sticks the given node onto the end of the list.
function _linkToEnd(list,value) { function _linkToEnd(list,value) {
var old = list.next.get(value); if(list.first === undefined) {
var last = list.prev.get(null); list.first = value;
// Does it already exists?
if(old !== undefined) {
if(!Array.isArray(old)) {
old = [old];
list.next.set(value,old);
list.prev.set(value,[list.prev.get(value)]);
}
old.push(null);
list.prev.get(value).push(last);
} else { } else {
list.next.set(value,null); // Does it already exists?
list.prev.set(value,last); if(list.first === value || list.prev[value] !== undefined) {
} if(typeof list.next[value] === "string") {
// Make the old last point to this new one. list.next[value] = [list.next[value]];
if(value !== last) { list.prev[value] = [list.prev[value]];
var array = list.next.get(last); } else if(typeof list.next[value] === "undefined") {
if(Array.isArray(array)) { // list.next[value] must be undefined.
array[array.length-1] = value; // Special case. List already has 1 value. It's at the end.
list.next[value] = [];
list.prev[value] = [list.prev[value]];
}
list.prev[value].push(list.last);
// We do NOT append a new value onto "next" list. Iteration will
// figure out it must point to End-of-List on its own.
} else { } else {
list.next.set(last,value); list.prev[value] = list.last;
}
// Make the old last point to this new one.
if(typeof list.next[list.last] === "object") {
list.next[list.last].push(value);
} else {
list.next[list.last] = value;
} }
list.prev.set(null,value);
} else {
// Edge case, the pushed value was already the last value.
// The second-to-last nextPtr for that value must point to itself now.
var array = list.next.get(last);
array[array.length-2] = value;
} }
list.last = value;
list.length += 1; list.length += 1;
}; };
@@ -189,20 +199,6 @@ function _assertString(value) {
} }
}; };
var LLMap = function() {
this.map = Object.create(null);
};
// Just a wrapper so our object map can also accept null.
LLMap.prototype = {
set: function(key,val) {
(key === null) ? (this.null = val) : (this.map[key] = val);
},
get: function(key) {
return (key === null) ? this.null : this.map[key];
}
};
exports.LinkedList = LinkedList; exports.LinkedList = LinkedList;
})(); })();

View File

@@ -48,9 +48,7 @@ Logger.prototype.log = function(/* args */) {
this.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit); this.saveBufferLogger.buffer = this.saveBufferLogger.buffer.slice(-this.saveBufferLogger.saveLimit);
} }
if(console !== undefined && console.log !== undefined) { if(console !== undefined && console.log !== undefined) {
var logMessage = [$tw.utils.terminalColour(this.colour) + this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)); return Function.apply.call(console.log, console, [$tw.utils.terminalColour(this.colour),this.componentName + ":"].concat(Array.prototype.slice.call(arguments,0)).concat($tw.utils.terminalColour()));
logMessage[logMessage.length-1] += $tw.utils.terminalColour();
return Function.apply.call(console.log, console, logMessage);
} }
} }
}; };

View File

@@ -12,26 +12,12 @@ Parse tree utility functions.
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
/*
Add attribute to parse tree node
Can be invoked as (node,name,value) or (node,attr)
*/
exports.addAttributeToParseTreeNode = function(node,name,value) { exports.addAttributeToParseTreeNode = function(node,name,value) {
var attribute = typeof name === "object" ? name : {name: name, type: "string", value: value}; var attribute = {name: name, type: "string", value: value};
name = attribute.name;
node.attributes = node.attributes || {}; node.attributes = node.attributes || {};
node.orderedAttributes = node.orderedAttributes || [];
node.attributes[name] = attribute; node.attributes[name] = attribute;
var foundIndex = -1; if(node.orderedAttributes) {
$tw.utils.each(node.orderedAttributes,function(attr,index) {
if(attr.name === name) {
foundIndex = index;
}
});
if(foundIndex === -1) {
node.orderedAttributes.push(attribute); node.orderedAttributes.push(attribute);
} else {
node.orderedAttributes[foundIndex] = attribute;
} }
}; };
@@ -65,8 +51,10 @@ exports.addClassToParseTreeNode = function(node,classString) {
// If the class attribute does not exist, we must create it first. // If the class attribute does not exist, we must create it first.
attribute = {name: "class", type: "string", value: ""}; attribute = {name: "class", type: "string", value: ""};
node.attributes["class"] = attribute; node.attributes["class"] = attribute;
node.orderedAttributes = node.orderedAttributes || []; if(node.orderedAttributes) {
node.orderedAttributes.push(attribute); // If there are orderedAttributes, we've got to add them there too.
node.orderedAttributes.push(attribute);
}
} }
if(attribute.type === "string") { if(attribute.type === "string") {
if(attribute.value !== "") { if(attribute.value !== "") {
@@ -86,8 +74,10 @@ exports.addStyleToParseTreeNode = function(node,name,value) {
if(!attribute) { if(!attribute) {
attribute = {name: "style", type: "string", value: ""}; attribute = {name: "style", type: "string", value: ""};
node.attributes.style = attribute; node.attributes.style = attribute;
node.orderedAttributes = node.orderedAttributes || []; if(node.orderedAttributes) {
node.orderedAttributes.push(attribute); // If there are orderedAttributes, we've got to add them there too.
node.orderedAttributes.push(attribute);
}
} }
if(attribute.type === "string") { if(attribute.type === "string") {
attribute.value += name + ":" + value + ";"; attribute.value += name + ":" + value + ";";

View File

@@ -354,9 +354,6 @@ exports.formatDateString = function(date,template) {
var result = "", var result = "",
t = template, t = template,
matches = [ matches = [
[/^TIMESTAMP/, function() {
return date.getTime();
}],
[/^0hh12/, function() { [/^0hh12/, function() {
return $tw.utils.pad($tw.utils.getHours12(date)); return $tw.utils.pad($tw.utils.getHours12(date));
}], }],

View File

@@ -36,7 +36,7 @@ Compute the internal state of the widget
*/ */
DeleteFieldWidget.prototype.execute = function() { DeleteFieldWidget.prototype.execute = function() {
this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler")); this.actionTiddler = this.getAttribute("$tiddler",this.getVariable("currentTiddler"));
this.actionField = this.getAttribute("$field",null); this.actionField = this.getAttribute("$field");
}; };
/* /*
@@ -59,7 +59,7 @@ DeleteFieldWidget.prototype.invokeAction = function(triggeringWidget,event) {
tiddler = this.wiki.getTiddler(self.actionTiddler), tiddler = this.wiki.getTiddler(self.actionTiddler),
removeFields = {}, removeFields = {},
hasChanged = false; hasChanged = false;
if((this.actionField !== null) && tiddler) { if(this.actionField && tiddler) {
removeFields[this.actionField] = undefined; removeFields[this.actionField] = undefined;
if(this.actionField in tiddler.fields) { if(this.actionField in tiddler.fields) {
hasChanged = true; hasChanged = true;

View File

@@ -14,8 +14,6 @@ Action widget to trigger a popup.
var Widget = require("$:/core/modules/widgets/widget.js").widget; var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var ActionPopupWidget = function(parseTreeNode,options) { var ActionPopupWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options); this.initialise(parseTreeNode,options);
}; };
@@ -59,20 +57,20 @@ Invoke the action associated with this widget
*/ */
ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) { ActionPopupWidget.prototype.invokeAction = function(triggeringWidget,event) {
// Trigger the popup // Trigger the popup
var coordinates = Popup.parseCoordinates(this.actionCoords || ""); var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
if(coordinates) { match = popupLocationRegExp.exec(this.actionCoords || "");
if(match) {
$tw.popup.triggerPopup({ $tw.popup.triggerPopup({
domNode: null, domNode: null,
domNodeRect: { domNodeRect: {
left: coordinates.left, left: parseFloat(match[1]),
top: coordinates.top, top: parseFloat(match[2]),
width: coordinates.width, width: parseFloat(match[3]),
height: coordinates.height height: parseFloat(match[4])
}, },
title: this.actionState, title: this.actionState,
wiki: this.wiki, wiki: this.wiki,
floating: this.floating, floating: this.floating
absolute: coordinates.absolute
}); });
} else { } else {
$tw.popup.cancel(0); $tw.popup.cancel(0);

View File

@@ -14,8 +14,6 @@ Button widget
var Widget = require("$:/core/modules/widgets/widget.js").widget; var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var ButtonWidget = function(parseTreeNode,options) { var ButtonWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options); this.initialise(parseTreeNode,options);
}; };
@@ -48,8 +46,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
isPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp(); isPoppedUp = (this.popup || this.popupTitle) && this.isPoppedUp();
if(this.selectedClass) { if(this.selectedClass) {
if((this.set || this.setTitle) && this.setTo && this.isSelected()) { if((this.set || this.setTitle) && this.setTo && this.isSelected()) {
$tw.utils.pushTop(classes, this.selectedClass.split(" ")); $tw.utils.pushTop(classes,this.selectedClass.split(" "));
domNode.setAttribute("aria-checked", "true");
} }
if(isPoppedUp) { if(isPoppedUp) {
$tw.utils.pushTop(classes,this.selectedClass.split(" ")); $tw.utils.pushTop(classes,this.selectedClass.split(" "));
@@ -69,9 +66,6 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
if(this["aria-label"]) { if(this["aria-label"]) {
domNode.setAttribute("aria-label",this["aria-label"]); domNode.setAttribute("aria-label",this["aria-label"]);
} }
if (this.role) {
domNode.setAttribute("role", this.role);
}
if(this.popup || this.popupTitle) { if(this.popup || this.popupTitle) {
domNode.setAttribute("aria-expanded",isPoppedUp ? "true" : "false"); domNode.setAttribute("aria-expanded",isPoppedUp ? "true" : "false");
} }
@@ -149,7 +143,7 @@ ButtonWidget.prototype.isSelected = function() {
ButtonWidget.prototype.isPoppedUp = function() { ButtonWidget.prototype.isPoppedUp = function() {
var tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup); var tiddler = this.popupTitle ? this.wiki.getTiddler(this.popupTitle) : this.wiki.getTiddler(this.popup);
var result = tiddler && tiddler.fields.text ? Popup.readPopupState(tiddler.fields.text) : false; var result = tiddler && tiddler.fields.text ? $tw.popup.readPopupState(tiddler.fields.text) : false;
return result; return result;
}; };
@@ -175,7 +169,6 @@ ButtonWidget.prototype.triggerPopup = function(event) {
if(this.popupTitle) { if(this.popupTitle) {
$tw.popup.triggerPopup({ $tw.popup.triggerPopup({
domNode: this.domNodes[0], domNode: this.domNodes[0],
absolute: (this.popupAbsCoords === "yes"),
title: this.popupTitle, title: this.popupTitle,
wiki: this.wiki, wiki: this.wiki,
noStateReference: true noStateReference: true
@@ -183,7 +176,6 @@ ButtonWidget.prototype.triggerPopup = function(event) {
} else { } else {
$tw.popup.triggerPopup({ $tw.popup.triggerPopup({
domNode: this.domNodes[0], domNode: this.domNodes[0],
absolute: (this.popupAbsCoords === "yes"),
title: this.popup, title: this.popup,
wiki: this.wiki wiki: this.wiki
}); });
@@ -214,7 +206,6 @@ ButtonWidget.prototype.execute = function() {
this.popup = this.getAttribute("popup"); this.popup = this.getAttribute("popup");
this.hover = this.getAttribute("hover"); this.hover = this.getAttribute("hover");
this["aria-label"] = this.getAttribute("aria-label"); this["aria-label"] = this.getAttribute("aria-label");
this.role = this.getAttribute("role");
this.tooltip = this.getAttribute("tooltip"); this.tooltip = this.getAttribute("tooltip");
this.style = this.getAttribute("style"); this.style = this.getAttribute("style");
this["class"] = this.getAttribute("class",""); this["class"] = this.getAttribute("class","");
@@ -227,7 +218,6 @@ ButtonWidget.prototype.execute = function() {
this.setField = this.getAttribute("setField"); this.setField = this.getAttribute("setField");
this.setIndex = this.getAttribute("setIndex"); this.setIndex = this.getAttribute("setIndex");
this.popupTitle = this.getAttribute("popupTitle"); this.popupTitle = this.getAttribute("popupTitle");
this.popupAbsCoords = this.getAttribute("popupAbsCoords", "no");
this.tabIndex = this.getAttribute("tabindex"); this.tabIndex = this.getAttribute("tabindex");
this.isDisabled = this.getAttribute("disabled","no"); this.isDisabled = this.getAttribute("disabled","no");
// Make child widgets // Make child widgets
@@ -257,7 +247,7 @@ Selectively refreshes the widget if needed. Returns true if the widget or any of
*/ */
ButtonWidget.prototype.refresh = function(changedTiddlers) { ButtonWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(); var changedAttributes = this.computeAttributes();
if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) { if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} else if(changedAttributes["class"]) { } else if(changedAttributes["class"]) {

View File

@@ -66,14 +66,14 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
CheckboxWidget.prototype.getValue = function() { CheckboxWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.checkboxTitle); var tiddler = this.wiki.getTiddler(this.checkboxTitle);
if(tiddler || this.checkboxFilter) { if(tiddler || this.checkboxFilter) {
if(tiddler && this.checkboxTag) { if(this.checkboxTag) {
if(this.checkboxInvertTag === "yes") { if(this.checkboxInvertTag === "yes") {
return !tiddler.hasTag(this.checkboxTag); return !tiddler.hasTag(this.checkboxTag);
} else { } else {
return tiddler.hasTag(this.checkboxTag); return tiddler.hasTag(this.checkboxTag);
} }
} }
if(tiddler && (this.checkboxField || this.checkboxIndex)) { if(this.checkboxField || this.checkboxIndex) {
// Same logic applies to fields and indexes // Same logic applies to fields and indexes
var value; var value;
if(this.checkboxField) { if(this.checkboxField) {
@@ -206,18 +206,11 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
} }
// Set the list field (or index) if specified // Set the list field (or index) if specified
if(this.checkboxListField || this.checkboxListIndex) { if(this.checkboxListField || this.checkboxListIndex) {
var fieldContents, listContents, oldPos, newPos; var listContents, oldPos, newPos;
if(this.checkboxListField) { if(this.checkboxListField) {
fieldContents = tiddler ? tiddler.fields[this.checkboxListField] : undefined; listContents = tiddler.getFieldList(this.checkboxListField);
} else { } else {
fieldContents = this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex); listContents = $tw.utils.parseStringArray(this.wiki.extractTiddlerDataItem(this.checkboxTitle,this.checkboxListIndex) || "") || [];
}
if($tw.utils.isArray(fieldContents)) {
// Make a copy so we can modify it without changing original that's refrenced elsewhere
listContents = fieldContents.slice(0);
} else {
listContents = $tw.utils.parseStringArray(fieldContents) || [];
// No need to copy since parseStringArray returns a fresh array, not refrenced elsewhere
} }
oldPos = notValue ? listContents.indexOf(notValue) : -1; oldPos = notValue ? listContents.indexOf(notValue) : -1;
newPos = value ? listContents.indexOf(value) : -1; newPos = value ? listContents.indexOf(value) : -1;

View File

@@ -87,32 +87,12 @@ DraggableWidget.prototype.execute = function() {
this.makeChildWidgets(); this.makeChildWidgets();
}; };
DraggableWidget.prototype.updateDomNodeClasses = function() {
var domNodeClasses = this.domNodes[0].className.split(" "),
oldClasses = this.draggableClasses.split(" ");
this.draggableClasses = this.getAttribute("class");
//Remove classes assigned from the old value of class attribute
$tw.utils.each(oldClasses,function(oldClass){
var i = domNodeClasses.indexOf(oldClass);
if(i !== -1) {
domNodeClasses.splice(i,1);
}
});
//Add new classes from updated class attribute.
$tw.utils.pushTop(domNodeClasses,this.draggableClasses);
this.domNodes[0].setAttribute("class",domNodeClasses.join(" "))
}
/* /*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/ */
DraggableWidget.prototype.refresh = function(changedTiddlers) { DraggableWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(), var changedAttributes = this.computeAttributes();
changedAttributesCount = $tw.utils.count(changedAttributes); if($tw.utils.count(changedAttributes) > 0) {
if(changedAttributesCount === 1 && changedAttributes["class"]) {
this.updateDomNodeClasses();
} else if(changedAttributesCount > 0) {
this.refreshSelf(); this.refreshSelf();
return true; return true;
} }
@@ -121,4 +101,4 @@ DraggableWidget.prototype.refresh = function(changedTiddlers) {
exports.draggable = DraggableWidget; exports.draggable = DraggableWidget;
})(); })();

View File

@@ -42,22 +42,16 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
this.tag = "h" + headingLevel; this.tag = "h" + headingLevel;
} }
// Select the namespace for the tag // Select the namespace for the tag
var XHTML_NAMESPACE = "http://www.w3.org/1999/xhtml", var tagNamespaces = {
tagNamespaces = {
svg: "http://www.w3.org/2000/svg", svg: "http://www.w3.org/2000/svg",
math: "http://www.w3.org/1998/Math/MathML", math: "http://www.w3.org/1998/Math/MathML",
body: XHTML_NAMESPACE body: "http://www.w3.org/1999/xhtml"
}; };
this.namespace = tagNamespaces[this.tag]; this.namespace = tagNamespaces[this.tag];
if(this.namespace) { if(this.namespace) {
this.setVariable("namespace",this.namespace); this.setVariable("namespace",this.namespace);
} else { } else {
if(this.hasAttribute("xmlns")) { this.namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"});
this.namespace = this.getAttribute("xmlns");
this.setVariable("namespace",this.namespace);
} else {
this.namespace = this.getVariable("namespace",{defaultValue: XHTML_NAMESPACE});
}
} }
// Invoke the th-rendering-element hook // Invoke the th-rendering-element hook
var parseTreeNodes = $tw.hooks.invokeHook("th-rendering-element",null,this); var parseTreeNodes = $tw.hooks.invokeHook("th-rendering-element",null,this);

View File

@@ -1,63 +0,0 @@
/*\
title: $:/core/modules/widgets/error.js
type: application/javascript
module-type: widget
Error widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var ErrorWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
ErrorWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
ErrorWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
var message = this.getAttribute("$message","Unknown error"),
domNode = this.document.createElement("span");
domNode.appendChild(this.document.createTextNode(message));
domNode.className = "tc-error";
parent.insertBefore(domNode,nextSibling);
this.domNodes.push(domNode);
};
/*
Compute the internal state of the widget
*/
ErrorWidget.prototype.execute = function() {
// Nothing to do for a text node
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
ErrorWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes["$message"]) {
this.refreshSelf();
return true;
} else {
return false;
}
};
exports.error = ErrorWidget;
})();

View File

@@ -1,108 +0,0 @@
/*\
title: $:/core/modules/widgets/genesis.js
type: application/javascript
module-type: widget
Genesis widget for dynamically creating widgets
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var GenesisWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
GenesisWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
GenesisWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes({filterFn: function(name) {
// Only compute our own attributes which start with a single dollar
return name.charAt(0) === "$" && name.charAt(1) !== "$";
}});
this.execute();
this.renderChildren(parent,nextSibling);
};
/*
Compute the internal state of the widget
*/
GenesisWidget.prototype.execute = function() {
var self = this;
// Collect attributes
this.genesisType = this.getAttribute("$type","element");
this.genesisRemappable = this.getAttribute("$remappable","yes") === "yes";
this.genesisNames = this.getAttribute("$names","");
this.genesisValues = this.getAttribute("$values","");
// Construct parse tree
var isElementWidget = this.genesisType.charAt(0) !== "$",
nodeType = isElementWidget ? "element" : this.genesisType.substr(1),
nodeTag = isElementWidget ? this.genesisType : undefined;
var parseTreeNodes = [{
type: nodeType,
tag: nodeTag,
attributes: {},
orderedAttributes: [],
children: this.parseTreeNode.children || [],
isNotRemappable: !this.genesisRemappable
}];
// Apply explicit attributes
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
var name = attribute.name;
if(name.charAt(0) === "$") {
if(name.charAt(1) === "$") {
// Double $$ is changed to a single $
name = name.substr(1);
} else {
// Single dollar is ignored
return;
}
}
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],$tw.utils.extend({},attribute,{name: name}));
});
// Apply attributes in $names/$values
this.attributeNames = [];
this.attributeValues = [];
if(this.genesisNames && this.genesisValues) {
this.attributeNames = this.wiki.filterTiddlers(self.genesisNames,this);
this.attributeValues = this.wiki.filterTiddlers(self.genesisValues,this);
$tw.utils.each(this.attributeNames,function(varname,index) {
$tw.utils.addAttributeToParseTreeNode(parseTreeNodes[0],varname,self.attributeValues[index] || "");
});
}
// Construct the child widgets
this.makeChildWidgets(parseTreeNodes);
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
GenesisWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes(),
filterNames = this.getAttribute("$names",""),
filterValues = this.getAttribute("$values",""),
attributeNames = this.wiki.filterTiddlers(filterNames,this),
attributeValues = this.wiki.filterTiddlers(filterValues,this);
if($tw.utils.count(changedAttributes) > 0 || !$tw.utils.isArrayEqual(this.attributeNames,attributeNames) || !$tw.utils.isArrayEqual(this.attributeValues,attributeValues)) {
this.refreshSelf();
return true;
} else {
return this.refreshChildren(changedTiddlers);
}
};
exports.genesis = GenesisWidget;
})();

View File

@@ -111,9 +111,6 @@ ImageWidget.prototype.render = function(parent,nextSibling) {
if(this.imageAlt) { if(this.imageAlt) {
domNode.setAttribute("alt",this.imageAlt); domNode.setAttribute("alt",this.imageAlt);
} }
if(this.lazyLoading && tag === "img") {
domNode.setAttribute("loading",this.lazyLoading);
}
// Add classes when the image loads or fails // Add classes when the image loads or fails
$tw.utils.addClass(domNode,"tc-image-loading"); $tw.utils.addClass(domNode,"tc-image-loading");
domNode.addEventListener("load",function() { domNode.addEventListener("load",function() {
@@ -140,7 +137,6 @@ ImageWidget.prototype.execute = function() {
this.imageClass = this.getAttribute("class"); this.imageClass = this.getAttribute("class");
this.imageTooltip = this.getAttribute("tooltip"); this.imageTooltip = this.getAttribute("tooltip");
this.imageAlt = this.getAttribute("alt"); this.imageAlt = this.getAttribute("alt");
this.lazyLoading = this.getAttribute("loading");
}; };
/* /*

View File

@@ -39,10 +39,7 @@ Compute the internal state of the widget
ImportVariablesWidget.prototype.execute = function(tiddlerList) { ImportVariablesWidget.prototype.execute = function(tiddlerList) {
var widgetPointer = this; var widgetPointer = this;
// Got to flush all the accumulated variables // Got to flush all the accumulated variables
this.variables = Object.create(null); this.variables = new this.variablesConstructor();
if(this.parentWidget) {
Object.setPrototypeOf(this.variables,this.parentWidget.variables);
}
// Get our parameters // Get our parameters
this.filter = this.getAttribute("filter"); this.filter = this.getAttribute("filter");
// Compute the filter // Compute the filter

View File

@@ -53,10 +53,6 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
}; };
KeyboardWidget.prototype.handleChangeEvent = function(event) { KeyboardWidget.prototype.handleChangeEvent = function(event) {
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
return true;
}
var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray); var keyInfo = $tw.keyboardManager.getMatchingKeyDescriptor(event,this.keyInfoArray);
if(keyInfo) { if(keyInfo) {
var handled = this.invokeActions(this,event); var handled = this.invokeActions(this,event);

View File

@@ -51,9 +51,11 @@ LetWidget.prototype.computeAttributes = function() {
$tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) { $tw.utils.each($tw.utils.getOrderedAttributesFromParseTreeNode(this.parseTreeNode),function(attribute) {
var value = self.computeAttribute(attribute), var value = self.computeAttribute(attribute),
name = attribute.name; name = attribute.name;
// Now that it's prepped, we're allowed to look this variable up if(name.charAt(0) !== "$") {
// when defining later variables // Now that it's prepped, we're allowed to look this variable up
self.currentValueFor[name] = value; // when defining later variables
self.currentValueFor[name] = value;
}
}); });
// Run through again, setting variables and looking for differences // Run through again, setting variables and looking for differences
$tw.utils.each(this.currentValueFor,function(value,name) { $tw.utils.each(this.currentValueFor,function(value,name) {

View File

@@ -14,8 +14,6 @@ Reveal widget
var Widget = require("$:/core/modules/widgets/widget.js").widget; var Widget = require("$:/core/modules/widgets/widget.js").widget;
var Popup = require("$:/core/modules/utils/dom/popup.js");
var RevealWidget = function(parseTreeNode,options) { var RevealWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options); this.initialise(parseTreeNode,options);
}; };
@@ -96,13 +94,6 @@ RevealWidget.prototype.positionPopup = function(domNode) {
left = Math.max(0,left); left = Math.max(0,left);
top = Math.max(0,top); top = Math.max(0,top);
} }
if (this.popup.absolute) {
// Traverse the offsetParent chain and correct the offset to make it relative to the parent node.
for (var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {
left -= offsetParentDomNode.offsetLeft;
top -= offsetParentDomNode.offsetTop;
}
}
domNode.style.left = left + "px"; domNode.style.left = left + "px";
domNode.style.top = top + "px"; domNode.style.top = top + "px";
}; };
@@ -192,11 +183,19 @@ RevealWidget.prototype.compareStateText = function(state) {
}; };
RevealWidget.prototype.readPopupState = function(state) { RevealWidget.prototype.readPopupState = function(state) {
this.popup = Popup.parseCoordinates(state); var popupLocationRegExp = /^\((-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+),(-?[0-9\.E]+)\)$/,
match = popupLocationRegExp.exec(state);
// Check if the state matches the location regexp // Check if the state matches the location regexp
if(this.popup) { if(match) {
// If so, we're open // If so, we're open
this.isOpen = true; this.isOpen = true;
// Get the location
this.popup = {
left: parseFloat(match[1]),
top: parseFloat(match[2]),
width: parseFloat(match[3]),
height: parseFloat(match[4])
};
} else { } else {
// If not, we're closed // If not, we're closed
this.isOpen = false; this.isOpen = false;

View File

@@ -42,9 +42,6 @@ SelectWidget.prototype.render = function(parent,nextSibling) {
this.execute(); this.execute();
this.renderChildren(parent,nextSibling); this.renderChildren(parent,nextSibling);
this.setSelectValue(); this.setSelectValue();
if(this.selectFocus == "yes") {
this.getSelectDomNode().focus();
}
$tw.utils.addEventListeners(this.getSelectDomNode(),[ $tw.utils.addEventListeners(this.getSelectDomNode(),[
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"} {name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
]); ]);
@@ -146,7 +143,6 @@ SelectWidget.prototype.execute = function() {
this.selectMultiple = this.getAttribute("multiple", false); this.selectMultiple = this.getAttribute("multiple", false);
this.selectSize = this.getAttribute("size"); this.selectSize = this.getAttribute("size");
this.selectTooltip = this.getAttribute("tooltip"); this.selectTooltip = this.getAttribute("tooltip");
this.selectFocus = this.getAttribute("focus");
// Make the child widgets // Make the child widgets
var selectNode = { var selectNode = {
type: "element", type: "element",
@@ -179,11 +175,6 @@ SelectWidget.prototype.refresh = function(changedTiddlers) {
return true; return true;
// If the target tiddler value has changed, just update setting and refresh the children // If the target tiddler value has changed, just update setting and refresh the children
} else { } else {
if(changedAttributes.class) {
this.selectClass = this.getAttribute("class");
this.getSelectDomNode().setAttribute("class",this.selectClass);
}
var childrenRefreshed = this.refreshChildren(changedTiddlers); var childrenRefreshed = this.refreshChildren(changedTiddlers);
if(changedTiddlers[this.selectTitle] || childrenRefreshed) { if(changedTiddlers[this.selectTitle] || childrenRefreshed) {
this.setSelectValue(); this.setSelectValue();

View File

@@ -70,9 +70,11 @@ TranscludeWidget.prototype.execute = function() {
// Check for recursion // Check for recursion
if(parser) { if(parser) {
if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) { if(this.parentWidget && this.parentWidget.hasVariable("transclusion",recursionMarker)) {
parseTreeNodes = [{type: "error", attributes: { parseTreeNodes = [{type: "element", tag: "span", attributes: {
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")} "class": {type: "string", value: "tc-error"}
}}]; }, children: [
{type: "text", text: $tw.language.getString("Error/RecursiveTransclusion")}
]}];
} }
} }
// Construct the child widgets // Construct the child widgets

View File

@@ -12,9 +12,6 @@ Widget base class
/*global $tw: false */ /*global $tw: false */
"use strict"; "use strict";
/* Maximum permitted depth of the widget tree for recursion detection */
var MAX_WIDGET_TREE_DEPTH = 1000;
/* /*
Create a widget object for a parse tree node Create a widget object for a parse tree node
parseTreeNode: reference to the parse tree node to be rendered parseTreeNode: reference to the parse tree node to be rendered
@@ -41,10 +38,9 @@ Widget.prototype.initialise = function(parseTreeNode,options) {
this.parseTreeNode = parseTreeNode; this.parseTreeNode = parseTreeNode;
this.wiki = options.wiki; this.wiki = options.wiki;
this.parentWidget = options.parentWidget; this.parentWidget = options.parentWidget;
this.variables = Object.create(null); this.variablesConstructor = function() {};
if(this.parentWidget) { this.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};
Object.setPrototypeOf(this.variables,this.parentWidget.variables); this.variables = new this.variablesConstructor();
}
this.document = options.document; this.document = options.document;
this.attributes = {}; this.attributes = {};
this.children = []; this.children = [];
@@ -361,20 +357,6 @@ Widget.prototype.assignAttributes = function(domNode,options) {
} }
}; };
/*
Get the number of ancestor widgets for this widget
*/
Widget.prototype.getAncestorCount = function() {
if(this.ancestorCount === undefined) {
if(this.parentWidget) {
this.ancestorCount = this.parentWidget.getAncestorCount() + 1;
} else {
this.ancestorCount = 0;
}
}
return this.ancestorCount;
};
/* /*
Make child widgets correspondng to specified parseTreeNodes Make child widgets correspondng to specified parseTreeNodes
*/ */
@@ -382,29 +364,21 @@ Widget.prototype.makeChildWidgets = function(parseTreeNodes,options) {
options = options || {}; options = options || {};
this.children = []; this.children = [];
var self = this; var self = this;
// Check for too much recursion // Create set variable widgets for each variable
if(this.getAncestorCount() > MAX_WIDGET_TREE_DEPTH) { $tw.utils.each(options.variables,function(value,name) {
this.children.push(this.makeChildWidget({type: "error", attributes: { var setVariableWidget = {
"$message": {type: "string", value: $tw.language.getString("Error/RecursiveTransclusion")} type: "set",
}})); attributes: {
} else { name: {type: "string", value: name},
// Create set variable widgets for each variable value: {type: "string", value: value}
$tw.utils.each(options.variables,function(value,name) { },
var setVariableWidget = { children: parseTreeNodes
type: "set", };
attributes: { parseTreeNodes = [setVariableWidget];
name: {type: "string", value: name}, });
value: {type: "string", value: value} $tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {
}, self.children.push(self.makeChildWidget(childNode));
children: parseTreeNodes });
};
parseTreeNodes = [setVariableWidget];
});
// Create the child widgets
$tw.utils.each(parseTreeNodes || (this.parseTreeNode && this.parseTreeNode.children),function(childNode) {
self.children.push(self.makeChildWidget(childNode));
});
}
}; };
/* /*

View File

@@ -50,7 +50,7 @@ exports.getTextReference = function(textRef,defaultText,currTiddlerTitle) {
if(tr.field) { if(tr.field) {
var tiddler = this.getTiddler(title); var tiddler = this.getTiddler(title);
if(tr.field === "title") { // Special case so we can return the title of a non-existent tiddler if(tr.field === "title") { // Special case so we can return the title of a non-existent tiddler
return title || defaultText; return title;
} else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) { } else if(tiddler && $tw.utils.hop(tiddler.fields,tr.field)) {
return tiddler.getFieldString(tr.field); return tiddler.getFieldString(tr.field);
} else { } else {

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333333 foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333353 foreground: #333353
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333333 foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #00a external-link-foreground-visited: #00a
external-link-foreground: #00e external-link-foreground: #00e
foreground: #000 foreground: #000
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour foreground>> message-background: <<colour foreground>>
message-border: <<colour background>> message-border: <<colour background>>
message-foreground: <<colour background>> message-foreground: <<colour background>>

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #00a external-link-foreground-visited: #00a
external-link-foreground: #00e external-link-foreground: #00e
foreground: #fff foreground: #fff
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour foreground>> message-background: <<colour foreground>>
message-border: <<colour background>> message-border: <<colour background>>
message-foreground: <<colour background>> message-foreground: <<colour background>>

View File

@@ -32,8 +32,6 @@ external-link-foreground-hover:
external-link-foreground-visited: #BF5AF2 external-link-foreground-visited: #BF5AF2
external-link-foreground: #32D74B external-link-foreground: #32D74B
foreground: #FFFFFF foreground: #FFFFFF
highlight-background: #ffff78
highlight-foreground: #000000
menubar-background: #464646 menubar-background: #464646
menubar-foreground: #ffffff menubar-foreground: #ffffff
message-background: <<colour background>> message-background: <<colour background>>

View File

@@ -36,8 +36,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333333 foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -40,8 +40,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #313163 external-link-foreground-visited: #313163
external-link-foreground: #555592 external-link-foreground: #555592
foreground: #2D2A23 foreground: #2D2A23
highlight-background: #ffff00
highlight-foreground: #000000
menubar-background: #CDC2A6 menubar-background: #CDC2A6
menubar-foreground: #5A5446 menubar-foreground: #5A5446
message-background: #ECE5CF message-background: #ECE5CF

View File

@@ -41,8 +41,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #d3869b external-link-foreground-visited: #d3869b
external-link-foreground: #8ec07c external-link-foreground: #8ec07c
foreground: #fbf1c7 foreground: #fbf1c7
highlight-background: #ffff79
highlight-foreground: #000000
menubar-background: #504945 menubar-background: #504945
menubar-foreground: <<colour foreground>> menubar-foreground: <<colour foreground>>
message-background: #83a598 message-background: #83a598

View File

@@ -41,8 +41,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #5E81AC external-link-foreground-visited: #5E81AC
external-link-foreground: #8FBCBB external-link-foreground: #8FBCBB
foreground: #d8dee9 foreground: #d8dee9
highlight-background: #ffff78
highlight-foreground: #000000
menubar-background: #2E3440 menubar-background: #2E3440
menubar-foreground: #d8dee9 menubar-foreground: #d8dee9
message-background: #2E3440 message-background: #2E3440

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333333 foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -131,8 +131,6 @@ external-link-background-hover: inherit
external-link-background-visited: inherit external-link-background-visited: inherit
external-link-background: inherit external-link-background: inherit
external-link-foreground-hover: inherit external-link-foreground-hover: inherit
highlight-background: #ffff00
highlight-foreground: #000000
message-border: #cfd6e6 message-border: #cfd6e6
modal-border: #999999 modal-border: #999999
select-tag-background: select-tag-background:

View File

@@ -35,8 +35,6 @@ external-link-foreground: #268bd2
external-link-foreground-hover: external-link-foreground-hover:
external-link-foreground-visited: #268bd2 external-link-foreground-visited: #268bd2
foreground: #839496 foreground: #839496
highlight-background: #ffff78
highlight-foreground: #000000
message-background: #002b36 message-background: #002b36
message-border: #586e75 message-border: #586e75
message-foreground: #839496 message-foreground: #839496

View File

@@ -35,8 +35,6 @@ external-link-foreground: #268bd2
external-link-foreground-hover: inherit external-link-foreground-hover: inherit
external-link-foreground-visited: #268bd2 external-link-foreground-visited: #268bd2
foreground: #657b83 foreground: #657b83
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #fdf6e3 message-background: #fdf6e3
message-border: #93a1a1 message-border: #93a1a1
message-foreground: #657b83 message-foreground: #657b83

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover:
external-link-foreground-visited: external-link-foreground-visited:
external-link-foreground: external-link-foreground:
foreground: rgba(0, 0, 0, 0.87) foreground: rgba(0, 0, 0, 0.87)
highlight-background: #ffff00
highlight-foreground: #000000
message-background: <<colour background>> message-background: <<colour background>>
message-border: <<colour very-muted-foreground>> message-border: <<colour very-muted-foreground>>
message-foreground: rgba(0, 0, 0, 0.54) message-foreground: rgba(0, 0, 0, 0.54)

View File

@@ -34,8 +34,6 @@ external-link-foreground-hover:
external-link-foreground-visited: #7c318c external-link-foreground-visited: #7c318c
external-link-foreground: #9e3eb3 external-link-foreground: #9e3eb3
foreground: rgba(255, 255, 255, 0.7) foreground: rgba(255, 255, 255, 0.7)
highlight-background: #ffff78
highlight-foreground: #000000
message-background: <<colour background>> message-background: <<colour background>>
message-border: <<colour very-muted-foreground>> message-border: <<colour very-muted-foreground>>
message-foreground: rgba(255, 255, 255, 0.54) message-foreground: rgba(255, 255, 255, 0.54)

View File

@@ -43,8 +43,6 @@ external-link-foreground: rgb(179, 179, 255)
external-link-foreground-hover: inherit external-link-foreground-hover: inherit
external-link-foreground-visited: rgb(153, 153, 255) external-link-foreground-visited: rgb(153, 153, 255)
foreground: rgb(179, 179, 179) foreground: rgb(179, 179, 179)
highlight-background: #ffff78
highlight-foreground: #000000
message-background: <<colour tag-foreground>> message-background: <<colour tag-foreground>>
message-border: #96ccff message-border: #96ccff
message-foreground: <<colour tag-background>> message-foreground: <<colour tag-background>>

View File

@@ -42,8 +42,6 @@ external-link-foreground-hover: inherit
external-link-foreground-visited: #0000aa external-link-foreground-visited: #0000aa
external-link-foreground: #0000ee external-link-foreground: #0000ee
foreground: #333333 foreground: #333333
highlight-background: #ffff00
highlight-foreground: #000000
message-background: #ecf2ff message-background: #ecf2ff
message-border: #cfd6e6 message-border: #cfd6e6
message-foreground: #547599 message-foreground: #547599

View File

@@ -4,7 +4,5 @@ title: $:/core/save/all-external-js
\define saveTiddlerFilter() \define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ [is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
\end \end
\define defaultCoreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js \define coreURL() %24%3A%2Fcore%2Ftemplates%2Ftiddlywiki5.js
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}> {{$:/core/templates/tiddlywiki5-external-js.html}}
{{$:/core/templates/tiddlywiki5-external-js.html}}
</$let>

View File

@@ -4,7 +4,5 @@ title: $:/core/save/offline-external-js
\define saveTiddlerFilter() \define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$ [is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
\end \end
\define defaultCoreURL() tiddlywikicore-$(version)$.js \define coreURL() tiddlywikicore-$(version)$.js
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}> {{$:/core/templates/tiddlywiki5-external-js.html}}
{{$:/core/templates/tiddlywiki5-external-js.html}}
</$let>

View File

@@ -1,7 +1,7 @@
title: $:/core/templates/server/static.sidebar.wikitext title: $:/core/templates/server/static.sidebar.wikitext
\whitespace trim \whitespace trim
<div class="tc-sidebar-scrollable" style="overflow: auto;" role="region" aria-label={{$:/language/SideBar/Caption}}> <div class="tc-sidebar-scrollable" style="overflow: auto;">
<div class="tc-sidebar-header"> <div class="tc-sidebar-header">
<h1 class="tc-site-title"> <h1 class="tc-site-title">
<$transclude tiddler="$:/SiteTitle"/> <$transclude tiddler="$:/SiteTitle"/>

View File

@@ -19,8 +19,8 @@ title: $:/core/templates/server/static.tiddler.html
</head> </head>
<body class="tc-body"> <body class="tc-body">
<$transclude tiddler="$:/core/templates/server/static.sidebar.wikitext" mode="inline"/> <$transclude tiddler="$:/core/templates/server/static.sidebar.wikitext" mode="inline"/>
<section class="tc-story-river" role="main"> <section class="tc-story-river">
<div class="tc-tiddler-frame" role="article"> <div class="tc-tiddler-frame">
<$transclude tiddler="$:/core/templates/server/static.tiddler.wikitext" mode="inline"/> <$transclude tiddler="$:/core/templates/server/static.tiddler.wikitext" mode="inline"/>
</div> </div>
</section> </section>

View File

@@ -18,7 +18,7 @@ tc-page-container tc-page-view-$(storyviewTitle)$ tc-language-$(languageTitle)$
<$navigator story="$:/StoryList" history="$:/HistoryList"> <$navigator story="$:/StoryList" history="$:/HistoryList">
<$transclude tiddler="$:/core/ui/ViewTemplate/body" mode="block"/> <$transclude mode="block"/>
</$navigator> </$navigator>

View File

@@ -2,5 +2,11 @@ title: $:/core/ui/Actions/new-image
tags: $:/tags/Actions tags: $:/tags/Actions
description: create a new image tiddler description: create a new image tiddler
\define get-type()
image/$(imageType)$
\end
\define get-tags() $(textFieldTags)$ $(tagsFieldTags)$
\whitespace trim \whitespace trim
<$action-sendmessage $message="tm-new-tiddler" type={{{ [{$:/config/NewImageType}addprefix[image/]] }}}/> <$vars imageType={{$:/config/NewImageType}} textFieldTags={{$:/config/NewJournal/Tags}} tagsFieldTags={{$:/config/NewJournal/Tags!!tags}}>
<$action-sendmessage $message="tm-new-tiddler" type=<<get-type>> tags=<<get-tags>>/>
</$vars>

View File

@@ -3,7 +3,7 @@ tags: $:/tags/AdvancedSearch/FilterButton
\whitespace trim \whitespace trim
<$reveal state="$:/temp/advancedsearch" type="nomatch" text=""> <$reveal state="$:/temp/advancedsearch" type="nomatch" text="">
<$button tooltip={{$:/language/Buttons/DeleteTiddlers/Hint}} popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible"> <$button popup=<<qualify "$:/state/filterDeleteDropdown">> class="tc-btn-invisible">
{{$:/core/images/delete-button}} {{$:/core/images/delete-button}}
</$button> </$button>
</$reveal> </$reveal>
@@ -13,13 +13,13 @@ tags: $:/tags/AdvancedSearch/FilterButton
<div class="tc-block-dropdown tc-edit-type-dropdown"> <div class="tc-block-dropdown tc-edit-type-dropdown">
<div class="tc-dropdown-item-plain"> <div class="tc-dropdown-item-plain">
<$set name="resultCount" value="""<$count filter={{$:/temp/advancedsearch}}/>"""> <$set name="resultCount" value="""<$count filter={{$:/temp/advancedsearch}}/>""">
{{$:/language/ConfirmDeleteTiddlers}} Are you sure you wish to delete <<resultCount>> tiddler(s)?
</$set> </$set>
</div> </div>
<div class="tc-dropdown-item-plain"> <div class="tc-dropdown-item-plain">
<$button class="tc-btn"> <$button class="tc-btn">
<$action-deletetiddler $filter={{$:/temp/advancedsearch}}/> <$action-deletetiddler $filter={{$:/temp/advancedsearch}}/>
{{$:/language/Buttons/DeleteTiddlers/Hint}} Delete these tiddlers
</$button> </$button>
</div> </div>
</div> </div>

View File

@@ -14,8 +14,8 @@ tags: $:/tags/AdvancedSearch/FilterButton
<$linkcatcher actions="<$action-setfield $tiddler='$:/temp/advancedsearch' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/input' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/refresh' text='yes'/><$action-sendmessage $message='tm-focus-selector' $param='.tc-advanced-search input' />"> <$linkcatcher actions="<$action-setfield $tiddler='$:/temp/advancedsearch' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/input' text=<<navigateTo>>/><$action-setfield $tiddler='$:/temp/advancedsearch/refresh' text='yes'/><$action-sendmessage $message='tm-focus-selector' $param='.tc-advanced-search input' />">
<div class="tc-block-dropdown-wrapper"> <div class="tc-block-dropdown-wrapper">
<div class="tc-block-dropdown tc-edit-type-dropdown"> <div class="tc-block-dropdown tc-edit-type-dropdown">
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]!is[draft]]"> <$list filter="[all[shadows+tiddlers]tag[$:/tags/Filter]]">
<$link to={{!!filter}}><$let tv-wikilinks="no"><$transclude field="description"/></$let></$link> <$link to={{!!filter}}><$transclude field="description"/></$link>
</$list> </$list>
</div> </div>
</div> </div>

View File

@@ -20,16 +20,15 @@ caption: {{$:/language/ControlPanel/Basics/Caption}}
\end \end
\whitespace trim \whitespace trim
|tc-max-width tc-edit-max-width|k
|<<lingo Version/Prompt>> |''<<version>>'' | |<<lingo Version/Prompt>> |''<<version>>'' |
|<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> | |<$link to="$:/SiteTitle"><<lingo Title/Prompt>></$link> |<$edit-text tiddler="$:/SiteTitle" default="" tag="input"/> |
|<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> | |<$link to="$:/SiteSubtitle"><<lingo Subtitle/Prompt>></$link> |<$edit-text tiddler="$:/SiteSubtitle" default="" tag="input"/> |
|<$link to="$:/status/UserName"><<lingo Username/Prompt>></$link> |<$edit-text tiddler="$:/status/UserName" default="" tag="input"/> | |<$link to="$:/status/UserName"><<lingo Username/Prompt>></$link> |<$edit-text tiddler="$:/status/UserName" default="" tag="input"/> |
|<$link to="$:/config/AnimationDuration"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler="$:/config/AnimationDuration" default="" tag="input"/> | |<$link to="$:/config/AnimationDuration"><<lingo AnimDuration/Prompt>></$link> |<$edit-text tiddler="$:/config/AnimationDuration" default="" tag="input"/> |
|<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit class="tc-edit-texteditor" tiddler="$:/DefaultTiddlers"/><br>//<<lingo DefaultTiddlers/BottomHint>>// | |<$link to="$:/DefaultTiddlers"><<lingo DefaultTiddlers/Prompt>></$link> |<<lingo DefaultTiddlers/TopHint>><br> <$edit tag="textarea" tiddler="$:/DefaultTiddlers" class="tc-edit-texteditor"/><br>//<<lingo DefaultTiddlers/BottomHint>>// |
|<$link to="$:/language/DefaultNewTiddlerTitle"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler="$:/language/DefaultNewTiddlerTitle" default="" tag="input"/> | |<$link to="$:/language/DefaultNewTiddlerTitle"><<lingo NewTiddler/Title/Prompt>></$link> |<$edit-text tiddler="$:/language/DefaultNewTiddlerTitle" default="" tag="input"/> |
|<$link to="$:/config/NewJournal/Title"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler="$:/config/NewJournal/Title" default="" tag="input"/> | |<$link to="$:/config/NewJournal/Title"><<lingo NewJournal/Title/Prompt>></$link> |<$edit-text tiddler="$:/config/NewJournal/Title" default="" tag="input"/> |
|<$link to="$:/config/NewJournal/Text"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler="$:/config/NewJournal/Text" class="tc-edit-texteditor" default=""/> | |<$link to="$:/config/NewJournal/Text"><<lingo NewJournal/Text/Prompt>></$link> |<$edit tiddler="$:/config/NewJournal/Text" tag="textarea" class="tc-edit-texteditor" default=""/> |
|<$link to="$:/config/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> | |<$link to="$:/config/NewTiddler/Tags"><<lingo NewTiddler/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewTiddler/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> | |<$link to="$:/config/NewJournal/Tags"><<lingo NewJournal/Tags/Prompt>></$link> |<$vars currentTiddler="$:/config/NewJournal/Tags" tagField="text">{{||$:/core/ui/EditTemplate/tags}}<$list filter="[<currentTiddler>tags[]] +[limit[1]]" variable="ignore"><$button tooltip={{$:/language/ControlPanel/Basics/RemoveTags/Hint}}><<lingo RemoveTags>><$action-listops $tiddler=<<currentTiddler>> $field="text" $subfilter={{{ [<currentTiddler>get[tags]] }}}/><$action-setfield $tiddler=<<currentTiddler>> tags=""/></$button></$list></$vars> |
|<$link to="$:/config/AutoFocus"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} | |<$link to="$:/config/AutoFocus"><<lingo AutoFocus/Prompt>></$link> |{{$:/snippets/minifocusswitcher}} |

View File

@@ -1,3 +0,0 @@
title: $:/snippets/retain-story-ordering-button
<$button set="$:/DefaultTiddlers" setTo={{$:/config/ControlPanel/Basics/DefaultTiddlers/RetainStory}} ><<currentTiddler>></$button>

View File

@@ -1,12 +1,7 @@
title: $:/core/ui/EditTemplate title: $:/core/ui/EditTemplate
\define delete-edittemplate-state-tiddlers() \define delete-edittemplate-state-tiddlers() <$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix<newFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
<$set name="safeNewFieldValueTiddlerPrefix" value=<<newFieldValueTiddlerPrefix>> emptyValue=<<qualify "$:/temp/NewFieldValue">> >
<$action-deletetiddler $filter="[<newFieldNameTiddler>] [prefix[$:/temp/NewFieldValue]prefix<safeNewFieldValueTiddlerPrefix>] [<newFieldNameInputTiddler>] [<newFieldNameSelectionTiddler>] [<newTagNameTiddler>] [<newTagNameInputTiddler>] [<newTagNameSelectionTiddler>] [<typeInputTiddler>] [<typeSelectionTiddler>]"/>
</$set>
\end
<!-- Beware this is duplicated from fields.tid. For details see bug #7054 -->
\define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>] \define get-field-value-tiddler-filter() [subfilter<get-field-editor-filter>sha256[16]addprefix[/]addprefix<newFieldValueTiddlerPrefix>]
\define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}] \define get-field-editor-filter() [<newFieldNameTiddler>get[text]else[]] :cascade[all[shadows+tiddlers]tag[$:/tags/FieldEditorFilter]!is[draft]get[text]] :and[!is[blank]else{$:/core/ui/EditTemplate/fieldEditor/default}]
@@ -28,9 +23,7 @@ title: $:/core/ui/EditTemplate
<div <div
data-tiddler-title=<<currentTiddler>> data-tiddler-title=<<currentTiddler>>
data-tags={{!!tags}} data-tags={{!!tags}}
class={{{ [all[shadows+tiddlers]tag[$:/tags/ClassFilters/TiddlerTemplate]!is[draft]] :map:flat[subfilter{!!text}] tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}} class={{{ tc-tiddler-frame tc-tiddler-edit-frame [<currentTiddler>is[tiddler]then[tc-tiddler-exists]] [<currentTiddler>is[missing]!is[shadow]then[tc-tiddler-missing]] [<currentTiddler>is[shadow]then[tc-tiddler-exists tc-tiddler-shadow]] [<currentTiddler>is[system]then[tc-tiddler-system]] [{!!class}] [<currentTiddler>tags[]encodeuricomponent[]addprefix[tc-tagged-]] +[join[ ]] }}}>
role="region"
aria-label={{$:/language/EditTemplate/Caption}}>
<$fieldmangler> <$fieldmangler>
<$vars <$vars
storyTiddler=<<currentTiddler>> storyTiddler=<<currentTiddler>>

View File

@@ -5,6 +5,6 @@ caption: {{$:/language/EditTemplate/Body/Preview/Type/Output}}
\import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]] \import [all[shadows+tiddlers]tag[$:/tags/Macro/View]!has[draft.of]] [all[shadows+tiddlers]tag[$:/tags/Macro/View/Body]!has[draft.of]]
<$set name="tv-tiddler-preview" value="yes"> <$set name="tv-tiddler-preview" value="yes">
<$transclude tiddler={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/ViewTemplateBodyFilter]!is[draft]get[text]] :and[!is[blank]else[$:/core/ui/ViewTemplate/body/default]] }}} /> <$transclude />
</$set> </$set>

View File

@@ -19,7 +19,7 @@ $:/config/EditorToolbarButtons/Visibility/$(currentTiddler)$
<$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/> <$transclude tiddler="$:/core/ui/EditTemplate/body/editor" mode="inline"/>
<div class="tc-tiddler-preview-preview" data-tiddler-title={{!!draft.title}} data-tags={{!!tags}}> <div class="tc-tiddler-preview-preview">
<$transclude tiddler={{$:/state/editpreviewtype}} mode="inline"> <$transclude tiddler={{$:/state/editpreviewtype}} mode="inline">

Some files were not shown because too many files have changed in this diff Show More