1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2026-01-25 12:23:42 +00:00

Compare commits

...

562 Commits

Author SHA1 Message Date
Jermolene
8f6ee1d2a8 Version number update for 5.0.7-beta 2014-01-26 21:04:38 +00:00
Jermolene
183e9544b4 Readme update 2014-01-26 20:59:36 +00:00
Jermolene
dfc57ffa49 More logging 2014-01-26 20:59:30 +00:00
Jermolene
3f9561dd95 Better logging 2014-01-26 18:53:31 +00:00
Jermolene
37ca86ff3d Docs updates 2014-01-26 17:49:43 +00:00
Jermolene
cf26986061 Update upgrading instructions 2014-01-26 13:54:08 +00:00
Jermolene
54822e25d4 Update static link generation 2014-01-26 13:34:53 +00:00
Jermolene
4a9108154d Readme update 2014-01-26 13:26:25 +00:00
Jermolene
8a88253b4e Remove the white background rectangle from Motovun Jack.svg 2014-01-26 13:24:39 +00:00
Jermolene
7891824883 Fix video protocol
YouTube’s default of missing out the protocol for the iframe src
unfortunately makes videos malfunction when viewing TiddlyWiki on a
file: URL
2014-01-26 13:24:27 +00:00
Jermolene
fca5681a1a Docs updates 2014-01-26 13:04:09 +00:00
Jeremy Ruston
5c9a5f5cba Merge pull request #360 from pmario/docs-cm
docs: CodeMirror config tiddler
2014-01-26 02:01:57 -08:00
Jermolene
69d342d46a Stop the reveal widget caching hidden content
Previously, when displayed content is hidden by the reveal widget there
was an optimisation such that the content was retained in the DOM but
hidden using CSS, so that it could be shown again quickly.

It turns out that a sideeffect of that optimisation is that clicking
through all the sidebar tabs leaves them all active, so that they all
need to be refreshed whenever a character is typed in an editor.

This commit suppresses the optimisation, so that hidden content is
removed from the DOM and the render tree.
2014-01-26 09:57:46 +00:00
Mario Pietsch
66254b436c fix #215 cm gutter adjust .CodeMirror-linenumber min-width, font-size. It should work up to 999 lines now. There should be a ControlPanel tab for codemirror 2014-01-25 23:33:24 +01:00
Mario Pietsch
d42981f201 docs: CodeMirror config tiddler needs to be type:application/json 2014-01-25 22:53:52 +01:00
Jeremy Ruston
04dbf99e54 Merge pull request #359 from pmario/fix-docs
some doc updates.
2014-01-25 13:26:42 -08:00
Jermolene
762940adbc No longer save system modules separately in the main HTML template
These tiddlers were being handled as `<script>` tags to make it easier
to debug them. But in fact modern dev tools are quite happy to debug
code that has been eval’d, and this arrangement was causing problems
for importing.

Fixes #335
2014-01-25 21:22:43 +00:00
Mario Pietsch
f58d4fb531 some doc updates. server default IP fix and changed Ton's entry page 2014-01-25 22:02:48 +01:00
Jermolene
45c45e098f Add a cancel button to the 'set password' dialog
Fixes #185
2014-01-25 19:55:56 +00:00
Jermolene
b5629ccc82 Update codemirror plugin docs
@pmario and @jbolila - could you kindly check whether the docs cover
everything?
2014-01-25 19:34:32 +00:00
Jermolene
bd067c6b1e Include the nodewebkitsaver in tw5.com
Just for the moment, to make it easier for people to find it.
2014-01-25 19:33:35 +00:00
Jermolene
1d10ccb368 Update release notes for 5.0.7 2014-01-25 19:33:00 +00:00
Jermolene
9297b27b89 Reference correct wiki object 2014-01-25 18:17:33 +00:00
Jermolene
0b3efe179e Extend list filter operator to take a text reference
Instead of just a title. Means that we can apply the list operator to
fields other than the list field.
2014-01-25 18:14:30 +00:00
Jermolene
e6843aabff Refactoring of new filter list operators 2014-01-25 17:44:36 +00:00
Jermolene
02d3861d7d Tests for the new filter operators 2014-01-25 17:44:14 +00:00
Jeremy Ruston
592ef257a2 Merge pull request #326 from Skeeve/listops
New list operations from @Skeeve
2014-01-25 08:51:26 -08:00
Jermolene
6ba9bf9a95 Boost the priority of the upload saver
If we’ve got an upload wiki name then we should always use the upload
saver.

See https://groups.google.com/d/topic/tiddlywiki/Jqd2jbPmYFA/discussion
2014-01-25 16:38:08 +00:00
Jermolene
18fe0c0f75 Add Jeffrey Kishner link to Community tiddler 2014-01-25 14:51:43 +00:00
Jermolene
c49681ecf3 Docs tweaks 2014-01-25 14:47:25 +00:00
Jermolene
6255b97b14 Resolve merge conflict 2014-01-25 14:41:48 +00:00
Jermolene
6cb44ac0cc Fix typo in field mangler docs
Fixes #358
2014-01-25 14:07:32 +00:00
Jermolene
b1b9c7d6cd Fix typo in codemirror editor 2014-01-25 14:07:10 +00:00
Jermolene
951147d502 Style tweaks 2014-01-24 21:45:37 +00:00
Jermolene
9539664e46 Merge branch 'codemirror_keymap' of https://github.com/jbolila/TiddlyWiki5 into jbolila-codemirror_keymap 2014-01-24 21:39:55 +00:00
Jermolene
f9b5d75446 Clarify that global macros are coming 2014-01-24 20:42:09 +00:00
Jermolene
70a7321edd Take editor configuration from configuration tiddlers
This should enable @buggyj to add an html editor by including a
configuration tiddler in the plugin.
2014-01-24 20:22:23 +00:00
Jermolene
9522050aa7 Merge @buggyj's CLA signature 2014-01-24 19:19:56 +00:00
Jermolene
8d37219545 Add some tests 2014-01-24 19:15:34 +00:00
Jermolene
a76da88380 Rename the operator portion after the colon to "suffix" 2014-01-24 19:15:27 +00:00
Jermolene
42262a637c Docs tweaks 2014-01-24 18:54:55 +00:00
Jermolene
e6a7a0db1e Style tweaks 2014-01-24 18:54:50 +00:00
Jermolene
edc71cb920 Merge branch 'regexp_filter' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-regexp_filter 2014-01-24 18:40:27 +00:00
Jermolene
bd48ecfcb1 Generate the copyright.md file in the same way we generate readme.md
Fixing #351
2014-01-24 18:35:17 +00:00
Jermolene
f4b27b33de Fixed problem with multiple tiddlers created from dragging a single file 2014-01-24 14:09:06 +00:00
Jermolene
644d88a6c5 Adjust control panel links 2014-01-24 13:43:51 +00:00
Jermolene
43eb81173d Add note about system tiddler naming conventions 2014-01-23 08:23:49 +00:00
Jermolene
a8eff78b62 Fix formatting 2014-01-23 08:22:55 +00:00
Jermolene
f90db97625 Correct year of release for 5.0.6 2014-01-23 08:22:45 +00:00
Jermolene
e339b6dffe Add documentation on sharing via Dropbox 2014-01-22 09:06:07 +00:00
Jermolene
64304f9b7f Ensure that new tiddlers created from a skeleton don't inherit created/creator fields 2014-01-21 21:00:08 +00:00
Jermolene
867dfabff8 Change initial default tiddlers to include most recently created tiddlers 2014-01-20 18:26:32 +00:00
Jermolene
b627bba277 Added link to download instructions 2014-01-20 17:48:03 +00:00
Jermolene
b9b1b001da Update Typed Blocks documentation 2014-01-20 17:14:38 +00:00
Jermolene
e9ae8d2015 Clarify upgrading instructions for encrypted wikis 2014-01-20 13:38:57 +00:00
Jermolene
2fc6451bf7 Rejigged encrypted import so that the current password isn't changed
We still try the currently stored password. If that doesn’t work then
we prompt for a password, but we no longer store the password in the
store.
2014-01-20 13:35:55 +00:00
Jermolene
f31369035b Update JavaScript Macro docs 2014-01-20 13:02:12 +00:00
Jermolene
1e54b1bcc9 Remove empty tag fields in the field mangler
This means that removing the last tag from a tiddler will remove the
tags field.
2014-01-20 11:53:26 +00:00
Jermolene
d3c421985c Add delete icon for the tiddler type editor 2014-01-20 11:21:12 +00:00
Jermolene
1c283c5586 Tighten "has" filter operator
We now require the field not to be an empty string in order to be
counted.
2014-01-20 08:59:01 +00:00
Jermolene
4f5a923ca0 Update release note 2014-01-19 21:46:01 +00:00
Jermolene
95cb99adb9 Enhance text widget to optionally use "text" attribute
This lets us use the text widget to render text in macros that we don’t
want to be wikified.
2014-01-19 21:45:55 +00:00
Jermolene
d5df78d979 Docs update 2014-01-19 20:16:29 +00:00
Jermolene
ed5cf8b044 Refactor importing of encrypted TiddlyWiki files so that it works on Node.js 2014-01-19 20:13:55 +00:00
Jermolene
98edbec46d Adjust the position of modal dialogues
The top was off the top of the window
2014-01-19 20:12:55 +00:00
Jermolene
299e9d15fb Add support for importing encrypted TiddlyWiki documents 2014-01-19 18:43:02 +00:00
Jermolene
2f4932fefc Expose the option to retain story ordering across restarts 2014-01-19 18:42:32 +00:00
Jermolene
5f1d49f2e0 Clarify the shadow GettingStarted docs 2014-01-19 18:42:20 +00:00
Jermolene
6ea9dc997f Remove extraneous full stop 2014-01-19 18:42:08 +00:00
Jermolene
c9d06ad18a Add link to French thesis notebook 2014-01-18 14:58:24 +00:00
Jermolene
3414f1ca8e Move node-webkit saver into a plugin
We don’t need it for TiddlyDesktop now that it reuses the TiddlyFox
saver. But it is still useful for embedding a TW directly into a
node-webkit app
2014-01-18 14:57:42 +00:00
Jermolene
60926198b1 Improve logic for initialising reading node tiddlers
We want fine control of whether tiddlers are read from the DOM or the
file system, without ganging it to whether we’re on node vs. browser.
2014-01-18 14:53:26 +00:00
Jermolene
2c790d982f Switch to using $tw.fakeDocument for the fakedom document object
So that we can free us `$tw.document` to be the actual DOM document
2014-01-15 14:57:35 +00:00
Jermolene
839361d54f Futher refactoring for TiddlyDesktop
We need finer control over the boot process so that we can force it to
load tiddlers from the Node.js file APIs rather than from the DOM
2014-01-15 14:51:04 +00:00
Stephan Hradek
14ca91a949 implemented the new regexp syntax 2014-01-14 22:08:05 +01:00
Stephan Hradek
81de74342d implemented the new regexp syntax 2014-01-14 22:07:20 +01:00
Stephan Hradek
0338c36610 implemented the field: syntax 2014-01-14 16:19:34 +01:00
Jermolene
c7fb0bd349 Start updating the boot kernel for more node-webkit integration
The goal is to make it possible to use the Node.js boot code under
node-webkit, so that we can directly load wiki folders
2014-01-14 14:09:04 +00:00
João Bolila
d7d5165847 all configuration and required libs in the config tiddler 2014-01-13 23:34:11 +00:00
Jeremy Ruston
aefc7b7ce2 Merge pull request #343 from csugden/patch-1
Updates "main" in package.json
2014-01-13 13:40:44 -08:00
Jeremy Ruston
1657111cb7 Merge pull request #344 from csugden/patch-2
Update cla-individual.md
2014-01-13 13:39:08 -08:00
csugden
08a8689117 Update cla-individual.md 2014-01-13 21:22:13 +00:00
csugden
b1b38dc143 Updates "main" in package.json
Fixes require "Error: Cannot find module 'tiddlywiki'"
2014-01-13 18:29:22 +00:00
Jermolene
22f48198bd Update release note 2014-01-13 17:59:22 +00:00
Jermolene
4072c4461d Switch to using a real ellipsis for advanced search 2014-01-13 17:59:14 +00:00
Jermolene
43fb16f232 Updates to the batch files
We should build highlightdemo.html on Windows
2014-01-13 17:33:33 +00:00
Jermolene
809c441ab3 Merge branch 'master' of https://github.com/jbolila/TiddlyWiki5 into jbolila-master 2014-01-13 17:28:08 +00:00
Jermolene
9985efa406 Fix link to tutsplus.com node-webkit tutorial 2014-01-13 17:02:21 +00:00
Jermolene
84e149e36c Reset the JavaScript error dialogue width
It inadvertantly got affected by the change to the password dialogue.
2014-01-13 16:17:08 +00:00
Jermolene
25423d2d07 Clarified the PHP instructions 2014-01-13 12:32:46 +00:00
Jermolene
12770ca3e6 Use an explicit default host
Thus fixing #339
2014-01-13 09:09:54 +00:00
Stephan Hradek
a5d75db8d2 Thinking about your mail led me to this new push -> Mail follows 2014-01-13 08:44:53 +01:00
Stephan Hradek
9444ef095f I feel ashamed :( Somehow this slipped me :( Sorry! 2014-01-12 23:37:11 +01:00
Jermolene
b04141fefd Don't load tiddlers that don't have a title
We were getting problems (eg, adding a `readme.md` to a plugin without
an accompanying `readme.md.meta` would end up creating a tiddler called
“undefined”)
2014-01-12 21:48:18 +00:00
João Bolila
c74bf6a655 in resp to https://github.com/Jermolene/TiddlyWiki5/pull/328#issuecomment-32131402 2014-01-12 21:48:03 +00:00
Jermolene
19080f9958 Update coding style guidelines 2014-01-12 21:28:58 +00:00
Jermolene
b5d2b79a37 Add nbsp handling to htmlDecode 2014-01-12 20:11:51 +00:00
João Bolila
17b542980f if a function 2014-01-12 20:03:34 +00:00
João Bolila
8f4e1587a2 rename from mode to keymap bindings (Vim and Emacs bindings) 2014-01-12 19:38:27 +00:00
Jermolene
4b000fac72 Added some docs about naming conventions for system tiddlers 2014-01-12 19:02:15 +00:00
João Bolila
426f2978cf fixes of a newbie, me 2014-01-12 17:09:24 +00:00
Jermolene
bad2e36e45 Remove obsolete itemClass attribute on the list widget 2014-01-12 17:01:18 +00:00
Jermolene
a4f895dc4d Introduce coding style guidelines 2014-01-12 16:56:05 +00:00
Jermolene
e254529763 More configuration controls for TiddlySpot saver
And more reliable checking of the result returned from the server
2014-01-12 12:05:15 +00:00
Jermolene
5dff212e5a Clarify comment in main template 2014-01-12 11:58:45 +00:00
Jermolene
b7a1db1e9f Display tiddler data dictionaries as plain text 2014-01-12 11:58:32 +00:00
Jermolene
6964120fce Move PHP docs 2014-01-11 21:46:33 +00:00
João Bolila
a704498155 added suport for vim and emacs keymaps (codemirror updated to 3.20) 2014-01-11 15:23:49 +00:00
Jermolene
83811bc2a9 Updated docs 2014-01-11 10:22:17 +00:00
Jermolene
bd40977c85 Fix docs error 2014-01-11 09:50:34 +00:00
Jermolene
e87097c22e Updated docs for saving to a PHP server 2014-01-11 09:39:50 +00:00
Jermolene
e74cb05540 Adjust CLA docs 2014-01-11 08:58:54 +00:00
Jermolene
b326315b0e Make the password dialogue narrower
To make it work better on mobile devices
2014-01-10 16:51:39 +00:00
Stephan Hradek
a3384d101e Extended the filter documentation 2014-01-10 13:23:26 +01:00
Stephan Hradek
8ef520ef37 Created regexp search for milestone 5.1 2014-01-10 10:32:49 +01:00
Jermolene
b64b7982af Fix notification removal to not rely on transitionEnd events 2014-01-09 22:26:21 +00:00
João Bolila
c5035fc0b0 highlight.js updated to version 8.0 (http://highlightjs.org/) 2014-01-09 14:32:31 +00:00
Jermolene
2740f8c1f0 A trivial change for testing purposes 2014-01-08 18:04:49 +00:00
Jermolene
209bc78268 Clean up whitespace 2014-01-08 16:51:42 +00:00
Jermolene
ffcc215e8f Add ellipsis for advanced search next to search box 2014-01-08 10:43:50 +00:00
Jermolene
0fb13e649b Exclude non-system tiddlers from system tiddler search 2014-01-08 09:55:06 +00:00
João Bolila
b42eefe1e8 Merge remote-tracking branch 'upstream/master' 2014-01-08 04:47:20 +00:00
João Bolila
82a48cf85c codeblock as a widget and plugin for highlight code blocks 2014-01-07 22:57:46 +00:00
Stephan Hradek
9fee9b1043 Fix for Paul's concerns 2014-01-07 21:12:59 +01:00
Jermolene
d57010d2fb Docs updates 2014-01-07 11:57:42 +00:00
Jermolene
f2409d4245 Fixed problem with positioning of the sidebar in the centralised theme 2014-01-07 11:09:56 +00:00
João Bolila
4181de5b74 sign contributor license agreement 2014-01-05 20:01:26 +00:00
Jermolene
954901d788 Start adding export options to the control panel 2014-01-05 17:24:53 +00:00
Jermolene
4688190c96 Docs update 2014-01-05 16:33:01 +00:00
João Bolila
a1d2e70307 Plugin for syntax highlighting with highlight.js from Ivan Sagalaev 2014-01-05 09:58:01 +00:00
Jermolene
e0f428b9b2 Fixed problem with Element.ELEMENT_NODE undefined on Safari 2014-01-04 15:15:12 +00:00
Jermolene
504f353844 Update docs with new video tutorials 2014-01-04 13:56:21 +00:00
Jermolene
7857464ab5 Correct another npm typo 2014-01-04 12:05:24 +00:00
Stephan Hradek
103f4f6637 added some more filters 2014-01-04 00:01:17 +01:00
Jermolene
b06e09a4d3 Fix typo in default date format string for view widget
Fixes #320
2014-01-03 18:34:27 +00:00
Jermolene
9d72570092 Update version number for next version 2014-01-03 18:33:03 +00:00
Jermolene
1638824adc Version number update for 5.0.6-beta 2014-01-03 17:16:19 +00:00
Jermolene
79bed656bb Update release date of 5.0.6 2014-01-03 17:15:27 +00:00
Jermolene
6fcfa2738a Docs updates 2014-01-03 17:14:01 +00:00
Jermolene
47ebed87f9 Docs updates 2014-01-03 17:13:03 +00:00
Jermolene
3c35c9ecf8 Improved instructions for TiddlyFox on Android 2014-01-03 13:55:30 +00:00
Jermolene
027421f5e6 More coding style consistency 2014-01-03 10:54:00 +00:00
Jermolene
1a74e2538c Cleaning up further coding style inconsistencies that have crept in 2014-01-03 10:50:00 +00:00
Jermolene
8fc5c1d4a0 Further style tweaks to #321 2014-01-03 10:48:00 +00:00
Jermolene
1374bd9d78 Coding style fixes for #321 2014-01-03 10:43:08 +00:00
Jermolene
307b5c7d6b Merging #321 Table valign from @Skeeve 2014-01-03 10:39:55 +00:00
Jeremy Ruston
5dea8ca758 Merge pull request #324 from Skeeve/nsort
Add numeric sort filter operators
2014-01-03 02:30:12 -08:00
Jermolene
3677fdd3b0 Moved docs to right edition 2014-01-03 09:18:36 +00:00
Jermolene
5758fcb69b Add instructions for adding a Twitter Follow button 2014-01-03 09:16:58 +00:00
Jermolene
385099c4f7 Clarify references to sudo 2014-01-02 21:47:01 +00:00
Jermolene
2343bb3e5b Switch to using 127.0.0.1 in docs 2014-01-02 20:07:05 +00:00
Jermolene
b132e1023d Add error checking to $tw.utils.setStyle() 2014-01-02 19:00:46 +00:00
Jermolene
2d99f4dc15 Update copyright year 2014-01-02 10:55:19 +00:00
Stephan Hradek
c9b319c41c nsort - adapted documentation 2014-01-01 23:59:09 +01:00
Stephan Hradek
b652238650 fixed issue #241 - created first, last, rest and reverse filter functions 2014-01-01 22:38:08 +01:00
Jermolene
d0cd72ed85 Docs update 2014-01-01 20:51:38 +00:00
Jermolene
4289367b7f Add some more filter examples 2014-01-01 18:37:46 +00:00
Jermolene
b76ca5dc3b Clarify use of double square brackets in default tiddlers 2014-01-01 18:27:27 +00:00
Jermolene
71b5c561f2 Docs update 2014-01-01 18:19:50 +00:00
Jermolene
6a02535d08 Docs update 2014-01-01 17:59:55 +00:00
Jermolene
87fbd988f1 Add support for running TiddlyWiki under node-webkit 2014-01-01 17:59:47 +00:00
Jermolene
3d79eb87d1 First pass at an advanced search tiddler 2013-12-31 13:11:01 +00:00
Jermolene
089a838611 Docs update 2013-12-31 11:36:51 +00:00
Jermolene
e48e7e9443 Style improvements for alltiddlers.html 2013-12-31 11:34:10 +00:00
Stephan Hradek
917865c393 fixed an initialization error 2013-12-31 11:09:17 +01:00
Stephan Hradek
ec14a0a16d vertical alignment of cells - version 2 2013-12-31 11:05:08 +01:00
Jermolene
b9e80a270b All-in-one static HTML support
Added a first pass at generating an all-in-one static HTML
representation of a wiki, incorporating anchor links for wiki links
2013-12-31 09:43:46 +00:00
Jermolene
44568dc6ef Hide encryption status when running on the server
A partial fix for #303
2013-12-30 15:05:07 +00:00
Jermolene
d043bdd289 Fix problem with view widget relativedate format
Fixes #319
2013-12-30 13:08:48 +00:00
Stephan Hradek
ce8cc7607f changed to conform to Jeremy's standards - sorry… 2013-12-30 13:44:32 +01:00
Jermolene
6d6e8afb9c Add a style rule for padding paragraphs within dropdowns
Fixes #306
2013-12-30 12:38:45 +00:00
Jermolene
bb0be9e02f Correct npm upgrading instructions
Fixes #304
2013-12-30 12:16:06 +00:00
Jermolene
5dd33904e7 Update docs for double backtick syntax 2013-12-30 12:13:23 +00:00
Jeremy Ruston
2ee5093944 Merge pull request #305 from Skeeve/issue_186
added a fix for issue #186
2013-12-30 04:06:05 -08:00
Jermolene
87a553d75d Docs update 2013-12-30 11:54:56 +00:00
Jermolene
ec7dff291d Fix problem with "import" button not working
Fixes #308
2013-12-30 11:54:51 +00:00
Jeremy Ruston
de2e5adf15 Merge pull request #307 from Skeeve/issue_94
added fix for issue #94 for horizontal rules, tables and typed block
2013-12-30 03:46:16 -08:00
Jermolene
b3ad61ce20 Add a failing test for @Skeeve's upcoming #307 2013-12-30 11:45:18 +00:00
Jeremy Ruston
5eb57365b6 Merge pull request #312 from Skeeve/issue_232
fixed issue#232
2013-12-30 03:25:37 -08:00
Jermolene
c49bc2b0a6 Update docs for tables in wikitext
Fixes #314
2013-12-30 10:51:25 +00:00
Jeremy Ruston
3494dd019d Merge pull request #318 from davidjade/master
Fix for #317
2013-12-30 02:33:27 -08:00
Jermolene
784e6d17f0 Update issues policy 2013-12-30 10:16:32 +00:00
Jermolene
9efd45dda9 Docs update 2013-12-30 10:16:24 +00:00
Stephan Hradek
eb7b82696b fixed documentation for issue #314 2013-12-30 09:51:54 +01:00
David Jade
3b114371d0 Only set placeholders when field has no data (fixes #317) 2013-12-29 17:18:00 -08:00
Stephan Hradek
14868d8228 also fixed issue #315 2013-12-30 00:28:43 +01:00
Stephan Hradek
3cc8138133 fixed issue #314 - fix for > at end of line 2013-12-29 23:57:42 +01:00
Jermolene
b6f2f1e1aa Add margin around message box icons 2013-12-29 22:54:26 +00:00
Jermolene
424147234e Add TiddlyWikiClassic upgrading warning 2013-12-29 22:52:46 +00:00
Stephan Hradek
8e080eac0a fixed issue #314 2013-12-29 23:51:22 +01:00
Stephan Hradek
38142d2b19 Missed that I need to explicitly need to git rm … 2013-12-29 22:32:23 +01:00
Jermolene
bd7db62da0 Added support for specifying hostname for the --server command
Fixes #301
2013-12-29 13:07:06 +00:00
Jermolene
4cdfbd6b36 Docs update 2013-12-29 12:54:08 +00:00
Jermolene
ef59a3743f Fix crashes when attempting full screen mode on browsers that don't support it
Fixes #311
2013-12-29 12:54:00 +00:00
Stephan Hradek
cee1bc0863 small typofix 2013-12-29 00:19:51 +01:00
Stephan Hradek
ce8c79ecfa changed sort and sortcs to support nsort and nsortcs 2013-12-29 00:15:11 +01:00
Jermolene
ac81d9d43f Docs update
Hopefully fixing #309
2013-12-28 17:57:11 +00:00
Jermolene
d69614259f Add TiddlyWiki Classic markup to type dropdown 2013-12-28 17:56:48 +00:00
Jermolene
0e88417e62 Update version number for next release 2013-12-28 17:49:35 +00:00
Stephan Hradek
46892371cb fixed issue#232 2013-12-28 17:46:53 +01:00
Stephan Hradek
f9de55ad5f added fix for issue #94 for horizontal rules, tables and typed block 2013-12-25 23:06:42 +01:00
Stephan Hradek
81106e500d added a fix for issue #186 2013-12-25 14:31:35 +01:00
Jermolene
cfad04a5d0 Version number update for 5.0.5-beta 2013-12-24 14:22:28 +00:00
Jermolene
1aa5dedfaf Docs update 2013-12-24 14:21:35 +00:00
Jermolene
98fdd3e184 Fix problem with modal positioning on narrow screens
Fixes #302
2013-12-24 09:44:40 +00:00
Jermolene
73c5ecdaa7 Added a green version of the favicon for the static pages 2013-12-24 09:09:01 +00:00
Jermolene
eef32e70e3 Added support for dynamic favicons
Now it’s possible to edit $:/favicon.ico with the image editor, and see
the changes instantly reflected in the browser.
2013-12-24 09:08:25 +00:00
Jermolene
ad6bf4f9c5 Extend support for .ico files
Now we can parse image/x-icon tiddlers for display, and provide an
entry for them in the type dropdown.
2013-12-24 09:07:25 +00:00
Jermolene
7db31dc138 Typo correction 2013-12-24 09:06:09 +00:00
Jermolene
7b7e799a70 Fixed problem with static content being included in empty.html
A bit of a hack to fix this problem:

https://groups.google.com/forum/#!topic/tiddlywikidev/Ucpbq5eeq8g
2013-12-23 09:53:31 +00:00
Jermolene
3aab737bea Docs update 2013-12-23 08:55:15 +00:00
Jermolene
12b4cc5d3e Update wiki.readFiles() to call the callback just once
Now we accumulate the results and just pass them to the callback once.
2013-12-23 08:55:11 +00:00
Jermolene
10c25c1692 Fix slow regexp in importing TiddlyWiki HTML files 2013-12-23 08:54:33 +00:00
Jermolene
c35742f916 Prepare version info for 5.0.5 2013-12-23 08:54:07 +00:00
Jermolene
15a41d7e57 Docs update 2013-12-22 16:25:01 +00:00
Jermolene
4e37fa7e47 Docs updates 2013-12-22 15:50:27 +00:00
Jermolene
1c17cfb0ff Version number update for 5.0.4-beta 2013-12-22 15:48:22 +00:00
Jermolene
912c26f848 Correct previous commit 2013-12-22 15:46:41 +00:00
Jermolene
a5de1cf7fb Docs update 2013-12-22 15:46:06 +00:00
Jermolene
84e0dc9d1a Docs update 2013-12-22 15:32:04 +00:00
Jermolene
39743b4758 Docs update 2013-12-22 15:07:32 +00:00
Jermolene
6091b41960 Docs update 2013-12-22 11:28:08 +00:00
Jermolene
2d1d53893a Adjust regex to work around an issue with importing certain tiddlers on Firefox 2013-12-22 11:28:03 +00:00
Jermolene
861e350444 Docs update 2013-12-21 20:56:38 +00:00
Jermolene
9a15cb0516 Docs correction 2013-12-21 20:56:31 +00:00
Jermolene
74fd683a22 Clean up indenting 2013-12-21 20:56:19 +00:00
Jermolene
8cc10d87d4 Added missing RawWidget
Fixes #298. Thanks to @buggyj for pointing it out.
2013-12-21 16:11:48 +00:00
Jeremy Ruston
ce13548884 Merge pull request #299 from davidjade/master
Better drag/drop for Firefox/Chrome and improved IE support
2013-12-21 05:34:43 -08:00
Jermolene
ffcc5a09f2 Improve TiddlyFox instructions 2013-12-21 09:12:30 +00:00
David Jade
7f5a8fc937 Better drag/drop for Firefox/Chrome and improved IE support 2013-12-20 19:57:05 -08:00
Jermolene
c740792105 Fixed illegal HTML comments
Pointed out by @Skeeve, double hyphens are not allowed inside HTML
comments
2013-12-20 18:22:01 +00:00
Jermolene
bd80bf4acc Regex optimisation suggested by @Skeeve 2013-12-20 18:14:11 +00:00
Jermolene
e66fb948c1 Typo from #296 2013-12-20 17:07:30 +00:00
Jermolene
79046c52b4 Make the tiddler text prompt be a placeholder 2013-12-20 17:07:15 +00:00
Jermolene
062c4e5400 Make the edit widget pass through the placeholder attribute 2013-12-20 17:06:57 +00:00
Jermolene
8538d69dc1 Update navigator widget to use wiki.generateNewTitle() 2013-12-20 16:53:49 +00:00
Jermolene
274c52005d Merge branch 'tiddlerexistsloops' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-tiddlerexistsloops 2013-12-20 16:49:12 +00:00
Jermolene
99dd029816 Drop the backticks around colour values
It’s safe to do since no CSS color could be inadvertantly wikified.
2013-12-20 16:44:04 +00:00
Jermolene
1c529ddcd4 Refactored stylesheet implementation
This way we reuse the refresh mechanism properly so that theme tweaks
can be applied interactively.
2013-12-20 15:31:16 +00:00
Jermolene
1491c261f5 Add quick build
For testing it’s handy to be able to build index.html quickly
2013-12-20 15:29:53 +00:00
Jermolene
3bcaab513d Fixed problem with insertBefore() method in fakedom
Was preventing refreshing of widget trees built against the fakedom.
2013-12-20 15:29:01 +00:00
Stephan Hradek
04077549ca Fixed the typos Mario noticed 2013-12-19 20:38:59 +01:00
Jermolene
6c1489fc2f Remove duplicate header
And provide a slightly more informative prompt
2013-12-19 16:53:48 +00:00
Jermolene
1336058336 Docs updates 2013-12-19 16:45:13 +00:00
Jermolene
b659c65959 Add offline download to TiddlyWeb control panel
Add button to download an offline-compatible snapshot to the TiddlyWeb
control panel
2013-12-19 16:28:42 +00:00
Jermolene
e8f16c1c97 Correct description of github-fork-ribbon plugin 2013-12-19 16:26:00 +00:00
Jermolene
6b51a51609 Docs updates 2013-12-19 10:08:14 +00:00
Jermolene
a4d063e884 Docs update 2013-12-19 07:59:18 +00:00
Stephan Hradek
42ba6852d1 changed 2 loops resolving name conflicts for new tiddlers as suggested in issue 294 2013-12-18 23:48:04 +01:00
Jermolene
638c8b2070 Fixes to fullscreen support
Prompted by this article:

http://generatedcontent.org/post/70347573294/is-your-fullscreen-api-code
-up-to-date-find-out-how-to
2013-12-18 21:39:59 +00:00
Jermolene
cc39686693 Create tiddlers subfolder in wiki folder if it is not present 2013-12-18 21:11:52 +00:00
Jermolene
2b72e48a3a Improve prompt for --server command 2013-12-18 21:11:16 +00:00
Jermolene
0ec2224757 Fallback to a default tiddlywiki.info file if it does not exist
We fallback to settings suitable for the server version, to help people
get up and running quickly.
2013-12-18 21:11:00 +00:00
Jermolene
218b9c967e Docs update 2013-12-18 17:34:33 +00:00
Jermolene
a4e4b6797a Give a different coloured favicon for the client server edition 2013-12-18 17:34:02 +00:00
Jermolene
a4e3f66809 Add favicon.ico support to the server 2013-12-18 17:27:24 +00:00
Jermolene
07dd524016 Adjust build scripts to save favicon.ico from wiki
And add file type information for `image/x-icon`
2013-12-18 17:27:10 +00:00
Jermolene
f3b2788ed1 Add a savetiddler command
It saves tiddlers in their original, unrendered format
2013-12-18 17:26:23 +00:00
Jeremy Ruston
a389f9bc8c Merge pull request #181 from natecain/excludes_refactor
A small refactor and addition to exclude more files
2013-12-18 08:51:36 -08:00
Jermolene
1144504bb3 Docs update 2013-12-18 16:29:45 +00:00
Jeremy Ruston
72f07947ea Merge pull request #286 from willover/285
Fix Issue #285: Minor typo
2013-12-18 08:26:08 -08:00
Jeremy Ruston
e8549cba4b Merge pull request #292 from willover/291
Sign CLA (Issue #291)
2013-12-18 08:23:21 -08:00
willover
a5aa2c08b2 Sign CLA (@willover) 2013-12-18 15:47:57 +00:00
Jermolene
14b98f5966 Docs update 2013-12-18 12:05:26 +00:00
Jermolene
7ec516a746 Correct template for the static HTML rendering 2013-12-17 19:36:55 +00:00
willover
886b069dce Fix Issue #285: Minor typo
Fix Issue #285: and TiddlyWikiClassic is -> and "TiddlyWikiClassic" is
2013-12-17 18:49:54 +00:00
Jermolene
b50eb8da30 Fixed problem with tiddler navigation ordering 2013-12-17 15:42:53 +00:00
Jermolene
4ece301a97 Fix fieldmanger to update modified and modifier fields 2013-12-17 15:04:22 +00:00
Jermolene
810167bc7b Improve handling of double square brackets within tags
Now a [[ has to be preceded by the beginning of the string or a
whitespace and a ]] has to be followed by whitespace or the end of the
string to act as quotes.

Thanks to @Skeeve for the regex
2013-12-17 14:53:02 +00:00
Jermolene
1b2a5fe130 Fixed hover effects for Firefox
For some reason Firefox doesn’t like :hover on an SVG element
2013-12-17 13:59:39 +00:00
Jermolene
88d483a2c8 Docs update 2013-12-17 13:42:19 +00:00
Jermolene
db85bfe513 Fix problem with covering of the dragger image
Fixes #253
2013-12-17 13:39:46 +00:00
Jermolene
066a4d9fbc Coding style and layout tweaks 2013-12-17 13:32:15 +00:00
Jermolene
3e2f475324 Merge branch 'master' of https://github.com/davidjade/TiddlyWiki5 into davidjade-master 2013-12-17 13:26:08 +00:00
Jermolene
a5f33d875b Fix up rootwidget and page container
We need to properly link the page container to the rootwidget.

Fixes #223
2013-12-17 13:13:43 +00:00
Jermolene
6d09db5608 Add a favicon 2013-12-16 23:27:26 +00:00
Jermolene
23b2f74e94 Docs update 2013-12-16 08:57:05 +00:00
Jermolene
37a46adac8 Fix problem with radio widget refreshing 2013-12-16 08:52:18 +00:00
Jermolene
65e3780cc1 Preparing for 5.0.4 2013-12-16 08:52:06 +00:00
Jermolene
7d33dd71a2 Version number update for 5.0.3-beta 2013-12-15 17:00:25 +00:00
Jermolene
d03728ea71 Preparation for 5.0.3 2013-12-15 16:57:58 +00:00
Jermolene
9396d52b42 Docs updates 2013-12-15 16:57:51 +00:00
Jermolene
7dc7559b90 Adjust references to five.tiddlywiki.com 2013-12-15 16:53:10 +00:00
Jermolene
5ac5b2c76d Move markdown.js
Leaving it in node_modules meant that it wasn’t getting installed by npm

Fixes #281
2013-12-15 16:44:49 +00:00
Jermolene
d4d8cdf9a4 Getting ready for 5.0.3 2013-12-15 16:41:36 +00:00
Jermolene
9e5e08a7d3 Docs update 2013-12-15 14:57:56 +00:00
Jermolene
41c592b758 Revert the bump to 5.0.3
So that we can do rebuilds if needed as we execute the move to
tiddlywiki.com
2013-12-15 14:44:55 +00:00
Jermolene
84ad161eab Adjust cname for move to tiddlywiki.com 2013-12-15 14:44:33 +00:00
Jermolene
4ab431bb93 Preparing for 5.0.3 2013-12-15 14:40:30 +00:00
Jermolene
f6bea8f58b Docs updates 2013-12-15 14:37:37 +00:00
Jermolene
b8c9422161 Version number update for 5.0.2-beta 2013-12-15 14:35:15 +00:00
Jermolene
d7ebd461f2 Update for beta 2013-12-15 14:25:02 +00:00
Jermolene
57adbe5bf7 Fixed typo in hardlinebreak parser 2013-12-14 17:42:50 +00:00
Jermolene
34e6d79ef6 Tweak background colour of HTML-in-SVG demo
To make it look different from the page background colour
2013-12-14 17:38:46 +00:00
Jermolene
713d6945c6 Misplaced space 2013-12-14 17:22:26 +00:00
Jermolene
ef9175e7bc Remove debugging info 2013-12-14 17:07:47 +00:00
Jermolene
6a8feb216a Add parser rule for hard linebreaks 2013-12-14 17:05:57 +00:00
Jermolene
b1e7ba29f1 Improved static content for tw5.com 2013-12-14 15:17:34 +00:00
Jermolene
79c8935aef Style cleanups for MOTW
@davidjade I assume these changes are all safe from the BHO’s point of
view? Many thanks
2013-12-14 09:53:39 +00:00
Jermolene
8496337d30 Remove "coreversion" metadata from plugins
There’s no support for it yet, so it’s confusing.
2013-12-14 09:49:39 +00:00
Jermolene
2126ce1d17 Docs update 2013-12-14 09:46:10 +00:00
Jermolene
3f06384516 Adjusted plugin encoding so that the JSON text no longer duplicates the fields 2013-12-14 09:46:02 +00:00
Jermolene
053e09af6e Docs update 2013-12-14 09:25:11 +00:00
David Jade
0984e9322f Revised fix for IE drag/drop issue #252
Also improve browser drag/drop inter-op a tiny bit
2013-12-13 03:12:56 -08:00
Jermolene
c190b0f1ea Docs updates 2013-12-13 10:16:37 +00:00
David Jade
80e0714c0d Fix for IE drag/drop issue #252 2013-12-12 17:32:06 -08:00
Jermolene
819843e4b0 Docs updates 2013-12-12 22:38:19 +00:00
Jermolene
6386e60896 Docs for the radio widget 2013-12-12 20:37:05 +00:00
Jermolene
7c9b920e26 More style adjustments 2013-12-12 20:36:54 +00:00
Jermolene
ae4a2b58ed Complete renaming the radio widget 2013-12-12 19:49:43 +00:00
Jermolene
c73a7af95b Remove file mistakenly included in previous commit 2013-12-12 19:49:29 +00:00
Jermolene
1420aa2f58 Complete renamign the 'fieldradio' widget to 'radio' 2013-12-12 19:41:40 +00:00
Jermolene
0814f3623d Rename 'fieldradio' widget to just 'radio'
We’ve already got two widgets starting “field…”, and “radio” is more
consistent with the existing “checkbox” widget.
2013-12-12 19:40:27 +00:00
Jermolene
382d7e4449 Coding style consistency 2013-12-12 19:39:02 +00:00
Jermolene
e2cd611e45 Typo correction 2013-12-12 19:37:57 +00:00
Jermolene
bb03bb942f Merge branch 'fieldradio' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-fieldradio 2013-12-12 19:23:39 +00:00
Jermolene
fd996bad20 Fix problem with edit-text widget gaining class="undefined"
Fixes #269
2013-12-12 18:52:51 +00:00
Jermolene
3f3cac12ba Docs update
@davidjade - is what I’ve said about the FSO saver reasonable? I’m
conscious that it doesn’t really explain why TiddlyIE is better.
2013-12-12 18:45:20 +00:00
Jeremy Ruston
761b66028d Merge pull request #276 from davidjade/master
Added TiddlyIE and FSO saver modules
2013-12-12 10:18:30 -08:00
Jermolene
7e151a98da Docs update
Fixes #247

@giffmex - I appreciate that I haven’t fixed everything you mentioned
2013-12-12 18:16:16 +00:00
Jeremy Ruston
e537457d4b Merge pull request #265 from shakerlxxv/sign-cla
sign contributor license agreement
2013-12-12 09:19:35 -08:00
Jermolene
e686d62400 Docs updates 2013-12-12 17:19:17 +00:00
Jermolene
ae6d1b1685 Major refactoring of the navigator widget
Cleans things up, and hopefully fixes #267
2013-12-12 15:17:12 +00:00
Jermolene
49b3165fbd Fix occasional crash from trying to save a tiddler after it has been deleted 2013-12-12 15:16:44 +00:00
Jermolene
6a21965cee Docs updates 2013-12-12 10:38:00 +00:00
Jermolene
b9faadbbc9 Docs updates 2013-12-12 09:48:08 +00:00
Jermolene
c610161455 Adjust link colour
It was a bit too bright
2013-12-12 09:47:58 +00:00
Jermolene
6dbd178378 Merge branch 'issue_270' of https://github.com/Skeeve/TiddlyWiki5 into Skeeve-issue_270 2013-12-11 22:19:19 +00:00
Jermolene
77bca22d42 Docs update 2013-12-11 22:14:40 +00:00
Jermolene
9f058925f7 Fix problem with deleting tiddlers with the filesystemadaptor
Fixes #266
2013-12-11 22:02:34 +00:00
Jermolene
1b75242345 Fix up caller of wiki.forEachTiddler() 2013-12-11 22:01:20 +00:00
Jermolene
6298c7aa43 Refactor wiki.forEachTiddler() and wiki.getTiddlers() to take an options parameter 2013-12-11 22:01:02 +00:00
Stephan Hradek
853cca906c allowing variable number of arguments for non-argument macros 2013-12-11 22:59:52 +01:00
David Jade
cffe9375b2 Added TiddlyIE and FSO saver modules
Modified tiddlywiki5 template to support TiddlyIE and HTAs
Added empty.hta creation to bld scripts
Added TiddlyIE topics
2013-12-11 12:45:35 -08:00
Jermolene
b8897f86fb Ensure that tiddler manipulations affect the history
Previously edit tiddler etc wouldn’t actually navigate to the new
tiddler
2013-12-11 16:30:25 +00:00
Jermolene
409311b61e Docs update 2013-12-11 16:06:58 +00:00
Jermolene
d11cda4854 Rearrange control panel
Introduce version number too
2013-12-11 16:06:52 +00:00
Jermolene
6a71b399b0 Fix problem with transcluding non-string fields
Transcluding date or list fields (like `modified` or `tags`) was
crashing.
2013-12-11 15:51:32 +00:00
Jermolene
2e188a48f4 Docs update 2013-12-11 15:50:58 +00:00
Jermolene
b4733414e5 Improve upgrading instructions
Thanks @giffmex
2013-12-11 14:31:57 +00:00
Jermolene
67072371a0 Get rid of extraneous logging on filesystemadaptor 2013-12-11 13:13:48 +00:00
Jermolene
a9c209c62e Docs updates to get ready for beta
There will be quite a lot more of these updates…
2013-12-11 13:13:37 +00:00
Jermolene
bc84df1707 Formatting for definition lists 2013-12-11 13:12:56 +00:00
Jermolene
062822d45c Fix file system behaviour for loading new tiddlers
We don’t need to load tiddlers because they will all have been loaded
during bootup, or been created through the file system adaptor.
2013-12-11 11:45:15 +00:00
Jermolene
2e0e8a879f Docs update 2013-12-11 07:57:19 +00:00
Jermolene
2ffcbb76eb Remove modifier and creator fields from tiddlers in tw5.com
Keeps things tidier
2013-12-11 07:57:12 +00:00
Jermolene
50e1727ef7 Stop falling back to anonymous username
The `serve` command used to fallback the username parameter to
“ANONYMOUS” if it was not provided. Better is just to not set a
username if it is not provided; newly created tiddlers won’t get a
‘modifier’ field at all.
2013-12-11 07:45:36 +00:00
Jermolene
7a99fb1250 Update template used for deployment to TiddlyWeb
Missed from 5.0.0-alpha.16
2013-12-11 07:37:08 +00:00
Brian Shaver
e6e47ca83d sign contributor license agreement 2013-12-07 18:23:28 -05:00
Jermolene
489b40314b Docs update 2013-12-07 08:59:38 +00:00
Jermolene
14cf9ad24a Fix typo preventing page controls from being reordered 2013-12-07 08:59:32 +00:00
Jermolene
428e27d4bf Prepare version number for 5.0.2 release 2013-12-07 08:59:16 +00:00
Jermolene
0edf46dee1 Update 5.0.1-alpha release date 2013-12-06 17:54:25 +00:00
Jermolene
c38cd500f6 Readme update 2013-12-06 17:52:50 +00:00
Jermolene
3da825c6e1 Version number update for 5.0.1-alpha 2013-12-06 17:50:39 +00:00
Jermolene
559f9da9b4 Version number update for 5.0.1 2013-12-06 17:33:38 +00:00
Jermolene
8f6e3c641d More docs updates 2013-12-06 17:29:46 +00:00
Jermolene
aae8587660 Docs updates 2013-12-06 17:09:30 +00:00
Jermolene
5bb7ee2f88 Docs updates 2013-12-06 16:24:11 +00:00
Jeremy Ruston
0a93edb1b6 Merge pull request #249 from Skeeve/quotes
added quote rules
2013-12-06 01:16:39 -08:00
Stephan Hradek
b0ff8bee6a as requested - quote.js removed because of quotelist - do not forget to add some css classes 2013-12-06 09:57:56 +01:00
Jermolene
48f8046cf5 Fixed problem with cancelling editing the tiddler $:/StoryList 2013-12-06 08:45:24 +00:00
Jermolene
d4e6516a61 Improved upgrading docs 2013-12-06 07:12:35 +00:00
Jermolene
1fddcf075f Big docs update
Finally sorting out the wikitext documentation
2013-12-05 16:21:10 +00:00
Jermolene
d64c37c3b7 Block quote styles 2013-12-05 16:20:37 +00:00
Jermolene
ffcf2bfaac Missing comma
Omitted from 4d4a0e01b4
2013-12-05 16:20:22 +00:00
Jeremy Ruston
4d4a0e01b4 Merge pull request #258 from Skeeve/quotelist
inserted > into lists
2013-12-05 07:16:05 -08:00
Jermolene
b37a139aa7 Typo that prevented edit widget tiddler attribute from working 2013-12-05 10:37:40 +00:00
Jermolene
17277cf8fd Docs update 2013-12-05 10:37:23 +00:00
Stephan Hradek
374743883d inserted > into lists 2013-12-05 00:31:55 +01:00
Stephan Hradek
d739b6939a added core/modules/widgets/fieldradio.js 2013-12-05 00:15:06 +01:00
Jermolene
49ade66540 Extend navigator widget to allow target tiddler to be specified for certain events
Now the edit tiddler, delete tiddler, save tiddler and cancel tiddler
events can all be passed the tiddler title as the message param.
2013-12-04 13:09:26 +00:00
Jermolene
09e14dd8ad Docs updates 2013-12-03 18:05:45 +00:00
Jermolene
c30392c0c5 Docs update 2013-12-03 11:12:57 +00:00
Jermolene
fa8cc1c512 Update docs 2013-12-03 10:11:03 +00:00
Jermolene
21f795b542 Include the release date in the release history 2013-12-03 10:10:56 +00:00
Jermolene
1363d24e86 Retrospectively add a release date to earlier release notes 2013-12-03 10:10:41 +00:00
Jermolene
4cffa58df3 Fix viewing of date fields 2013-12-03 10:09:58 +00:00
Jermolene
7d0b930335 Update verbump script to include version number in commit message
Easier to find.
2013-12-03 10:09:37 +00:00
Jermolene
f3954d374d Add error reporting for the syncer module
Things were failing silently.
2013-12-03 09:35:02 +00:00
Jermolene
16170ce504 Blank out Google Analytics account information from clientserver edition
This also fixes a recently introduced problem: when I removed the last
`.tid` file from the `editions/clientserver/tiddlers/` directory, git
promptly stopped recording the directory in commits, and so newly
downloaded copies of the repo lacked the directory. That caused the
filesystemadaptor to fail to save newly created tiddlers.
2013-12-03 09:20:09 +00:00
Jermolene
9dcbdb5297 Move the docs to the right place 2013-12-03 09:17:59 +00:00
Jermolene
ecdfce1985 Fix tiddler layout on narrow viewports 2013-12-03 09:10:07 +00:00
Jermolene
88e0bd3251 Docs update 2013-12-03 09:05:53 +00:00
Jermolene
5ccd4988aa Update TiddlyDocs documentation 2013-12-02 20:30:38 +00:00
Jermolene
1e99f6cb67 Updated docs 2013-12-02 14:36:38 +00:00
Jermolene
41fc06ab4d Docs updates 2013-12-02 09:59:44 +00:00
Jermolene
b149ab47f4 Refactor importing to to use new wiki.importTiddler method 2013-12-02 09:59:38 +00:00
Jermolene
1b99dbb677 Add wiki.importTiddler()
Exactly like addTiddler except that it rejects plugins that are older
than the currently installed version.
2013-12-02 09:59:17 +00:00
Jermolene
c4814cec91 Include plugin version numbers in control panel 2013-12-02 09:58:44 +00:00
Jermolene
698efb66bb Update the version number preparatory to 5.0.1-alpha
The “prerelease” string will be changed to “alpha” when 5.0.1 is
released.
2013-12-02 09:58:33 +00:00
Jermolene
7a4abba9fd Ensure system tiddlers are imported
We no longer generate a separate “systemArea” for system tiddlers but
we still need to import it for older wikis
2013-12-02 09:57:54 +00:00
Jermolene
026a27c1ab Split out the parsing of semantic version strings 2013-12-02 09:57:19 +00:00
Jermolene
34ae1387a5 Expand the theme switcher in the control panel 2013-12-01 21:57:19 +00:00
Stephan Hradek
62b9fb336b fixed a small bug related to closing wiki-tag - no really 2013-12-01 22:05:49 +01:00
Stephan Hradek
8ed364ed72 fixed a small bug related to closing wiki-tag 2013-12-01 22:01:21 +01:00
Jermolene
b1aadc7e94 Docs update 2013-12-01 20:52:34 +00:00
Jermolene
eb41ca578d Fallback to a list of default themes
Avoids the situation where an empty wiki uses the vanilla theme unless
you explicitly apply a different theme.
2013-12-01 20:28:56 +00:00
Stephan Hradek
2ec58f7fa2 added quote rules 2013-12-01 21:21:15 +01:00
Jermolene
6be7e2c30e Resolve conflict 2013-12-01 20:11:40 +00:00
Jeremy Ruston
7ebb8702b2 Merge pull request #248 from davidjade/master
sign cla
2013-12-01 12:02:09 -08:00
David Jade
eac07fb6c3 sign cla 2013-12-01 11:46:53 -08:00
Jermolene
3a07cd4c55 Docs update
Added a link to @giffmex’s Bible study notebook, and updated the link
to Ton’s guide to building top menus and toolbars.
2013-12-01 13:35:59 +00:00
Jermolene
a12310f225 Fixed problem with rearranging $:/tags/PageControls/ 2013-12-01 13:25:48 +00:00
Stephan Hradek
593503fe09 sign contributor license agreement 2013-11-30 22:31:00 +01:00
Jermolene
7f4dffca77 Clarify location of license files 2013-11-30 16:25:15 +00:00
Jermolene
f9f9c96ca1 Update version number and ribbon colour for alpha-18 2013-11-30 15:23:43 +00:00
Jermolene
28d6627632 Version update 2013-11-30 15:19:11 +00:00
Jermolene
91f10af53f Fixed small but important bug that prevented downloading an empty wiki 2013-11-30 15:17:42 +00:00
Jermolene
ba796c3f23 Update version number and ribbon colour ready for the next release 2013-11-30 13:58:03 +00:00
Jermolene
64ff422c80 Version update 2013-11-30 13:25:26 +00:00
Jermolene
6c6f53a69f Add docs about the release process
Mainly for me, beause I keep getting it wrong
2013-11-30 13:22:03 +00:00
Jermolene
7fcf52543f Make sure tags are in alphabetical order in the view template
Fixes #242
2013-11-30 13:15:17 +00:00
Jermolene
933c61e611 Docs updates 2013-11-30 10:56:13 +00:00
Jermolene
da613f7dee Change link for ribbon to ReleaseHistory 2013-11-30 10:56:05 +00:00
Jermolene
2db3043d6e Tweak appearance of tags editor
Making it a bit more like http://aehlke.github.io/tag-it/
2013-11-30 10:55:45 +00:00
Jermolene
208c64aa9d Slightly improve the dislocated formatting of the static banner for tw5.com 2013-11-29 22:44:16 +00:00
Jermolene
2c9152fa56 Update template name for saving empty.html 2013-11-29 22:36:50 +00:00
Jermolene
3da17c8e04 Lotsa docs updates 2013-11-29 17:20:10 +00:00
Jermolene
fe19909034 Include the nighttime theme in tw5.com 2013-11-29 17:19:49 +00:00
Jermolene
6ee0e07036 Add a class to the button icon SVGs
So that we can default their size to 1em
2013-11-29 17:11:48 +00:00
Jermolene
8a2b3bc831 Lotsa docs updates 2013-11-29 12:26:48 +00:00
Jermolene
7baf8431a4 Refactor the download buttons into reusable snippets 2013-11-29 09:12:23 +00:00
Jermolene
4352e81b98 More docs updates 2013-11-28 18:17:47 +00:00
Jermolene
a651c2cb72 Remove text input showing static URL preview
It wasn’t working due to the recent change whereby attributes set as
macros are no longer wikified. Thus, the widget invocation inside the
macro outerMakeLink isn’t executed.

To get it working again we’ll need a way to specify a macro as an
attribute and force it to be wikified.
2013-11-28 17:32:46 +00:00
Jermolene
2261fd4b84 Merge the dev material back into the main tw5.com wiki
It was getting a pain to manage the content in separate places, and I
suspect confusing for end users.

I think the best time to move the dev content out is when we’ve
established the community wiki for TW5, which is a much more natural
home for it.

In the meantime, a feature that I’m interested in exploring is the
ability to hide tiddlers from the UI based on tag. Then the tw5.com
wiki could disable all tiddlers tagged ‘dev’ until explicitly
overridden by the user.
2013-11-28 17:12:18 +00:00
Jermolene
717f959c04 Docs update 2013-11-28 16:57:00 +00:00
Jermolene
3e1899ee17 Forgot to add the vanilla theme to existing editions 2013-11-28 16:42:38 +00:00
Jermolene
7d12d89a0a Added primitive support for basic authentication
Note that the password will be passed over HTTP in plain text.
2013-11-28 14:03:08 +00:00
Jermolene
c0a6e94b21 Hash the state qualifier to make it shorter
We were having problems with TW5 generating filepaths that were longer
than Windows likes.

Fixes #240
2013-11-28 10:53:37 +00:00
Jermolene
1e14ba48f9 Docs updates 2013-11-28 10:36:48 +00:00
Jermolene
b8f15feca4 Force newly created field names to be lowercase
Fixes #239
2013-11-28 10:35:16 +00:00
Jermolene
b77aa3908f Better styles for the message box 2013-11-28 07:41:28 +00:00
Jermolene
2c1ed36a91 Message box styling 2013-11-27 21:30:11 +00:00
Jermolene
5b89eca5e9 Fix up filenames
Left overs from the Great Refactoring
2013-11-27 21:15:35 +00:00
Jermolene
0956ae10a0 Add support for downloading files
We were re-using the `tw-save-wiki` message both for saving the current
wiki and downloading a new wiki. Now we’ll use the separate
`tw-download-file` message for downloading.

Fixes #236
2013-11-27 20:51:08 +00:00
Jermolene
7175f1cbf1 Split a basic Vanilla theme out of Snow White
And add a new Night-Time theme for the /dev wiki.

The idea is that the Vanilla theme will make a more convenient base for
retheming.
2013-11-27 12:38:03 +00:00
Jermolene
384ab80c42 Fix broken tiddler control icon colours 2013-11-27 12:30:22 +00:00
Jermolene
f534d98e8b Move developer docs into their own separate wiki
Will be served at http://five.tiddlywiki.com/dev/
2013-11-27 10:27:57 +00:00
Jermolene
3a9dc1a36d Add a link to BramChen's translation of TW5 2013-11-27 10:22:11 +00:00
Jermolene
f9ef7b783b Simplify production of empty.html
Move over to using the empty.html generated by editions/tw5.com, rather
than editions/empty
2013-11-26 23:51:09 +00:00
Jeremy Ruston
65a2ae8428 Merge pull request #234 from asampal/master
Sync bld.cmd with latest bld.sh
2013-11-26 15:46:41 -08:00
Jermolene
5ce112d431 Docs updates 2013-11-26 22:47:27 +00:00
Jermolene
9d60cb50ed Make sure the github ribbon is behind any notifications 2013-11-26 22:46:36 +00:00
Jermolene
584043deee Add a notification when starting to save with the upload plugin 2013-11-26 22:46:20 +00:00
Adrian Sampaleanu
c4a85e3b82 Sync bld.cmd with latest bld.sh
Synced bld.cmd to bld.sh, added some mostly cosmetic changes in the command scripts to make them even more 1-to-1 with the .sh scripts.
2013-11-26 16:43:00 -05:00
Jermolene
1b54313615 Add SVG images to the type dropdown 2013-11-26 19:42:44 +00:00
Jermolene
42fce1929c Improve save notifications for TiddlySpot 2013-11-26 12:50:40 +00:00
Jermolene
d96f85ac83 Add a link to the backup URL to the TiddlySpot control panel tab 2013-11-26 12:30:11 +00:00
Jermolene
e3c770ca4a Docs updates 2013-11-26 10:48:23 +00:00
Jermolene
d7454b100a Big green download buttons 2013-11-26 08:42:03 +00:00
Jermolene
ee9cf60aa2 Add screenshot of tiddlywiki classic 2013-11-26 08:30:04 +00:00
Jermolene
3a446dc240 Build an experimental empty.html from the tw5.com edition 2013-11-25 23:15:24 +00:00
Jermolene
8cf2b06e53 Move Google Analytics integration into a proper plugin 2013-11-25 23:14:12 +00:00
Jeremy Ruston
0184375ad1 Merge pull request #231 from pmario/fix-media-queries
adjust media query to remove box-shadow for small screens. thanks @pmario
2013-11-25 14:19:06 -08:00
Jermolene
b805633dc9 Reorganise the main file saving templates
We’re introducing a mechanism that allows us to decide which tiddlers
get saved. Using `$:/core/save/all` gives all tiddlers, as before.
Using `$:/core/save/empty` gives an empty wiki. Saving an empty wiki
from tw5.com isn’t the same as the empty wiki cooked from
editions/empty because the two editions have different plugins and
other system tiddlers.
2013-11-25 21:16:27 +00:00
Mario Pietsch
638a774fc9 adjust media query to remove box-shadow for small screens. fix some @media indentations 2013-11-25 14:58:49 +01:00
Jermolene
b33a3293fe Rejig the main save template to get rid of the separate system tiddler area
It dates from an ancient version of TW5, and is really redundant now.
It also meant that system tiddlers were not encrypted, which seems
confusing for end users.
2013-11-24 20:40:10 +00:00
Jermolene
802fe9beae Add [is[tiddler]] filter operator
For selecting all non-shadow tiddlers, whether or not they are system
tiddlers
2013-11-24 20:38:58 +00:00
Jermolene
78f56ba875 Stop generating static content when we're saving an encrypted wiki 2013-11-24 20:28:27 +00:00
Jermolene
c29975f6b3 Remove special provision for jQuery
This dates from an ancient version of TW5 which had a dependency on
jQuery. Now we’d install jQuery as an ordinary tiddler module, not a
library module.
2013-11-24 20:16:44 +00:00
Jermolene
ce03690989 Fix problem with tag-configurable item lists not being able to interleave shadow and non-shadow 2013-11-24 19:38:32 +00:00
Jermolene
b1c6f2d1c3 Docs updates 2013-11-22 20:02:54 +00:00
Jermolene
f380d4b27d Change macro attributes to not wikify their content
One consequence of wikifying macro attributes before use was that we
couldn’t have tiddler titles with wikitext syntax in, which was
definitely a problem.
2013-11-22 20:02:44 +00:00
Jermolene
f19da7af8c Add StephanHradek's new tw5magick site 2013-11-21 17:32:44 +00:00
Jermolene
0013f3a31c Sort out the docs for the tabs macro 2013-11-21 17:32:24 +00:00
Jermolene
a45f64e738 Trap filter syntax errors
Now a syntax error on a filter just causes the filter to return the
error message as it’s single result.

Fixes #189
2013-11-21 08:52:41 +00:00
Jeremy Ruston
a29c0dfce9 Merge pull request #226 from asampal/master
Style changes in user visible text node -> Node
2013-11-20 14:53:04 -08:00
Jermolene
c4e6c91986 Fix problem with dragging images within TW5
Dragging an image within the same TW5 window was causing a crash
2013-11-20 22:52:48 +00:00
Adrian Sampaleanu
03a81bd8b1 Style changes in user visible text node -> Node
Went through all user visible text and changed lowercase node to Node as per Node.js site.
2013-11-20 17:35:36 -05:00
Jermolene
6945283fec Docs updates 2013-11-20 21:48:17 +00:00
Jermolene
113b48d046 Merge branch 'master' of https://github.com/asampal/TiddlyWiki5 into asampal-master 2013-11-20 21:46:38 +00:00
Jermolene
cc9c6e4f42 Ensure that we don't overwrite the modified/modifier fields of imported tiddlers
Fixes #225
2013-11-20 20:49:32 +00:00
Adrian Sampaleanu
97feef8909 Added Windows specific build scripts.
Added equivalent scripts for all .sh files and modified appropriate tiddlers to generate updated readme.md for the GitHub site.
2013-11-19 19:57:05 -05:00
Jermolene
db4f38c75b Docs update 2013-11-19 20:19:18 +00:00
Jermolene
99852c3cab Added a "Download" tiddler 2013-11-19 19:59:02 +00:00
Jermolene
b6cb879ad1 Use the github ribbon on tw5.com to advertise the version number 2013-11-19 19:44:53 +00:00
Jermolene
f9fbbc12a6 Ensure github-fork-ribbon styles tiddlylinks
Otherwise CSS specificity means that the TW core styles win
2013-11-19 19:44:40 +00:00
Jermolene
59bb3c66d6 Add a github ribbon to tw5.com 2013-11-19 14:23:42 +00:00
Jermolene
dc9ec22156 A plugin for adding github ribbons 2013-11-19 14:23:30 +00:00
Jermolene
b8875e126f Refactor page template to be tag driven 2013-11-19 14:12:31 +00:00
Jermolene
26ed978cf9 Docs update 2013-11-19 14:12:21 +00:00
Jermolene
bd511cb9f3 Docs updates 2013-11-19 13:22:35 +00:00
Jermolene
20ea6433e6 Add data tiddler types 2013-11-19 13:22:27 +00:00
Jermolene
16444e023a Refactor control panel to add "Saving" tab
Currently just hardwired to the options for TiddlySpot, but will in due
course be driven by the loaded saver modules.
2013-11-19 13:21:45 +00:00
Jermolene
9c579e3596 Update version number to 5.0.0-alpha.16-prerelease 2013-11-19 12:43:12 +00:00
Jermolene
4710431e6b Readme update 2013-11-19 12:22:58 +00:00
Jermolene
f1e909278c Version update 2013-11-19 12:21:12 +00:00
Jermolene
8d3613e8b4 Docs updates 2013-11-19 12:21:08 +00:00
Jermolene
3fd3e408fc Adopt a brighter link colour 2013-11-19 12:17:31 +00:00
Jermolene
a2fcc59648 Docs update 2013-11-19 12:17:22 +00:00
Jermolene
223e9c4747 FIx margins and spacing 2013-11-19 12:17:16 +00:00
Jermolene
b63f7a7416 Fix missing seconds in serialised date fields 2013-11-19 12:14:37 +00:00
Jermolene
905d3e6e1e Docs update 2013-11-18 09:01:06 +00:00
Jermolene
90a0eca2f5 Add dropdown interface for setting the type of a tiddler 2013-11-18 09:00:25 +00:00
Jermolene
7658789971 Style tweaks for the edit template 2013-11-18 09:00:00 +00:00
Jermolene
9257c8205f More information about Jermolene 2013-11-18 08:58:23 +00:00
Jermolene
b117f74666 Make the toolbars be tag driven 2013-11-17 21:53:39 +00:00
Jermolene
3b35d7dfe4 Fixed problem with greedy regexp for macrocalls
It was preventing this from working:

```
<<macro>><<bacrp>><<sdf>><<qweqwe>>
```
2013-11-17 21:53:12 +00:00
Jermolene
29c0f7156b Fix overlooked typo
Ouch.
2013-11-16 22:50:10 +00:00
Jermolene
0d2ed8f112 More release docs 2013-11-16 17:51:20 +00:00
Jermolene
99a6b1bcc0 More TiddlyWeb docs 2013-11-15 23:02:30 +00:00
Jermolene
da4cdf2d3b Refactor edit template to be driven by $:/tags/EditTemplate tag 2013-11-15 22:55:32 +00:00
Jermolene
26cc62cff7 Fix problem with tiddler info panel in Firefox
Fixes #104
2013-11-15 22:46:17 +00:00
Jermolene
b1992714ed Docs update 2013-11-15 22:09:42 +00:00
Jermolene
ecca7a3ea9 TiddlyWeb control panel update 2013-11-15 22:09:06 +00:00
Jermolene
4b84d9bfe5 Update to pre-release version number
I should have done this immediately after the alpha.14 release.
2013-11-15 22:08:57 +00:00
Jermolene
92b1932fcf Update docs for TiddlyWeb 2013-11-15 22:08:23 +00:00
Jermolene
9a6e404215 Fix modules list in the Internal tab of Control Panel 2013-11-15 22:08:16 +00:00
Jermolene
939ad11eae Rename the 'setvariable' widget to 'set'
Sleeker.
2013-11-15 18:31:39 +00:00
Jermolene
6785c49734 Better styling for embedded PDFs 2013-11-15 18:30:57 +00:00
Jermolene
45c51481de Improve performance of tag handling with some caching 2013-11-13 23:33:32 +00:00
Jermolene
874bd7b2b8 Tweaks tests
This was the only place we were using the `variables` option to the
widget constructor.
2013-11-13 21:26:13 +00:00
Jermolene
fc6dd83f2f Use prototypal inheritance to speed up the inheritance of widget variables
Now we reuse the prototype mechanism to let javascript do the work of
searching up the parent chain.
2013-11-13 21:25:45 +00:00
Jermolene
a8129874fb Docs update 2013-11-13 20:21:28 +00:00
Jermolene
c7d5905242 Fix view format=date so that it doesn't crash on empty fields 2013-11-13 19:41:54 +00:00
Jermolene
02d3620d93 Update the tiddler info panel to use the new tw-popup class
This fixes the problem with the inability to click on items within the
tiddler info panel (including the static URL)
2013-11-12 22:03:20 +00:00
Jermolene
b304e3fe40 Update the reveal widget to set the tw-popup class 2013-11-12 22:02:43 +00:00
Jermolene
06a66cf24e Improve popup dismissal
Now we ignore clicks if they come from an element that has an ancestor
with the class `tw-popup`
2013-11-12 22:02:26 +00:00
Jermolene
145e3ece78 Fix $tw.utils.hasClass() to work even if the element doesn't have a className property 2013-11-12 22:01:31 +00:00
Jermolene
24e361da77 Removed inadvertent alert() 2013-11-12 20:58:54 +00:00
Jermolene
1b9614eb9d Docs update 2013-11-12 20:54:28 +00:00
Jermolene
791033d751 First pass at a saver for IE10 and above
It's not great, sadly. Clicking save in the browser pulls up an
unobtrusive bar at the bottom of the browser window where you can click
"save". You then get a new copy of your wiki in the downloads folder.
2013-11-12 20:49:00 +00:00
Jermolene
9748709759 Fix up prematutely committed static link tab for tw5.com 2013-11-12 20:29:53 +00:00
Jermolene
b885743efe Fix typo 2013-11-12 20:29:22 +00:00
Jermolene
8ec92405fd Add urlencoded and doubleurlencoded formats to the view widget 2013-11-12 20:29:14 +00:00
Jermolene
e68ab95ecb For tw5.com add a link in the info panel to the static tiddler representation 2013-11-12 19:52:57 +00:00
Jermolene
d2dbc73448 Correct typo 2013-11-12 19:52:25 +00:00
Jermolene
4a5a8dd773 Fix the execution context for widget attributes specified as macros
We need to ensure that variables in the tree up to this point are
accessible when we render the macro text.
2013-11-12 19:52:17 +00:00
Jermolene
439dfcb172 Added a link to Bob Robison's TW5 theme 2013-11-12 15:34:14 +00:00
Jermolene
f6a4ea6b0f Fixed typo from d64590a12b 2013-11-11 23:44:55 +00:00
Jeremy Ruston
8681e0228d Merge pull request #212 from grayeul/closeAllOthers
Add support for close-others
2013-11-11 14:46:05 -08:00
Jeremy Ruston
c1123cb3e9 Merge pull request #214 from grayeul/sign-cla2
CLA signature from @grayeul
2013-11-11 14:45:12 -08:00
Jermolene
d64590a12b Fixed problem with target fields/index being erroneously applied to template
See here for discussion:

https://groups.google.com/d/msg/TiddlyWiki/D3MBNhjaT3E/ph0ZuAhuPFMJ
2013-11-11 22:29:38 +00:00
Jermolene
e274a0c7d1 Make sure we use state tiddler titles in the $:/state namespace 2013-11-11 15:27:12 +00:00
Jermolene
51fe1e20e8 Make sure that searching for the empty string returns all available tiddlers
Makes sense because every tiddler contains the empty string. This
restores the functionality of the tag editor dropdown.
2013-11-11 15:26:41 +00:00
Grayeul
9c4ffae1b3 Remove close-others-button from core/images 2013-11-11 07:52:04 -06:00
Grayeul
3d0c6cf41e Fixed missing reference to old CloseAllOthers 2013-11-11 07:48:54 -06:00
Grayeul
3800d3b2b1 Merge branch 'closeAllOthers' of https://github.com/grayeul/TiddlyWiki5 into closeAllOthers
Conflicts:
	core/modules/widgets/navigator.js

merging namechange.
2013-11-11 07:41:22 -06:00
Grayeul
da54236f5a Change names to tw=close-other-tiddlers and handleCloseOtherTiddlersEvent 2013-11-11 07:34:19 -06:00
Grayeul
c930d84d01 Add support for close-all-others 2013-11-11 07:28:29 -06:00
Grayeul
2317f779e9 sign cla 2013-11-11 07:18:58 -06:00
Jermolene
c501e70512 Add new blog post link to docs 2013-11-11 12:42:49 +00:00
Jermolene
8357d90e59 Fix bug caused when creating a tiddler title starting or ending with a space 2013-11-11 08:48:06 +00:00
Grayeul
efef6261b8 Add support for close-all-others 2013-11-10 22:09:52 -06:00
Jermolene
95b7a5d4fe Add host configuration to TiddlyWeb control panel tab 2013-11-10 23:28:03 +00:00
Jermolene
2c55c7ca82 Fix typo 2013-11-10 23:27:44 +00:00
Jermolene
02dda51269 Docs updates 2013-11-10 23:17:10 +00:00
Jermolene
083cb848f2 Version update 2013-11-10 23:15:19 +00:00
Jermolene
254da0b170 Clean up the tools tab 2013-11-10 23:14:23 +00:00
Jermolene
8b0b9eafb8 Simplify the page controls by dropping the drop shadow
Makes the icons less blurry in Retina™ displays
2013-11-10 23:04:41 +00:00
Jermolene
04e2f18ff1 Remove tooltip, classes and styles from transclusion syntax
Now that transclusion doesn't generate any intrinsic elements we don't
have an element to attach the tooltip, classes and styles to.
2013-11-10 22:46:37 +00:00
Jermolene
a4783a2c19 Add a demo control panel page for the Starlight theme
If you open the control panel and then use the tools sidebar to switch
themes to and from Starlight, you'll see this tab dynamically appear
and disappear
2013-11-10 22:45:53 +00:00
Jermolene
8fb6f26729 Make sure we don't try to wikify the names of modules in the module listing 2013-11-10 22:45:11 +00:00
Jermolene
0e7ffa677a Narrow the gap between tabs 2013-11-10 21:53:56 +00:00
Jermolene
a668f09522 More refinements to the control panel
Including adding a TiddlyWeb-specific control panel tab
2013-11-10 21:53:39 +00:00
Jermolene
2598e22422 Spruce up the control panel
Structure things with extensible tabs.
2013-11-10 21:40:03 +00:00
Jermolene
dc6a9c6348 Release note for alpha.14 2013-11-10 19:24:34 +00:00
Jermolene
b1667259f0 Fix default password
The password widget was defaulting to the password "null".
2013-11-10 19:22:10 +00:00
Jermolene
c77b451863 Fixed bug when using checkbox widget to apply a tag to a tiddler that is untagged 2013-11-10 19:21:37 +00:00
Jermolene
9e48460940 Docs update 2013-11-09 19:29:57 +00:00
natecain
5e743262d4 A small refactor and addition to exclude more files
Refactored duplicated `excludeRegExp` into `$tw.boot.excludeRegExp`
  Added NPM's ignore list to ignore more files during node bootstrap
2013-10-13 12:58:10 -04:00
545 changed files with 12067 additions and 6850 deletions

32
2bld.cmd Normal file
View File

@@ -0,0 +1,32 @@
@echo off
rem build TiddlyWiki 2.x
rem create a temporary directory if it doesn't already exist
setlocal enableextensions
mkdir tmp\tw2
setlocal disableextensions
rem Delete any existing content
del /q /s tmp\tw2
echo.
rem Prepare the readme file from the revelant content in the tw5.com wiki
node .\tiddlywiki.js ^
editions\tw5.com ^
--verbose ^
--rendertiddler TiddlyWiki2ReadMe editions\tw2\readme.md text/html ^
|| exit 1
rem cook the TiddlyWiki 2.x.x index file
node .\tiddlywiki.js ^
editions\tw2 ^
--verbose ^
--load editions\tw2\source\tiddlywiki.com\index.html.recipe ^
--rendertiddler $:/core/templates/tiddlywiki2.template.html .\tmp\tw2\index.html text/plain ^
|| exit 1
fc tmp\tw2\index.html editions\tw2\target\prebuilt.html

107
bld.cmd Normal file
View File

@@ -0,0 +1,107 @@
@echo off
rem build TiddlyWiki5 for tiddlywiki.com
rem Set up the build output directory
if "x%TW5_BUILD_OUTPUT%" == "x" (
set TW5_BUILD_OUTPUT=..\jermolene.github.com
)
if not exist %TW5_BUILD_OUTPUT%\nul (
echo A valid TW5_BUILD_OUTPUT environment variable must be set
exit 1
)
echo Using TW5_BUILD_OUTPUT as %TW5_BUILD_OUTPUT%
echo.
rem Create the `static` directories if necessary
setlocal enableextensions
mkdir %TW5_BUILD_OUTPUT%\static
setlocal disableextensions
rem Delete any existing content
del /q /s %TW5_BUILD_OUTPUT%\static
rem The tw5.com wiki
rem index.html: the main file, including content
rem empty.html: the main file, excluding content
rem static.html: the static version of the default tiddlers
node .\tiddlywiki.js ^
.\editions\tw5.com ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\index.html text/plain ^
--savetiddler $:/favicon.ico %TW5_BUILD_OUTPUT%\favicon.ico ^
--rendertiddler ReadMe .\readme.md text/html ^
--rendertiddler ContributingTemplate .\contributing.md text/html ^
--rendertiddler $:/core/copyright.txt .\licenses\copyright.md text/plain ^
--rendertiddler $:/editions/tw5.com/download-empty %TW5_BUILD_OUTPUT%\empty.html text/plain ^
--rendertiddler $:/editions/tw5.com/download-empty %TW5_BUILD_OUTPUT%\empty.hta text/plain ^
--savetiddler $:/green_favicon.ico %TW5_BUILD_OUTPUT%/static/favicon.ico ^
--rendertiddler $:/core/templates/static.template.html %TW5_BUILD_OUTPUT%\static.html text/plain ^
--rendertiddler $:/core/templates/alltiddlers.template.html %TW5_BUILD_OUTPUT%\alltiddlers.html text/plain ^
--rendertiddler $:/core/templates/static.template.css %TW5_BUILD_OUTPUT%\static\static.css text/plain ^
--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html %TW5_BUILD_OUTPUT%\static text/plain ^
|| exit 1
rem encrypted.html: a version of the main file encrypted with the password "password"
node .\tiddlywiki.js ^
.\editions\tw5.com ^
--verbose ^
--password password ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\encrypted.html text/plain ^
|| exit 1
rem tahoelafs.html: empty wiki with plugin for Tahoe-LAFS
node .\tiddlywiki.js ^
.\editions\tahoelafs ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\tahoelafs.html text/plain ^
|| exit 1
rem d3demo.html: wiki to demo d3 plugin
node .\tiddlywiki.js ^
.\editions\d3demo ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\d3demo.html text/plain ^
|| exit 1
rem codemirrordemo.html: wiki to demo codemirror plugin
node .\tiddlywiki.js ^
.\editions\codemirrordemo ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\codemirrordemo.html text/plain ^
|| exit 1
rem markdowndemo.html: wiki to demo markdown plugin
node .\tiddlywiki.js ^
.\editions\markdowndemo ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\markdowndemo.html text/plain ^
|| exit 1
rem highlightdemo.html: wiki to demo highlight plugin
node .\tiddlywiki.js ^
.\editions\highlightdemo ^
--verbose ^
--rendertiddler $:/core/save/all %TW5_BUILD_OUTPUT%\highlightdemo.html text/plain ^
|| exit 1
rem Make the CNAME file that GitHub Pages requires
echo tiddlywiki.com > %TW5_BUILD_OUTPUT%\CNAME
rem Run the test edition to run the Node.js tests and to generate test.html for tests in the browser
.\test.cmd

56
bld.sh
View File

@@ -1,6 +1,6 @@
#!/bin/bash
# build TiddlyWiki5 for five.tiddlywiki.com
# build TiddlyWiki5 for tiddlywiki.com
# Set up the build output directory
@@ -17,9 +17,9 @@ echo "Using TW5_BUILD_OUTPUT as [$TW5_BUILD_OUTPUT]"
# Make the CNAME file that GitHub Pages requires
echo "five.tiddlywiki.com" > $TW5_BUILD_OUTPUT/CNAME
echo "tiddlywiki.com" > $TW5_BUILD_OUTPUT/CNAME
# Create the `static` directory if necessary
# Create the `static` directories if necessary
mkdir -p $TW5_BUILD_OUTPUT/static
@@ -27,71 +27,77 @@ mkdir -p $TW5_BUILD_OUTPUT/static
rm $TW5_BUILD_OUTPUT/static/*
# First,
# readme.md: the readme file for GitHub
# The tw5.com wiki
# index.html: the main file, including content
# empty.html: the main file, excluding content
# static.html: the static version of the default tiddlers
node ./tiddlywiki.js \
./editions/tw5.com \
--verbose \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/index.html text/plain \
--savetiddler $:/favicon.ico $TW5_BUILD_OUTPUT/favicon.ico \
--rendertiddler ReadMe ./readme.md text/html \
--rendertiddler ContributingTemplate ./contributing.md text/html \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/index.html text/plain \
--rendertiddler $:/core/copyright.txt ./licenses/copyright.md text/plain \
--rendertiddler $:/editions/tw5.com/download-empty $TW5_BUILD_OUTPUT/empty.html text/plain \
--rendertiddler $:/editions/tw5.com/download-empty $TW5_BUILD_OUTPUT/empty.hta text/plain \
--savetiddler $:/green_favicon.ico $TW5_BUILD_OUTPUT/static/favicon.ico \
--rendertiddler $:/core/templates/static.template.html $TW5_BUILD_OUTPUT/static.html text/plain \
--rendertiddler $:/core/templates/alltiddlers.template.html $TW5_BUILD_OUTPUT/alltiddlers.html text/plain \
--rendertiddler $:/core/templates/static.template.css $TW5_BUILD_OUTPUT/static/static.css text/plain \
--rendertiddlers [!is[system]] $:/core/templates/static.tiddler.html $TW5_BUILD_OUTPUT/static text/plain \
|| exit 1
# Second, encrypted.html: a version of the main file encrypted with the password "password"
# encrypted.html: a version of the main file encrypted with the password "password"
node ./tiddlywiki.js \
./editions/tw5.com \
--verbose \
--password password \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/encrypted.html text/plain \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/encrypted.html text/plain \
|| exit 1
# Third, empty.html: empty wiki for reuse
node ./tiddlywiki.js \
./editions/empty \
--verbose \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/empty.html text/plain \
|| exit 1
# Fourth, tahoelafs.html: empty wiki with plugin for Tahoe-LAFS
# tahoelafs.html: empty wiki with plugin for Tahoe-LAFS
node ./tiddlywiki.js \
./editions/tahoelafs \
--verbose \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/tahoelafs.html text/plain \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/tahoelafs.html text/plain \
|| exit 1
# Fifth, d3demo.html: wiki to demo d3 plugin
# d3demo.html: wiki to demo d3 plugin
node ./tiddlywiki.js \
./editions/d3demo \
--verbose \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/d3demo.html text/plain \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/d3demo.html text/plain \
|| exit 1
# Sixth, codemirrordemo.html: wiki to demo codemirror plugin
# codemirrordemo.html: wiki to demo codemirror plugin
node ./tiddlywiki.js \
./editions/codemirrordemo \
--verbose \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/codemirrordemo.html text/plain \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/codemirrordemo.html text/plain \
|| exit 1
# Seventh, codemirrordemo.html: wiki to demo codemirror plugin
# markdowndemo.html: wiki to demo markdown plugin
node ./tiddlywiki.js \
./editions/markdowndemo \
--verbose \
--rendertiddler $:/core/templates/tiddlywiki5.template.html $TW5_BUILD_OUTPUT/markdowndemo.html text/plain \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/markdowndemo.html text/plain \
|| exit 1
# Eighth, run the test edition to run the node.js tests and to generate test.html for tests in the browser
# highlightdemo.html: wiki to demo highlight plugin
node ./tiddlywiki.js \
./editions/highlightdemo \
--verbose \
--rendertiddler $:/core/save/all $TW5_BUILD_OUTPUT/highlightdemo.html text/plain \
|| exit 1
# Run the test edition to run the Node.js tests and to generate test.html for tests in the browser
./test.sh

View File

@@ -14,10 +14,10 @@ Error message and password prompt
z-index: 20000;
position: fixed;
text-align: center;
width: 480px;
width: 200px;
top: 4em;
left: 50%;
margin-left: -264px; /* - width/2 - paddingHorz/2 - border */
margin-left: -144px; /* - width/2 - paddingHorz/2 - border */
padding: 16px 16px 16px 16px;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
@@ -29,6 +29,8 @@ Error message and password prompt
text-shadow: 0 1px 0 rgba(0, 0, 0, 0.5);
background-color: rgb(255, 75, 75);
border: 8px solid rgb(255, 0, 0);
width: 480px;
margin-left: -244px; /* - width/2 - paddingHorz/2 - border */
}
.tw-error-form div {
@@ -54,4 +56,9 @@ Error message and password prompt
.tw-password-wrapper h1 {
font-size: 16px;
line-height: 20px;
padding-bottom: 16px;
}
.tw-password-wrapper input {
width: 100%;
}

View File

@@ -38,7 +38,7 @@ $tw.boot = $tw.boot || {};
/////////////////////////// Standard node.js libraries
var fs, path, vm;
if(!$tw.browser) {
if($tw.node) {
fs = require("fs");
path = require("path");
vm = require("vm");
@@ -46,15 +46,6 @@ if(!$tw.browser) {
/////////////////////////// Utility functions
/*
Log a message
*/
$tw.utils.log = function(/* args */) {
if(console !== undefined && console.log !== undefined) {
return Function.apply.call(console.log, console, arguments);
}
};
/*
Check if an object has a property
*/
@@ -207,10 +198,10 @@ $tw.utils.deepDefaults = function(object /*, sourceObjectList */) {
};
/*
Convert "&amp;" to &, "&lt;" to <, "&gt;" to > and "&quot;" to "
Convert "&amp;" to &, "&nbsp;" to nbsp, "&lt;" to <, "&gt;" to > and "&quot;" to "
*/
$tw.utils.htmlDecode = function(s) {
return s.toString().replace(/&lt;/mg,"<").replace(/&gt;/mg,">").replace(/&quot;/mg,"\"").replace(/&amp;/mg,"&");
return s.toString().replace(/&lt;/mg,"<").replace(/&nbsp;/mg,"\x40").replace(/&gt;/mg,">").replace(/&quot;/mg,"\"").replace(/&amp;/mg,"&");
};
/*
@@ -225,17 +216,18 @@ $tw.utils.pad = function(value,length) {
return s;
};
// Convert a date into UTC YYYYMMDDHHMM format
// Convert a date into UTC YYYYMMDDHHMMSSmmm format
$tw.utils.stringifyDate = function(value) {
return value.getUTCFullYear() +
$tw.utils.pad(value.getUTCMonth() + 1) +
$tw.utils.pad(value.getUTCDate()) +
$tw.utils.pad(value.getUTCHours()) +
$tw.utils.pad(value.getUTCMinutes()) +
$tw.utils.pad(value.getUTCSeconds()) +
$tw.utils.pad(value.getUTCMilliseconds(),3);
};
// Parse a date from a UTC YYYYMMDDHHMMSSMMM format string
// Parse a date from a UTC YYYYMMDDHHMMSSmmm format string
$tw.utils.parseDate = function(value) {
if(typeof value === "string") {
return new Date(Date.UTC(parseInt(value.substr(0,4),10),
@@ -245,7 +237,7 @@ $tw.utils.parseDate = function(value) {
parseInt(value.substr(10,2)||"00",10),
parseInt(value.substr(12,2)||"00",10),
parseInt(value.substr(14,3)||"000",10)));
} else if ($tw.utils.isDate(value)) {
} else if($tw.utils.isDate(value)) {
return value;
} else {
return null;
@@ -268,7 +260,7 @@ $tw.utils.stringifyList = function(value) {
// Parse a string array from a bracketted list. For example "OneTiddler [[Another Tiddler]] LastOne"
$tw.utils.parseStringArray = function(value) {
if(typeof value === "string") {
var memberRegExp = /(?:\[\[([^\]]+)\]\])|([^\s]+)/mg,
var memberRegExp = /(?:^|\s)(?:\[\[(.*?)\]\])(?=\s|$)|(\S+)/mg,
results = [],
match;
do {
@@ -281,7 +273,7 @@ $tw.utils.parseStringArray = function(value) {
}
} while(match);
return results;
} else if ($tw.utils.isArray(value)) {
} else if($tw.utils.isArray(value)) {
return value;
} else {
return null;
@@ -343,14 +335,35 @@ $tw.utils.resolvePath = function(sourcepath,rootpath) {
};
/*
Returns true if the `actual` version is greater than or equal to the `required` version. Both are in `x.y.z` format.
Parse a semantic version string into its constituent parts
*/
$tw.utils.checkVersions = function(required,actual) {
var targetVersion = required.split("."),
currVersion = actual.split("."),
diff = [parseInt(targetVersion[0],10) - parseInt(currVersion[0],10),
parseInt(targetVersion[1],10) - parseInt(currVersion[1],10),
parseInt(targetVersion[2],10) - parseInt(currVersion[2],10)];
$tw.utils.parseVersion = function(version) {
var match = /^((\d+)\.(\d+)\.(\d+))(?:-([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?(?:\+([\dA-Za-z\-]+(?:\.[\dA-Za-z\-]+)*))?$/.exec(version);
if(match) {
return {
version: match[1],
major: parseInt(match[2],10),
minor: parseInt(match[3],10),
patch: parseInt(match[4],10),
prerelease: match[5],
build: match[6]
};
} else {
return null;
}
};
/*
Returns true if the version string A is greater than the version string B
*/
$tw.utils.checkVersions = function(versionStringA,versionStringB) {
var versionA = $tw.utils.parseVersion(versionStringA),
versionB = $tw.utils.parseVersion(versionStringB),
diff = [
versionA.major - versionB.major,
versionA.minor - versionB.minor,
versionA.patch - versionB.patch
];
return (diff[0] > 0) ||
(diff[0] === 0 && diff[1] > 0) ||
(diff[0] === 0 && diff[1] === 0 && diff[2] > 0);
@@ -426,11 +439,13 @@ Adds a new password prompt. Options are:
submitText: text to use for submit button (defaults to "Login")
serviceName: text of the human readable service name
noUserName: set true to disable username prompt
canCancel: set true to enable a cancel button (callback called with null)
callback: function to be called on submission with parameter of object {username:,password:}. Callback must return `true` to remove the password prompt
*/
$tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
// Create and add the prompt to the DOM
var submitText = options.submitText || "Login",
var self = this,
submitText = options.submitText || "Login",
dm = $tw.utils.domMaker,
children = [dm("h1",{text: options.serviceName})];
if(!options.noUserName) {
@@ -443,6 +458,19 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
attributes: {type: "password", name: "password", placeholder: "Password"},
"class": "input-small"
}));
if(options.canCancel) {
children.push(dm("button",{
text: "Cancel",
"class": "btn",
eventListeners: [{
name: "click",
handlerFunction: function(event) {
self.removePrompt(promptInfo);
options.callback(null);
}
}]
}));
}
children.push(dm("button",{
attributes: {type: "submit"},
text: submitText,
@@ -470,12 +498,7 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
// Call the callback
if(options.callback(data)) {
// Remove the prompt if the callback returned true
var i = self.passwordPrompts.indexOf(promptInfo);
if(i !== -1) {
self.passwordPrompts.splice(i,1);
promptInfo.form.parentNode.removeChild(promptInfo.form);
self.setWrapperDisplay();
}
self.removePrompt(promptInfo);
} else {
// Clear the password if the callback returned false
$tw.utils.each(form.elements,function(element) {
@@ -498,17 +521,29 @@ $tw.utils.PasswordPrompt.prototype.createPrompt = function(options) {
this.setWrapperDisplay();
};
$tw.utils.PasswordPrompt.prototype.removePrompt = function(promptInfo) {
var i = this.passwordPrompts.indexOf(promptInfo);
if(i !== -1) {
this.passwordPrompts.splice(i,1);
promptInfo.form.parentNode.removeChild(promptInfo.form);
this.setWrapperDisplay();
}
}
/*
Crypto helper object for encrypted content. It maintains the password text in a closure, and provides methods to change
the password, and to encrypt/decrypt a block of text
*/
$tw.utils.Crypto = function() {
var sjcl = $tw.browser ? window.sjcl : require("./sjcl.js"),
password = null,
callSjcl = function(method,inputText) {
currentPassword = null,
callSjcl = function(method,inputText,password) {
password = password || currentPassword;
var outputText;
try {
outputText = sjcl[method](password,inputText);
if(password) {
outputText = sjcl[method](password,inputText);
}
} catch(ex) {
console.log("Crypto error:" + ex);
outputText = null;
@@ -516,22 +551,22 @@ $tw.utils.Crypto = function() {
return outputText;
};
this.setPassword = function(newPassword) {
password = newPassword;
currentPassword = newPassword;
this.updateCryptoStateTiddler();
};
this.updateCryptoStateTiddler = function() {
if($tw.wiki && $tw.wiki.addTiddler) {
$tw.wiki.addTiddler(new $tw.Tiddler({title: "$:/isEncrypted", text: password ? "yes" : "no"}));
$tw.wiki.addTiddler(new $tw.Tiddler({title: "$:/isEncrypted", text: currentPassword ? "yes" : "no"}));
}
};
this.hasPassword = function() {
return !!password;
return !!currentPassword;
}
this.encrypt = function(text) {
return callSjcl("encrypt",text);
this.encrypt = function(text,password) {
return callSjcl("encrypt",text,password);
};
this.decrypt = function(text) {
return callSjcl("decrypt",text);
this.decrypt = function(text,password) {
return callSjcl("decrypt",text,password);
};
};
@@ -554,6 +589,7 @@ $tw.modules.execute = function(moduleName,moduleRoot) {
clearInterval: clearInterval,
setTimeout: setTimeout,
clearTimeout: clearTimeout,
Buffer: $tw.browser ? {} : Buffer,
$tw: $tw,
require: function(title) {
return $tw.modules.execute(title, name);
@@ -756,7 +792,9 @@ $tw.Wiki.prototype.addTiddler = function(tiddler) {
if(!(tiddler instanceof $tw.Tiddler)) {
tiddler = new $tw.Tiddler(tiddler);
}
this.tiddlers[tiddler.fields.title] = tiddler;
if(tiddler.fields.title) {
this.tiddlers[tiddler.fields.title] = tiddler;
}
};
$tw.Wiki.prototype.addTiddlers = function(tiddlers) {
@@ -836,10 +874,12 @@ $tw.Wiki.prototype.unpackPluginTiddlers = function() {
// Extract the constituent tiddlers
$tw.utils.each(pluginInfo.tiddlers,function(constituentTiddler,constituentTitle) {
// Save the tiddler object
self.shadowTiddlers[constituentTitle] = {
source: tiddler.fields.title,
tiddler: new $tw.Tiddler(constituentTiddler,{title: constituentTitle})
};
if(constituentTitle) {
self.shadowTiddlers[constituentTitle] = {
source: tiddler.fields.title,
tiddler: new $tw.Tiddler(constituentTiddler,{title: constituentTitle})
};
}
});
});
};
@@ -888,7 +928,7 @@ $tw.Wiki.prototype.getTiddler = function(title) {
var t = this.tiddlers[title];
if(t instanceof $tw.Tiddler) {
return t;
} else if($tw.utils.hop(this.shadowTiddlers,title)) {
} else if(title !== undefined && $tw.utils.hop(this.shadowTiddlers,title)) {
return this.shadowTiddlers[title].tiddler;
} else {
return undefined;
@@ -1073,7 +1113,7 @@ $tw.modules.define("$:/boot/tiddlerdeserializer/dom","tiddlerdeserializer",{
}
});
$tw.loadTiddlers = function() {
$tw.loadTiddlersBrowser = function() {
// In the browser, we load tiddlers from certain elements
var containerIds = [
"libraryModules",
@@ -1108,6 +1148,12 @@ $tw.boot.decryptEncryptedTiddlers = function(callback) {
callback();
};
}
/////////////////////////// Node definitions
if($tw.node) {
/*
Load the tiddlers contained in a particular file (and optionally extract fields from the accompanying .meta file) returned as {filepath:,type:,tiddlers:[],hasMetaFile:}
*/
@@ -1129,11 +1175,18 @@ $tw.loadTiddlersFromFile = function(filepath,fields) {
return {filepath: filepath, type: type, tiddlers: tiddlers, hasMetaFile: !!metadata};
};
/*
A default set of files for TiddlyWiki to ignore during load.
This matches what NPM ignores, and adds "*.meta" to ignore tiddler
metadata files.
*/
$tw.boot.excludeRegExp = /^\.DS_Store$|^.*\.meta$|^\..*\.swp$|^\._.*$|^\.git$|^\.hg$|^\.lock-wscript$|^\.svn$|^\.wafpickle-.*$|^CVS$|^npm-debug\.log$/;
/*
Load all the tiddlers recursively from a directory, including honouring `tiddlywiki.files` files for drawing in external files. Returns an array of {filepath:,type:,tiddlers: [{..fields...}],hasMetaFile:}. Note that no file information is returned for externally loaded tiddlers, just the `tiddlers` property.
*/
$tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
excludeRegExp = excludeRegExp || /^\.DS_Store$|.meta$/;
excludeRegExp = excludeRegExp || $tw.boot.excludeRegExp;
var tiddlers = [];
if(fs.existsSync(filepath)) {
var stat = fs.statSync(filepath);
@@ -1175,7 +1228,7 @@ $tw.loadTiddlersFromPath = function(filepath,excludeRegExp) {
Load the tiddlers from a plugin folder, and package them up into a proper JSON plugin tiddler
*/
$tw.loadPluginFolder = function(filepath,excludeRegExp) {
excludeRegExp = excludeRegExp || /^\.DS_Store$|.meta$/;
excludeRegExp = excludeRegExp || $tw.boot.excludeRegExp;
var stat, files, pluginInfo, pluginTiddlers = [], f, file, titlePrefix, t;
if(fs.existsSync(filepath)) {
stat = fs.statSync(filepath);
@@ -1196,7 +1249,9 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
// Save the plugin tiddlers into the plugin info
pluginInfo.tiddlers = pluginInfo.tiddlers || {};
for(t=0; t<pluginTiddlers.length; t++) {
pluginInfo.tiddlers[pluginTiddlers[t].title] = pluginTiddlers[t];
if(pluginTiddlers[t].title) {
pluginInfo.tiddlers[pluginTiddlers[t].title] = pluginTiddlers[t];
}
}
}
}
@@ -1209,13 +1264,14 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
var fields = {
title: pluginInfo.title,
type: "application/json",
text: JSON.stringify(pluginInfo,null,4),
text: JSON.stringify({tiddlers: pluginInfo.tiddlers},null,4),
"plugin-priority": pluginInfo["plugin-priority"],
"name": pluginInfo["name"],
"version": pluginInfo["version"],
"thumbnail": pluginInfo["thumbnail"],
"description": pluginInfo["description"],
"plugin-type": pluginInfo["plugin-type"] || "plugin"
"plugin-type": pluginInfo["plugin-type"] || "plugin",
"dependents": $tw.utils.stringifyList(pluginInfo["dependents"] || [])
}
return fields;
} else {
@@ -1223,6 +1279,20 @@ $tw.loadPluginFolder = function(filepath,excludeRegExp) {
}
};
/*
Fallback tiddlywiki.info content
*/
$tw.boot.defaultWikiInfo = {
"plugins": [
"tiddlywiki/tiddlyweb",
"tiddlywiki/filesystem"
],
"themes": [
"tiddlywiki/vanilla",
"tiddlywiki/snowwhite"
]
};
/*
path: path of wiki directory
parentPaths: array of parent paths that we mustn't recurse into
@@ -1230,13 +1300,14 @@ parentPaths: array of parent paths that we mustn't recurse into
$tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
parentPaths = parentPaths || [];
var wikiInfoPath = path.resolve(wikiPath,$tw.config.wikiInfo),
wikiInfo = {},
wikiInfo,
pluginFields;
// Bail if we don't have a wiki info file
if(!fs.existsSync(wikiInfoPath)) {
$tw.utils.error("Missing tiddlywiki.info file at " + wikiPath);
if(fs.existsSync(wikiInfoPath)) {
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
} else {
wikiInfo = $tw.boot.defaultWikiInfo;
}
wikiInfo = JSON.parse(fs.readFileSync(wikiInfoPath,"utf8"));
// Load any parent wikis
if(wikiInfo.includeWikis) {
parentPaths = parentPaths.slice(0);
@@ -1311,7 +1382,7 @@ $tw.loadWikiTiddlers = function(wikiPath,parentPaths) {
return wikiInfo;
};
$tw.loadTiddlers = function() {
$tw.loadTiddlersNode = function() {
// Load the boot tiddlers
$tw.utils.each($tw.loadTiddlersFromPath($tw.boot.bootPath),function(tiddlerFile) {
$tw.wiki.addTiddlers(tiddlerFile.tiddlers);
@@ -1324,12 +1395,17 @@ $tw.loadTiddlers = function() {
}
};
// End of if(!$tw.browser)
// End of if($tw.node)
}
/////////////////////////// Main startup function called once tiddlers have been decrypted
$tw.boot.startup = function() {
/*
Startup TiddlyWiki. Options are:
readBrowserTiddlers: whether to read tiddlers from the HTML file we're executing within; if not, tiddlers are read from the file system with Node.js APIs
*/
$tw.boot.startup = function(options) {
options = options || {};
// Initialise some more $tw properties
$tw.utils.deepDefaults($tw,{
modules: { // Information about each module
@@ -1348,7 +1424,7 @@ $tw.boot.startup = function() {
contentTypeInfo: {} // Map type to {encoding:,extension:}
}
});
if(!$tw.browser) {
if(!options.readBrowserTiddlers) {
// For writable tiddler files, a hashmap of title to {filepath:,type:,hasMetaFile:}
$tw.boot.files = {};
// System paths and filenames
@@ -1367,7 +1443,7 @@ $tw.boot.startup = function() {
$tw.boot.wikiPath = process.cwd();
}
// Read package info
$tw.packageInfo = require("../package");
$tw.packageInfo = require("../package.json");
// Check node version number
if($tw.utils.checkVersions($tw.packageInfo.engines.node.substr(2),process.version.substr(1))) {
$tw.utils.error("TiddlyWiki5 requires node.js version " + $tw.packageInfo.engines.node);
@@ -1388,6 +1464,7 @@ $tw.boot.startup = function() {
$tw.utils.registerFileType("image/png","base64",".png");
$tw.utils.registerFileType("image/gif","base64",".gif");
$tw.utils.registerFileType("image/svg+xml","utf8",".svg");
$tw.utils.registerFileType("image/x-icon","base64",".ico");
$tw.utils.registerFileType("application/font-woff","base64",".woff");
// Create the wiki store for the app
$tw.wiki = new $tw.Wiki();
@@ -1397,7 +1474,11 @@ $tw.boot.startup = function() {
$tw.Wiki.tiddlerDeserializerModules = {};
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
// Load tiddlers
$tw.loadTiddlers();
if(options.readBrowserTiddlers) {
$tw.loadTiddlersBrowser();
} else {
$tw.loadTiddlersNode();
}
// Unpack plugin tiddlers
$tw.wiki.registerPluginTiddlers("plugin");
$tw.wiki.unpackPluginTiddlers();
@@ -1406,7 +1487,9 @@ $tw.boot.startup = function() {
// And any modules within plugins
$tw.wiki.defineShadowModules();
// Make sure the crypto state tiddler is up to date
$tw.crypto.updateCryptoStateTiddler();
if($tw.crypto) {
$tw.crypto.updateCryptoStateTiddler();
}
// Run any startup modules
$tw.modules.forEachModuleOfType("startup",function(title,module) {
if(module.startup) {
@@ -1427,13 +1510,15 @@ $tw.boot.boot = function() {
// Preload any encrypted tiddlers
$tw.boot.decryptEncryptedTiddlers(function() {
// Startup
$tw.boot.startup();
$tw.boot.startup({
readBrowserTiddlers: !!$tw.browser
});
});
};
/////////////////////////// Autoboot in the browser
if($tw.browser) {
if($tw.browser && !$tw.boot.suppressBoot) {
$tw.boot.boot();
}

View File

@@ -16,7 +16,12 @@ var _bootprefix = (function($tw) {
"use strict";
$tw = $tw || {browser: typeof(window) !== "undefined" ? {} : null};
$tw = $tw || {};
// Detect platforms
$tw.browser = typeof(window) !== "undefined" ? {} : null;
$tw.node = typeof(process) === "object" ? {} : null;
$tw.nodeWebKit = $tw.node && global.window && global.window.nwDispatcher ? {} : null;
/*
Information about each module is kept in an object with these members:
@@ -92,6 +97,3 @@ if(typeof(exports) === "undefined") {
// Export functionality as a module
exports.bootprefix = _bootprefix;
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/image/gif
bitmap

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/image/jpeg
bitmap

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/image/jpg
bitmap

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/image/png
bitmap

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/image/x-icon
bitmap

View File

@@ -0,0 +1,3 @@
title: $:/config/EditorTypeMappings/text/vnd.tiddlywiki
text

View File

@@ -4,7 +4,7 @@ type: text/plain
TiddlyWiki created by Jeremy Ruston, (jeremy [at] jermolene [dot] com)
Copyright © Jeremy Ruston 2004-2007
Copyright © UnaMesa Association 2007-2013
Copyright © UnaMesa Association 2007-2014
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/application/json
description: JSON data
name: application/json

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/application/x-tiddler-dictionary
description: Data dictionary
name: application/x-tiddler-dictionary

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/image/gif
description: GIF image
name: image/gif

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/image/jpeg
description: JPEG image
name: image/jpeg

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/image/png
description: PNG image
name: image/png

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/image/svg+xml
description: Structured Vector Graphics image
name: image/svg+xml

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/image/x-icon
description: ICO format icon file
name: image/x-icon

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/text/plain
description: Plain text
name: text/plain

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/text/vnd.tiddlywiki
description: TiddlyWiki version 5 wikitext
name: text/vnd.tiddlywiki

View File

@@ -0,0 +1,3 @@
title: $:/docs/types/text/x-tiddlywiki
description: TiddlyWiki Classic wikitext
name: text/x-tiddlywiki

View File

@@ -1,3 +1,3 @@
title: $:/core/images/cancel-button
<svg class="tw-image-cancel-button" viewBox="366 150 58 58" width="22pt" height="22pt"><path d="M 414.76236 158.98764 C 403.77887 148.0041 385.97113 148.0041 374.98764 158.98764 C 364.0041 169.97113 364.0041 187.77887 374.98764 198.76236 C 385.97113 209.7459 403.77887 209.7459 414.76236 198.76236 C 425.7459 187.77887 425.7459 169.97113 414.76236 158.98764 M 385.3967 165.32954 L 385.3967 165.32954 L 394.77674 174.7096 L 404.3533 165.13303 C 405.53068 163.95566 407.4396 163.95566 408.61697 165.13303 C 409.79434 166.31041 409.79434 168.21932 408.61697 169.39669 L 399.0404 178.97325 L 408.42046 188.35331 C 409.59783 189.53068 409.59783 191.43959 408.42046 192.61697 L 408.42046 192.61697 C 407.24308 193.79434 405.33417 193.79434 404.1568 192.61697 L 394.77675 183.23692 L 385.5932 192.42046 C 384.41583 193.59783 382.50692 193.59783 381.32954 192.42046 L 381.32954 192.42046 C 380.15217 191.24308 380.15217 189.33417 381.32954 188.1568 C 381.32954 188.1568 381.32954 188.1568 381.32954 188.1568 L 381.32954 188.1568 L 381.32954 188.1568 L 390.51309 178.97326 L 381.13303 169.5932 C 379.95566 168.41583 379.95566 166.50692 381.13303 165.32954 L 381.13303 165.32954 C 382.3104 164.15217 384.21932 164.15217 385.3967 165.32954 C 385.3967 165.32954 385.3967 165.32954 385.3967 165.32954 Z"/></svg>
<svg class="tw-image-cancel-button tw-image-button" viewBox="366 150 58 58" width="22pt" height="22pt"><path d="M 414.76236 158.98764 C 403.77887 148.0041 385.97113 148.0041 374.98764 158.98764 C 364.0041 169.97113 364.0041 187.77887 374.98764 198.76236 C 385.97113 209.7459 403.77887 209.7459 414.76236 198.76236 C 425.7459 187.77887 425.7459 169.97113 414.76236 158.98764 M 385.3967 165.32954 L 385.3967 165.32954 L 394.77674 174.7096 L 404.3533 165.13303 C 405.53068 163.95566 407.4396 163.95566 408.61697 165.13303 C 409.79434 166.31041 409.79434 168.21932 408.61697 169.39669 L 399.0404 178.97325 L 408.42046 188.35331 C 409.59783 189.53068 409.59783 191.43959 408.42046 192.61697 L 408.42046 192.61697 C 407.24308 193.79434 405.33417 193.79434 404.1568 192.61697 L 394.77675 183.23692 L 385.5932 192.42046 C 384.41583 193.59783 382.50692 193.59783 381.32954 192.42046 L 381.32954 192.42046 C 380.15217 191.24308 380.15217 189.33417 381.32954 188.1568 C 381.32954 188.1568 381.32954 188.1568 381.32954 188.1568 L 381.32954 188.1568 L 381.32954 188.1568 L 390.51309 178.97326 L 381.13303 169.5932 C 379.95566 168.41583 379.95566 166.50692 381.13303 165.32954 L 381.13303 165.32954 C 382.3104 164.15217 384.21932 164.15217 385.3967 165.32954 C 385.3967 165.32954 385.3967 165.32954 385.3967 165.32954 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/close-button
<svg class="tw-image-close-button" viewBox="222 150 56 56" width="22pt" height="22pt"><path d="M 249.56668 185.88827 L 267.06757 203.38916 C 269.26427 205.58586 272.82582 205.58586 275.02252 203.38916 L 275.02252 203.38916 C 277.21922 201.19246 277.21922 197.63091 275.02252 195.43421 L 257.52163 177.93332 L 275.38916 160.06579 C 277.58586 157.86909 277.58586 154.30754 275.38916 152.11084 C 273.19246 149.91414 269.63091 149.91414 267.43421 152.11084 L 249.56668 169.97837 L 232.06579 152.47748 L 232.06579 152.47748 C 232.06579 152.47748 232.06579 152.47748 232.06579 152.47748 C 229.86909 150.28078 226.30754 150.28078 224.11084 152.47748 L 224.11084 152.47748 C 221.91414 154.674175 221.91414 158.23573 224.11084 160.43243 L 241.61173 177.93332 L 224.47748 195.06757 L 224.47748 195.06757 L 224.47748 195.06757 C 224.47748 195.06757 224.47748 195.06757 224.47748 195.06757 C 222.28078 197.26427 222.28078 200.82583 224.47748 203.02252 L 224.47748 203.02252 C 226.67418 205.21922 230.23573 205.21922 232.43243 203.02252 Z"/></svg>
<svg class="tw-image-close-button tw-image-button" viewBox="222 150 56 56" width="22pt" height="22pt"><path d="M 249.56668 185.88827 L 267.06757 203.38916 C 269.26427 205.58586 272.82582 205.58586 275.02252 203.38916 L 275.02252 203.38916 C 277.21922 201.19246 277.21922 197.63091 275.02252 195.43421 L 257.52163 177.93332 L 275.38916 160.06579 C 277.58586 157.86909 277.58586 154.30754 275.38916 152.11084 C 273.19246 149.91414 269.63091 149.91414 267.43421 152.11084 L 249.56668 169.97837 L 232.06579 152.47748 L 232.06579 152.47748 C 232.06579 152.47748 232.06579 152.47748 232.06579 152.47748 C 229.86909 150.28078 226.30754 150.28078 224.11084 152.47748 L 224.11084 152.47748 C 221.91414 154.674175 221.91414 158.23573 224.11084 160.43243 L 241.61173 177.93332 L 224.47748 195.06757 L 224.47748 195.06757 L 224.47748 195.06757 C 224.47748 195.06757 224.47748 195.06757 224.47748 195.06757 C 222.28078 197.26427 222.28078 200.82583 224.47748 203.02252 L 224.47748 203.02252 C 226.67418 205.21922 230.23573 205.21922 232.43243 203.02252 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/delete-button
<svg class="tw-image-delete-button" viewBox="303 155 39 50" width="17pt" height="22pt"><path d="M 333 164.25 L 333 157.25 C 333 156.14543 332.10457 155.25 331 155.25 L 314.75 155.25 C 314.75 155.25 314.75 155.25 314.75 155.25 C 313.64543 155.25 312.75 156.14543 312.75 157.25 L 312.75 164.25 L 303.75 164.25 L 303.75 168.75 L 306 168.75 L 306 201.75 L 306 201.75 L 306 201.75 C 306 203.40685 307.34315 204.75 309 204.75 L 336.75 204.75 C 338.40685 204.75 339.75 203.40685 339.75 201.75 L 339.75 168.75 L 342 168.75 L 342 164.25 Z M 317.25 160.75 L 317.25 160.75 C 317.25 160.19772 317.69772 159.75 318.25 159.75 C 318.25 159.75 318.25 159.75 318.25 159.75 L 327.5 159.75 C 328.05228 159.75 328.5 160.19772 328.5 160.75 L 328.5 164.25 L 317.25 164.25 L 317.25 160.75 Z M 310.5 168.75 L 312.75 168.75 L 312.75 200.25 L 310.5 200.25 Z M 317.25 168.75 L 319.5 168.75 L 319.5 200.25 L 317.25 200.25 Z M 324 168.75 L 326.25 168.75 L 326.25 200.25 L 324 200.25 Z M 330.75 168.75 L 333 168.75 L 333 200.25 L 330.75 200.25 Z"/></svg>
<svg class="tw-image-delete-button tw-image-button" viewBox="303 155 39 50" width="17pt" height="22pt"><path d="M 333 164.25 L 333 157.25 C 333 156.14543 332.10457 155.25 331 155.25 L 314.75 155.25 C 314.75 155.25 314.75 155.25 314.75 155.25 C 313.64543 155.25 312.75 156.14543 312.75 157.25 L 312.75 164.25 L 303.75 164.25 L 303.75 168.75 L 306 168.75 L 306 201.75 L 306 201.75 L 306 201.75 C 306 203.40685 307.34315 204.75 309 204.75 L 336.75 204.75 C 338.40685 204.75 339.75 203.40685 339.75 201.75 L 339.75 168.75 L 342 168.75 L 342 164.25 Z M 317.25 160.75 L 317.25 160.75 C 317.25 160.19772 317.69772 159.75 318.25 159.75 C 318.25 159.75 318.25 159.75 318.25 159.75 L 327.5 159.75 C 328.05228 159.75 328.5 160.19772 328.5 160.75 L 328.5 164.25 L 317.25 164.25 L 317.25 160.75 Z M 310.5 168.75 L 312.75 168.75 L 312.75 200.25 L 310.5 200.25 Z M 317.25 168.75 L 319.5 168.75 L 319.5 200.25 L 317.25 200.25 Z M 324 168.75 L 326.25 168.75 L 326.25 200.25 L 324 200.25 Z M 330.75 168.75 L 333 168.75 L 333 200.25 L 330.75 200.25 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/done-button
<svg class="tw-image-done-button" viewBox="434 150 68 55" width="22pt" height="18pt"><path d="M 438.49266 178.00797 L 439.00744 177.49319 C 441.35054 175.15008 445.14946 175.15004 447.49262 177.49309 L 452.50734 182.50757 C 454.8505 184.85063 458.6494 184.85058 460.99252 182.50748 L 488.50747 154.99255 C 490.85058 152.64944 494.6495 152.6494 496.99266 154.99246 L 497.50722 155.506995 C 499.8504 157.85009 499.8505 161.64908 497.5074 163.99228 C 497.50738 163.99229 497.50736 163.99231 497.50734 163.99233 L 460.9926 200.5077 C 458.64947 202.85087 454.85048 202.8509 452.50732 200.50778 C 452.5073 200.50777 452.5073 200.50777 452.5073 200.50776 L 438.49268 186.49327 C 436.14952 184.15013 436.1495 180.35114 438.49264 178.00799 C 438.49265 178.00798 438.49265 178.00797 438.49266 178.00797 Z"/></svg>
<svg class="tw-image-done-button tw-image-button" viewBox="434 150 68 55" width="22pt" height="18pt"><path d="M 438.49266 178.00797 L 439.00744 177.49319 C 441.35054 175.15008 445.14946 175.15004 447.49262 177.49309 L 452.50734 182.50757 C 454.8505 184.85063 458.6494 184.85058 460.99252 182.50748 L 488.50747 154.99255 C 490.85058 152.64944 494.6495 152.6494 496.99266 154.99246 L 497.50722 155.506995 C 499.8504 157.85009 499.8505 161.64908 497.5074 163.99228 C 497.50738 163.99229 497.50736 163.99231 497.50734 163.99233 L 460.9926 200.5077 C 458.64947 202.85087 454.85048 202.8509 452.50732 200.50778 C 452.5073 200.50777 452.5073 200.50777 452.5073 200.50776 L 438.49268 186.49327 C 436.14952 184.15013 436.1495 180.35114 438.49264 178.00799 C 438.49265 178.00798 438.49265 178.00797 438.49266 178.00797 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/down-arrow
<svg class="tw-image-down-arrow" viewBox="441 306 59 45" width="24pt" height="22pt"><path d="M 441 306 L 470.25 351 L 499.5 306 Z"/></svg>
<svg class="tw-image-down-arrow tw-image-button" viewBox="441 306 59 45" width="24pt" height="22pt"><path d="M 441 306 L 470.25 351 L 499.5 306 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/edit-button
<svg class="tw-image-edit-button" viewBox="244 193 20 22" width="20pt" height="22pt"><path d="M 257.33334 196.80951 L 245.90476 207.2857 L 244 212.0476 L 248.7619 210.14284 L 260.19048 199.66665 Z M 259.2381 194.90475 L 258.28566 195.85716 L 261.14284 198.71428 L 262.09522 197.76187 Z M 261.14286 193 L 260.19042 193.95241 L 263.04762 196.80953 L 264 195.85714 Z M 244 213.72882 C 244 213.72882 247.4281 215.43353 250.8572 213.7288 C 254.28599 212.02405 261.14284 214.86531 261.14284 214.86531 L 261.14284 213.72884 C 261.14284 213.72884 254.28577 210.88755 250.8572 212.5923 C 247.42858 214.29712 244 212.59228 244 212.59228 Z"/></svg>
<svg class="tw-image-edit-button tw-image-button" viewBox="244 193 20 22" width="20pt" height="22pt"><path d="M 257.33334 196.80951 L 245.90476 207.2857 L 244 212.0476 L 248.7619 210.14284 L 260.19048 199.66665 Z M 259.2381 194.90475 L 258.28566 195.85716 L 261.14284 198.71428 L 262.09522 197.76187 Z M 261.14286 193 L 260.19042 193.95241 L 263.04762 196.80953 L 264 195.85714 Z M 244 213.72882 C 244 213.72882 247.4281 215.43353 250.8572 213.7288 C 254.28599 212.02405 261.14284 214.86531 261.14284 214.86531 L 261.14284 213.72884 C 261.14284 213.72884 254.28577 210.88755 250.8572 212.5923 C 247.42858 214.29712 244 212.59228 244 212.59228 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/info-button
<svg class="tw-image-info-button" viewBox="294 150 58 58" width="22pt" height="22pt"><path d="M 342.76236 158.98764 C 331.77887 148.0041 313.97113 148.0041 302.98764 158.98764 C 292.0041 169.97113 292.0041 187.77887 302.98764 198.76236 C 313.97113 209.7459 331.77887 209.7459 342.76236 198.76236 C 353.7459 187.77887 353.7459 169.97113 342.76236 158.98764 M 326.5425 157.5 L 326.5425 157.5 C 327.72545 157.5 328.72201 157.91022 329.5337 158.73088 C 330.34465 159.55157 330.75 160.54402 330.75 161.7075 C 330.75 162.87172 330.33979 163.86316 329.51911 164.68385 C 328.69842 165.5045 327.70674 165.91501 326.5425 165.91501 C 325.39801 165.91501 324.4153 165.5045 323.5946 164.68385 C 322.77393 163.86316 322.36372 162.87172 322.36372 161.7075 C 322.36372 160.54402 322.76906 159.55157 323.58 158.73088 C 324.39171 157.91022 325.3793 157.5 326.5425 157.5 Z M 327.80211 190.47259 C 324.91945 195.49132 321.85778 198 318.61462 198 C 317.37452 198 316.38691 197.65158 315.65186 196.9555 C 314.9176 196.25866 314.54943 195.37617 314.54943 194.30782 C 314.54943 193.60202 314.71223 192.70572 315.03629 191.61813 L 319.0151 177.93651 C 319.39685 176.61922 319.58735 175.62754 319.58735 174.95991 C 319.58735 174.53996 319.40582 174.16692 319.04356 173.84286 C 318.68052 173.51905 318.18469 173.35701 317.55527 173.35701 C 317.26861 173.35701 316.92506 173.36677 316.5246 173.38548 L 316.89661 172.2407 L 326.59967 170.66627 L 328.31744 170.66627 L 322.44986 191.01638 C 322.12503 192.18064 321.963 192.94337 321.963 193.30666 C 321.963 193.51588 322.04862 193.71121 322.2204 193.89273 C 322.39218 194.07425 322.5737 194.16554 322.7642 194.16477 C 323.08903 194.16554 323.4131 194.02221 323.73792 193.73559 C 324.59605 193.02976 325.6267 191.75142 326.82838 189.90008 Z"/></svg>
<svg class="tw-image-info-button tw-image-button" viewBox="294 150 58 58" width="22pt" height="22pt"><path d="M 342.76236 158.98764 C 331.77887 148.0041 313.97113 148.0041 302.98764 158.98764 C 292.0041 169.97113 292.0041 187.77887 302.98764 198.76236 C 313.97113 209.7459 331.77887 209.7459 342.76236 198.76236 C 353.7459 187.77887 353.7459 169.97113 342.76236 158.98764 M 326.5425 157.5 L 326.5425 157.5 C 327.72545 157.5 328.72201 157.91022 329.5337 158.73088 C 330.34465 159.55157 330.75 160.54402 330.75 161.7075 C 330.75 162.87172 330.33979 163.86316 329.51911 164.68385 C 328.69842 165.5045 327.70674 165.91501 326.5425 165.91501 C 325.39801 165.91501 324.4153 165.5045 323.5946 164.68385 C 322.77393 163.86316 322.36372 162.87172 322.36372 161.7075 C 322.36372 160.54402 322.76906 159.55157 323.58 158.73088 C 324.39171 157.91022 325.3793 157.5 326.5425 157.5 Z M 327.80211 190.47259 C 324.91945 195.49132 321.85778 198 318.61462 198 C 317.37452 198 316.38691 197.65158 315.65186 196.9555 C 314.9176 196.25866 314.54943 195.37617 314.54943 194.30782 C 314.54943 193.60202 314.71223 192.70572 315.03629 191.61813 L 319.0151 177.93651 C 319.39685 176.61922 319.58735 175.62754 319.58735 174.95991 C 319.58735 174.53996 319.40582 174.16692 319.04356 173.84286 C 318.68052 173.51905 318.18469 173.35701 317.55527 173.35701 C 317.26861 173.35701 316.92506 173.36677 316.5246 173.38548 L 316.89661 172.2407 L 326.59967 170.66627 L 328.31744 170.66627 L 322.44986 191.01638 C 322.12503 192.18064 321.963 192.94337 321.963 193.30666 C 321.963 193.51588 322.04862 193.71121 322.2204 193.89273 C 322.39218 194.07425 322.5737 194.16554 322.7642 194.16477 C 323.08903 194.16554 323.4131 194.02221 323.73792 193.73559 C 324.59605 193.02976 325.6267 191.75142 326.82838 189.90008 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/new-button
<svg class="tw-image-new-button" viewBox="83 81 50 50" width="22pt" height="22pt"><path d="M 101.25 112.5 L 101.25 127.5 C 101.25 127.5 101.25 127.5 101.25 127.5 L 101.25 127.5 C 101.25 129.156855 102.593146 130.5 104.25 130.5 L 111.75 130.5 C 113.406854 130.5 114.75 129.156854 114.75 127.5 L 114.75 112.5 L 129.75 112.5 C 131.406854 112.5 132.75 111.156854 132.75 109.5 L 132.75 102 C 132.75 100.343146 131.406854 99 129.75 99 L 114.75 99 L 114.75 84 C 114.75 82.343146 113.406854 81 111.75 81 L 104.25 81 C 104.25 81 104.25 81 104.25 81 C 102.593146 81 101.25 82.343146 101.25 84 L 101.25 99 L 86.25 99 C 86.25 99 86.25 99 86.25 99 C 84.593146 99 83.25 100.343146 83.25 102 L 83.25 109.5 C 83.25 109.5 83.25 109.5 83.25 109.5 L 83.25 109.5 C 83.25 111.156855 84.593146 112.5 86.25 112.5 Z"/></svg>
<svg class="tw-image-new-button tw-image-button" viewBox="83 81 50 50" width="22pt" height="22pt"><path d="M 101.25 112.5 L 101.25 127.5 C 101.25 127.5 101.25 127.5 101.25 127.5 L 101.25 127.5 C 101.25 129.156855 102.593146 130.5 104.25 130.5 L 111.75 130.5 C 113.406854 130.5 114.75 129.156854 114.75 127.5 L 114.75 112.5 L 129.75 112.5 C 131.406854 112.5 132.75 111.156854 132.75 109.5 L 132.75 102 C 132.75 100.343146 131.406854 99 129.75 99 L 114.75 99 L 114.75 84 C 114.75 82.343146 113.406854 81 111.75 81 L 104.25 81 C 104.25 81 104.25 81 104.25 81 C 102.593146 81 101.25 82.343146 101.25 84 L 101.25 99 L 86.25 99 C 86.25 99 86.25 99 86.25 99 C 84.593146 99 83.25 100.343146 83.25 102 L 83.25 109.5 C 83.25 109.5 83.25 109.5 83.25 109.5 L 83.25 109.5 C 83.25 111.156855 84.593146 112.5 86.25 112.5 Z"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/options-button
<svg class="tw-image-options-button" viewBox="434 218 68 68" width="22pt" height="22pt"><path d="M 478.39696 232.53705 L 478.39696 232.53705 C 477.11453 231.85132 475.77877 231.30146 474.4106 230.88735 L 474.4106 218.24993 L 461.58944 218.24993 L 461.58944 230.88735 C 460.22126 231.30146 458.8855 231.85132 457.60308 232.53705 L 448.66825 223.60214 L 439.6022 232.66814 L 448.53716 241.60304 C 447.8515 242.88541 447.30158 244.22116 446.88747 245.58935 L 434.25 245.58935 L 434.25 258.41052 L 446.88747 258.41052 C 447.30158 259.7787 447.8515 261.11446 448.53716 262.39689 L 439.6022 271.33173 L 448.66825 280.39779 L 457.60308 271.46281 C 458.8855 272.14862 460.22126 272.69847 461.58944 273.11251 L 461.58944 285.74986 L 474.4106 285.74986 L 474.4106 273.11251 C 475.77877 272.69847 477.11453 272.14862 478.39696 271.46281 L 487.3318 280.39779 L 496.3977 271.33173 L 487.46287 262.39689 C 488.14854 261.11446 488.6984 259.7787 489.11257 258.41052 L 501.7499 258.41052 L 501.7499 245.58935 L 489.11257 245.58935 C 488.6984 244.22116 488.14854 242.88541 487.46287 241.60304 L 496.3977 232.66814 L 487.3318 223.60214 Z M 475.3328 244.66714 C 479.38253 248.71698 479.38253 255.2829 475.3328 259.33273 C 471.28297 263.3826 464.71706 263.3826 460.66723 259.33273 C 456.61737 255.2829 456.61737 248.71698 460.66723 244.66714 C 464.71706 240.61734 471.28297 240.61734 475.3328 244.66714"/></svg>
<svg class="tw-image-options-button tw-image-button" viewBox="434 218 68 68" width="22pt" height="22pt"><path d="M 478.39696 232.53705 L 478.39696 232.53705 C 477.11453 231.85132 475.77877 231.30146 474.4106 230.88735 L 474.4106 218.24993 L 461.58944 218.24993 L 461.58944 230.88735 C 460.22126 231.30146 458.8855 231.85132 457.60308 232.53705 L 448.66825 223.60214 L 439.6022 232.66814 L 448.53716 241.60304 C 447.8515 242.88541 447.30158 244.22116 446.88747 245.58935 L 434.25 245.58935 L 434.25 258.41052 L 446.88747 258.41052 C 447.30158 259.7787 447.8515 261.11446 448.53716 262.39689 L 439.6022 271.33173 L 448.66825 280.39779 L 457.60308 271.46281 C 458.8855 272.14862 460.22126 272.69847 461.58944 273.11251 L 461.58944 285.74986 L 474.4106 285.74986 L 474.4106 273.11251 C 475.77877 272.69847 477.11453 272.14862 478.39696 271.46281 L 487.3318 280.39779 L 496.3977 271.33173 L 487.46287 262.39689 C 488.14854 261.11446 488.6984 259.7787 489.11257 258.41052 L 501.7499 258.41052 L 501.7499 245.58935 L 489.11257 245.58935 C 488.6984 244.22116 488.14854 242.88541 487.46287 241.60304 L 496.3977 232.66814 L 487.3318 223.60214 Z M 475.3328 244.66714 C 479.38253 248.71698 479.38253 255.2829 475.3328 259.33273 C 471.28297 263.3826 464.71706 263.3826 460.66723 259.33273 C 456.61737 255.2829 456.61737 248.71698 460.66723 244.66714 C 464.71706 240.61734 471.28297 240.61734 475.3328 244.66714"/></svg>

View File

@@ -1,3 +1,3 @@
title: $:/core/images/save-button
<svg class="tw-image-save-button" viewBox="4 512 64 60" width="22pt" height="21pt"><path d="M 13.5 537.75 L 11.5 537.75 C 11.5 537.75 11.5 537.75 11.5 537.75 C 7.6340064 537.75 4.4999994 540.884 4.5 544.75 L 4.5 564.5 L 4.5 564.5 C 4.5 564.5 4.5 564.5 4.5 564.5 L 4.5 564.5 C 4.5000006 568.366 7.634007 571.5 11.5 571.5 L 60.5 571.5 C 64.365993 571.5 67.5 568.366 67.5 564.5 L 67.5 544.75 C 67.5 540.884 64.365993 537.75 60.5 537.75 L 58.5 537.75 L 49.5 546.75 L 50 546.75 C 52.20914 546.75 54 548.54086 54 550.75 L 54 556.25 C 54 558.45914 52.20914 560.25 50 560.25 L 36 560.25 L 22 560.25 C 19.790861 560.25 18 558.45914 18 556.25 L 18 556.25 C 18 556.25 18 556.25 18 556.25 L 18 550.75 C 18 548.54086 19.790861 546.75 22 546.75 C 22 546.75 22 546.75 22 546.75 L 22.5 546.75 Z"/><path d="M 16.37132 533.87132 L 33.87868 551.37868 C 35.050253 552.55025 36.949747 552.55025 38.12132 551.37868 L 55.62868 533.87132 C 56.800252 532.69975 56.800252 530.80025 55.62868 529.62868 C 55.06607 529.06607 54.30301 528.75 53.50736 528.75 L 48 528.75 C 46.343146 528.75 45 527.40685 45 525.75 L 45 516 C 45 514.34315 43.656854 513 42 513 L 30 513 C 28.343146 513 27 514.34315 27 516 L 27 525.75 C 27 527.40685 25.656854 528.75 24 528.75 L 18.492641 528.75 C 16.835786 528.75 15.492641 530.09315 15.492641 531.75 C 15.492641 532.54565 15.808711 533.3087 16.37132 533.87132 Z"/></svg>
<svg class="tw-image-save-button tw-image-button" viewBox="4 512 64 60" width="22pt" height="21pt"><path d="M 13.5 537.75 L 11.5 537.75 C 11.5 537.75 11.5 537.75 11.5 537.75 C 7.6340064 537.75 4.4999994 540.884 4.5 544.75 L 4.5 564.5 L 4.5 564.5 C 4.5 564.5 4.5 564.5 4.5 564.5 L 4.5 564.5 C 4.5000006 568.366 7.634007 571.5 11.5 571.5 L 60.5 571.5 C 64.365993 571.5 67.5 568.366 67.5 564.5 L 67.5 544.75 C 67.5 540.884 64.365993 537.75 60.5 537.75 L 58.5 537.75 L 49.5 546.75 L 50 546.75 C 52.20914 546.75 54 548.54086 54 550.75 L 54 556.25 C 54 558.45914 52.20914 560.25 50 560.25 L 36 560.25 L 22 560.25 C 19.790861 560.25 18 558.45914 18 556.25 L 18 556.25 C 18 556.25 18 556.25 18 556.25 L 18 550.75 C 18 548.54086 19.790861 546.75 22 546.75 C 22 546.75 22 546.75 22 546.75 L 22.5 546.75 Z"/><path d="M 16.37132 533.87132 L 33.87868 551.37868 C 35.050253 552.55025 36.949747 552.55025 38.12132 551.37868 L 55.62868 533.87132 C 56.800252 532.69975 56.800252 530.80025 55.62868 529.62868 C 55.06607 529.06607 54.30301 528.75 53.50736 528.75 L 48 528.75 C 46.343146 528.75 45 527.40685 45 525.75 L 45 516 C 45 514.34315 43.656854 513 42 513 L 30 513 C 28.343146 513 27 514.34315 27 516 L 27 525.75 C 27 527.40685 25.656854 528.75 24 528.75 L 18.492641 528.75 C 16.835786 528.75 15.492641 530.09315 15.492641 531.75 C 15.492641 532.54565 15.808711 533.3087 16.37132 533.87132 Z"/></svg>

View File

@@ -0,0 +1,3 @@
title: $:/messages/StartingSave
Starting to save wiki

View File

@@ -42,7 +42,7 @@ Command.prototype.execute = function() {
$tw.utils.each(tiddlers,function(title) {
var parser = wiki.parseTiddler(template),
widgetNode = wiki.makeWidget(parser,{variables: {currentTiddler: title}});
var container = $tw.document.createElement("div");
var container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = type === "text/html" ? container.innerHTML : container.textContent;
fs.writeFileSync(path.resolve(pathname,encodeURIComponent(title) + extension),text,"utf8");

View File

@@ -0,0 +1,46 @@
/*\
title: $:/core/modules/commands/savetiddler.js
type: application/javascript
module-type: command
Command to save the content of a tiddler to a file
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.info = {
name: "savetiddler",
synchronous: false
};
var Command = function(params,commander,callback) {
this.params = params;
this.commander = commander;
this.callback = callback;
};
Command.prototype.execute = function() {
if(this.params.length < 2) {
return "Missing filename";
}
var self = this,
fs = require("fs"),
path = require("path"),
title = this.params[0],
filename = this.params[1],
tiddler = this.commander.wiki.getTiddler(title),
type = tiddler.fields.type || "text/vnd.tiddlywiki",
contentTypeInfo = $tw.config.contentTypeInfo[type] || {encoding: "utf8"};
fs.writeFile(filename,tiddler.fields.text,contentTypeInfo.encoding,function(err) {
self.callback(err);
});
return null;
};
exports.Command = Command;
})();

View File

@@ -49,27 +49,57 @@ SimpleServer.prototype.addRoute = function(route) {
this.routes.push(route);
};
SimpleServer.prototype.listen = function(port) {
SimpleServer.prototype.findMatchingRoute = function(request,state) {
for(var t=0; t<this.routes.length; t++) {
var potentialRoute = this.routes[t],
pathRegExp = potentialRoute.path,
match = potentialRoute.path.exec(state.urlInfo.pathname);
if(match && request.method === potentialRoute.method) {
state.params = [];
for(var p=1; p<match.length; p++) {
state.params.push(match[p]);
}
return potentialRoute;
}
}
return null;
};
SimpleServer.prototype.checkCredentials = function(request,incomingUsername,incomingPassword) {
var header = request.headers["authorization"] || "",
token = header.split(/\s+/).pop() || "",
auth = $tw.utils.base64Decode(token),
parts = auth.split(/:/),
username = parts[0],
password = parts[1];
if(incomingUsername === username && incomingPassword === password) {
return "ALLOWED";
} else {
return "DENIED";
}
}
SimpleServer.prototype.listen = function(port,host) {
var self = this;
http.createServer(function(request, response) {
http.createServer(function(request,response) {
// Compose the state object
var state = {};
state.wiki = self.wiki;
state.server = self;
state.urlInfo = url.parse(request.url);
// Find the route that matches this path
var route;
for(var t=0; t<self.routes.length; t++) {
var potentialRoute = self.routes[t],
pathRegExp = potentialRoute.path,
match = potentialRoute.path.exec(state.urlInfo.pathname);
if(request.method === potentialRoute.method && match) {
state.params = [];
for(var p=1; p<match.length; p++) {
state.params.push(match[p]);
}
route = potentialRoute;
break;
var route = self.findMatchingRoute(request,state);
// Check for the username and password if we've got one
var username = self.get("username"),
password = self.get("password");
if(username && password) {
// Check they match
if(self.checkCredentials(request,username,password) !== "ALLOWED") {
response.writeHead(401,"Authentication required",{
"WWW-Authenticate": 'Basic realm="Please provide your username and password to login to TiddlyWiki5"'
});
response.end();
return;
}
}
// Return a 404 if we didn't find a route
@@ -95,7 +125,7 @@ SimpleServer.prototype.listen = function(port) {
});
break;
}
}).listen(port);
}).listen(port,host);
};
var Command = function(params,commander,callback) {
@@ -166,13 +196,22 @@ var Command = function(params,commander,callback) {
response.end(text,"utf8");
}
});
this.server.addRoute({
method: "GET",
path: /^\/favicon.ico$/,
handler: function(request,response,state) {
response.writeHead(200, {"Content-Type": "image/x-icon"});
var buffer = state.wiki.getTiddlerText("$:/favicon.ico","");
response.end(buffer,"base64");
}
});
this.server.addRoute({
method: "GET",
path: /^\/recipes\/default\/tiddlers.json$/,
handler: function(request,response,state) {
response.writeHead(200, {"Content-Type": "application/json"});
var tiddlers = [];
state.wiki.forEachTiddler("title",function(title,tiddler) {
state.wiki.forEachTiddler({sortField: "title"},function(title,tiddler) {
var tiddlerFields = {};
$tw.utils.each(tiddler.fields,function(field,name) {
if(name !== "text") {
@@ -221,20 +260,22 @@ var Command = function(params,commander,callback) {
Command.prototype.execute = function() {
var port = this.params[0] || "8080",
rootTiddler = this.params[1] || "$:/core/templates/tiddlywiki5.template.html",
rootTiddler = this.params[1] || "$:/core/save/all",
renderType = this.params[2] || "text/plain",
serveType = this.params[3] || "text/html",
username = this.params[4] || "ANONYMOUS";
username = this.params[4],
password = this.params[5],
host = this.params[6] || "127.0.0.1";
this.server.set({
rootTiddler: rootTiddler,
renderType: renderType,
serveType: serveType,
username: username
username: username,
password: password
});
this.server.listen(port);
if(this.commander.verbose) {
console.log("Serving on port " + port);
}
this.server.listen(port,host);
console.log("Serving on " + host + ":" + port);
console.log("(press ctrl-C to exit)");
return null;
};

View File

@@ -36,30 +36,35 @@ var parseTiddlerDiv = function(text /* [,fields] */) {
}
}
// Parse the DIV body
var divRegExp = /^\s*<div\s+([^>]*)>((?:\s|\S)*)<\/div>\s*$/gi,
subDivRegExp = /^\s*<pre>((?:\s|\S)*)<\/pre>\s*$/gi,
attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi,
match = divRegExp.exec(text);
var startRegExp = /^\s*<div\s+([^>]*)>(\s*<pre>)?/gi,
endRegExp,
match = startRegExp.exec(text);
if(match) {
var subMatch = subDivRegExp.exec(match[2]); // Body of the <DIV> tag
if(subMatch) {
result.text = subMatch[1];
// Old-style DIVs don't have the <pre> tag
if(match[2]) {
endRegExp = /<\/pre>\s*<\/div>\s*$/gi;
} else {
result.text = match[2];
endRegExp = /<\/div>\s*$/gi;
}
var endMatch = endRegExp.exec(text);
if(endMatch) {
// Extract the text
result.text = text.substring(match.index + match[0].length,endMatch.index);
// Process the attributes
var attrRegExp = /\s*([^=\s]+)\s*=\s*"([^"]*)"/gi,
attrMatch;
do {
attrMatch = attrRegExp.exec(match[1]);
if(attrMatch) {
var name = attrMatch[1];
var value = attrMatch[2];
result[name] = value;
}
} while(attrMatch);
return result;
}
var attrMatch;
do {
attrMatch = attrRegExp.exec(match[1]);
if(attrMatch) {
var name = attrMatch[1];
var value = attrMatch[2];
result[name] = value;
}
} while(attrMatch);
return result;
} else {
return undefined;
}
return undefined;
};
exports["application/x-tiddler-html-div"] = function(text,fields) {
@@ -95,11 +100,26 @@ exports["text/html"] = function(text,fields) {
var storeAreaMarkerRegExp = /<div id=["']?storeArea['"]?( style=["']?display:none;["']?)?>/gi,
match = storeAreaMarkerRegExp.exec(text);
if(match) {
// If so, it's either a classic TiddlyWiki file or a TW5 file
return deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
// If so, it's either a classic TiddlyWiki file or an unencrypted TW5 file
// First read the normal tiddlers
var results = deserializeTiddlyWikiFile(text,storeAreaMarkerRegExp.lastIndex,!!match[1],fields);
// Then any system tiddlers
var systemAreaMarkerRegExp = /<div id=["']?systemArea['"]?( style=["']?display:none;["']?)?>/gi,
sysMatch = systemAreaMarkerRegExp.exec(text);
if(sysMatch) {
results.push.apply(results,deserializeTiddlyWikiFile(text,systemAreaMarkerRegExp.lastIndex,!!sysMatch[1],fields));
}
return results
} else {
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
return deserializeHtmlFile(text,fields);
// Check whether we've got an encrypted file
var encryptedStoreArea = $tw.utils.extractEncryptedStoreArea(text);
if(encryptedStoreArea) {
// If so, attempt to decrypt it using the current password
return $tw.utils.decryptStoreArea(encryptedStoreArea);
} else {
// It's not a TiddlyWiki so we'll return the entire HTML file as a tiddler
return deserializeHtmlFile(text,fields);
}
}
};

View File

@@ -33,31 +33,55 @@ function parseFilterOperation(operators,filterString,p) {
operator.prefix = filterString.charAt(p++);
}
// Get the operator name
bracketPos = filterString.indexOf("[",p);
curlyBracketPos = filterString.indexOf("{",p);
if((bracketPos === -1) && (curlyBracketPos === -1)) {
var nextBracketPos = filterString.substring(p).search(/[\[\{\/]/);
if(nextBracketPos === -1) {
throw "Missing [ in filter expression";
}
if(bracketPos === -1 || (curlyBracketPos !== -1 && curlyBracketPos < bracketPos)) {
// Curly brackets
operator.indirect = true;
operator.operator = filterString.substring(p,curlyBracketPos);
p = curlyBracketPos + 1;
} else {
// Square brackets
operator.operator = filterString.substring(p,bracketPos);
p = bracketPos + 1;
nextBracketPos += p;
var bracket = filterString.charAt(nextBracketPos);
operator.operator = filterString.substring(p,nextBracketPos);
// Any suffix?
var colon = operator.operator.indexOf(':');
if(colon > -1) {
operator.suffix = operator.operator.substring(colon + 1);
operator.operator = operator.operator.substring(0,colon) || "field";
}
if(operator.operator === "") {
// Empty operator means: title
else if(operator.operator === "") {
operator.operator = "title";
}
// Get the operand
bracketPos = filterString.indexOf(operator.indirect ? "}" : "]",p);
if(bracketPos === -1) {
p = nextBracketPos + 1;
switch (bracket) {
case '{': // Curly brackets
operator.indirect = true;
nextBracketPos = filterString.indexOf('}',p);
break;
case '[': // Square brackets
nextBracketPos = filterString.indexOf(']',p);
break;
case '/': // regexp brackets
var rex = /^((?:[^\\\/]*|\\.))*\/(?:\(([mygi]+)\))?/g,
rexMatch = rex.exec(filterString.substring(p));
if(rexMatch) {
operator.regexp = new RegExp(rexMatch[1], rexMatch[2]);
nextBracketPos = p + rex.lastIndex - 1;
}
else {
throw "Unterminated regular expression in filter expression";
}
break;
}
if(nextBracketPos === -1) {
throw "Missing closing bracket in filter expression";
}
operator.operand = filterString.substring(p,bracketPos);
p = bracketPos + 1;
if(!operator.regexp) {
operator.operand = filterString.substring(p,nextBracketPos);
}
p = nextBracketPos + 1;
// Push this operator
operators.push(operator);
} while(filterString.charAt(p) !== "]");
@@ -131,7 +155,14 @@ exports.filterTiddlers = function(filterString,currTiddlerTitle,tiddlerList) {
};
exports.compileFilter = function(filterString) {
var filterParseTree = this.parseFilter(filterString);
var filterParseTree;
try {
filterParseTree = this.parseFilter(filterString);
} catch(e) {
return function(source,currTiddlerTitle) {
return ["Filter error: " + e];
};
}
// Get the hashmap of filter operator functions
var filterOperators = this.getFilterOperators();
// Assemble array of functions, one for each operation
@@ -154,7 +185,9 @@ exports.compileFilter = function(filterString) {
results = operatorFunction(accumulator,{
operator: operator.operator,
operand: operand,
prefix: operator.prefix
prefix: operator.prefix,
suffix: operator.suffix,
regexp: operator.regexp
},{
wiki: self,
currTiddlerTitle: currTiddlerTitle

View File

@@ -16,12 +16,19 @@ Filter operator for comparing fields for equality
Export our filter function
*/
exports.field = function(source,operator,options) {
var results = [];
var results = [],
fieldname = (operator.suffix || operator.operator).toLowerCase();
// Function to check an individual title
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = tiddler.getFieldString(operator.operator) === operator.operand;
var match,
text = tiddler.getFieldString(fieldname);
if(operator.regexp) {
match = !!operator.regexp.exec(text);
} else {
match = text === operator.operand;
}
if(operator.prefix === "!") {
match = !match;
}

View File

@@ -21,7 +21,7 @@ exports.has = function(source,operator,options) {
function checkTiddler(title) {
var tiddler = options.wiki.getTiddler(title);
if(tiddler) {
var match = $tw.utils.hop(tiddler.fields,operator.operand);
var match = $tw.utils.hop(tiddler.fields,operator.operand) && tiddler.fields[operator.operand] !== "";
if(operator.prefix === "!") {
match = !match;
}

View File

@@ -0,0 +1,43 @@
/*\
title: $:/core/modules/filters/is/tiddler.js
type: application/javascript
module-type: isfilteroperator
Filter function for [is[tiddler]]
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.tiddler = function(source,prefix,options) {
var results = [];
// Function to check a tiddler
function checkTiddler(title) {
var match = options.wiki.tiddlerExists(title);
if(prefix === "!") {
match = !match;
}
if(match) {
results.push(title);
}
};
// Iterate through the source tiddlers
if($tw.utils.isArray(source)) {
$tw.utils.each(source,function(title) {
checkTiddler(title);
});
} else {
$tw.utils.each(source,function(element,title) {
checkTiddler(title);
});
}
return results;
};
})();

View File

@@ -17,7 +17,8 @@ Export our filter function
*/
exports.list = function(source,operator,options) {
var results = [],
list = options.wiki.getTiddlerList(operator.operand);
tr = $tw.utils.parseTextReference(operator.operand),
list = options.wiki.getTiddlerList(tr.title,tr.field,tr.index);
function checkTiddler(title) {
var match = list.indexOf(title) !== -1;
if(operator.prefix === "!") {

View File

@@ -0,0 +1,87 @@
/*\
title: $:/core/modules/filters/listops.js
type: application/javascript
module-type: filteroperator
Filter operators for manipulating the current selection list
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Reverse list
*/
exports.reverse = function(source,operator,options) {
var results = [];
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
$tw.utils.each(source,function(title) {
results.unshift(title);
});
return results;
};
/*
First entry/entries in list
*/
exports.first = function(source,operator,options) {
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(0,Math.min(count,source.length));
};
/*
Last entry/entries in list
*/
exports.last = function(source,operator,options) {
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(-count);
};
/*
All but the first entry/entries of the list
*/
exports.rest = function(source,operator,options) {
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(count);
};
exports.butfirst = exports.rest;
exports.bf = exports.rest;
/*
All but the last entry/entries of the list
*/
exports.butlast = function(source,operator,options) {
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(0,-count);
};
exports.bl = exports.butlast;
/*
The nth member of the list
*/
exports.nth = function(source,operator,options) {
var count = parseInt(operator.operand) || 1;
if(!$tw.utils.isArray(source)) {
source = Object.keys(source).sort();
}
return source.slice(count-1,count);
};
})();

View File

@@ -16,6 +16,30 @@ Filter operator for sorting
Export our filter function
*/
exports.sort = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",false,false);
return results;
};
exports.nsort = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",false,true);
return results;
};
exports.sortcs = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true,false);
return results;
};
exports.nsortcs = function(source,operator,options) {
var results = prepare_results(source);
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true,true);
return results;
};
var prepare_results = function (source) {
var results;
if($tw.utils.isArray(source)) {
results = source;
@@ -25,8 +49,7 @@ exports.sort = function(source,operator,options) {
results.push(title);
});
}
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!");
return results;
};
}
})();

View File

@@ -1,32 +0,0 @@
/*\
title: $:/core/modules/filters/sortcs.js
type: application/javascript
module-type: filteroperator
Filter operator for case-sensitive sorting
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Export our filter function
*/
exports.sortcs = function(source,operator,options) {
var results;
if($tw.utils.isArray(source)) {
results = source;
} else {
results = [];
$tw.utils.each(source,function(element,title) {
results.push(title);
});
}
options.wiki.sortTiddlers(results,operator.operand,operator.prefix === "!",true);
return results;
};
})();

View File

@@ -38,6 +38,7 @@ exports["image/jpeg"] = ImageParser;
exports["image/png"] = ImageParser;
exports["image/gif"] = ImageParser;
exports["application/pdf"] = ImageParser;
exports["image/x-icon"] = ImageParser;
})();

View File

@@ -28,6 +28,7 @@ exports["text/x-tiddlywiki"] = TextParser;
exports["application/javascript"] = TextParser;
exports["application/json"] = TextParser;
exports["text/css"] = TextParser;
exports["application/x-tiddler-dictionary"] = TextParser;
})();

View File

@@ -23,14 +23,15 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /```\r?\n/mg;
// Regexp to match and get language if defined
this.matchRegExp = /```([\w-]*)\r?\n/mg;
};
exports.parse = function() {
var reEnd = /(\r?\n```$)/mg;
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
// Look for the end of the block
reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source),
@@ -43,14 +44,14 @@ exports.parse = function() {
text = this.parser.source.substr(this.parser.pos);
this.parser.pos = this.parser.sourceLength;
}
// Return the pre element
// Return the $codeblock widget
return [{
type: "element",
tag: "pre",
children: [{
type: "text",
text: text
}]
type: "element",
tag: "$codeblock",
attributes: {
code: {type: "string", value: text},
language: {type: "string", value: this.match[1]}
}
}];
};

View File

@@ -7,6 +7,7 @@ Wiki text inline rule for code runs. For example:
```
This is a `code run`.
This is another ``code run``
```
\*/
@@ -22,13 +23,13 @@ exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /`/mg;
this.matchRegExp = /(``?)/mg;
};
exports.parse = function() {
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
var reEnd = /`/mg;
var reEnd = new RegExp(this.match[1], "mg");
// Look for the end marker
reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source),

View File

@@ -0,0 +1,58 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/hardlinebreaks.js
type: application/javascript
module-type: wikirule
Wiki text inline rule for marking areas with hard line breaks. For example:
```
"""
This is some text
That is set like
It is a Poem
When it is
Clearly
Not
"""
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "hardlinebreaks";
exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /"""(?:\r?\n)?/mg;
};
exports.parse = function() {
var reEnd = /(""")|(\r?\n)/mg,
tree = [];
// Move past the match
this.parser.pos = this.matchRegExp.lastIndex;
do {
// Parse the run up to the terminator
tree.push.apply(tree,this.parser.parseInlineRun(reEnd,{eatTerminator: false}));
// Redo the terminator match
reEnd.lastIndex = this.parser.pos;
var match = reEnd.exec(this.parser.source);
if(match) {
this.parser.pos = reEnd.lastIndex;
// Add a line break if the terminator was a line break
if(match[2]) {
tree.push({type: "element", tag: "br"});
}
}
} while(match && !match[1]);
// Return the nodes
return tree;
};
})();

View File

@@ -22,7 +22,7 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /-{3,}\r?\n/mg;
this.matchRegExp = /-{3,}\r?(?:\n|$)/mg;
};
exports.parse = function() {

View File

@@ -52,14 +52,15 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /([\*#;:]+)/mg;
this.matchRegExp = /([\*#;:>]+)/mg;
};
var listTypes = {
"*": {listTag: "ul", itemTag: "li"},
"#": {listTag: "ol", itemTag: "li"},
";": {listTag: "dl", itemTag: "dt"},
":": {listTag: "dl", itemTag: "dd"}
":": {listTag: "dl", itemTag: "dd"},
">": {listTag: "blockquote", itemTag: "p"}
};
/*
@@ -71,7 +72,7 @@ exports.parse = function() {
// Cycle through the items in the list
while(true) {
// Match the list marker
var reMatch = /([\*#;:]+)/mg;
var reMatch = /([\*#;:>]+)/mg;
reMatch.lastIndex = this.parser.pos;
var match = reMatch.exec(this.parser.source);
if(!match || match.index !== this.parser.pos) {

View File

@@ -22,7 +22,7 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /<<([^\s>]+)\s*([\s\S]*?)>>(?:\r?\n|$)/mg;
this.matchRegExp = /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*?)>>(?:\r?\n|$)/mg;
};
/*

View File

@@ -0,0 +1,93 @@
/*\
title: $:/core/modules/parsers/wikiparser/rules/quoteblock.js
type: application/javascript
module-type: wikirule
Wiki text rule for quote blocks. For example:
```
<<<.optionalClass(es) optional cited from
a quote
<<<
<<<.optionalClass(es)
a quote
<<< optional cited from
```
Quotes can be quoted by putting more <s
```
<<<
Quote Level 1
<<<<
QuoteLevel 2
<<<<
<<<
```
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
exports.name = "quoteblock";
exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /(<<<+)/mg;
};
exports.parse = function() {
var classes = ["tw-quote"];
// Get all the details of the match
var reEndString = "^" + this.match[1] + "(?!<)";
// Move past the <s
this.parser.pos = this.matchRegExp.lastIndex;
// Parse any classes, whitespace and then the optional cite itself
classes.push.apply(classes, this.parser.parseClasses());
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
// before handling the cite, parse the body of the quote
var tree= this.parser.parseBlocks(reEndString);
// If we got a cite, put it before the text
if(cite.length > 0) {
tree.unshift({
type: "element",
tag: "cite",
children: cite
});
}
// Parse any optional cite
this.parser.skipWhitespace({treatNewlinesAsNonWhitespace: true});
var cite = this.parser.parseInlineRun(/(\r?\n)/mg);
// If we got a cite, push it
if(cite.length > 0) {
tree.push({
type: "element",
tag: "cite",
children: cite
});
}
// Return the blockquote element
return [{
type: "element",
tag: "blockquote",
attributes: {
class: { type: "string", value: classes.join(" ") },
},
children: tree
}];
};
})();

View File

@@ -18,11 +18,11 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /^\|(?:[^\n]*)\|(?:[fhck]?)\r?\n/mg;
this.matchRegExp = /^\|(?:[^\n]*)\|(?:[fhck]?)\r?(?:\n|$)/mg;
};
var processRow = function(prevColumns) {
var cellRegExp = /(?:\|([^\n\|]*)\|)|(\|[fhck]?\r?\n)/mg,
var cellRegExp = /(?:\|([^\n\|]*)\|)|(\|[fhck]?\r?(?:\n|$))/mg,
cellTermRegExp = /((?:\x20*)\|)/mg,
tree = [],
col = 0,
@@ -38,7 +38,8 @@ var processRow = function(prevColumns) {
if(last) {
last.rowSpanCount++;
$tw.utils.addAttributeToParseTreeNode(last.element,"rowspan",last.rowSpanCount);
$tw.utils.addAttributeToParseTreeNode(last.element,"valign","center");
var vAlign = $tw.utils.getAttributeValueFromParseTreeNode(last.element,"valign","center");
$tw.utils.addAttributeToParseTreeNode(last.element,"valign",vAlign);
if(colSpanCount > 1) {
$tw.utils.addAttributeToParseTreeNode(last.element,"colspan",colSpanCount);
colSpanCount = 1;
@@ -51,9 +52,20 @@ var processRow = function(prevColumns) {
colSpanCount++;
// Move to just before the `|` terminating the cell
this.parser.pos = cellRegExp.lastIndex - 1;
} else if(cellMatch[1] === "<" && prevCell) {
colSpanCount = 1 + $tw.utils.getAttributeValueFromParseTreeNode(prevCell,"colspan",1);
$tw.utils.addAttributeToParseTreeNode(prevCell,"colspan",colSpanCount);
colSpanCount = 1;
// Move to just before the `|` terminating the cell
this.parser.pos = cellRegExp.lastIndex - 1;
} else if(cellMatch[2]) {
// End of row
if(prevCell && colSpanCount > 1) {
if(prevCell.attributes && prevCell.attributes && prevCell.attributes.colspan) {
colSpanCount += prevCell.attributes.colspan.value;
} else {
colSpanCount -= 1;
}
$tw.utils.addAttributeToParseTreeNode(prevCell,"colspan",colSpanCount);
}
this.parser.pos = cellRegExp.lastIndex - 1;
@@ -63,7 +75,16 @@ var processRow = function(prevColumns) {
this.parser.pos++;
// Look for a space at the start of the cell
var spaceLeft = false,
chr = this.parser.source.substr(this.parser.pos,1);
vAlign = null;
if(this.parser.source.substr(this.parser.pos).search(/^\^([^\^]|\^\^)/) === 0) {
vAlign = "top";
} else if(this.parser.source.substr(this.parser.pos).search(/^,([^,]|,,)/) === 0) {
vAlign = "bottom";
}
if(vAlign) {
this.parser.pos++;
}
var chr = this.parser.source.substr(this.parser.pos,1);
while(chr === " ") {
spaceLeft = true;
this.parser.pos++;
@@ -89,7 +110,10 @@ var processRow = function(prevColumns) {
// Parse the cell
cell.children = this.parser.parseInlineRun(cellTermRegExp,{eatTerminator: true});
// Set the alignment for the cell
if(cellMatch[1].substr(cellMatch[1].length-1,1) === " ") { // spaceRight
if(vAlign) {
$tw.utils.addAttributeToParseTreeNode(cell,"valign",vAlign);
}
if(this.parser.source.substr(this.parser.pos - 2,1) === " ") { // spaceRight
$tw.utils.addAttributeToParseTreeNode(cell,"align",spaceLeft ? "center" : "left");
} else if(spaceLeft) {
$tw.utils.addAttributeToParseTreeNode(cell,"align","right");
@@ -107,8 +131,8 @@ var processRow = function(prevColumns) {
exports.parse = function() {
var rowContainerTypes = {"c":"caption", "h":"thead", "":"tbody", "f":"tfoot"},
table = {type: "element", tag: "table", children: []},
rowRegExp = /^\|([^\n]*)\|([fhck]?)\r?\n/mg,
rowTermRegExp = /(\|(?:[fhck]?)\r?\n)/mg,
rowRegExp = /^\|([^\n]*)\|([fhck]?)\r?(?:\n|$)/mg,
rowTermRegExp = /(\|(?:[fhck]?)\r?(?:\n|$))/mg,
prevColumns = [],
currRowType,
rowContainer,
@@ -124,7 +148,7 @@ exports.parse = function() {
this.parser.pos = rowMatch.index + rowMatch[0].length;
} else {
// Otherwise, create a new row if this one is of a different type
if(rowType != currRowType) {
if(rowType !== currRowType) {
rowContainer = {type: "element", tag: rowContainerTypes[rowType], children: []};
table.children.push(rowContainer);
currRowType = rowType;

View File

@@ -7,10 +7,7 @@ Wiki text rule for block-level transclusion. For example:
```
{{MyTiddler}}
{{MyTiddler|tooltip}}
{{MyTiddler||TemplateTitle}}
{{MyTiddler|tooltip||TemplateTitle}}
{{MyTiddler}width:40;height:50;}.class.class
```
\*/
@@ -26,7 +23,7 @@ exports.types = {block: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|([^\|\{\}]+))?(?:\|\|([^\|\{\}]+))?\}([^\}]*)\}(?:\.(\S+))?(?:\r?\n|$)/mg;
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|\|([^\|\{\}]+))?\}\}(?:\r?\n|$)/mg;
};
exports.parse = function() {
@@ -38,17 +35,12 @@ exports.parse = function() {
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tooltip = this.match[2],
template = $tw.utils.trim(this.match[3]),
style = this.match[4],
classes = this.match[5];
template = $tw.utils.trim(this.match[2]);
// Prepare the transclude widget
var transcludeNode = {
type: "element",
tag: "$transclude",
attributes: {
tiddler: {type: "string", value: template || targetTitle}
},
attributes: {},
isBlock: true
};
var tiddlerNode = {
@@ -60,20 +52,16 @@ exports.parse = function() {
isBlock: true,
children: [transcludeNode]
};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
if(tooltip) {
transcludeNode.attributes.tooltip = {type: "string", value: tooltip};
}
if(style) {
transcludeNode.attributes.style = {type: "string", value: style};
}
if(classes) {
transcludeNode.attributes["class"] = {type: "string", value: classes.split(".").join(" ")};
if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template};
} else {
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
}
return [tiddlerNode];
};

View File

@@ -7,10 +7,7 @@ Wiki text rule for inline-level transclusion. For example:
```
{{MyTiddler}}
{{MyTiddler|tooltip}}
{{MyTiddler||TemplateTitle}}
{{MyTiddler|tooltip||TemplateTitle}}
{{MyTiddler}width:40;height:50;}.class.class
```
\*/
@@ -26,7 +23,7 @@ exports.types = {inline: true};
exports.init = function(parser) {
this.parser = parser;
// Regexp to match
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|([^\|\{\}]+))?(?:\|\|([^\|\{\}]+))?\}([^\}]*)\}(?:\.(\S+))?/mg;
this.matchRegExp = /\{\{([^\{\}\|]+)(?:\|\|([^\|\{\}]+))?\}\}/mg;
};
exports.parse = function() {
@@ -38,17 +35,12 @@ exports.parse = function() {
targetTitle = tr.title,
targetField = tr.field,
targetIndex = tr.index,
tooltip = this.match[2],
template = $tw.utils.trim(this.match[3]),
style = this.match[4],
classes = this.match[5];
template = $tw.utils.trim(this.match[2]);
// Prepare the transclude widget
var transcludeNode = {
type: "element",
tag: "$transclude",
attributes: {
tiddler: {type: "string", value: template || targetTitle}
}
attributes: {}
};
var tiddlerNode = {
type: "element",
@@ -58,20 +50,16 @@ exports.parse = function() {
},
children: [transcludeNode]
};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
if(tooltip) {
transcludeNode.attributes.tooltip = {type: "string", value: tooltip};
}
if(style) {
transcludeNode.attributes.style = {type: "string", value: style};
}
if(classes) {
transcludeNode.attributes["class"] = {type: "string", value: classes.split(".").join(" ")};
if(template) {
transcludeNode.attributes.tiddler = {type: "string", value: template};
} else {
transcludeNode.attributes.tiddler = {type: "string", value: targetTitle};
if(targetField) {
transcludeNode.attributes.field = {type: "string", value: targetField};
}
if(targetIndex) {
transcludeNode.attributes.index = {type: "string", value: targetIndex};
}
}
return [tiddlerNode];
};

View File

@@ -40,7 +40,7 @@ exports.init = function(parser) {
};
exports.parse = function() {
var reEnd = /\r?\n\$\$\$\r?\n/mg;
var reEnd = /\r?\n\$\$\$\r?(?:\n|$)/mg;
// Save the type
var parseType = this.match[1],
renderType = this.match[2];
@@ -66,7 +66,7 @@ exports.parse = function() {
} else {
// Otherwise, render to the rendertype and return in a <PRE> tag
var widgetNode = this.parser.wiki.makeWidget(parser),
container = $tw.document.createElement("div");
container = $tw.fakeDocument.createElement("div");
widgetNode.render(container,null);
var text = renderType === "text/html" ? container.innerHTML : container.textContent;
return [{

View File

@@ -15,7 +15,11 @@ Handles saving changes via the AndTidWiki Android app
var AndTidWiki = function(wiki) {
};
AndTidWiki.prototype.save = function(text,callback) {
AndTidWiki.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
// Get the pathname of this document
var pathname = decodeURIComponent(document.location.toString());
// Strip the file://

View File

@@ -18,7 +18,7 @@ Select the appropriate saver module and set it up
var DownloadSaver = function(wiki) {
};
DownloadSaver.prototype.save = function(text) {
DownloadSaver.prototype.save = function(text,method,callback) {
// Get the current filename
var filename = "tiddlywiki.html",
p = document.location.pathname.lastIndexOf("/");
@@ -28,7 +28,7 @@ DownloadSaver.prototype.save = function(text) {
// Set up the link
var link = document.createElement("a");
link.setAttribute("target","_blank");
if(Blob != undefined) {
if(Blob !== undefined) {
var blob = new Blob([text], {type: "text/html"});
link.setAttribute("href", URL.createObjectURL(blob));
} else {

View File

@@ -0,0 +1,75 @@
/*\
title: $:/core/modules/savers/fsosaver.js
type: application/javascript
module-type: saver
Handles saving changes via MS FileSystemObject ActiveXObject
Note: Since TiddlyWiki's markup contains the MOTW, the FileSystemObject normally won't be available.
However, if the wiki is loaded as an .HTA file (Windows HTML Applications) then the FSO can be used.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Select the appropriate saver module and set it up
*/
var FSOSaver = function(wiki) {
};
FSOSaver.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
// Get the pathname of this document
var pathname = unescape(document.location.pathname);
// Test for a Windows path of the form /x:\blah...
if(/^\/[A-Z]\:\\[^\\]+/i.test(pathname)) { // ie: ^/[a-z]:/[^/]+
// Remove the leading slash
pathname = pathname.substr(1);
} else if(document.location.hostname !== "" && /^\/\\[^\\]+\\[^\\]+/i.test(pathname)) { // test for \\server\share\blah... - ^/[^/]+/[^/]+
// Remove the leading slash
pathname = pathname.substr(1);
// reconstruct UNC path
pathname = "\\\\" + document.location.hostname + pathname;
} else return false;
// Save the file (as UTF-16)
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.OpenTextFile(pathname,2,-1,-1);
file.Write(text);
file.Close();
return true;
};
/*
Information about this saver
*/
FSOSaver.prototype.info = {
name: "FSOSaver",
priority: 120
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
try {
return (window.location.protocol === "file:") && !!(new ActiveXObject("Scripting.FileSystemObject"));
} catch(e) { return false; }
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new FSOSaver(wiki);
};
})();

View File

@@ -21,7 +21,7 @@ Select the appropriate saver module and set it up
var ManualDownloadSaver = function(wiki) {
};
ManualDownloadSaver.prototype.save = function(text) {
ManualDownloadSaver.prototype.save = function(text,method,callback) {
$tw.modal.display(downloadInstructionsTitle,{
downloadLink: "data:text/html," + encodeURIComponent(text)
});

View File

@@ -0,0 +1,56 @@
/*\
title: $:/core/modules/savers/msdownload.js
type: application/javascript
module-type: saver
Handles saving changes via window.navigator.msSaveBlob()
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Select the appropriate saver module and set it up
*/
var MsDownloadSaver = function(wiki) {
};
MsDownloadSaver.prototype.save = function(text,method,callback) {
// Get the current filename
var filename = "tiddlywiki.html",
p = document.location.pathname.lastIndexOf("/");
if(p !== -1) {
filename = document.location.pathname.substr(p+1);
}
// Set up the link
var blob = new Blob([text], {type: "text/html"});
window.navigator.msSaveBlob(blob,filename);
return true;
};
/*
Information about this saver
*/
MsDownloadSaver.prototype.info = {
name: "msdownload",
priority: 110
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return !!window.navigator.msSaveBlob;
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new MsDownloadSaver(wiki);
};
})();

View File

@@ -15,7 +15,11 @@ Handles saving changes via the TiddlyFox file extension
var TiddlyFoxSaver = function(wiki) {
};
TiddlyFoxSaver.prototype.save = function(text,callback) {
TiddlyFoxSaver.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
var messageBox = document.getElementById("tiddlyfox-message-box");
if(messageBox) {
// Get the pathname of this document

View File

@@ -0,0 +1,73 @@
/*\
title: $:/core/modules/savers/tiddlyie.js
type: application/javascript
module-type: saver
Handles saving changes via Internet Explorer BHO extenion (TiddlyIE)
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Select the appropriate saver module and set it up
*/
var TiddlyIESaver = function(wiki) {
};
TiddlyIESaver.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
// check existence of TiddlyIE BHO extension (note: only works after document is complete)
if(typeof(window.TiddlyIE) != "undefined") {
// Get the pathname of this document
var pathname = unescape(document.location.pathname);
// Test for a Windows path of the form /x:/blah...
if(/^\/[A-Z]\:\/[^\/]+/i.test(pathname)) { // ie: ^/[a-z]:/[^/]+ (is this better?: ^/[a-z]:/[^/]+(/[^/]+)*\.[^/]+ )
// Remove the leading slash
pathname = pathname.substr(1);
// Convert slashes to backslashes
pathname = pathname.replace(/\//g,"\\");
} else if(document.hostname !== "" && /^\/[^\/]+\/[^\/]+/i.test(pathname)) { // test for \\server\share\blah... - ^/[^/]+/[^/]+
// Convert slashes to backslashes
pathname = pathname.replace(/\//g,"\\");
// reconstruct UNC path
pathname = "\\\\" + document.location.hostname + pathname;
} else return false;
// Prompt the user to save the file
window.TiddlyIE.save(pathname, text);
return true;
} else {
return false;
}
};
/*
Information about this saver
*/
TiddlyIESaver.prototype.info = {
name: "tiddlyiesaver",
priority: 1500
};
/*
Static method that returns true if this saver is capable of working
*/
exports.canSave = function(wiki) {
return (window.location.protocol === "file:");
};
/*
Create an instance of this saver
*/
exports.create = function(wiki) {
return new TiddlyIESaver(wiki);
};
})();

View File

@@ -15,7 +15,11 @@ Handles saving changes via the TWEdit iOS app
var TWEditSaver = function(wiki) {
};
TWEditSaver.prototype.save = function(text,callback) {
TWEditSaver.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
// Bail if we're not running under TWEdit
if(typeof DeviceInfo !== "object") {
return false;

View File

@@ -21,12 +21,17 @@ var UploadSaver = function(wiki) {
this.wiki = wiki;
};
UploadSaver.prototype.save = function(text) {
UploadSaver.prototype.save = function(text,method,callback) {
// Bail out unless this is a save (rather than a download)
if(method !== "save") {
return false;
}
// Get the various parameters we need
var backupDir = ".",
var backupDir = this.wiki.getTextReference("$:/UploadBackupDir") || ".",
username = this.wiki.getTextReference("$:/UploadName"),
password = $tw.utils.getPassword("upload"),
uploadDir = ".",
uploadDir = this.wiki.getTextReference("$:/UploadDir") || ".",
uploadFilename = this.wiki.getTextReference("$:/UploadFilename") || "index.html",
url = this.wiki.getTextReference("$:/UploadURL");
// Bail out if we don't have the bits we need
if(!username || username.toString().trim() === "" || !password || password.toString().trim() === "") {
@@ -43,7 +48,7 @@ UploadSaver.prototype.save = function(text) {
head.push("--" + boundary + "\r\nContent-disposition: form-data; name=\"UploadPlugin\"\r\n");
head.push("backupDir=" + backupDir + ";user=" + username + ";password=" + password + ";uploaddir=" + uploadDir + ";;");
head.push("\r\n" + "--" + boundary);
head.push("Content-disposition: form-data; name=\"userfile\"; filename=\"index.html\"");
head.push("Content-disposition: form-data; name=\"userfile\"; filename=\"" + uploadFilename + "\"");
head.push("Content-Type: text/html;charset=UTF-8");
head.push("Content-Length: " + text.length + "\r\n");
head.push("");
@@ -56,10 +61,15 @@ UploadSaver.prototype.save = function(text) {
http.setRequestHeader("Content-Type","multipart/form-data; ;charset=UTF-8; boundary=" + boundary);
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
window.alert(http.responseText);
if(http.responseText.substr(0,4) === "0 - ") {
callback(null);
} else {
callback(http.responseText);
}
}
};
http.send(data);
$tw.notifier.display("$:/messages/StartingSave");
return true;
};
@@ -68,7 +78,7 @@ Information about this saver
*/
UploadSaver.prototype.info = {
name: "upload",
priority: 500
priority: 2000
};
/*

View File

@@ -16,10 +16,13 @@ var widget = require("$:/core/modules/widgets/widget.js");
exports.startup = function() {
var modules,n,m,f,commander;
// Load modules
// Load utility modules and initialise the logger
$tw.modules.applyMethods("utils",$tw.utils);
$tw.logger = new $tw.utils.Logger();
$tw.log = $tw.logger.log;
// Load other modules
$tw.modules.applyMethods("global",$tw);
$tw.modules.applyMethods("config",$tw.config);
$tw.modules.applyMethods("utils",$tw.utils);
if($tw.browser) {
$tw.utils.getBrowserInfo($tw.browser);
}
@@ -59,13 +62,14 @@ exports.startup = function() {
});
// Install the animator
$tw.anim = new $tw.utils.Animator();
// Kick off the stylesheet manager
$tw.stylesheetManager = new $tw.utils.StylesheetManager($tw.wiki);
// Create a root widget for attaching event handlers. By using it as the parentWidget for another widget tree, one can reuse the event handlers
$tw.rootWidget = new widget.widget({type: "widget", children: []},{
wiki: $tw.wiki,
document: document
});
$tw.rootWidget = new widget.widget({
type: "widget",
children: []
},{
wiki: $tw.wiki,
document: document
});
// Install the modal message mechanism
$tw.modal = new $tw.utils.Modal($tw.wiki);
$tw.rootWidget.addEventListener("tw-modal",function(event) {
@@ -89,14 +93,24 @@ exports.startup = function() {
downloadType: "text/plain"
});
});
$tw.rootWidget.addEventListener("tw-download-file",function(event) {
$tw.wiki.saveWiki({
method: "download",
template: event.param,
downloadType: "text/plain"
});
});
// Install the crypto event handlers
$tw.rootWidget.addEventListener("tw-set-password",function(event) {
$tw.passwordPrompt.createPrompt({
serviceName: "Set a new password for this TiddlyWiki",
noUserName: true,
submitText: "Set password",
canCancel: true,
callback: function(data) {
$tw.crypto.setPassword(data.password);
if(data) {
$tw.crypto.setPassword(data.password);
}
return true; // Get rid of the password prompt
}
});
@@ -104,6 +118,35 @@ exports.startup = function() {
$tw.rootWidget.addEventListener("tw-clear-password",function(event) {
$tw.crypto.setPassword(null);
});
// Set up the favicon
var faviconTitle = "$:/favicon.ico",
faviconLink = document.getElementById("faviconLink"),
setFavicon = function() {
var tiddler = $tw.wiki.getTiddler(faviconTitle);
if(tiddler) {
faviconLink.setAttribute("href","data:" + tiddler.fields.type + ";base64," + tiddler.fields.text);
}
};
setFavicon();
$tw.wiki.addEventListener("change",function(changes) {
if($tw.utils.hop(changes,faviconTitle)) {
setFavicon();
}
});
// Set up the styles
var styleTemplateTitle = "$:/core/ui/PageStylesheet",
styleParser = $tw.wiki.parseTiddler(styleTemplateTitle);
$tw.styleWidgetNode = $tw.wiki.makeWidget(styleParser,{document: $tw.fakeDocument});
$tw.styleContainer = $tw.fakeDocument.createElement("style");
$tw.styleWidgetNode.render($tw.styleContainer,null);
$tw.styleElement = document.createElement("style");
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
document.head.insertBefore($tw.styleElement,document.head.firstChild);
$tw.wiki.addEventListener("change",function(changes) {
if($tw.styleWidgetNode.refresh(changes,$tw.styleContainer,null)) {
$tw.styleElement.innerHTML = $tw.styleContainer.textContent;
}
});
// Display the PageMacros, which includes the PageTemplate
var templateTitle = "$:/core/ui/PageMacros",
parser = $tw.wiki.parseTiddler(templateTitle);
@@ -115,6 +158,9 @@ exports.startup = function() {
$tw.wiki.addEventListener("change",function(changes) {
$tw.pageWidgetNode.refresh(changes,$tw.pageContainer,null);
});
// Fix up the link between the root widget and the page container
$tw.rootWidget.domNodes = [$tw.pageContainer];
$tw.rootWidget.children = [$tw.pageWidgetNode];
// If we're being viewed on a data: URI then give instructions for how to save
if(document.location.protocol === "data:") {
$tw.utils.dispatchCustomEvent(document,"tw-modal",{

View File

@@ -19,6 +19,8 @@ wiki: wiki to be synced
function Syncer(options) {
var self = this;
this.wiki = options.wiki;
// Make a logger
this.log = $tw.logger.makeLog("syncer");
// Find a working syncadaptor
this.syncadaptor = undefined;
$tw.modules.forEachModuleOfType("syncadaptor",function(title,module) {
@@ -36,18 +38,7 @@ function Syncer(options) {
Error handling
*/
Syncer.prototype.showError = function(error) {
alert("Syncer error: " + error);
$tw.utils.log("Syncer error: " + error);
};
/*
Message logging
*/
Syncer.prototype.log = function(/* arguments */) {
var args = Array.prototype.slice.call(arguments,0);
args[0] = "Syncer: " + args[0];
// Temporarily disable logging to help the wood vs. trees situation; we need better filtering of log messages
//$tw.utils.log.apply(null,args);
this.log("Error: " + error);
};
/*
@@ -68,13 +59,11 @@ Syncer.prototype.init = function() {
// Hashmap by title of {revision:,changeCount:,adaptorInfo:}
this.tiddlerInfo = {};
// Record information for known tiddlers
this.wiki.forEachTiddler(function(title,tiddler) {
if(tiddler.fields["revision"]) {
self.tiddlerInfo[title] = {
revision: tiddler.fields["revision"],
adaptorInfo: self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
}
this.wiki.forEachTiddler({includeSystem: true},function(title,tiddler) {
self.tiddlerInfo[title] = {
revision: tiddler.fields["revision"],
adaptorInfo: self.syncadaptor.getTiddlerInfo(tiddler),
changeCount: self.wiki.getChangeCount(title)
}
});
// Tasks are {type: "load"/"save"/"delete", title:, queueTime:, lastModificationTime:}
@@ -385,6 +374,9 @@ Syncer.prototype.processTaskQueue = function() {
this.taskInProgress[task.title] = task;
// Dispatch the task
this.dispatchTask(task,function(err) {
if(err) {
self.showError("Sync error while processing '" + task.title + "':\n" + err);
}
// Mark that this task is no longer in progress
delete self.taskInProgress[task.title];
// Process the next task
@@ -436,19 +428,21 @@ Syncer.prototype.dispatchTask = function(task,callback) {
var changeCount = this.wiki.getChangeCount(task.title),
tiddler = this.wiki.getTiddler(task.title);
this.log("Dispatching 'save' task:",task.title);
this.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {
if(err) {
return callback(err);
}
// Adjust the info stored about this tiddler
self.tiddlerInfo[task.title] = {
changeCount: changeCount,
adaptorInfo: adaptorInfo,
revision: revision
};
// Invoke the callback
callback(null);
});
if(tiddler) {
this.syncadaptor.saveTiddler(tiddler,function(err,adaptorInfo,revision) {
if(err) {
return callback(err);
}
// Adjust the info stored about this tiddler
self.tiddlerInfo[task.title] = {
changeCount: changeCount,
adaptorInfo: adaptorInfo,
revision: revision
};
// Invoke the callback
callback(null);
});
}
} else if(task.type === "load") {
// Load the tiddler
this.log("Dispatching 'load' task:",task.title);
@@ -457,7 +451,9 @@ Syncer.prototype.dispatchTask = function(task,callback) {
return callback(err);
}
// Store the tiddler
self.storeTiddler(tiddlerFields);
if(tiddlerFields) {
self.storeTiddler(tiddlerFields);
}
// Invoke the callback
callback(null);
});

View File

@@ -13,7 +13,10 @@ Manages themes and styling.
"use strict";
var THEME_PLUGIN_TITLE = "$:/theme", // This tiddler contains the title of the current theme plugin
DEFAULT_THEME_PLUGIN = "$:/themes/tiddlywiki/snowwhite";
DEFAULT_THEME_PLUGINS = [
"$:/themes/tiddlywiki/snowwhite",
"$:/themes/tiddlywiki/vanilla"
];
function ThemeManager(wiki) {
this.wiki = wiki;
@@ -32,7 +35,12 @@ function ThemeManager(wiki) {
ThemeManager.prototype.switchTheme = function() {
// Get the name of the current theme
var themePluginTitle = this.wiki.getTiddlerText(THEME_PLUGIN_TITLE,DEFAULT_THEME_PLUGIN);
var themePluginTitle = this.wiki.getTiddlerText(THEME_PLUGIN_TITLE);
// If it doesn't exist, then fallback to one of the default themes
var index = 0;
while(!this.wiki.getTiddler(themePluginTitle) && index < DEFAULT_THEME_PLUGINS.length) {
themePluginTitle = DEFAULT_THEME_PLUGINS[index++];
}
// Accumulate the titles of the plugins that we need to load
var themePlugins = [],
self = this,
@@ -40,8 +48,9 @@ ThemeManager.prototype.switchTheme = function() {
var tiddler = self.wiki.getTiddler(title);
if(tiddler && tiddler.isPlugin() && themePlugins.indexOf(title) === -1) {
themePlugins.push(title);
var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title));
$tw.utils.each(pluginInfo.dependents,function(title) {
var pluginInfo = JSON.parse(self.wiki.getTiddlerText(title)),
dependents = $tw.utils.parseStringArray(tiddler.fields.dependents || "");
$tw.utils.each(dependents,function(title) {
accumulatePlugin(title);
});
}

View File

@@ -0,0 +1,81 @@
/*\
title: $:/core/modules/utils/crypto.js
type: application/javascript
module-type: utils
Utility functions related to crypto.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Look for an encrypted store area in the text of a TiddlyWiki file
*/
exports.extractEncryptedStoreArea = function(text) {
var encryptedStoreAreaStartMarker = "<pre id=\"encryptedStoreArea\" type=\"text/plain\" style=\"display:none;\">",
encryptedStoreAreaStart = text.indexOf(encryptedStoreAreaStartMarker);
if(encryptedStoreAreaStart !== -1) {
var encryptedStoreAreaEnd = text.indexOf("</pre>",encryptedStoreAreaStart);
if(encryptedStoreAreaEnd !== -1) {
return $tw.utils.htmlDecode(text.substring(encryptedStoreAreaStart + encryptedStoreAreaStartMarker.length,encryptedStoreAreaEnd-1));
}
}
return null;
};
/*
Attempt to extract the tiddlers from an encrypted store area using the current password. If the password is not provided then the password in the password store will be used
*/
exports.decryptStoreArea = function(encryptedStoreArea,password) {
var decryptedText = $tw.crypto.decrypt(encryptedStoreArea,password);
if(decryptedText) {
var json = JSON.parse(decryptedText),
tiddlers = [];
for(var title in json) {
if(title !== "$:/isEncrypted") {
tiddlers.push(json[title]);
}
}
return tiddlers;
} else {
return null;
}
};
exports.decryptStoreAreaInteractive = function(encryptedStoreArea,callback) {
// Try to decrypt with the current password
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea);
if(tiddlers) {
callback(tiddlers);
} else {
// Prompt for a new password and keep trying
$tw.passwordPrompt.createPrompt({
serviceName: "Enter a password to decrypt the imported TiddlyWiki",
noUserName: true,
canCancel: true,
submitText: "Decrypt",
callback: function(data) {
// Exit if the user cancelled
if(!data) {
return false;
}
// Attempt to decrypt the tiddlers
var tiddlers = $tw.utils.decryptStoreArea(encryptedStoreArea,data.password);
if(tiddlers) {
callback(tiddlers);
// Exit and remove the password prompt
return true;
} else {
// We didn't decrypt everything, so continue to prompt for password
return false;
}
}
});
}
};
})();

View File

@@ -18,9 +18,11 @@ Set style properties of an element
styles: ordered array of {name: value} pairs
*/
exports.setStyle = function(element,styles) {
for(var t=0; t<styles.length; t++) {
for(var styleName in styles[t]) {
element.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];
if(element.nodeType === 1) { // Element.ELEMENT_NODE
for(var t=0; t<styles.length; t++) {
for(var styleName in styles[t]) {
element.style[$tw.utils.convertStyleNameToPropertyName(styleName)] = styles[t][styleName];
}
}
}
};
@@ -130,15 +132,7 @@ exports.convertEventName = function(eventName) {
// Setup constants for the current browser
exports.getBrowserInfo = function(info) {
info.requestFullScreen = document.body.webkitRequestFullScreen !== undefined ? "webkitRequestFullScreen" :
document.body.mozRequestFullScreen !== undefined ? "mozRequestFullScreen" :
document.body.requestFullScreen !== undefined ? "requestFullScreen" : "";
info.cancelFullScreen = document.webkitCancelFullScreen !== undefined ? "webkitCancelFullScreen" :
document.mozCancelFullScreen !== undefined ? "mozCancelFullScreen" :
document.cancelFullScreen !== undefined ? "cancelFullScreen" : "";
info.isFullScreen = document.webkitIsFullScreen !== undefined ? "webkitIsFullScreen" :
document.mozFullScreen !== undefined ? "mozFullScreen" :
document.fullScreen !== undefined ? "fullScreen" : "";
info.isIE = (/msie|trident/i.test(navigator.userAgent));
};
})();

View File

@@ -18,7 +18,7 @@ Code thanks to John Resig, http://ejohn.org/blog/comparing-document-position/
*/
exports.domContains = function(a,b) {
return a.contains ?
a != b && a.contains(b) :
a !== b && a.contains(b) :
!!(a.compareDocumentPosition(b) & 16);
};
@@ -29,7 +29,7 @@ exports.removeChildren = function(node) {
};
exports.hasClass = function(el,className) {
return el.className.split(" ").indexOf(className) !== -1;
return el && el.className && el.className.split(" ").indexOf(className) !== -1;
};
exports.addClass = function(el,className) {

View File

@@ -67,13 +67,12 @@ Notifier.prototype.display = function(title,options) {
{opacity: "0.0"},
{transform: "translateX(" + (notification.offsetWidth) + "px)"}
]);
// Set up an event for the transition end
notification.addEventListener($tw.utils.convertEventName("transitionEnd"),function(event) {
// Remove the modal message from the DOM once the transition ends
setTimeout(function() {
if(notification.parentNode) {
// Remove the modal message from the DOM
document.body.removeChild(notification);
}
},false);
},duration);
},$tw.config.preferences.notificationDuration);
};

View File

@@ -26,16 +26,28 @@ Popup.prototype.show = function(options) {
this.title = options.title;
this.wiki = options.wiki;
this.anchorDomNode = options.domNode;
$tw.utils.addClass(this.anchorDomNode,"tw-popup");
this.rootElement.addEventListener("click",this,false);
};
Popup.prototype.handleEvent = function(event) {
if(event.type === "click" && this.anchorDomNode !== event.target && !$tw.utils.domContains(this.anchorDomNode,event.target)) {
this.cancel();
// Dismiss the popup if we get a click on an element that doesn't have .tw-popup class
if(event.type === "click") {
var node = event.target;
while(node && !$tw.utils.hasClass(node,"tw-popup")) {
node = node.parentNode;
}
if(!node) {
this.cancel();
}
}
};
Popup.prototype.cancel = function() {
if(this.anchorDomNode) {
$tw.utils.removeClass(this.anchorDomNode,"tw-popup");
this.anchorDomNode = null;
}
this.rootElement.removeEventListener("click",this,false);
if(this.title) {
this.wiki.deleteTiddler(this.title);

View File

@@ -1,75 +0,0 @@
/*\
title: $:/core/modules/utils/styles.js
type: application/javascript
module-type: utils
The stylesheet manager automatically renders any tiddlers tagged "$:/tags/stylesheet" as HTML style elements.
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var STYLESHEET_ID_PREFIX = "tw-tiddler-stylesheet-",
STYLESHEET_TAG = "$:/tags/stylesheet";
function StylesheetManager(wiki) {
this.wiki = wiki;
this.stylesheets = {}; // Hashmap of currently rendered stylesheets
// Apply initial stylesheets
var self = this,
stylesheetTiddlers = this.wiki.filterTiddlers("[is[shadow]!has[draft.of]tag[" + STYLESHEET_TAG + "]] [!is[shadow]!has[draft.of]tag[" + STYLESHEET_TAG + "]]");
$tw.utils.each(stylesheetTiddlers,function(title,index) {
self.addStylesheet(title);
});
// Listen out for changes
this.wiki.addEventListener("change",function(changes) {
self.handleTiddlerChanges(changes);
});
}
StylesheetManager.prototype.addStylesheet = function(title) {
// Record the stylesheet in the hashmap
this.stylesheets[title] = true;
// Parse the tiddler and render as plain text
var text = this.wiki.renderTiddler("text/plain",title);
// Create a style element and put it in the document
var styleNode = document.createElement("style");
styleNode.setAttribute("type","text/css");
styleNode.setAttribute("id",STYLESHEET_ID_PREFIX + title);
styleNode.appendChild(document.createTextNode(text));
document.getElementsByTagName("head")[0].appendChild(styleNode);
};
StylesheetManager.prototype.removeStylesheet = function(title) {
// Remove the stylesheet from the hashmap
if($tw.utils.hop(this.stylesheets,title)) {
delete this.stylesheets[title];
}
// Remove the stylesheet from the document
var styleNode = document.getElementById(STYLESHEET_ID_PREFIX + title);
if(styleNode) {
styleNode.parentNode.removeChild(styleNode);
}
};
StylesheetManager.prototype.handleTiddlerChanges = function(changes) {
var self = this;
$tw.utils.each(changes,function(change,title) {
// Remove any existing stylesheet for the changed tiddler
if($tw.utils.hop(self.stylesheets,title)) {
self.removeStylesheet(title);
}
// Add the stylesheet if it is tagged and not a draft
var tiddler = self.wiki.getTiddler(title);
if(tiddler && tiddler.hasTag(STYLESHEET_TAG) && !tiddler.hasField("draft.of")) {
self.addStylesheet(title);
}
});
};
exports.StylesheetManager = StylesheetManager;
})();

View File

@@ -66,6 +66,7 @@ TW_Element.prototype.insertBefore = function(node,nextSibling) {
var p = this.children.indexOf(nextSibling);
if(p !== -1) {
this.children.splice(p,0,node);
node.parentNode = this;
} else {
this.appendChild(node);
}
@@ -181,6 +182,6 @@ var document = {
},
};
exports.document = document;
exports.fakeDocument = document;
})();

View File

@@ -0,0 +1,43 @@
/*\
title: $:/core/modules/utils/logger.js
type: application/javascript
module-type: utils
A basic logging implementation
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
/*
Make a new logger
*/
function Logger() {
}
/*
Make a log function for a particular component
*/
Logger.prototype.makeLog = function(componentName) {
var self = this;
return function(/* args */) {
self.log.apply(self.log,[componentName + ":"].concat(Array.prototype.slice.call(arguments,0)));
};
};
/*
Log a message
*/
Logger.prototype.log = function(/* args */) {
if(console !== undefined && console.log !== undefined) {
return Function.apply.call(console.log, console, arguments);
}
};
exports.Logger = Logger;
})();

View File

@@ -19,6 +19,13 @@ exports.addAttributeToParseTreeNode = function(node,name,value) {
}
};
exports.getAttributeValueFromParseTreeNode = function(node,name,defaultValue) {
if(node.type === "element" && node.attributes && node.attributes[name] && node.attributes[name].value !== undefined) {
return node.attributes[name].value;
}
return defaultValue;
};
exports.addClassToParseTreeNode = function(node,classString) {
var classes = [];
if(node.type === "element") {

View File

@@ -275,7 +275,7 @@ exports.unescapeLineBreaks = function(s) {
// Copied from peg.js, thanks to David Majda
exports.escape = function(ch) {
var charCode = ch.charCodeAt(0);
if (charCode <= 0xFF) {
if(charCode <= 0xFF) {
return '\\x' + $tw.utils.pad(charCode.toString(16).toUpperCase());
} else {
return '\\u' + $tw.utils.pad(charCode.toString(16).toUpperCase(),4);
@@ -402,4 +402,27 @@ exports.getAnimationDuration = function() {
return parseInt($tw.wiki.getTiddlerText("$:/config/AnimationDuration","400"),10);
};
/*
Hash a string to a number
Derived from http://stackoverflow.com/a/15710692
*/
exports.hashString = function(str) {
return str.split("").reduce(function(a,b) {
a = ((a << 5) - a) + b.charCodeAt(0);
return a & a;
},0);
};
/*
Decode a base64 string
*/
exports.base64Decode = function(string64) {
if($tw.browser) {
// TODO
throw "$tw.utils.base64Decode() doesn't work in the browser";
} else {
return (new Buffer(string64,"base64")).toString();
}
};
})();

View File

@@ -39,8 +39,8 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
domNode.setAttribute("multiple","multiple");
// Add a click event handler
domNode.addEventListener("change",function (event) {
self.wiki.readFiles(event.target.files,function(tiddlerFields) {
self.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify([tiddlerFields])});
self.wiki.readFiles(event.target.files,function(tiddlerFieldsArray) {
self.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)});
});
return false;
},false);

View File

@@ -62,7 +62,7 @@ CheckboxWidget.prototype.handleChangeEvent = function(event) {
var checked = this.inputDomNode.checked,
tiddler = this.wiki.getTiddler(this.checkboxTitle);
if(tiddler && tiddler.hasTag(this.checkboxTag) !== checked) {
var newTags = tiddler.fields.tags.slice(0),
var newTags = (tiddler.fields.tags || []).slice(0),
pos = newTags.indexOf(this.checkboxTag);
if(pos !== -1) {
newTags.splice(pos,1);

View File

@@ -0,0 +1,64 @@
/*\
title: $:/core/modules/widgets/codeblock.js
type: application/javascript
module-type: widget
Code block node widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var CodeBlockWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
CodeBlockWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
CodeBlockWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
var codeNode = this.document.createElement("code");
if(this.getAttribute("language")) {
codeNode.setAttribute("class",this.getAttribute("language"));
}
var domNode = this.document.createElement("pre");
codeNode.appendChild(this.document.createTextNode(this.getAttribute("code")));
domNode.appendChild(codeNode);
parent.insertBefore(domNode,nextSibling);
this.domNodes.push(domNode);
if(this.postRender) {
this.postRender();
}
};
/*
Compute the internal state of the widget
*/
CodeBlockWidget.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
*/
CodeBlockWidget.prototype.refresh = function(changedTiddlers) {
return false;
};
exports.codeblock = CodeBlockWidget;
})();

View File

@@ -87,12 +87,14 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
this.dragEnterCount = 0;
// Remove highlighting
$tw.utils.removeClass(this.domNodes[0],"tw-dragover");
// Try to import the various data types we understand
this.importData(dataTransfer);
// Import any files in the drop
this.wiki.readFiles(dataTransfer.files,function(tiddlerFields) {
self.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify([tiddlerFields])});
var numFiles = this.wiki.readFiles(dataTransfer.files,function(tiddlerFieldsArray) {
self.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify(tiddlerFieldsArray)});
});
// Try to import the various data types we understand
if(numFiles === 0) {
this.importData(dataTransfer);
}
// Tell the browser that we handled the drop
event.preventDefault();
// Stop the drop ripple up to any parent handlers
@@ -100,30 +102,62 @@ DropZoneWidget.prototype.handleDropEvent = function(event) {
};
DropZoneWidget.prototype.importData = function(dataTransfer) {
// Try each provided data type in turn
for(var t=0; t<this.importDataTypes.length; t++) {
var dataType = this.importDataTypes[t];
var data = dataTransfer.getData(dataType.type);
if(data !== "") {
var tiddlerFields = dataType.convertToFields(data);
if(!tiddlerFields.title) {
tiddlerFields.title = this.generateTitle("Untitled");
if(!$tw.browser.isIE || this.importDataTypes[t].IECompatible) {
// Get the data
var dataType = this.importDataTypes[t];
var data = dataTransfer.getData(dataType.type);
// Import the tiddlers in the data
if(data !== "" && data !== null) {
var tiddlerFields = dataType.convertToFields(data);
if(!tiddlerFields.title) {
tiddlerFields.title = this.wiki.generateNewTitle("Untitled");
}
this.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify([tiddlerFields])});
return;
}
this.dispatchEvent({type: "tw-import-tiddlers", param: JSON.stringify([tiddlerFields])});
return;
}
};
};
DropZoneWidget.prototype.importDataTypes = [
{type: "text/vnd.tiddler", convertToFields: function(data) {
{type: "text/vnd.tiddler", IECompatible: false, convertToFields: function(data) {
return JSON.parse(data);
}},
{type: "text/plain", convertToFields: function(data) {
{type: "URL", IECompatible: true, convertToFields: function(data) {
// Check for tiddler data URI
var match = decodeURI(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
if(match) {
return JSON.parse(match[1]);
} else {
return { // As URL string
text: data
};
}
}},
{type: "text/x-moz-url", IECompatible: false, convertToFields: function(data) {
// Check for tiddler data URI
var match = decodeURI(data).match(/^data\:text\/vnd\.tiddler,(.*)/i);
if(match) {
return JSON.parse(match[1]);
} else {
return { // As URL string
text: data
};
}
}},
{type: "text/plain", IECompatible: false, convertToFields: function(data) {
return {
text: data
};
}},
{type: "text/uri-list", convertToFields: function(data) {
{type: "Text", IECompatible: true, convertToFields: function(data) {
return {
text: data
};
}},
{type: "text/uri-list", IECompatible: false, convertToFields: function(data) {
return {
text: data
};

View File

@@ -37,17 +37,19 @@ EditTextWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Create our element
var editInfo = this.getEditInfo();
var domNode = this.document.createElement(this.editTag);
if(this.editType) {
domNode.setAttribute("type",this.editType);
}
if(this.editPlaceholder) {
if(editInfo.value === "" && this.editPlaceholder) {
domNode.setAttribute("placeholder",this.editPlaceholder);
}
// Assign classes
domNode.className = this.editClass;
if(this.editClass) {
domNode.className = this.editClass;
}
// Set the text
var editInfo = this.getEditInfo();
if(this.editTag === "textarea") {
domNode.appendChild(this.document.createTextNode(editInfo.value));
} else {

View File

@@ -33,16 +33,8 @@ EditWidget.prototype.render = function(parent,nextSibling) {
this.renderChildren(parent,nextSibling);
};
// Mappings from content type to editor type
// TODO: This information should be configurable/extensible
var editorTypeMappings = {
"text/vnd.tiddlywiki": "text",
"image/svg+xml": "text",
"image/jpg": "bitmap",
"image/jpeg": "bitmap",
"image/gif": "bitmap",
"image/png": "bitmap"
};
// Mappings from content type to editor type are stored in tiddlers with this prefix
var EDITOR_MAPPING_PREFIX = "$:/config/EditorTypeMappings/";
/*
Compute the internal state of the widget
@@ -53,6 +45,7 @@ EditWidget.prototype.execute = function() {
this.editField = this.getAttribute("field","text");
this.editIndex = this.getAttribute("index");
this.editClass = this.getAttribute("class");
this.editPlaceholder = this.getAttribute("placeholder");
// Get the content type of the thing we're editing
var type;
if(this.editField === "text") {
@@ -63,15 +56,16 @@ EditWidget.prototype.execute = function() {
}
type = type || "text/vnd.tiddlywiki";
// Choose the appropriate edit widget
var editorType = editorTypeMappings[type] || "text";
var editorType = this.wiki.getTiddlerText(EDITOR_MAPPING_PREFIX + type) || "text";
// Make the child widgets
this.makeChildWidgets([{
type: "edit-" + editorType,
attributes: {
title: {type: "string", value: this.editTitle},
tiddler: {type: "string", value: this.editTitle},
field: {type: "string", value: this.editField},
index: {type: "string", value: this.editIndex},
"class": {type: "string", value: this.editClass}
"class": {type: "string", value: this.editClass},
"placeholder": {type: "string", value: this.editPlaceholder}
}
}]);
};

View File

@@ -72,10 +72,13 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle);
if(tiddler && typeof event.param === "string" && event.param !== "" && !$tw.utils.hop(tiddler.fields,event.param)) {
var addition = {};
addition[event.param] = "";
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
if(tiddler && typeof event.param === "string") {
var name = event.param.toLowerCase();
if(name !== "" && !$tw.utils.hop(tiddler.fields,name)) {
var addition = this.wiki.getModificationFields();
addition[name] = "";
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
}
}
return true;
};
@@ -85,9 +88,12 @@ FieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {
if(tiddler && tiddler.fields.tags) {
var p = tiddler.fields.tags.indexOf(event.param);
if(p !== -1) {
var modification = {};
var modification = this.wiki.getModificationFields();
modification.tags = (tiddler.fields.tags || []).slice(0);
modification.tags.splice(p,1);
if(modification.tags.length === 0) {
modification.tags = undefined;
}
this.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));
}
}
@@ -97,7 +103,7 @@ FieldManglerWidget.prototype.handleRemoveTagEvent = function(event) {
FieldManglerWidget.prototype.handleAddTagEvent = function(event) {
var tiddler = this.wiki.getTiddler(this.mangleTitle);
if(tiddler && typeof event.param === "string" && event.param !== "") {
var modification = {};
var modification = this.wiki.getModificationFields();
modification.tags = (tiddler.fields.tags || []).slice(0);
$tw.utils.pushTop(modification.tags,event.param);
this.wiki.addTiddler(new $tw.Tiddler(tiddler,modification));

View File

@@ -91,7 +91,7 @@ LinkWidget.prototype.handleClickEvent = function (event) {
this.dispatchEvent({
type: "tw-navigate",
navigateTo: this.to,
navigateFromTitle: this.getVariable("currentTiddler"),
navigateFromTitle: this.getVariable("storyTiddler"),
navigateFromNode: this,
navigateFromClientRect: { top: bounds.top, left: bounds.left, width: bounds.width, right: bounds.right, bottom: bounds.bottom, height: bounds.height
}
@@ -114,21 +114,32 @@ LinkWidget.prototype.handleDragStartEvent = function(event) {
this.dragImage.appendChild(inner);
this.document.body.appendChild(this.dragImage);
// Astoundingly, we need to cover the dragger up: http://www.kryogenix.org/code/browser/custom-drag-image.html
var bounds = this.dragImage.firstChild.getBoundingClientRect(),
cover = this.document.createElement("div");
var cover = this.document.createElement("div");
cover.className = "tw-tiddler-dragger-cover";
cover.style.left = (bounds.left - 16) + "px";
cover.style.top = (bounds.top - 16) + "px";
cover.style.width = (bounds.width + 32) + "px";
cover.style.height = (bounds.height + 32) + "px";
cover.style.left = (inner.offsetLeft - 16) + "px";
cover.style.top = (inner.offsetTop - 16) + "px";
cover.style.width = (inner.offsetWidth + 32) + "px";
cover.style.height = (inner.offsetHeight + 32) + "px";
this.dragImage.appendChild(cover);
// Set the data transfer properties
var dataTransfer = event.dataTransfer;
// First the image
dataTransfer.effectAllowed = "copy";
dataTransfer.setDragImage(this.dragImage.firstChild,-16,-16);
if(dataTransfer.setDragImage) {
dataTransfer.setDragImage(this.dragImage.firstChild,-16,-16);
}
// Then the data
dataTransfer.clearData();
dataTransfer.setData("text/vnd.tiddler",this.wiki.getTiddlerAsJson(this.to));
dataTransfer.setData("text/plain",this.wiki.getTiddlerText(this.to,""));
var jsonData = this.wiki.getTiddlerAsJson(this.to),
textData = this.wiki.getTiddlerText(this.to,"");
// IE doesn't like these content types
if(!$tw.browser.isIE) {
dataTransfer.setData("text/vnd.tiddler",jsonData);
dataTransfer.setData("text/plain",textData);
dataTransfer.setData("text/x-moz-url","data:text/vnd.tiddler," + encodeURI(jsonData));
}
dataTransfer.setData("URL","data:text/vnd.tiddler," + encodeURI(jsonData));
dataTransfer.setData("Text",textData);
event.stopPropagation();
} else {
event.preventDefault();

View File

@@ -24,6 +24,7 @@ var NavigatorWidget = function(parseTreeNode,options) {
{type: "tw-cancel-tiddler", handler: "handleCancelTiddlerEvent"},
{type: "tw-close-tiddler", handler: "handleCloseTiddlerEvent"},
{type: "tw-close-all-tiddlers", handler: "handleCloseAllTiddlersEvent"},
{type: "tw-close-other-tiddlers", handler: "handleCloseOtherTiddlersEvent"},
{type: "tw-new-tiddler", handler: "handleNewTiddlerEvent"},
{type: "tw-import-tiddlers", handler: "handleImportTiddlersEvent"},
]);
@@ -69,125 +70,154 @@ NavigatorWidget.prototype.refresh = function(changedTiddlers) {
};
NavigatorWidget.prototype.getStoryList = function() {
this.storyList = this.wiki.getTiddlerList(this.storyTitle);
return this.storyTitle ? this.wiki.getTiddlerList(this.storyTitle) : null;
};
NavigatorWidget.prototype.saveStoryList = function() {
NavigatorWidget.prototype.saveStoryList = function(storyList) {
var storyTiddler = this.wiki.getTiddler(this.storyTitle);
this.wiki.addTiddler(new $tw.Tiddler({
title: this.storyTitle
},storyTiddler,{list: this.storyList}));
this.wiki.addTiddler(new $tw.Tiddler(
{title: this.storyTitle},
storyTiddler,
{list: storyList}
));
};
NavigatorWidget.prototype.findTitleInStory = function(title,defaultIndex) {
for(var t=0; t<this.storyList.length; t++) {
if(this.storyList[t] === title) {
return t;
NavigatorWidget.prototype.findTitleInStory = function(storyList,title,defaultIndex) {
var p = storyList.indexOf(title);
return p === -1 ? defaultIndex : p;
};
NavigatorWidget.prototype.removeTitleFromStory = function(storyList,title) {
var p = storyList.indexOf(title);
while(p !== -1) {
storyList.splice(p,1);
p = storyList.indexOf(title);
}
};
NavigatorWidget.prototype.replaceFirstTitleInStory = function(storyList,oldTitle,newTitle) {
var pos = storyList.indexOf(oldTitle);
if(pos !== -1) {
storyList[pos] = newTitle;
do {
pos = storyList.indexOf(oldTitle,pos + 1);
if(pos !== -1) {
storyList.splice(pos,1);
}
} while(pos !== -1);
} else {
storyList.splice(0,0,newTitle);
}
};
NavigatorWidget.prototype.addToStory = function(title,fromTitle) {
var storyList = this.getStoryList();
if(storyList) {
// See if the tiddler is already there
var slot = this.findTitleInStory(storyList,title,-1);
// If not we need to add it
if(slot === -1) {
// First we try to find the position of the story element we navigated from
slot = this.findTitleInStory(storyList,fromTitle,-1) + 1;
// Add the tiddler
storyList.splice(slot,0,title);
// Save the story
this.saveStoryList(storyList);
}
}
return defaultIndex;
}
};
/*
Add a new record to the top of the history stack
title: a title string or an array of title strings
fromPageRect: page coordinates of the origin of the navigation
*/
NavigatorWidget.prototype.addToHistory = function(title,fromPageRect) {
var titles = $tw.utils.isArray(title) ? title : [title];
// Add a new record to the top of the history stack
if(this.historyTitle) {
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
$tw.utils.each(titles,function(title) {
historyList.push({title: title, fromPageRect: fromPageRect});
});
this.wiki.setTiddlerData(this.historyTitle,historyList);
}
};
/*
Handle a tw-navigate event
*/
NavigatorWidget.prototype.handleNavigateEvent = function(event) {
if(this.storyTitle) {
// Update the story tiddler if specified
this.getStoryList();
// See if the tiddler is already there
var slot = this.findTitleInStory(event.navigateTo,-1);
// If not we need to add it
if(slot === -1) {
// First we try to find the position of the story element we navigated from
slot = this.findTitleInStory(event.navigateFromTitle,-1) + 1;
// Add the tiddler
this.storyList.splice(slot,0,event.navigateTo);
// Save the story
this.saveStoryList();
}
}
// Add a new record to the top of the history stack
if(this.historyTitle) {
var historyList = this.wiki.getTiddlerData(this.historyTitle,[]);
historyList.push({title: event.navigateTo, fromPageRect: event.navigateFromClientRect});
this.wiki.setTiddlerData(this.historyTitle,historyList);
}
this.addToStory(event.navigateTo,event.navigateFromTitle);
this.addToHistory(event.navigateTo,event.navigateFromClientRect);
return false;
};
// Close a specified tiddler
NavigatorWidget.prototype.handleCloseTiddlerEvent = function(event) {
this.getStoryList();
var title = event.param || event.tiddlerTitle,
storyList = this.getStoryList();
// Look for tiddlers with this title to close
var slot = this.findTitleInStory(event.tiddlerTitle,-1);
if(slot !== -1) {
this.storyList.splice(slot,1);
this.saveStoryList();
}
this.removeTitleFromStory(storyList,title);
this.saveStoryList(storyList);
return false;
};
// Close all tiddlers
NavigatorWidget.prototype.handleCloseAllTiddlersEvent = function(event) {
this.storyList = [];
this.saveStoryList();
this.saveStoryList([]);
return false;
};
// Close other tiddlers
NavigatorWidget.prototype.handleCloseOtherTiddlersEvent = function(event) {
var title = event.param || event.tiddlerTitle;
this.saveStoryList([title]);
return false;
};
// Place a tiddler in edit mode
NavigatorWidget.prototype.handleEditTiddlerEvent = function(event) {
this.getStoryList();
// Replace the specified tiddler with a draft in edit mode
var draftTiddler = this.getDraftTiddler(event.tiddlerTitle),
gotOne = false;
for(var t=this.storyList.length-1; t>=0; t--) {
// Replace the first story instance of the original tiddler name with the draft title
if(this.storyList[t] === event.tiddlerTitle) {
if(!gotOne) {
this.storyList[t] = draftTiddler.fields.title;
gotOne = true;
} else {
this.storyList.splice(t,1);
}
} else if(this.storyList[t] === draftTiddler.fields.title) {
// Remove any existing references to the draft
this.storyList.splice(t,1);
}
}
this.saveStoryList();
var title = event.param || event.tiddlerTitle,
draftTiddler = this.makeDraftTiddler(title),
draftTitle = draftTiddler.fields.title,
storyList = this.getStoryList();
this.removeTitleFromStory(storyList,draftTitle);
this.replaceFirstTitleInStory(storyList,title,draftTitle);
this.addToHistory(draftTitle,event.navigateFromClientRect);
this.saveStoryList(storyList);
return false;
};
// Delete a tiddler
NavigatorWidget.prototype.handleDeleteTiddlerEvent = function(event) {
// Get the tiddler we're deleting
var tiddler = this.wiki.getTiddler(event.tiddlerTitle);
var title = event.param || event.tiddlerTitle,
tiddler = this.wiki.getTiddler(title),
storyList = this.getStoryList();
// Check if the tiddler we're deleting is in draft mode
if(tiddler.hasField("draft.title")) {
// Delete the original tiddler
this.wiki.deleteTiddler(tiddler.fields["draft.of"]);
var originalTitle = tiddler.fields["draft.of"];
this.wiki.deleteTiddler(originalTitle);
this.removeTitleFromStory(storyList,originalTitle);
}
// Delete this tiddler
this.wiki.deleteTiddler(event.tiddlerTitle);
this.wiki.deleteTiddler(title);
// Remove the closed tiddler from the story
this.getStoryList();
// Look for tiddler with this title to close
var slot = this.findTitleInStory(event.tiddlerTitle,-1);
if(slot !== -1) {
this.storyList.splice(slot,1);
this.saveStoryList();
}
this.removeTitleFromStory(storyList,title);
this.saveStoryList(storyList);
return false;
};
/*
Create/reuse the draft tiddler for a given title
*/
NavigatorWidget.prototype.getDraftTiddler = function(targetTitle) {
NavigatorWidget.prototype.makeDraftTiddler = function(targetTitle) {
// See if there is already a draft tiddler for this tiddler
var drafts = [];
this.wiki.forEachTiddler(function(title,tiddler) {
this.wiki.forEachTiddler({includeSystem: true},function(title,tiddler) {
if(tiddler.fields["draft.title"] && tiddler.fields["draft.of"] === targetTitle) {
drafts.push(tiddler);
}
@@ -227,71 +257,58 @@ NavigatorWidget.prototype.generateDraftTitle = function(title) {
// Take a tiddler out of edit mode, saving the changes
NavigatorWidget.prototype.handleSaveTiddlerEvent = function(event) {
this.getStoryList();
var storyTiddlerModified = false; // We have to special case saving the story tiddler itself
for(var t=0; t<this.storyList.length; t++) {
if(this.storyList[t] === event.tiddlerTitle) {
var tiddler = this.wiki.getTiddler(event.tiddlerTitle);
if(tiddler) {
var draftTitle = tiddler.fields["draft.title"],
draftOf = tiddler.fields["draft.of"];
if(draftTitle) {
var isRename = draftOf !== draftTitle,
isConfirmed = true;
if(isRename && this.wiki.tiddlerExists(draftTitle)) {
isConfirmed = confirm("Do you wish to overwrite the tiddler '" + draftTitle + "'?");
}
if(isConfirmed) {
// Save the draft tiddler as the real tiddler
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{
title: draftTitle,
"draft.title": undefined,
"draft.of": undefined
},this.wiki.getModificationFields()));
// Remove the draft tiddler
this.wiki.deleteTiddler(event.tiddlerTitle);
// Remove the original tiddler if we're renaming it
if(isRename) {
this.wiki.deleteTiddler(draftOf);
}
// Make the story record point to the newly saved tiddler
this.storyList[t] = draftTitle;
// Check if we're modifying the story tiddler itself
if(draftTitle === this.storyTitle) {
storyTiddlerModified = true;
}
}
var title = event.param || event.tiddlerTitle,
tiddler = this.wiki.getTiddler(title),
storyList = this.getStoryList(),
storyTiddlerModified = false; // We have to special case saving the story tiddler itself
// Replace the original tiddler with the draft
if(tiddler) {
var draftTitle = (tiddler.fields["draft.title"] || "").trim(),
draftOf = (tiddler.fields["draft.of"] || "").trim();
if(draftTitle) {
var isRename = draftOf !== draftTitle,
isConfirmed = true;
if(isRename && this.wiki.tiddlerExists(draftTitle)) {
isConfirmed = confirm("Do you wish to overwrite the tiddler '" + draftTitle + "'?");
}
if(isConfirmed) {
// Save the draft tiddler as the real tiddler
this.wiki.addTiddler(new $tw.Tiddler(this.wiki.getCreationFields(),tiddler,{
title: draftTitle,
"draft.title": undefined,
"draft.of": undefined
},this.wiki.getModificationFields()));
// Remove the draft tiddler
this.wiki.deleteTiddler(title);
// Remove the original tiddler if we're renaming it
if(isRename) {
this.wiki.deleteTiddler(draftOf);
}
// Replace the draft in the story with the original
this.replaceFirstTitleInStory(storyList,title,draftTitle);
this.addToHistory(draftTitle,event.navigateFromClientRect);
if(draftTitle !== this.storyTitle) {
this.saveStoryList(storyList);
}
}
}
}
if(!storyTiddlerModified) {
this.saveStoryList();
}
return false;
};
// Take a tiddler out of edit mode without saving the changes
NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
this.getStoryList();
var storyTiddlerModified = false;
for(var t=0; t<this.storyList.length; t++) {
if(this.storyList[t] === event.tiddlerTitle) {
var tiddler = this.wiki.getTiddler(event.tiddlerTitle);
if(tiddler && tiddler.hasField("draft.title")) {
// Remove the draft tiddler
this.wiki.deleteTiddler(event.tiddlerTitle);
// Make the story record point to the original tiddler
this.storyList[t] = tiddler.fields["draft.title"];
// Check if we're modifying the story tiddler itself
if(tiddler.fields["draft.title"] === this.storyTitle) {
storyTiddlerModified = true;
}
}
}
}
if(!storyTiddlerModified) {
this.saveStoryList();
// Flip the specified tiddler from draft back to the original
var draftTitle = event.param || event.tiddlerTitle,
draftTiddler = this.wiki.getTiddler(draftTitle),
originalTitle = draftTiddler.fields["draft.of"],
storyList = this.getStoryList();
if(draftTiddler && originalTitle) {
// Remove the draft tiddler
this.wiki.deleteTiddler(draftTitle);
this.replaceFirstTitleInStory(storyList,draftTitle,originalTitle);
this.addToHistory(originalTitle,event.navigateFromClientRect);
this.saveStoryList(storyList);
}
return false;
};
@@ -299,18 +316,11 @@ NavigatorWidget.prototype.handleCancelTiddlerEvent = function(event) {
// Create a new draft tiddler
NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
// Get the story details
this.getStoryList();
var storyList = this.getStoryList();
// Get the template tiddler if there is one
var templateTiddler = this.wiki.getTiddler(event.param);
// Create the new tiddler
var baseTitle = (templateTiddler && templateTiddler.fields.title) || "New Tiddler",
title;
for(var t=0; true; t++) {
title = baseTitle + (t ? " " + t : "");
if(!this.wiki.tiddlerExists(title)) {
break;
}
}
var title = this.wiki.generateNewTitle((templateTiddler && templateTiddler.fields.title) || "New Tiddler");
var tiddler = new $tw.Tiddler(this.wiki.getCreationFields(),{
text: "Newly created tiddler",
title: title
@@ -319,22 +329,22 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
// Create the draft tiddler
var draftTitle = this.generateDraftTitle(title),
draftTiddler = new $tw.Tiddler({
text: "Type the text for the new tiddler"
},templateTiddler,{
text: ""
},templateTiddler,
this.wiki.getCreationFields(),
{
title: draftTitle,
"draft.title": title,
"draft.of": title
},this.wiki.getModificationFields());
this.wiki.addTiddler(draftTiddler);
// Update the story to insert the new draft at the top
var slot = this.findTitleInStory(event.navigateFromTitle,-1) + 1;
this.storyList.splice(slot,0,draftTitle);
var slot = storyList.indexOf(event.navigateFromTitle);
storyList.splice(slot + 1,0,draftTitle);
// Save the updated story
this.saveStoryList();
this.saveStoryList(storyList);
// Add a new record to the top of the history stack
var history = this.wiki.getTiddlerData(this.historyTitle,[]);
history.push({title: draftTitle});
this.wiki.setTiddlerData(this.historyTitle,history);
this.addToHistory(draftTitle);
return false;
};
@@ -342,8 +352,8 @@ NavigatorWidget.prototype.handleNewTiddlerEvent = function(event) {
NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
var self = this;
// Get the story and history details
this.getStoryList();
var history = this.wiki.getTiddlerData(this.historyTitle,[]);
var storyList = this.getStoryList();
var history = [];
// Get the tiddlers
var tiddlers = [];
try {
@@ -352,25 +362,25 @@ NavigatorWidget.prototype.handleImportTiddlersEvent = function(event) {
}
// Process each tiddler
$tw.utils.each(tiddlers,function(tiddlerFields) {
// Generate a unique title for the tiddler
var title = self.wiki.generateNewTitle(tiddlerFields.title);
var title = tiddlerFields.title;
// Add it to the store
self.wiki.addTiddler(new $tw.Tiddler(
var imported = self.wiki.importTiddler(new $tw.Tiddler(
self.wiki.getCreationFields(),
tiddlerFields,
self.wiki.getModificationFields(),
{title: title}
tiddlerFields
));
// Add it to the story
if(self.storyList.indexOf(title) === -1) {
self.storyList.unshift(title);
if(imported) {
// Add it to the story
if(storyList.indexOf(title) === -1) {
storyList.unshift(title);
}
// And to history
history.push(title);
}
// And to history
history.push({title: title});
});
// Save the updated story and history
this.saveStoryList();
this.wiki.setTiddlerData(this.historyTitle,history);
this.saveStoryList(storyList);
this.addToHistory(history);
return false;
};

View File

@@ -34,7 +34,7 @@ PasswordWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Get the current password
var password = $tw.browser ? $tw.utils.getPassword(this.passwordName) : "";
var password = $tw.browser ? $tw.utils.getPassword(this.passwordName) || "" : "";
// Create our element
var domNode = this.document.createElement("input");
domNode.setAttribute("type","password");

View File

@@ -0,0 +1,129 @@
/*\
title: $:/core/modules/widgets/radio.js
type: application/javascript
module-type: widget
Radio widget
Will set a field to the selected value:
```
<$radio field="myfield" value="check 1">one</$radio>
<$radio field="myfield" value="check 2">two</$radio>
<$radio field="myfield" value="check 3">three</$radio>
```
|Parameter |Description |h
|tiddler |Name of the tiddler in which the field should be set. Defaults to current tiddler |
|field |The name of the field to be set |
|value |The value to set |
|class |Optional class name(s) |
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var RadioWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
RadioWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
RadioWidget.prototype.render = function(parent,nextSibling) {
// Save the parent dom node
this.parentDomNode = parent;
// Compute our attributes
this.computeAttributes();
// Execute our logic
this.execute();
// Create our elements
this.labelDomNode = this.document.createElement("label");
this.labelDomNode.setAttribute("class",this.radioClass);
this.inputDomNode = this.document.createElement("input");
this.inputDomNode.setAttribute("type","radio");
if(this.getValue() == this.radioValue) {
this.inputDomNode.setAttribute("checked","true");
}
this.labelDomNode.appendChild(this.inputDomNode);
this.spanDomNode = this.document.createElement("span");
this.labelDomNode.appendChild(this.spanDomNode);
// Add a click event handler
$tw.utils.addEventListeners(this.inputDomNode,[
{name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
]);
// Insert the label into the DOM and render any children
parent.insertBefore(this.labelDomNode,nextSibling);
this.renderChildren(this.spanDomNode,null);
this.domNodes.push(this.labelDomNode);
};
RadioWidget.prototype.getValue = function() {
var tiddler = this.wiki.getTiddler(this.radioTitle);
return tiddler && tiddler.getFieldString(this.radioField);
};
RadioWidget.prototype.setValue = function() {
if(this.radioField) {
var tiddler = this.wiki.getTiddler(this.radioTitle),
addition = {};
addition[this.radioField] = this.radioValue;
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
}
};
RadioWidget.prototype.handleChangeEvent = function(event) {
if(this.inputDomNode.checked) {
this.setValue();
}
};
/*
Compute the internal state of the widget
*/
RadioWidget.prototype.execute = function() {
// Get the parameters from the attributes
this.radioTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.radioField = this.getAttribute("field");
this.radioValue = this.getAttribute("value");
this.radioClass = this.getAttribute("class","");
if(this.radioClass !== "") {
this.radioClass += " ";
}
this.radioClass += "tw-radio";
// Make the child widgets
this.makeChildWidgets();
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
RadioWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.tiddler || changedAttributes.field || changedAttributes.value || changedAttributes["class"]) {
this.refreshSelf();
return true;
} else {
var refreshed = false;
if(changedTiddlers[this.radioTitle]) {
this.inputDomNode.checked = this.getValue() === this.radioValue;
refreshed = true;
}
return this.refreshChildren(changedTiddlers) || refreshed;
}
};
exports.radio = RadioWidget;
})();

View File

@@ -0,0 +1,53 @@
/*\
title: $:/core/modules/widgets/raw.js
type: application/javascript
module-type: widget
Raw widget
\*/
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var RawWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
RawWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
RawWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.execute();
var div = this.document.createElement("div");
div.innerHTML=this.parseTreeNode.html;
parent.insertBefore(div,nextSibling);
this.domNodes.push(div);
};
/*
Compute the internal state of the widget
*/
RawWidget.prototype.execute = function() {
};
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
RawWidget.prototype.refresh = function(changedTiddlers) {
return false;
};
exports.raw = RawWidget;
})();

View File

@@ -38,6 +38,7 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
this.renderChildren(domNode,null);
if(!domNode.isTiddlyWikiFakeDom && this.type === "popup" && this.isOpen) {
this.positionPopup(domNode);
$tw.utils.addClass(domNode,"tw-popup"); // Make sure that clicks don't dismiss popups within the revealed content
}
if(!this.isOpen) {
domNode.setAttribute("hidden","true")
@@ -156,7 +157,8 @@ RevealWidget.prototype.refresh = function(changedTiddlers) {
} else {
var refreshed = false;
if(changedTiddlers[this.stateTitle]) {
this.updateState();
// this.updateState();
this.refreshSelf();
refreshed = true;
}
return this.refreshChildren(changedTiddlers) || refreshed;
@@ -179,6 +181,8 @@ RevealWidget.prototype.updateState = function() {
// Animate our DOM node
if(!domNode.isTiddlyWikiFakeDom && this.type === "popup" && this.isOpen) {
this.positionPopup(domNode);
$tw.utils.addClass(domNode,"tw-popup"); // Make sure that clicks don't dismiss popups within the revealed content
}
if(this.isOpen) {
domNode.removeAttribute("hidden");

View File

@@ -1,9 +1,9 @@
/*\
title: $:/core/modules/widgets/setvariable.js
title: $:/core/modules/widgets/set.js
type: application/javascript
module-type: widget
Setvariable widget
Set variable widget
\*/
(function(){
@@ -14,19 +14,19 @@ Setvariable widget
var Widget = require("$:/core/modules/widgets/widget.js").widget;
var SetVariableWidget = function(parseTreeNode,options) {
var SetWidget = function(parseTreeNode,options) {
this.initialise(parseTreeNode,options);
};
/*
Inherit from the base widget class
*/
SetVariableWidget.prototype = new Widget();
SetWidget.prototype = new Widget();
/*
Render this widget into the DOM
*/
SetVariableWidget.prototype.render = function(parent,nextSibling) {
SetWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
@@ -36,7 +36,7 @@ SetVariableWidget.prototype.render = function(parent,nextSibling) {
/*
Compute the internal state of the widget
*/
SetVariableWidget.prototype.execute = function() {
SetWidget.prototype.execute = function() {
// Get our parameters
this.setName = this.getAttribute("name","currentTiddler");
this.setValue = this.getAttribute("value");
@@ -49,7 +49,7 @@ SetVariableWidget.prototype.execute = function() {
/*
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
*/
SetVariableWidget.prototype.refresh = function(changedTiddlers) {
SetWidget.prototype.refresh = function(changedTiddlers) {
var changedAttributes = this.computeAttributes();
if(changedAttributes.name || changedAttributes.value) {
this.refreshSelf();
@@ -59,6 +59,7 @@ SetVariableWidget.prototype.refresh = function(changedTiddlers) {
}
};
exports.setvariable = SetVariableWidget;
exports.setvariable = SetWidget;
exports.set = SetWidget;
})();

View File

@@ -28,8 +28,10 @@ Render this widget into the DOM
*/
TextNodeWidget.prototype.render = function(parent,nextSibling) {
this.parentDomNode = parent;
this.computeAttributes();
this.execute();
var textNode = this.document.createTextNode(this.parseTreeNode.text);
var text = this.getAttribute("text",this.parseTreeNode.text),
textNode = this.document.createTextNode(text);
parent.insertBefore(textNode,nextSibling);
this.domNodes.push(textNode);
};

View File

@@ -57,6 +57,12 @@ ViewWidget.prototype.execute = function() {
case "htmlencoded":
this.text = this.getValueAsHtmlEncoded();
break;
case "urlencoded":
this.text = this.getValueAsUrlEncoded();
break;
case "doubleurlencoded":
this.text = this.getValueAsDoubleUrlEncoded();
break;
case "date":
this.text = this.getValueAsDate(this.viewTemplate);
break;
@@ -126,20 +132,34 @@ ViewWidget.prototype.getValueAsText = function() {
};
ViewWidget.prototype.getValueAsHtmlWikified = function() {
return this.wiki.renderText("text/html","text/vnd.tiddlywiki",this.getValueAsText(),this);
return this.wiki.renderText("text/html","text/vnd.tiddlywiki",this.getValueAsText(),{parentWidget: this});
};
ViewWidget.prototype.getValueAsHtmlEncoded = function() {
return $tw.utils.htmlEncode(this.getValueAsText());
};
ViewWidget.prototype.getValueAsUrlEncoded = function() {
return encodeURIComponent(this.getValueAsText());
};
ViewWidget.prototype.getValueAsDoubleUrlEncoded = function() {
return encodeURIComponent(encodeURIComponent(this.getValueAsText()));
};
ViewWidget.prototype.getValueAsDate = function(format) {
return $tw.utils.formatDateString(this.getValue(),format);
format = format || "YYYY MM DD 0hh:0mm";
var value = $tw.utils.parseDate(this.getValue());
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
return $tw.utils.formatDateString(value,format);
} else {
return "";
}
};
ViewWidget.prototype.getValueAsRelativeDate = function(format) {
var value = this.getValue();
if(value) {
var value = $tw.utils.parseDate(this.getValue());
if(value && $tw.utils.isDate(value) && value.toString() !== "Invalid Date") {
return $tw.utils.getRelativeDate((new Date()) - (new Date(value))).description;
} else {
return "";

View File

@@ -38,8 +38,10 @@ Widget.prototype.initialise = function(parseTreeNode,options) {
// Save widget info
this.parseTreeNode = parseTreeNode;
this.wiki = options.wiki;
this.variables = options.variables || {};
this.parentWidget = options.parentWidget;
this.variablesConstructor = function() {};
this.variablesConstructor.prototype = this.parentWidget ? this.parentWidget.variables : {};
this.variables = new this.variablesConstructor();
this.document = options.document;
this.attributes = {};
this.children = [];
@@ -67,6 +69,16 @@ Widget.prototype.execute = function() {
this.makeChildWidgets();
};
/*
Set the value of a context variable
name: name of the variable
value: value of the variable
params: array of {name:, default:} for each parameter
*/
Widget.prototype.setVariable = function(name,value,params) {
this.variables[name] = {value: value, params: params};
};
/*
Get the prevailing value of a context variable
name: name of variable
@@ -78,19 +90,14 @@ defaultValue: default value if the variable is not defined
Widget.prototype.getVariable = function(name,options) {
options = options || {};
var actualParams = options.params || [];
// Search up the widget tree for the variable name
var node = this;
while(node && !$tw.utils.hop(node.variables,name)) {
node = node.parentWidget;
}
// If we get to the root then look for a macro module
if(!node) {
// If the variable doesn't exist then look for a macro module
if(!(name in this.variables)) {
return this.evaluateMacroModule(name,actualParams,options.defaultValue);
}
// Get the value
var value = node.variables[name].value || "";
var variable = this.variables[name],
value = variable.value || "";
// Substitute any parameters specified in the definition
value = this.substituteVariableParameters(value,node.variables[name].params,actualParams);
value = this.substituteVariableParameters(value,variable.params,actualParams);
value = this.substituteVariableReferences(value);
return value;
};
@@ -136,29 +143,34 @@ Widget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue)
if($tw.utils.hop($tw.macros,name)) {
var macro = $tw.macros[name],
args = [];
var nextAnonParameter = 0, // Next candidate anonymous parameter in macro call
paramInfo, paramValue;
// Step through each of the parameters in the macro definition
for(var p=0; p<macro.params.length; p++) {
// Check if we've got a macro call parameter with the same name
paramInfo = macro.params[p];
paramValue = undefined;
for(var m=0; m<actualParams.length; m++) {
if(actualParams[m].name === paramInfo.name) {
paramValue = actualParams[m].value;
if(macro.params.length > 0) {
var nextAnonParameter = 0, // Next candidate anonymous parameter in macro call
paramInfo, paramValue;
// Step through each of the parameters in the macro definition
for(var p=0; p<macro.params.length; p++) {
// Check if we've got a macro call parameter with the same name
paramInfo = macro.params[p];
paramValue = undefined;
for(var m=0; m<actualParams.length; m++) {
if(actualParams[m].name === paramInfo.name) {
paramValue = actualParams[m].value;
}
}
// If not, use the next available anonymous macro call parameter
while(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {
nextAnonParameter++;
}
if(paramValue === undefined && nextAnonParameter < actualParams.length) {
paramValue = actualParams[nextAnonParameter++].value;
}
// If we've still not got a value, use the default, if any
paramValue = paramValue || paramInfo["default"] || "";
// Save the parameter
args.push(paramValue);
}
// If not, use the next available anonymous macro call parameter
while(nextAnonParameter < actualParams.length && actualParams[nextAnonParameter].name) {
nextAnonParameter++;
}
if(paramValue === undefined && nextAnonParameter < actualParams.length) {
paramValue = actualParams[nextAnonParameter++].value;
}
// If we've still not got a value, use the default, if any
paramValue = paramValue || paramInfo["default"] || "";
// Save the parameter
args.push(paramValue);
}
else for(var i=0; i<actualParams.length; ++i) {
args.push(actualParams[i].value);
}
return macro.run.apply(this,args)
} else {
@@ -166,16 +178,6 @@ Widget.prototype.evaluateMacroModule = function(name,actualParams,defaultValue)
}
};
/*
Set the value of a context variable
name: name of the variable
value: value of the variable
params: array of {name:, default:} for each parameter
*/
Widget.prototype.setVariable = function(name,value,params) {
this.variables[name] = {value: value, params: params};
};
/*
Check whether a given context variable value exists in the parent chain
*/
@@ -191,7 +193,7 @@ Widget.prototype.hasVariable = function(name,value) {
};
/*
Construct a qualifying string based on concatenating the values of a given variable in the parent chain
Construct a qualifying string based on a hash of concatenating the values of a given variable in the parent chain
*/
Widget.prototype.getStateQualifier = function(name) {
name = name || "transclusion";
@@ -203,7 +205,7 @@ Widget.prototype.getStateQualifier = function(name) {
}
node = node.parentWidget;
}
return output.join("");
return "{" + $tw.utils.hashString(output.join("")) + "}";
};
/*
@@ -217,8 +219,7 @@ Widget.prototype.computeAttributes = function() {
if(attribute.type === "indirect") {
value = self.wiki.getTextReference(attribute.textReference,"",self.getVariable("currentTiddler"));
} else if(attribute.type === "macro") {
var text = self.getVariable(attribute.value.name,{params: attribute.value.params});
value = self.wiki.renderText("text/plain","text/vnd.tiddlywiki",text);
value = self.getVariable(attribute.value.name,{params: attribute.value.params});
} else { // String attribute
value = attribute.value;
}

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