tiddlywiki_cp 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
data/website/index.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <script type="text/javascript">
5
5
  //<![CDATA[
6
- var version = {title: "TiddlyWiki", major: 2, minor: 2, revision: 4, date: new Date("Jun 19, 2007"), extensions: {}};
6
+ var version = {title: "TiddlyWiki", major: 2, minor: 3, revision: 0, date: new Date("Dec 4, 2007"), extensions: {}};
7
7
  //]]>
8
8
  </script>
9
9
  <!--
@@ -36,13 +36,15 @@ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
36
36
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
37
37
  DAMAGE.
38
38
  -->
39
- <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
39
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
40
40
  <!--PRE-HEAD-START-->
41
41
  <!--{{{-->
42
42
  <link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
43
43
  <!--}}}-->
44
44
  <!--PRE-HEAD-END-->
45
- <title> tiddlywiki_cp - copy tiddlers to files and vice versa </title>
45
+ <title>
46
+ TiddlyWiki - a reusable non-linear personal web notebook
47
+ </title>
46
48
  <style type="text/css">
47
49
  #saveTest {display:none;}
48
50
  #messageArea {display:none;}
@@ -53,12 +55,10 @@ DAMAGE.
53
55
  #javascriptWarning {width:100%; text-align:center; font-weight:bold; background-color:#dd1100; color:#fff; padding:1em 0em;}
54
56
  </style>
55
57
  <!--POST-HEAD-START-->
56
-
57
58
  <!--POST-HEAD-END-->
58
59
  </head>
59
60
  <body onload="main();" onunload="if(window.checkUnsavedChanges) checkUnsavedChanges(); if(window.scrubNodes) scrubNodes(document.body);">
60
61
  <!--PRE-BODY-START-->
61
-
62
62
  <!--PRE-BODY-END-->
63
63
  <div id="copyright">
64
64
  Welcome to TiddlyWiki created by Jeremy Ruston, Copyright &copy; 2007 UnaMesa Association
@@ -76,6 +76,11 @@ Welcome to TiddlyWiki created by Jeremy Ruston, Copyright &copy; 2007 UnaMesa As
76
76
  <div id="contentWrapper"></div>
77
77
  <div id="contentStash"></div>
78
78
  <div id="shadowArea">
79
+ <div title="MarkupPreHead">
80
+ <pre>&lt;!--{{{--&gt;
81
+ &lt;link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/&gt;
82
+ &lt;!--}}}--&gt;</pre>
83
+ </div>
79
84
  <div title="ColorPalette">
80
85
  <pre>Background: #fff
81
86
  Foreground: #000
@@ -137,7 +142,7 @@ h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
137
142
  .wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
138
143
  .wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
139
144
  border:1px solid [[ColorPalette::PrimaryMid]];}
140
- .wizardStep.wizardStepDone {background::[[ColorPalette::TertiaryLight]];}
145
+ .wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
141
146
  .wizardFooter {background:[[ColorPalette::PrimaryPale]];}
142
147
  .wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
143
148
  .wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
@@ -400,27 +405,21 @@ table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px
400
405
  <div title="StyleSheetLocale">
401
406
  <pre>/***
402
407
  StyleSheet for use when a translation requires any css style changes.
403
- This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which use a logographic writing system and need larger font sizes.
408
+ This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
404
409
  ***/
405
-
406
410
  /*{{{*/
407
411
  body {font-size:0.8em;}
408
-
409
412
  #sidebarOptions {font-size:1.05em;}
410
413
  #sidebarOptions a {font-style:normal;}
411
414
  #sidebarOptions .sliderPanel {font-size:0.95em;}
412
-
413
415
  .subtitle {font-size:0.8em;}
414
-
415
416
  .viewer table.listView {font-size:0.95em;}
416
-
417
- .htmlarea .toolbarHA table {border:1px solid ButtonFace; margin:0em 0em;}
418
417
  /*}}}*/</pre>
419
418
  </div>
420
419
  <div title="StyleSheetPrint">
421
420
  <pre>/*{{{*/
422
421
  @media print {
423
- #mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton {display: none ! important;}
422
+ #mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
424
423
  #displayArea {margin: 1em 1em 0em 1em;}
425
424
  /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
426
425
  noscript {display:none;}
@@ -493,14 +492,107 @@ Your username for signing your edits. Write it as a WikiWord (eg JoeBloggs)
493
492
  ----
494
493
  Also see AdvancedOptions</pre>
495
494
  </div>
495
+ <div title="ImportTiddlers">
496
+ <pre>&lt;&lt;importTiddlers&gt;&gt;</pre>
497
+ </div>
496
498
  </div>
497
499
  <!--POST-SHADOWAREA-->
498
500
  <div id="storeArea">
499
- <div title="ChangeLog" modifier="loic" modified="200803302106" created="200707211630" changecount="1">
501
+ <div title="ChangeLog" modifier="loic" modified="200804062225" created="200707211630" changecount="1">
500
502
  <pre>{{{
501
- changeset: 59:6751afe5b8e2
503
+ changeset: 77:5e92b7ebcd70
502
504
  tag: tip
503
505
  user: root@dachary.org
506
+ date: Fri Apr 04 14:17:09 2008 +0000
507
+ summary: update plugin name
508
+
509
+ changeset: 76:b1a11d62dce4
510
+ user: root@dachary.org
511
+ date: Fri Apr 04 14:04:08 2008 +0000
512
+ summary: upgrade website to tw-2.3 and newer davplugin
513
+
514
+ changeset: 75:fb74e9bc08d4
515
+ user: root@dachary.org
516
+ date: Fri Apr 04 13:42:01 2008 +0000
517
+ summary: update documentation
518
+
519
+ changeset: 74:0dc051395239
520
+ user: root@dachary.org
521
+ date: Fri Apr 04 13:36:13 2008 +0000
522
+ summary: update documentation for 0.5.0
523
+
524
+ changeset: 73:dddb2fc4bbca
525
+ user: root@dachary.org
526
+ date: Fri Apr 04 13:01:52 2008 +0000
527
+ summary: 0.5.0 release ready
528
+
529
+ changeset: 72:7290595266bb
530
+ user: root@dachary.org
531
+ date: Fri Apr 04 12:59:23 2008 +0000
532
+ summary: documentation for lang support
533
+
534
+ changeset: 71:86e046e659af
535
+ user: root@dachary.org
536
+ date: Fri Apr 04 12:52:12 2008 +0000
537
+ summary: test file for tw 2.3
538
+
539
+ changeset: 70:301346066b75
540
+ user: root@dachary.org
541
+ date: Fri Apr 04 10:36:24 2008 +0000
542
+ summary: update lang tags
543
+
544
+ changeset: 69:7c7f3d279c28
545
+ user: root@dachary.org
546
+ date: Fri Apr 04 07:11:49 2008 +0000
547
+ summary: test tw-2.3 version detection
548
+
549
+ changeset: 68:e635348a3352
550
+ user: root@dachary.org
551
+ date: Thu Apr 03 15:43:32 2008 +0000
552
+ summary: generate index.html with website_generate target
553
+
554
+ changeset: 67:dd3534267e3c
555
+ user: root@dachary.org
556
+ date: Thu Apr 03 15:36:56 2008 +0000
557
+ summary: copy Markup* tiddlers to the corresponding zone in the tiddlywiki
558
+
559
+ changeset: 66:740b082f235a
560
+ user: loic@dachary.org
561
+ date: Thu Apr 03 09:29:57 2008 +0000
562
+ summary: apt-get install ruby-elisp
563
+
564
+ changeset: 65:47688556400d
565
+ user: root@dachary.org
566
+ date: Thu Apr 03 09:29:16 2008 +0000
567
+ summary: bump to version 0.5.0
568
+
569
+ changeset: 64:3544bb17985c
570
+ user: root@dachary.org
571
+ date: Thu Apr 03 08:58:43 2008 +0000
572
+ summary: fix invalid regexp including {
573
+
574
+ changeset: 63:13476d79f633
575
+ user: root@dachary.org
576
+ date: Thu Apr 03 08:44:20 2008 +0000
577
+ summary: update SimonBaird work local copy
578
+
579
+ changeset: 62:dfdfb30ccb97
580
+ user: root@dachary.org
581
+ date: Mon Mar 31 21:08:17 2008 +0000
582
+ summary: sync with SimonBaird version : systemServer replaces contentPublisher
583
+
584
+ changeset: 61:73d453e23b5d
585
+ user: root@dachary.org
586
+ date: Sun Mar 30 21:29:40 2008 +0000
587
+ summary: release information and web site
588
+
589
+ changeset: 60:4177e4981005
590
+ user: root@dachary.org
591
+ date: Sun Mar 30 21:18:27 2008 +0000
592
+ summary: remove extra SimonBaird files
593
+
594
+ changeset: 59:6751afe5b8e2
595
+ user: root@dachary.org
504
596
  date: Sun Mar 30 20:58:00 2008 +0000
505
597
  summary: tw 2.3 to 2.9 compatibility
506
598
 
@@ -805,331 +897,776 @@ summary: initial
805
897
  }}}
806
898
  </pre>
807
899
  </div>
808
- <div title="DefaultTiddlers" modifier="loic" modified="200707231424" created="200707211620" changecount="2">
809
- <pre>Introduction
810
- Usage</pre>
811
- </div>
812
- <div title="Introduction" modifier="loic" modified="200707231424" created="200707211630" changecount="5">
813
- <pre>a ruby gem (http://rubyforge.org/projects/tiddlywikicp/) providing a library and a command line interface to copy [[tiddlywiki|http://tiddlywiki.com/]] tiddlers to files and vice versa.
900
+ <div title="CryptoFunctionsPlugin" modifier="" created="200710115934" tags="systemConfig excludeLists excludeSearch">
901
+ <pre>/***
902
+ |''Name:''|CryptoFunctionsPlugin|
903
+ |''Description:''|Support for cryptographic functions|
904
+ ***/
905
+ //{{{
906
+ if(!version.extensions.CryptoFunctionsPlugin) {
907
+ version.extensions.CryptoFunctionsPlugin = {installed:true};
814
908
 
815
- Development is discussed at irc.freenode.net#tiddlywiki
909
+ //--
910
+ //-- Crypto functions and associated conversion routines
911
+ //--
816
912
 
817
- This tiddlywiki was created using the following commands:
818
- {{{
819
- tiddlywiki_cp 'http://tiddlylab.bidix.info/#WebDAVSavingPlugin' website/index.html
820
- tiddlywiki_cp -a website/index.html website/files
821
- ( echo '{{''{' ; RUBYLIB=lib ruby bin/tiddlywiki_cp --help ; echo '}}''}' ) &gt; website/files/Usage
822
- tiddlywiki_cp -a website/files website/index.html
823
- }}}
824
- Loic Dachary &lt;mailto:loic@dachary.org&gt;
825
- </pre>
826
- </div>
827
- <div title="MainMenu" modifier="loic" modified="200707231424" created="200707211619" changecount="2">
828
- <pre>[[Introduction]]
829
- [[Usage]]
830
- [[ChangeLog]]
831
- </pre>
832
- </div>
833
- <div title="SiteSubtitle" modifier="loic" modified="200707231424" created="200707211618" changecount="1">
834
- <pre>copy tiddlers to files and vice versa</pre>
835
- </div>
836
- <div title="SiteTitle" modifier="loic" modified="200707231424" created="200707211617" changecount="1">
837
- <pre>tiddlywiki_cp</pre>
838
- </div>
839
- <div title="Usage" modifier="loic" modified="200803302106" created="200707211620" changecount="1">
840
- <pre>{{{
841
- Usage: tiddlywiki_cp [options] FROM [FROM ...] TO|-
913
+ // Crypto &quot;namespace&quot;
914
+ function Crypto() {}
842
915
 
843
- -r, --[no-]recursive recurse into directories and tiddlywikies
844
- -t, --[no-]times preserve modification time
845
- -a, --all implies -rt
846
- -i, --include REGEX all files,directories or tiddlers must match regex.
847
- If specified multiple times,
848
- must match at least one of the regex.
849
- Includes are tested after excludes.
850
- --exclude REGEX all files,directories or tiddlers must NOT match regex.
851
- If specified multiple times,
852
- exclude if matches at least one of the regex.
853
- Includes are tested after excludes.
854
- -v, --[no-]verbose run verbosely
855
- -n, --[no-]dry-run show what would have been transferred
856
- --version show version
857
- --help show command usage
916
+ // Convert a string to an array of big-endian 32-bit words
917
+ Crypto.strToBe32s = function(str)
918
+ {
919
+ var be = Array();
920
+ var len = Math.floor(str.length/4);
921
+ var i, j;
922
+ for(i=0, j=0; i&lt;len; i++, j+=4) {
923
+ be[i] = ((str.charCodeAt(j)&amp;0xff) &lt;&lt; 24)|((str.charCodeAt(j+1)&amp;0xff) &lt;&lt; 16)|((str.charCodeAt(j+2)&amp;0xff) &lt;&lt; 8)|(str.charCodeAt(j+3)&amp;0xff);
924
+ }
925
+ while (j&lt;str.length) {
926
+ be[j&gt;&gt;2] |= (str.charCodeAt(j)&amp;0xff)&lt;&lt;(24-(j*8)%32);
927
+ j++;
928
+ }
929
+ return be;
930
+ };
858
931
 
859
- Examples:
932
+ // Convert an array of big-endian 32-bit words to a string
933
+ Crypto.be32sToStr = function(be)
934
+ {
935
+ var str = &quot;&quot;;
936
+ for(var i=0;i&lt;be.length*32;i+=8)
937
+ str += String.fromCharCode((be[i&gt;&gt;5]&gt;&gt;&gt;(24-i%32)) &amp; 0xff);
938
+ return str;
939
+ };
860
940
 
861
- mkdir /tmp/a ; tiddlywiki_cp -a http://tiddlywiki.com/index.html /tmp/a
862
- copies index.html tiddlers in separate files and preserve times.
863
- For each tiddler, a .div file contains the meta information.
864
- The files are named after their content:
865
- /tmp/a/HelloThere.tiddler
866
- /tmp/a/HelloThere.tiddler.div
867
- /tmp/a/Plugin.js
868
- /tmp/a/Plugin.js.div
869
- /tmp/a/OwnStyle.css
870
- /tmp/a/OwnStyle.css.div
871
- ...
941
+ // Convert an array of big-endian 32-bit words to a hex string
942
+ Crypto.be32sToHex = function(be)
943
+ {
944
+ var hex = &quot;0123456789ABCDEF&quot;;
945
+ var str = &quot;&quot;;
946
+ for(var i=0;i&lt;be.length*4;i++)
947
+ str += hex.charAt((be[i&gt;&gt;2]&gt;&gt;((3-i%4)*8+4))&amp;0xF) + hex.charAt((be[i&gt;&gt;2]&gt;&gt;((3-i%4)*8))&amp;0xF);
948
+ return str;
949
+ };
872
950
 
873
- tiddlywiki_cp 'http://tiddlylab.bidix.info/#WebDAVSavingPlugin' tiddlywiki.html
874
- copies the WebDAVSavingPlugin tiddler in the existing tiddlywiki.html
951
+ // Return, in hex, the SHA-1 hash of a string
952
+ Crypto.hexSha1Str = function(str)
953
+ {
954
+ return Crypto.be32sToHex(Crypto.sha1Str(str));
955
+ };
875
956
 
876
- tiddlywiki_cp http://tiddlywiki.com/index.html /tmp/i.html
877
- copies to a local file
957
+ // Return the SHA-1 hash of a string
958
+ Crypto.sha1Str = function(str)
959
+ {
960
+ return Crypto.sha1(Crypto.strToBe32s(str),str.length);
961
+ };
878
962
 
879
- tiddlywiki_cp -t myplugin.js tiddlywiki.html
880
- copies the tiddler in the existing tiddlywiki.html tiddlywiki
881
- and use file system modification time
963
+ // Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
964
+ Crypto.sha1 = function(x,blen)
965
+ {
966
+ // Add 32-bit integers, wrapping at 32 bits
967
+ add32 = function(a,b)
968
+ {
969
+ var lsw = (a&amp;0xFFFF)+(b&amp;0xFFFF);
970
+ var msw = (a&gt;&gt;16)+(b&gt;&gt;16)+(lsw&gt;&gt;16);
971
+ return (msw&lt;&lt;16)|(lsw&amp;0xFFFF);
972
+ };
973
+ // Add five 32-bit integers, wrapping at 32 bits
974
+ add32x5 = function(a,b,c,d,e)
975
+ {
976
+ var lsw = (a&amp;0xFFFF)+(b&amp;0xFFFF)+(c&amp;0xFFFF)+(d&amp;0xFFFF)+(e&amp;0xFFFF);
977
+ var msw = (a&gt;&gt;16)+(b&gt;&gt;16)+(c&gt;&gt;16)+(d&gt;&gt;16)+(e&gt;&gt;16)+(lsw&gt;&gt;16);
978
+ return (msw&lt;&lt;16)|(lsw&amp;0xFFFF);
979
+ };
980
+ // Bitwise rotate left a 32-bit integer by 1 bit
981
+ rol32 = function(n)
982
+ {
983
+ return (n&gt;&gt;&gt;31)|(n&lt;&lt;1);
984
+ };
882
985
 
883
- tiddlywiki_cp 'http://tiddlylab.bidix.info/#WebDAVSavingPlugin' WebDAVSavingPlugin.js
884
- get a local copy of the WebDAVSavingPlugin tiddler
986
+ var len = blen*8;
987
+ // Append padding so length in bits is 448 mod 512
988
+ x[len&gt;&gt;5] |= 0x80 &lt;&lt; (24-len%32);
989
+ // Append length
990
+ x[((len+64&gt;&gt;9)&lt;&lt;4)+15] = len;
991
+ var w = Array(80);
885
992
 
886
- mkdir A ; tiddlywiki_cp -a --include 'WebDAV' --include 'RSS' 'http://tiddlylab.bidix.info/' A
887
- copy all tiddlers with WebDAV or RSS in the url
993
+ var k1 = 0x5A827999;
994
+ var k2 = 0x6ED9EBA1;
995
+ var k3 = 0x8F1BBCDC;
996
+ var k4 = 0xCA62C1D6;
888
997
 
889
- mkdir A ; tiddlywiki_cp -a --exclude 'SEX' 'http://tiddlylab.bidix.info/' A
890
- copy all tiddlers except those with SEX in the url
998
+ var h0 = 0x67452301;
999
+ var h1 = 0xEFCDAB89;
1000
+ var h2 = 0x98BADCFE;
1001
+ var h3 = 0x10325476;
1002
+ var h4 = 0xC3D2E1F0;
891
1003
 
892
- tiddlywiki_cp -a A B C tiddlywiki.html
893
- copy all tiddlers found in the A B and C directories to tiddlywiki.html
894
- }}}
1004
+ for(var i=0;i&lt;x.length;i+=16) {
1005
+ var j,t;
1006
+ var a = h0;
1007
+ var b = h1;
1008
+ var c = h2;
1009
+ var d = h3;
1010
+ var e = h4;
1011
+ for(j = 0;j&lt;16;j++) {
1012
+ w[j] = x[i+j];
1013
+ t = add32x5(e,(a&gt;&gt;&gt;27)|(a&lt;&lt;5),d^(b&amp;(c^d)),w[j],k1);
1014
+ e=d; d=c; c=(b&gt;&gt;&gt;2)|(b&lt;&lt;30); b=a; a = t;
1015
+ }
1016
+ for(j=16;j&lt;20;j++) {
1017
+ w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
1018
+ t = add32x5(e,(a&gt;&gt;&gt;27)|(a&lt;&lt;5),d^(b&amp;(c^d)),w[j],k1);
1019
+ e=d; d=c; c=(b&gt;&gt;&gt;2)|(b&lt;&lt;30); b=a; a = t;
1020
+ }
1021
+ for(j=20;j&lt;40;j++) {
1022
+ w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
1023
+ t = add32x5(e,(a&gt;&gt;&gt;27)|(a&lt;&lt;5),b^c^d,w[j],k2);
1024
+ e=d; d=c; c=(b&gt;&gt;&gt;2)|(b&lt;&lt;30); b=a; a = t;
1025
+ }
1026
+ for(j=40;j&lt;60;j++) {
1027
+ w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
1028
+ t = add32x5(e,(a&gt;&gt;&gt;27)|(a&lt;&lt;5),(b&amp;c)|(d&amp;(b|c)),w[j],k3);
1029
+ e=d; d=c; c=(b&gt;&gt;&gt;2)|(b&lt;&lt;30); b=a; a = t;
1030
+ }
1031
+ for(j=60;j&lt;80;j++) {
1032
+ w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
1033
+ t = add32x5(e,(a&gt;&gt;&gt;27)|(a&lt;&lt;5),b^c^d,w[j],k4);
1034
+ e=d; d=c; c=(b&gt;&gt;&gt;2)|(b&lt;&lt;30); b=a; a = t;
1035
+ }
1036
+
1037
+ h0 = add32(h0,a);
1038
+ h1 = add32(h1,b);
1039
+ h2 = add32(h2,c);
1040
+ h3 = add32(h3,d);
1041
+ h4 = add32(h4,e);
1042
+ }
1043
+ return Array(h0,h1,h2,h3,h4);
1044
+ };
1045
+
1046
+
1047
+ }
1048
+ //}}}</pre>
1049
+ </div>
1050
+ <div title="DefaultTiddlers" modifier="loic" modified="200804041401" created="200707211620" changecount="2">
1051
+ <pre>[[Introduction]]
1052
+ [[Usage]]
895
1053
  </pre>
896
1054
  </div>
897
- <div title="WebDAVSavingPlugin" modifier="BidiX" modified="200707231424" created="200702221114" tags="systemConfig" changecount="4">
1055
+ <div title="DeprecatedFunctionsPlugin" modifier="" created="200710125059" tags="systemConfig excludeLists excludeSearch">
898
1056
  <pre>/***
899
- |''Name:''|WebDAVSavingPlugin|
900
- |''Description:''|Saves on a WebDAV server without the need of any ServerSide script.&lt;br&gt;When TiddlyWiki is accessed over http, this plugin permits to save back to the server, using http PUT.|
901
- |''Version:''|0.2.1|
902
- |''Date:''|Apr 21, 2007|
903
- |''Source:''|http://tiddlywiki.bidix.info/#WebDAVSavingPlugin|
904
- |''Author:''|BidiX (BidiX (at) bidix (dot) info)|
905
- |''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
906
- |''~CoreVersion:''|2.2.0 (Beta 5)|
1057
+ |''Name:''|DeprecatedFunctionsPlugin|
1058
+ |''Description:''|Support for deprecated functions removed from core|
907
1059
  ***/
908
1060
  //{{{
909
- version.extensions.WebDAVSavingPlugin = {
910
- major: 0, minor: 2, revision: 1,
911
- date: new Date(&quot;Apr 21, 2007&quot;),
912
- source: 'http://tiddlywiki.bidix.info/#WebDAVSavingPlugin',
913
- author: 'BidiX (BidiX (at) bidix (dot) info',
914
- license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
915
- coreVersion: '2.2.0 (Beta 5)'
1061
+ if(!version.extensions.DeprecatedFunctionsPlugin) {
1062
+ version.extensions.DeprecatedFunctionsPlugin = {installed:true};
1063
+
1064
+ //--
1065
+ //-- Deprecated code
1066
+ //--
1067
+
1068
+ // @Deprecated: Use createElementAndWikify and this.termRegExp instead
1069
+ config.formatterHelpers.charFormatHelper = function(w)
1070
+ {
1071
+ w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
916
1072
  };
917
1073
 
918
- if (!window.bidix) window.bidix = {};
919
- bidix.WebDAVSaving = {
920
- orig_saveChanges: saveChanges,
921
- defaultFilename: 'index.html',
922
- messages: {
923
- loadOriginalHttpDavError: &quot;Original file can't be loaded&quot;,
924
- optionsMethodError: &quot;The OPTIONS method can't be used on this ressource : %0&quot;,
925
- webDavNotEnabled: &quot;WebDAV is not enabled on this ressource : %0&quot;,
926
- notHTTPUrlError: &quot;WebDAV saving can be used for http viewed TiddlyWiki only&quot;,
927
- aboutToSaveOnHttpDav: 'About to save on %0 ...' ,
928
- folderCreated: &quot;Remote folder '%0' created&quot;
1074
+ // @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
1075
+ config.formatterHelpers.monospacedByLineHelper = function(w)
1076
+ {
1077
+ var lookaheadRegExp = new RegExp(this.lookahead,&quot;mg&quot;);
1078
+ lookaheadRegExp.lastIndex = w.matchStart;
1079
+ var lookaheadMatch = lookaheadRegExp.exec(w.source);
1080
+ if(lookaheadMatch &amp;&amp; lookaheadMatch.index == w.matchStart) {
1081
+ var text = lookaheadMatch[1];
1082
+ if(config.browser.isIE)
1083
+ text = text.replace(/\n/g,&quot;\r&quot;);
1084
+ createTiddlyElement(w.output,&quot;pre&quot;,null,null,text);
1085
+ w.nextMatch = lookaheadRegExp.lastIndex;
929
1086
  }
930
1087
  };
931
1088
 
932
- // Save this tiddlywiki with the pending changes
933
- saveChanges = function(onlyIfDirty,tiddlers)
1089
+ // @Deprecated: Use &lt;br&gt; or &lt;br /&gt; instead of &lt;&lt;br&gt;&gt;
1090
+ config.macros.br = {};
1091
+ config.macros.br.handler = function(place)
934
1092
  {
935
- var originalPath = document.location.toString();
936
- if (originalPath.substr(0,5) == &quot;file:&quot;)
937
- return bidix.WebDAVSaving.orig_saveChanges(onlyIfDirty,tiddlers);
938
- else
939
- return bidix.WebDAVSaving.saveChanges(onlyIfDirty,tiddlers);
940
- }
1093
+ createTiddlyElement(place,&quot;br&quot;);
1094
+ };
941
1095
 
942
- bidix.WebDAVSaving.saveChanges = function(onlyIfDirty,tiddlers)
943
- {
944
- var callback = function(status,params,original,url,xhr) {
945
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
946
- if (!status)
947
- displayMessage(bidix.WebDAVSaving.messages.optionsMethodError.format([url]));
948
- else {
949
- if (!xhr.getResponseHeader(&quot;DAV&quot;))
950
- alert(bidix.WebDAVSaving.messages.webDavNotEnabled.format([url]));
951
- else
952
- bidix.WebDAVSaving.doSaveChanges();
953
- }
954
- }
955
- if(onlyIfDirty &amp;&amp; !store.isDirty())
956
- return;
957
- clearMessage();
958
- var originalPath = document.location.toString();
959
- // Check we were loaded from a HTTP or HTTPS URL
960
- if(originalPath.substr(0,4) != &quot;http&quot;) {
961
- alert(bidix.WebDAVSaving.messages.notHTTPUrlError);
962
- return;
963
- }
964
- // is the server WebDAV enabled ?
965
- var r = doHttp(&quot;OPTIONS&quot;,originalPath,null,null,null,null,callback,null,null);
966
- if (typeof r == &quot;string&quot;)
967
- alert(r);
968
- }
969
-
970
- bidix.WebDAVSaving.doSaveChanges = function()
1096
+ // Find an entry in an array. Returns the array index or null
1097
+ // @Deprecated: Use indexOf instead
1098
+ Array.prototype.find = function(item)
971
1099
  {
972
- var callback = function(status,params,original,url,xhr) {
973
- if (!status) {
974
- alert(config.messages.loadOriginalHttpDavError);
975
- return;
976
- }
977
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
978
- // Locate the storeArea div's
979
- var posDiv = locateStoreArea(original);
980
- if((posDiv[0] == -1) || (posDiv[1] == -1)) {
981
- alert(config.messages.invalidFileError.format([localPath]));
982
- return;
983
- }
984
- bidix.WebDAVSaving.mkbackupfolder(null,null,params,original,posDiv);
985
- };
986
- // get original
987
- var originalPath = document.location.toString();
988
- if (originalPath.charAt(originalPath.length-1) == &quot;/&quot;)
989
- originalPath = originalPath + bidix.WebDAVSaving.defaultFilename;
990
- displayMessage(bidix.WebDAVSaving.messages.aboutToSaveOnHttpDav.format([originalPath]));
991
- doHttp(&quot;GET&quot;,originalPath,null,null,null,null,callback,originalPath,null);
1100
+ var i = this.indexOf(item);
1101
+ return i == -1 ? null : i;
992
1102
  };
993
1103
 
994
- bidix.WebDAVSaving.mkbackupfolder = function(root,dirs,url,original,posDiv) {
995
- if (!root || !dirs) {
996
- root = bidix.dirname(url);
997
- if (config.options.txtBackupFolder == &quot;&quot;)
998
- dirs = null;
999
- else
1000
- dirs = config.options.txtBackupFolder.split('/');
1001
- }
1002
- if (config.options.chkSaveBackups &amp;&amp; dirs &amp;&amp; (dirs.length &gt; 0))
1003
- bidix.WebDAVSaving.mkdir(root,dirs.shift(),dirs,url,original,posDiv);
1004
- else
1005
- bidix.WebDAVSaving.saveBackup(url,original,posDiv);
1104
+ // Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
1105
+ // @Deprecated: Use store.getLoader().internalizeTiddler instead
1106
+ Tiddler.prototype.loadFromDiv = function(divRef,title)
1107
+ {
1108
+ return store.getLoader().internalizeTiddler(store,this,title,divRef);
1006
1109
  };
1007
1110
 
1008
- bidix.WebDAVSaving.saveBackup = function(url,original,posDiv)
1111
+ // Format the text for storage in an HTML DIV
1112
+ // @Deprecated Use store.getSaver().externalizeTiddler instead.
1113
+ Tiddler.prototype.saveToDiv = function()
1009
1114
  {
1010
- var callback = function(status,params,responseText,url,xhr) {
1011
- if (!status) {
1012
- alert(config.messages.backupFailed);
1013
- return;
1014
- }
1015
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
1016
- displayMessage(config.messages.backupSaved,url);
1017
- bidix.WebDAVSaving.saveRss(params[0],params[1],params[2]);
1018
- };
1019
- if(config.options.chkSaveBackups) {
1020
- var backupPath = getBackupPath(url);
1021
- bidix.httpPut(backupPath,original,callback,Array(url,original,posDiv));
1022
- } else {
1023
- bidix.WebDAVSaving.saveRss(url,original,posDiv);
1024
- }
1025
- }
1115
+ return store.getSaver().externalizeTiddler(store,this);
1116
+ };
1026
1117
 
1027
- bidix.WebDAVSaving.saveRss = function(url,original,posDiv)
1118
+ // @Deprecated: Use store.allTiddlersAsHtml() instead
1119
+ function allTiddlersAsHtml()
1028
1120
  {
1029
- var callback = function(status,params,responseText,url,xhr) {
1030
- if (!status) {
1031
- alert(config.messages.rssFailed);
1032
- return;
1033
- }
1034
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
1035
- displayMessage(config.messages.rssSaved,url);
1036
- bidix.WebDAVSaving.saveEmpty(params[0],params[1],params[2]);
1037
- };
1038
- if(config.options.chkGenerateAnRssFeed) {
1039
- var rssPath = url.substr(0,url.lastIndexOf(&quot;.&quot;)) + &quot;.xml&quot;;
1040
- bidix.httpPut(rssPath,convertUnicodeToUTF8(generateRss()),callback,Array(url,original,posDiv));
1041
- } else {
1042
- bidix.WebDAVSaving.saveEmpty(url,original,posDiv);
1043
- }
1121
+ return store.allTiddlersAsHtml();
1044
1122
  }
1045
1123
 
1046
- bidix.WebDAVSaving.saveEmpty = function(url,original,posDiv)
1124
+ // @Deprecated: Use refreshPageTemplate instead
1125
+ function applyPageTemplate(title)
1047
1126
  {
1048
- var callback = function(status,params,responseText,url,xhr) {
1049
- if (!status) {
1050
- alert(config.messages.emptyFailed);
1051
- return;
1052
- }
1053
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
1054
- displayMessage(config.messages.emptySaved,url);
1055
- bidix.WebDAVSaving.saveMain(params[0],params[1],params[2]);
1056
- };
1057
- if(config.options.chkSaveEmptyTemplate) {
1058
- var emptyPath,p;
1059
- if((p = url.lastIndexOf(&quot;/&quot;)) != -1)
1060
- emptyPath = url.substr(0,p) + &quot;/empty.html&quot;;
1061
- else
1062
- emptyPath = url + &quot;.empty.html&quot;;
1063
- var empty = original.substr(0,posDiv[0] + startSaveArea.length) + original.substr(posDiv[1]);
1064
- bidix.httpPut(emptyPath,empty,callback,Array(url,original,posDiv));
1065
- } else {
1066
- bidix.WebDAVSaving.saveMain(url,original,posDiv);
1067
- }
1127
+ refreshPageTemplate(title);
1068
1128
  }
1069
1129
 
1070
- bidix.WebDAVSaving.saveMain = function(url,original,posDiv)
1130
+ // @Deprecated: Use story.displayTiddlers instead
1131
+ function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
1071
1132
  {
1072
- var callback = function(status,params,responseText,url,xhr) {
1073
- if(status) {
1074
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
1075
- displayMessage(config.messages.mainSaved,url);
1076
- store.setDirty(false);
1077
- } else
1078
- alert(config.messages.mainFailed);
1079
- };
1080
- // Save new file
1081
- var revised = updateOriginal(original,posDiv);
1082
- bidix.httpPut(url,revised,callback,null);
1083
- }
1084
-
1085
- // asynchronous mkdir
1086
- bidix.WebDAVSaving.mkdir = function(root,dir,dirs,url,original,posDiv) {
1087
- var callback = function(status,params,responseText,url,xhr) {
1088
- url = (url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1));
1089
- if (status == null) {
1090
- alert(&quot;Error in mkdir&quot;);
1091
- return;
1092
- }
1093
- if (xhr.status == httpStatus.ContentCreated) {
1094
- displayMessage(bidix.WebDAVSaving.messages.folderCreated.format([url]),url);
1095
- bidix.WebDAVSaving.mkbackupfolder(url,params[1],params[2],params[3],params[4]);
1096
- } else {
1097
- if (xhr.status == httpStatus.NotFound)
1098
- bidix.http('MKCOL',url,null,callback,params);
1099
- else
1100
- bidix.WebDAVSaving.mkbackupfolder(url,params[1],params[2],params[3],params[4]);
1101
- }
1102
- };
1103
- if (root.charAt(root.length) != '/')
1104
- root = root +'/';
1105
- bidix.http('HEAD',root+dir,null,callback,Array(root,dirs,url,original,posDiv));
1133
+ story.displayTiddlers(srcElement,titles,template,animate);
1106
1134
  }
1107
1135
 
1108
- bidix.httpPut = function(url,data,callback,params)
1136
+ // @Deprecated: Use story.displayTiddler instead
1137
+ function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
1109
1138
  {
1110
- return bidix.http(&quot;PUT&quot;,url,data,callback,params);
1139
+ story.displayTiddler(srcElement,title,template,animate);
1111
1140
  }
1112
1141
 
1113
- bidix.http = function(type,url,data,callback,params)
1114
- {
1115
- var r = doHttp(type,url,data,null,null,null,callback,params,null);
1116
- if (typeof r == &quot;string&quot;)
1117
- alert(r);
1118
- return r;
1142
+ // @Deprecated: Use functions on right hand side directly instead
1143
+ var createTiddlerPopup = Popup.create;
1144
+ var scrollToTiddlerPopup = Popup.show;
1145
+ var hideTiddlerPopup = Popup.remove;
1146
+
1147
+ // @Deprecated: Use right hand side directly instead
1148
+ var regexpBackSlashEn = new RegExp(&quot;\\\\n&quot;,&quot;mg&quot;);
1149
+ var regexpBackSlash = new RegExp(&quot;\\\\&quot;,&quot;mg&quot;);
1150
+ var regexpBackSlashEss = new RegExp(&quot;\\\\s&quot;,&quot;mg&quot;);
1151
+ var regexpNewLine = new RegExp(&quot;\n&quot;,&quot;mg&quot;);
1152
+ var regexpCarriageReturn = new RegExp(&quot;\r&quot;,&quot;mg&quot;);
1153
+
1119
1154
  }
1155
+ //}}}</pre>
1156
+ </div>
1157
+ <div title="Introduction" modifier="loic" modified="200804041355" created="200707211630" changecount="5">
1158
+ <pre>a ruby gem (http://rubyforge.org/projects/tiddlywikicp/) providing a library and a command line interface to copy [[tiddlywiki|http://tiddlywiki.com/]] tiddlers to files and vice versa.
1159
+
1160
+ Installation : gem install tiddlywiki_cp
1161
+
1162
+ Development is discussed at irc.freenode.net#tiddlywiki
1120
1163
 
1121
- bidix.dirname = function (filePath) {
1122
- if (!filePath)
1164
+ This tiddlywiki was created using the following commands:
1165
+ * copy an empty tiddlywiki to a local file
1166
+ {{{
1167
+ tiddlywiki_cp http://tiddlywiki.com/empty.html website/index.html
1168
+ }}}
1169
+ * copy and install a plugin
1170
+ {{{
1171
+ tiddlywiki_cp 'http://garden.dachary.org/#WebDavPlugin' website/index.html
1172
+ }}}
1173
+ * copy all tiddlers to a directory
1174
+ {{{
1175
+ mkdir website/files
1176
+ tiddlywiki_cp -a website/index.html website/files
1177
+ }}}
1178
+ * use regular shell commands to create or update files
1179
+ {{{
1180
+ ( echo '{{''{' ; RUBYLIB=lib ruby bin/tiddlywiki_cp --help ; echo '}}''}' ) &gt; website/files/Usage.tiddler
1181
+ ( echo '{{''{' ; hg log ; echo '}}''}' ) &gt; website/files/ChangeLog.tiddler
1182
+ }}}
1183
+ * copy all tiddlers in a directory into a tiddlywiki, updating existing ones and adding new ones
1184
+ {{{
1185
+ cd website ; RUBYLIB=../lib ruby ../bin/tiddlywiki_cp -a files index.html
1186
+ }}}
1187
+ Loic Dachary &lt;mailto:loic@dachary.org&gt;
1188
+ </pre>
1189
+ </div>
1190
+ <div title="LegacyStrikeThroughPlugin" modifier="MartinBudden" created="200607210000" tags="systemConfig">
1191
+ <pre>/***
1192
+ |''Name:''|LegacyStrikeThroughPlugin|
1193
+ |''Description:''|Support for legacy (pre 2.1) strike through formatting|
1194
+ |''Version:''|1.0.2|
1195
+ |''Date:''|Jul 21, 2006|
1196
+ |''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
1197
+ |''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
1198
+ |''License:''|[[BSD open source license]]|
1199
+ |''CoreVersion:''|2.1.0|
1200
+ ***/
1201
+
1202
+ //{{{
1203
+ // Ensure that the LegacyStrikeThrough Plugin is only installed once.
1204
+ if(!version.extensions.LegacyStrikeThroughPlugin) {
1205
+ version.extensions.LegacyStrikeThroughPlugin = {installed:true};
1206
+
1207
+ config.formatters.push(
1208
+ {
1209
+ name: &quot;legacyStrikeByChar&quot;,
1210
+ match: &quot;==&quot;,
1211
+ termRegExp: /(==)/mg,
1212
+ element: &quot;strike&quot;,
1213
+ handler: config.formatterHelpers.createElementAndWikify
1214
+ });
1215
+
1216
+ } //# end of &quot;install only once&quot;
1217
+ //}}}</pre>
1218
+ </div>
1219
+ <div title="MainMenu" modifier="loic" modified="200707231424" created="200707211619" changecount="2">
1220
+ <pre>[[Introduction]]
1221
+ [[Usage]]
1222
+ [[ChangeLog]]
1223
+ </pre>
1224
+ </div>
1225
+ <div title="SiteSubtitle" modifier="loic" modified="200707231424" created="200707211618" changecount="1">
1226
+ <pre>copy tiddlers to files and vice versa</pre>
1227
+ </div>
1228
+ <div title="SiteTitle" modifier="loic" modified="200707231424" created="200707211617" changecount="1">
1229
+ <pre>tiddlywiki_cp</pre>
1230
+ </div>
1231
+ <div title="SparklinePlugin" modifier="" created="200710125059" tags="systemConfig excludeLists excludeSearch">
1232
+ <pre>/***
1233
+ |''Name:''|SparklinePlugin|
1234
+ |''Description:''|Sparklines macro|
1235
+ ***/
1236
+ //{{{
1237
+ if(!version.extensions.SparklinePlugin) {
1238
+ version.extensions.SparklinePlugin = {installed:true};
1239
+
1240
+ //--
1241
+ //-- Sparklines
1242
+ //--
1243
+
1244
+ config.macros.sparkline = {};
1245
+ config.macros.sparkline.handler = function(place,macroName,params)
1246
+ {
1247
+ var data = [];
1248
+ var min = 0;
1249
+ var max = 0;
1250
+ var v;
1251
+ for(var t=0; t&lt;params.length; t++) {
1252
+ v = parseInt(params[t]);
1253
+ if(v &lt; min)
1254
+ min = v;
1255
+ if(v &gt; max)
1256
+ max = v;
1257
+ data.push(v);
1258
+ }
1259
+ if(data.length &lt; 1)
1123
1260
  return;
1124
- var lastpos;
1125
- if ((lastpos = filePath.lastIndexOf(&quot;/&quot;)) != -1) {
1126
- return filePath.substring(0, lastpos);
1127
- } else {
1128
- return filePath.substring(0, filePath.lastIndexOf(&quot;\\&quot;));
1261
+ var box = createTiddlyElement(place,&quot;span&quot;,null,&quot;sparkline&quot;,String.fromCharCode(160));
1262
+ box.title = data.join(&quot;,&quot;);
1263
+ var w = box.offsetWidth;
1264
+ var h = box.offsetHeight;
1265
+ box.style.paddingRight = (data.length * 2 - w) + &quot;px&quot;;
1266
+ box.style.position = &quot;relative&quot;;
1267
+ for(var d=0; d&lt;data.length; d++) {
1268
+ var tick = document.createElement(&quot;img&quot;);
1269
+ tick.border = 0;
1270
+ tick.className = &quot;sparktick&quot;;
1271
+ tick.style.position = &quot;absolute&quot;;
1272
+ tick.src = &quot;data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B&quot;;
1273
+ tick.style.left = d*2 + &quot;px&quot;;
1274
+ tick.style.width = &quot;2px&quot;;
1275
+ v = Math.floor(((data[d] - min)/(max-min)) * h);
1276
+ tick.style.top = (h-v) + &quot;px&quot;;
1277
+ tick.style.height = v + &quot;px&quot;;
1278
+ box.appendChild(tick);
1129
1279
  }
1130
1280
  };
1281
+
1282
+
1283
+ }
1131
1284
  //}}}</pre>
1132
1285
  </div>
1286
+ <div title="Usage" modifier="loic" modified="200804062225" created="200707211620" changecount="1">
1287
+ <pre>{{{
1288
+ Usage: tiddlywiki_cp [options] FROM [FROM ...] TO|-
1289
+
1290
+ -r, --[no-]recursive recurse into directories and tiddlywikies
1291
+ -t, --[no-]times preserve modification time
1292
+ -a, --all implies -rt
1293
+ -i, --include REGEX all files,directories or tiddlers must match regex.
1294
+ If specified multiple times,
1295
+ must match at least one of the regex.
1296
+ Includes are tested after excludes.
1297
+ --exclude REGEX all files,directories or tiddlers must NOT match regex.
1298
+ If specified multiple times,
1299
+ exclude if matches at least one of the regex.
1300
+ Includes are tested after excludes.
1301
+ -v, --[no-]verbose run verbosely
1302
+ -n, --[no-]dry-run show what would have been transferred
1303
+ --version show version
1304
+ --help show command usage
1305
+
1306
+ Examples:
1307
+
1308
+ mkdir /tmp/a ; tiddlywiki_cp -a http://tiddlywiki.com/index.html /tmp/a
1309
+ copies index.html tiddlers in separate files and preserve times.
1310
+ For each tiddler, a .div file contains the meta information.
1311
+ The files are named after their content:
1312
+ /tmp/a/HelloThere.tiddler
1313
+ /tmp/a/HelloThere.tiddler.div
1314
+ /tmp/a/Plugin.js
1315
+ /tmp/a/Plugin.js.div
1316
+ /tmp/a/OwnStyle.css
1317
+ /tmp/a/OwnStyle.css.div
1318
+ ...
1319
+
1320
+ tiddlywiki_cp 'http://tiddlylab.bidix.info/#WebDAVSavingPlugin' tiddlywiki.html
1321
+ copies the WebDAVSavingPlugin tiddler in the existing tiddlywiki.html
1322
+
1323
+ tiddlywiki_cp http://tiddlywiki.com/index.html /tmp/i.html
1324
+ copies to a local file
1325
+
1326
+ tiddlywiki_cp -t myplugin.js tiddlywiki.html
1327
+ copies the tiddler in the existing tiddlywiki.html tiddlywiki
1328
+ and use file system modification time
1329
+
1330
+ tiddlywiki_cp 'http://tiddlylab.bidix.info/#WebDAVSavingPlugin' WebDAVSavingPlugin.js
1331
+ get a local copy of the WebDAVSavingPlugin tiddler
1332
+
1333
+ mkdir A ; tiddlywiki_cp -a --include 'WebDAV' --include 'RSS' 'http://tiddlylab.bidix.info/' A
1334
+ copy all tiddlers with WebDAV or RSS in the url
1335
+
1336
+ mkdir A ; tiddlywiki_cp -a --exclude 'SEX' 'http://tiddlylab.bidix.info/' A
1337
+ copy all tiddlers except those with SEX in the url
1338
+
1339
+ tiddlywiki_cp -a A B C tiddlywiki.html
1340
+ copy all tiddlers found in the A B and C directories to tiddlywiki.html
1341
+
1342
+ MarkupPreHead, MarkupPostHead, MarkupPreBody, MarkupPostBody tiddlers:
1343
+
1344
+ When copying to a tiddlywiki file, the content of these tiddlers
1345
+ are copied to the corresponding HTML zones.
1346
+
1347
+ translations, i18n, l10n, linguo:
1348
+
1349
+ If a translation plugin such as the one found at
1350
+ http://trac.tiddlywiki.org/wiki/Translations
1351
+ is present, the tiddlywiki to which tiddlers are copied
1352
+ will have its lang and xml:lang attributes updated.
1353
+ Saving the tiddlywiki manually does the same.
1354
+
1355
+ }}}
1356
+ </pre>
1357
+ </div>
1358
+ <div title="WebDavPlugin" modifier="YourName" modified="200804041354" created="200711171415" tags="systemConfig" changecount="3">
1359
+ <pre>/***
1360
+ |''Name:''|WebDavPlugin|
1361
+ |''Description:''|Allows a TiddlyWiki to be saved to a WebDav server|
1362
+ |''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
1363
+ |''Co-author:''|Loic Dachary|
1364
+ |''Source:''|http://tw.lewcid.org/#WebDavPlugin|
1365
+ |''Code Repository:''|http://tw.lewcid.org/svn/plugins|
1366
+ |''Version:''|1.0|
1367
+ |''Date:''|17/11/2007|
1368
+ |''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
1369
+ |''~CoreVersion:''|2.2.3|
1370
+
1371
+ ***/
1372
+ // /%
1373
+ //!BEGIN-PLUGIN-CODE
1374
+ DAV = {
1375
+ run : function(type,u,data,cb,params,headers){
1376
+ var callback = function(status,params,responseText,url,xhr) {
1377
+ url = url.indexOf(&quot;nocache=&quot;) &lt; 0 ? url : url.substring(0,url.indexOf(&quot;nocache=&quot;)-1);
1378
+ if(params.length){
1379
+ params.shift().apply(this,[status,params,responseText,url,xhr]);
1380
+ }
1381
+ };
1382
+ params = params||[];
1383
+ params.unshift(cb);
1384
+ var r = doHttp.apply(this,[type,u,data,null,null,null,callback,params,headers]);
1385
+ if (typeof r == &quot;string&quot;)
1386
+ alert(r);
1387
+ return r;
1388
+ },
1389
+
1390
+ get : function(url,cb,params){
1391
+ return DAV.run(&quot;GET&quot;,url,null,cb,params,null);
1392
+ },
1393
+
1394
+ put : function(url,cb,params,data) {
1395
+ return DAV.run(&quot;PUT&quot;,url,data,cb,params,null);
1396
+ },
1397
+
1398
+ move : function(url,cb,params,destination) {
1399
+ return DAV.run(&quot;MOVE&quot;,url,null,cb,params,{&quot;Destination&quot;:destination,&quot;Overwrite&quot;:&quot;T&quot;});
1400
+ },
1401
+
1402
+ copy : function(url,cb,params,destination) {
1403
+ return DAV.run(&quot;COPY&quot;,url,null,cb,params,{&quot;Destination&quot;:destination,&quot;Overwrite&quot;:&quot;T&quot;,&quot;Depth&quot;:0});
1404
+ },
1405
+
1406
+ propfind : function(url,cb,params,prop,depth){ // !!!
1407
+ var xml = '&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; ?&gt;' +
1408
+ '&lt;D:propfind xmlns:D=&quot;DAV:&quot;&gt;' +
1409
+ '&lt;D:prop&gt;'+
1410
+ '&lt;D:'+prop+'/&gt;'+
1411
+ '&lt;/D:prop&gt;'+
1412
+ '&lt;/D:propfind&gt;';
1413
+ return DAV.run(&quot;PROPFIND&quot;,url,xml,cb,params,{&quot;Content-type&quot;:&quot;text/xml&quot;,&quot;Depth&quot;:depth?depth:0});
1414
+ },
1415
+
1416
+ makeDir : function(url,cb,params){
1417
+ return DAV.run(&quot;MKCOL&quot;,url,null,cb,params,null);
1418
+ },
1419
+
1420
+ options : function(url,cb,params){
1421
+ return DAV.run(&quot;OPTIONS&quot;,url,null,cb,params,null);
1422
+ },
1423
+
1424
+ safeput : function(url,cb,params,data){
1425
+ firstcb = function(status,p,responseText,u,xhr){
1426
+ if(status)
1427
+ DAV.move(u,cb,p,u.replace(&quot;-davsavingtemp&quot;,&quot;&quot;));
1428
+ else
1429
+ cb.apply(firstcb,arguments);
1430
+ };
1431
+ return DAV.put(url+&quot;-davsavingtemp&quot;,firstcb,params,data);
1432
+ }
1433
+ };
1434
+
1435
+ config.DavSaver = {
1436
+ defaultFileName : 'index.html',
1437
+ messages : {
1438
+ startSaveMessage : 'saving to server...',
1439
+ endSaveMessage : 'TiddlyWiki successfuly saved to server',
1440
+ overwriteNewerPrompt : 'The remote file has changed since you last loaded or saved it.\nDo you wish to overwrite it?',
1441
+ getModDateError : &quot;Could not get last modified date&quot;,
1442
+ raceError: &quot;Save failed because the remote file is newer than the one you are trying to save&quot;
1443
+ },
1444
+ errors:{
1445
+ raceconflict : 'The save failed because your file is out of date',
1446
+ getlastmodified : 'The save was aborted because the last modified date of the file could not be retrieved',
1447
+ davenabled : 'The server does not support WebDav',
1448
+ saverss : 'There was an error saving the rss file, the save was aborted',
1449
+ saveempty: 'There was an error saving the empty file, the save was aborted',
1450
+ savemain : 'Save failed! There was an error saving the main TW file',
1451
+ savebackup: 'Save failed! There was an error creating a backup file',
1452
+ makebackupdir: 'Save failed! The backup directory could not be created'
1453
+ },
1454
+ timestamp: new Date().toGMTString(),
1455
+ orig_saveChanges: saveChanges,
1456
+ saver : null
1457
+ };
1458
+
1459
+ DavSaver = function(){
1460
+
1461
+ this.Q = [];
1462
+
1463
+ this.reset = function(){
1464
+ config.DavSaver.saver = null;
1465
+ };
1466
+ this.runQ = function(){
1467
+ if(this.Q.length){
1468
+ this.Q.shift().apply(this,arguments);
1469
+ }
1470
+ else
1471
+ this.reset();
1472
+ };
1473
+ this.posDiv = null;
1474
+ this.original = null;
1475
+
1476
+ this.getOriginalPath = function(){
1477
+ var p = document.location.toString();
1478
+ p = convertUriToUTF8(p,config.options.txtFileSystemCharSet);
1479
+ var argPos = p.indexOf(&quot;?&quot;);
1480
+ if(argPos != -1)
1481
+ p = p.substr(0,argPos);
1482
+ var hashPos = p.indexOf(&quot;#&quot;);
1483
+ if(hashPos != -1)
1484
+ p = p.substr(0,hashPos);
1485
+ if (p.charAt(p.length-1) == &quot;/&quot;)
1486
+ p = p + config.DavSaver.defaultFileName;
1487
+ return p;
1488
+ };
1489
+
1490
+ this.originalPath = this.getOriginalPath();
1491
+ this.backupPath = null;
1492
+ this.emptyPath = null;
1493
+ this.rssPath = null;
1494
+ this.throwError = function(er){
1495
+ clearMessage();
1496
+ this.reset();
1497
+ alert(config.DavSaver.errors[er]); //clear message, reset and delete
1498
+ };
1499
+ };
1500
+
1501
+ DavSaver.prototype.getOriginal = function(){
1502
+ var callback = function(status,params,original,url,xhr) {
1503
+ var that = params[0];
1504
+ if(status){
1505
+ var p = that.posDiv = locateStoreArea(original);
1506
+ if(!p || (p[0] == -1) || (p[1] == -1)) {
1507
+ alert(config.messages.invalidFileError.format([url]));
1508
+ return;
1509
+ }
1510
+ that.original = original;
1511
+ that.runQ();
1512
+ }
1513
+ else
1514
+ that.throwError('getOriginal');
1515
+ };
1516
+
1517
+ DAV.get(this.originalPath,callback,[this]);
1518
+ };
1519
+
1520
+ DavSaver.prototype.checkRace = function(){
1521
+ var callback = function(status,params,responseText,url,xhr){
1522
+ var that = params[0];
1523
+ if(status){
1524
+ var lastmod = responseText.match(/&lt;(\w*?):getlastmodified&gt;(.*?)&lt;\/\1:getlastmodified&gt;/)[2];
1525
+ if(Date.parse(lastmod) &gt; Date.parse(config.DavSaver.timestamp)){
1526
+ if (confirm(config.DavSaver.messages.overwriteNewerPrompt))
1527
+ that.runQ();
1528
+ else
1529
+ that.throwError('raceconflict');
1530
+ }
1531
+ else
1532
+ that.runQ();
1533
+ }
1534
+ else
1535
+ that.throwError('getlastmodified');
1536
+ };
1537
+
1538
+ DAV.propfind(this.originalPath,callback,[this],&quot;getlastmodified&quot;,0);
1539
+ };
1540
+
1541
+ DavSaver.prototype.isDavEnabled = function(){
1542
+ var callback = function(status,params,responseText,url,xhr){
1543
+ that = params[0];
1544
+ if(status &amp;&amp; !! xhr.getResponseHeader(&quot;DAV&quot;)){
1545
+ that.runQ();
1546
+ }
1547
+ else
1548
+ that.throwError('davenabled');
1549
+ };
1550
+ DAV.options(this.originalPath,callback,[this]);
1551
+ };
1552
+
1553
+ DavSaver.prototype.saveRss = function(){
1554
+ var callback = function(status,params,responseText,url,xhr){
1555
+ var that = params[0];
1556
+ if(status){
1557
+ displayMessage(config.messages.rssSaved,that.rssPath);
1558
+ that.runQ();
1559
+ }
1560
+ else
1561
+ that.throwError('saverss');
1562
+ };
1563
+ var u = this.originalPath;
1564
+ var rssPath = this.rssPath = u.substr(0,u.lastIndexOf(&quot;.&quot;)) + &quot;.xml&quot;;
1565
+ DAV.safeput(rssPath,callback,[this],convertUnicodeToUTF8(generateRss()));
1566
+ };
1567
+
1568
+ DavSaver.prototype.saveEmpty = function(){
1569
+ var callback = function(status,params,responseText,url,xhr){
1570
+ var that = params[0];
1571
+ if(status){
1572
+ displayMessage(config.messages.emptySaved,that.emptyPath);
1573
+ that.runQ();
1574
+ }
1575
+ else
1576
+ that.throwError('saveempty');
1577
+ };
1578
+ var u = this.originalPath;
1579
+ var emptyPath,p;
1580
+ if((p = u.lastIndexOf(&quot;/&quot;)) != -1)
1581
+ emptyPath = u.substr(0,p) + &quot;/empty.html&quot;;
1582
+ else
1583
+ emptyPath = u + &quot;.empty.html&quot;;
1584
+ this.emptyPath = emptyPath;
1585
+ var empty = this.original.substr(0,this.posDiv[0] + startSaveArea.length) + this.original.substr(this.posDiv[1]);
1586
+ DAV.safeput(emptyPath,callback,[this],empty);
1587
+ };
1588
+
1589
+ DavSaver.prototype.saveMain = function(){
1590
+ var callback = function(status,params,responseText,url,xhr){
1591
+ var that = params[0];
1592
+ if(status){
1593
+ config.DavSaver.timestamp = xhr.getResponseHeader('Date');
1594
+ displayMessage(config.messages.mainSaved,that.originalPath);
1595
+ store.setDirty(false);
1596
+ that.runQ();
1597
+ }
1598
+ else
1599
+ that.throwError('savemain');
1600
+ };
1601
+ var revised = updateOriginal(this.original,this.posDiv);
1602
+ DAV.safeput(this.originalPath,callback,[this],revised);
1603
+ };
1604
+
1605
+ DavSaver.prototype.saveBackup = function(){
1606
+ var callback = function(status,params,responseText,url,xhr){
1607
+ var that = params[0];
1608
+ if(status){
1609
+ clearMessage();
1610
+ displayMessage(config.messages.backupSaved,that.backupPath);
1611
+ that.runQ();
1612
+ }
1613
+ else
1614
+ that.throwError('savebackup');
1615
+ };
1616
+
1617
+ var backupPath = this.backupPath = getBackupPath(this.originalPath);
1618
+ DAV.copy(this.originalPath,callback,[this],this.backupPath);
1619
+ };
1620
+
1621
+ DavSaver.prototype.makeBackupDir = function(){
1622
+ var callback = function(status,params,responseText,url,xhr){
1623
+ var that = params[0];
1624
+ if(status)
1625
+ that.runQ();
1626
+ else
1627
+ that.throwError('makebackupdir');
1628
+ };
1629
+ var u = getBackupPath(this.originalPath);
1630
+ var backupDirPath = u.substr(0,u.lastIndexOf(&quot;/&quot;));
1631
+ DAV.makeDir(backupDirPath,callback,[this]);
1632
+ };
1633
+
1634
+ DavSaver.prototype.save = function(onlyIfDirty,tiddlers){
1635
+ if(onlyIfDirty &amp;&amp; !store.isDirty())
1636
+ return;
1637
+ clearMessage();
1638
+ displayMessage(config.DavSaver.messages.startSaveMessage);
1639
+ var Q = this.Q =[];
1640
+ Q.push(this.isDavEnabled);
1641
+ Q.push(this.getOriginal);
1642
+ Q.push(this.checkRace);
1643
+ if (config.options.chkSaveBackups){
1644
+ if (config.options.txtBackupFolder!='')
1645
+ Q.push(this.makeBackupDir);
1646
+ Q.push(this.saveBackup);
1647
+ }
1648
+ Q.push(this.saveMain);
1649
+ if (config.options.chkGenerateAnRssFeed)
1650
+ Q.push(this.saveRss);
1651
+ if (config.options.chkSaveEmptyTemplate)
1652
+ Q.push(this.saveEmpty);
1653
+ //Q.push(this.reset);
1654
+ this.runQ();
1655
+ };
1656
+
1657
+ window.saveChanges = function(onlyIfDirty,tiddlers)
1658
+ {
1659
+ var c = config.DavSaver;
1660
+ if (document.location.protocol.toString() == &quot;http:&quot;){
1661
+ var saver = c.saver = new DavSaver();
1662
+ saver.save(onlyIfDirty,tiddlers);
1663
+ }
1664
+ else
1665
+ return c.orig_saveChanges(onlyIfDirty,tiddlers);
1666
+ };
1667
+ //!END-PLUGIN-CODE
1668
+ // %/</pre>
1669
+ </div>
1133
1670
  </div>
1134
1671
  <!--POST-STOREAREA-->
1135
1672
  <!--POST-BODY-START-->
@@ -1199,10 +1736,11 @@ config.options = {
1199
1736
  txtMainTab: "tabTimeline",
1200
1737
  txtMoreTab: "moreTabAll",
1201
1738
  txtMaxEditRows: "30",
1202
- txtFileSystemCharSet: "UTF-8"
1739
+ txtFileSystemCharSet: "UTF-8",
1740
+ txtTheme: ""
1203
1741
  };
1204
1742
  config.optionsDesc = {};
1205
-
1743
+
1206
1744
  // List of notification functions to be called when certain tiddlers are changed or deleted
1207
1745
  config.notifyTiddlers = [
1208
1746
  {name: "StyleSheetLayout", notify: refreshStyles},
@@ -1253,7 +1791,8 @@ config.macros = {
1253
1791
  missing: {},
1254
1792
  orphans: {},
1255
1793
  shadowed: {},
1256
- touched: {}
1794
+ touched: {},
1795
+ filter: {}
1257
1796
  },
1258
1797
  closeAll: {},
1259
1798
  permaview: {},
@@ -1263,7 +1802,6 @@ config.macros = {
1263
1802
  options: {},
1264
1803
  newTiddler: {},
1265
1804
  newJournal: {},
1266
- sparkline: {},
1267
1805
  tabs: {},
1268
1806
  gradient: {},
1269
1807
  message: {},
@@ -1271,7 +1809,6 @@ config.macros = {
1271
1809
  edit: {},
1272
1810
  tagChooser: {},
1273
1811
  toolbar: {},
1274
- br: {},
1275
1812
  plugins: {},
1276
1813
  refreshDisplay: {},
1277
1814
  importTiddlers: {},
@@ -1326,7 +1863,8 @@ if(config.browser.isBadSafari) {
1326
1863
  };
1327
1864
  }
1328
1865
  config.textPrimitives.sliceSeparator = "::";
1329
- config.textPrimitives.urlPattern = "[a-z]{3,8}:[^\\s:'\"][^\\s'\"]*(?:/|\\b)";
1866
+ config.textPrimitives.sectionSeparator = "##";
1867
+ config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
1330
1868
  config.textPrimitives.unWikiLink = "~";
1331
1869
  config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
1332
1870
  config.textPrimitives.lowerLetter + "+" +
@@ -1341,7 +1879,7 @@ config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssL
1341
1879
  config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
1342
1880
  config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
1343
1881
  config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
1344
- config.textPrimitives.brackettedLink + ")|(?:" +
1882
+ config.textPrimitives.brackettedLink + ")|(?:" +
1345
1883
  config.textPrimitives.urlPattern + ")","mg");
1346
1884
  config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
1347
1885
  config.textPrimitives.titledBrackettedLink + ")|(?:" +
@@ -1351,7 +1889,7 @@ config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitiv
1351
1889
  config.glyphs = {
1352
1890
  browsers: [
1353
1891
  function() {return config.browser.isIE;},
1354
- function() {return true}
1892
+ function() {return true;}
1355
1893
  ],
1356
1894
  currBrowser: null,
1357
1895
  codes: {
@@ -1368,7 +1906,7 @@ config.glyphs = {
1368
1906
 
1369
1907
  config.shadowTiddlers = {
1370
1908
  StyleSheet: "",
1371
- MarkupPreHead: "<!--{{{-->\n<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>\n<!--}}}-->",
1909
+ MarkupPreHead: "",
1372
1910
  MarkupPostHead: "",
1373
1911
  MarkupPreBody: "",
1374
1912
  MarkupPostBody: "",
@@ -1379,8 +1917,7 @@ config.shadowTiddlers = {
1379
1917
  TabMoreOrphans: '<<list orphans>>',
1380
1918
  TabMoreShadowed: '<<list shadowed>>',
1381
1919
  AdvancedOptions: '<<options>>',
1382
- PluginManager: '<<plugins>>',
1383
- ImportTiddlers: '<<importTiddlers>>'
1920
+ PluginManager: '<<plugins>>'
1384
1921
  };
1385
1922
 
1386
1923
  //--
@@ -1589,7 +2126,7 @@ merge(config.macros.options,{
1589
2126
  {name: 'Name', field: 'name', title: "Name", type: 'String'}
1590
2127
  ],
1591
2128
  rowClasses: [
1592
- {className: 'lowlight', field: 'lowlight'}
2129
+ {className: 'lowlight', field: 'lowlight'}
1593
2130
  ]}
1594
2131
  });
1595
2132
 
@@ -1699,7 +2236,7 @@ merge(config.macros.sync,{
1699
2236
  hasChanged: "Changed while unplugged",
1700
2237
  hasNotChanged: "Unchanged while unplugged",
1701
2238
  syncStatusList: {
1702
- none: {text: "...", color: "none"},
2239
+ none: {text: "...", color: "transparent"},
1703
2240
  changedServer: {text: "Changed on server", color: '#80ff80'},
1704
2241
  changedLocally: {text: "Changed while unplugged", color: '#80ff80'},
1705
2242
  changedBoth: {text: "Changed while unplugged and on server", color: '#ff8080'},
@@ -1785,7 +2322,7 @@ merge(config.shadowTiddlers,{
1785
2322
  SiteTitle: "My TiddlyWiki",
1786
2323
  SiteSubtitle: "a reusable non-linear personal web notebook",
1787
2324
  SiteUrl: "http://www.tiddlywiki.com/",
1788
- SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>',
2325
+ SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>',
1789
2326
  SideBarTabs: '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>',
1790
2327
  TabMore: '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>'});
1791
2328
 
@@ -1809,9 +2346,9 @@ merge(config.annotations,{
1809
2346
  SiteSubtitle: "This shadow tiddler is used as the second part of the page title",
1810
2347
  SiteTitle: "This shadow tiddler is used as the first part of the page title",
1811
2348
  SiteUrl: "This shadow tiddler should be set to the full target URL for publication",
1812
- StyleSheetColours: "This shadow tiddler contains CSS definitions related to the color of page elements",
2349
+ StyleSheetColors: "This shadow tiddler contains CSS definitions related to the color of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler.",
1813
2350
  StyleSheet: "This tiddler can contain custom CSS definitions",
1814
- StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements",
2351
+ StyleSheetLayout: "This shadow tiddler contains CSS definitions related to the layout of page elements. ''DO NOT EDIT THIS TIDDLER'', instead make your changes in the StyleSheet shadow tiddler.",
1815
2352
  StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale",
1816
2353
  StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing",
1817
2354
  TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar",
@@ -1833,11 +2370,12 @@ var store = null; // TiddlyWiki storage
1833
2370
  var story = null; // Main story
1834
2371
  var formatter = null; // Default formatters for the wikifier
1835
2372
  config.parsers = {}; // Hashmap of alternative parsers for the wikifier
1836
- var anim = new Animator(); // Animation engine
2373
+ var anim = typeof Animator == "function" ? new Animator() : null; // Animation engine
1837
2374
  var readOnly = false; // Whether we're in readonly mode
1838
2375
  var highlightHack = null; // Embarrassing hack department...
1839
2376
  var hadConfirmExit = false; // Don't warn more than once
1840
2377
  var safeMode = false; // Disable all plugins and cookies
2378
+ var showBackstage; // Whether to include the backstage area
1841
2379
  var installedPlugins = []; // Information filled in when plugins are executed
1842
2380
  var startingUp = false; // Whether we're in the process of starting up
1843
2381
  var pluginInfo,tiddler; // Used to pass information to plugins in loadPlugins()
@@ -1848,7 +2386,7 @@ var useJavaSaver = config.browser.isSafari || config.browser.isOpera;
1848
2386
  // Starting up
1849
2387
  function main()
1850
2388
  {
1851
- var t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
2389
+ var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
1852
2390
  startingUp = true;
1853
2391
  window.onbeforeunload = function(e) {if(window.confirmExit) return confirmExit();};
1854
2392
  params = getParameters();
@@ -1870,9 +2408,11 @@ function main()
1870
2408
  invokeParamifier(params,"onload");
1871
2409
  t4 = new Date();
1872
2410
  readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;
2411
+ showBackstage = !readOnly;
1873
2412
  var pluginProblem = loadPlugins();
1874
2413
  t5 = new Date();
1875
2414
  formatter = new Formatter(config.formatters);
2415
+ story.switchTheme(config.options.txtTheme);
1876
2416
  invokeParamifier(params,"onconfig");
1877
2417
  t6 = new Date();
1878
2418
  store.notifyAll();
@@ -1887,16 +2427,18 @@ function main()
1887
2427
  if(config.macros[m].init)
1888
2428
  config.macros[m].init();
1889
2429
  }
1890
- if(!readOnly)
1891
- backstage.init();
1892
2430
  t9 = new Date();
2431
+ if(showBackstage)
2432
+ backstage.init();
2433
+ t10 = new Date();
1893
2434
  if(config.options.chkDisplayStartupTime) {
1894
- displayMessage("Load in " + (t2-t1) + " ms");
1895
- displayMessage("Loadshadows in " + (t3-t2) + " ms");
1896
- displayMessage("Loadplugins in " + (t5-t4) + " ms");
1897
- displayMessage("Notify in " + (t7-t6) + " ms");
1898
- displayMessage("Restart in " + (t8-t7) + " ms");
1899
- displayMessage("Total startup in " + (t9-t0) + " ms");
2435
+ displayMessage("LoadFromDiv " + (t2-t1) + " ms");
2436
+ displayMessage("LoadShadows " + (t3-t2) + " ms");
2437
+ displayMessage("LoadPlugins " + (t5-t4) + " ms");
2438
+ displayMessage("Notify " + (t7-t6) + " ms");
2439
+ displayMessage("Restart " + (t8-t7) + " ms");
2440
+ displayMessage("Macro init " + (t9-t8) + " ms");
2441
+ displayMessage("Total: " + (t10-t0) + " ms");
1900
2442
  }
1901
2443
  startingUp = false;
1902
2444
  }
@@ -1906,8 +2448,8 @@ function restart()
1906
2448
  {
1907
2449
  invokeParamifier(params,"onstart");
1908
2450
  if(story.isEmpty()) {
1909
- var defaultParams = store.getTiddlerText("DefaultTiddlers").parseParams("open",null,false);
1910
- invokeParamifier(defaultParams,"onstart");
2451
+ var tiddlers = store.filterTiddlers(store.getTiddlerText("DefaultTiddlers"));
2452
+ story.displayTiddlers(null,tiddlers);
1911
2453
  }
1912
2454
  window.scrollTo(0,0);
1913
2455
  }
@@ -1942,9 +2484,10 @@ function loadPlugins()
1942
2484
  var p = getPluginInfo(tiddlers[i]);
1943
2485
  installedPlugins[i] = p;
1944
2486
  var n = p.Name;
1945
- if(n)
2487
+ if(n)
1946
2488
  map[n] = p;
1947
- if(n = p.Source)
2489
+ n = p.Source;
2490
+ if(n)
1948
2491
  map[n] = p;
1949
2492
  }
1950
2493
  var visit = function(p) {
@@ -1959,8 +2502,8 @@ function loadPlugins()
1959
2502
  }
1960
2503
  toLoad.push(p);
1961
2504
  };
1962
- for(i=0; i<nPlugins; i++)
1963
- visit(installedPlugins[i]);
2505
+ for(i=0; i<nPlugins; i++)
2506
+ visit(installedPlugins[i]);
1964
2507
  for(i=0; i<toLoad.length; i++) {
1965
2508
  p = toLoad[i];
1966
2509
  pluginInfo = p;
@@ -1977,7 +2520,7 @@ function loadPlugins()
1977
2520
  p.log.push(config.messages.pluginError.format([exceptionText(ex)]));
1978
2521
  p.error = true;
1979
2522
  }
1980
- pluginInfo.startupTime = String((new Date()) - startTime) + "ms";
2523
+ pluginInfo.startupTime = String((new Date()) - startTime) + "ms";
1981
2524
  } else {
1982
2525
  nPlugins--;
1983
2526
  }
@@ -2103,8 +2646,7 @@ config.paramifiers.searchRegExp = {
2103
2646
  config.paramifiers.tag = {
2104
2647
  onstart: function(v) {
2105
2648
  var tagged = store.getTaggedTiddlers(v,"title");
2106
- for(var t=0; t<tagged.length; t++)
2107
- story.displayTiddler("bottom",tagged[t].title,null,false,null);
2649
+ story.displayTiddlers(null,tagged,null,false,null);
2108
2650
  }
2109
2651
  };
2110
2652
 
@@ -2135,6 +2677,13 @@ config.paramifiers.readOnly = {
2135
2677
  }
2136
2678
  };
2137
2679
 
2680
+
2681
+ config.paramifiers.theme = {
2682
+ onconfig: function(v) {
2683
+ story.switchTheme(v);
2684
+ }
2685
+ };
2686
+
2138
2687
  //--
2139
2688
  //-- Formatter helpers
2140
2689
  //--
@@ -2156,7 +2705,7 @@ config.formatterHelpers = {
2156
2705
  {
2157
2706
  w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
2158
2707
  },
2159
-
2708
+
2160
2709
  inlineCssHelper: function(w)
2161
2710
  {
2162
2711
  var styles = [];
@@ -2213,7 +2762,7 @@ config.formatterHelpers = {
2213
2762
  if(urlRegExp.exec(link)) {
2214
2763
  return true;
2215
2764
  }
2216
- if (link.indexOf(".")!=-1 || link.indexOf("\\")!=-1 || link.indexOf("/")!=-1){
2765
+ if (link.indexOf(".")!=-1 || link.indexOf("\\")!=-1 || link.indexOf("/")!=-1 || link.indexOf("#")!=-1) {
2217
2766
  return true;
2218
2767
  }
2219
2768
  return false;
@@ -2234,7 +2783,6 @@ config.formatters = [
2234
2783
  cellRegExp: /(?:\|([^\n\|]*)\|)|(\|[fhck]?$\n?)/mg,
2235
2784
  cellTermRegExp: /((?:\x20*)\|)/mg,
2236
2785
  rowTypes: {"c":"caption", "h":"thead", "":"tbody", "f":"tfoot"},
2237
-
2238
2786
  handler: function(w)
2239
2787
  {
2240
2788
  var table = createTiddlyElement(w.output,"table",null,"twtable");
@@ -2263,7 +2811,10 @@ config.formatters = [
2263
2811
  rowContainer.setAttribute("align",rowCount == 0?"top":"bottom");
2264
2812
  w.subWikifyTerm(rowContainer,this.rowTermRegExp);
2265
2813
  } else {
2266
- this.rowHandler(w,createTiddlyElement(rowContainer,"tr",null,(rowCount&1)?"oddRow":"evenRow"),prevColumns);
2814
+ var theRow = createTiddlyElement(rowContainer,"tr",null,(rowCount&1)?"oddRow":"evenRow");
2815
+ theRow.onmouseover = function() {addClass(this,"hoverRow");};
2816
+ theRow.onmouseout = function() {removeClass(this,"hoverRow");};
2817
+ this.rowHandler(w,theRow,prevColumns);
2267
2818
  rowCount++;
2268
2819
  }
2269
2820
  }
@@ -2360,7 +2911,7 @@ config.formatters = [
2360
2911
  {
2361
2912
  var stack = [w.output];
2362
2913
  var currLevel = 0, currType = null;
2363
- var listLevel, listType, itemType;
2914
+ var listLevel, listType, itemType, baseType;
2364
2915
  w.nextMatch = w.matchStart;
2365
2916
  this.lookaheadRegExp.lastIndex = w.nextMatch;
2366
2917
  var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
@@ -2378,6 +2929,8 @@ config.formatters = [
2378
2929
  listType = "dl";
2379
2930
  itemType = "dd";
2380
2931
  }
2932
+ if(!baseType)
2933
+ baseType = listType;
2381
2934
  listLevel = lookaheadMatch[0].length;
2382
2935
  w.nextMatch += lookaheadMatch[0].length;
2383
2936
  var t;
@@ -2386,6 +2939,9 @@ config.formatters = [
2386
2939
  var target = (currLevel == 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
2387
2940
  stack.push(createTiddlyElement(target,listType));
2388
2941
  }
2942
+ } else if(listType!=baseType && listLevel==1) {
2943
+ w.nextMatch -= lookaheadMatch[0].length;
2944
+ return;
2389
2945
  } else if(listLevel < currLevel) {
2390
2946
  for(t=currLevel; t>listLevel; t--)
2391
2947
  stack.pop();
@@ -2456,53 +3012,37 @@ config.formatters = [
2456
3012
 
2457
3013
  {
2458
3014
  name: "monospacedByLine",
2459
- match: "^\\{\\{\\{\\n",
2460
- lookaheadRegExp: /^\{\{\{\n((?:^[^\n]*\n)+?)(^\}\}\}$\n?)/mg,
2461
- element: "pre",
2462
- handler: config.formatterHelpers.enclosedTextHelper
2463
- },
2464
-
2465
- {
2466
- name: "monospacedByLineForCSS",
2467
- match: "^/\\*\\{\\{\\{\\*/\\n",
2468
- lookaheadRegExp: /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\/\*\}\}\}\*\/$\n?)/mg,
3015
+ match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|<!--\\{\\{\\{-->)\\n",
2469
3016
  element: "pre",
2470
- handler: config.formatterHelpers.enclosedTextHelper
2471
- },
2472
-
2473
- {
2474
- name: "monospacedByLineForPlugin",
2475
- match: "^//\\{\\{\\{\\n",
2476
- lookaheadRegExp: /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\/\/\}\}\}$\n?)/mg,
2477
- element: "pre",
2478
- handler: config.formatterHelpers.enclosedTextHelper
2479
- },
2480
-
2481
- {
2482
- name: "monospacedByLineForTemplate",
2483
- match: "^<!--\\{\\{\\{-->\\n",
2484
- lookaheadRegExp: /<!--\{\{\{-->\n*((?:^[^\n]*\n)+?)(\n*^<!--\}\}\}-->$\n?)/mg,
2485
- element: "pre",
2486
- handler: config.formatterHelpers.enclosedTextHelper
2487
- },
2488
-
2489
- {
2490
- name: "wikifyCommentForPlugin",
2491
- match: "^/\\*\\*\\*\\n",
2492
- termRegExp: /(^\*\*\*\/\n)/mg,
2493
3017
  handler: function(w)
2494
3018
  {
2495
- w.subWikifyTerm(w.output,this.termRegExp);
3019
+ switch(w.matchText) {
3020
+ case "/*{{{*/\n": // CSS
3021
+ this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\/\*\}\}\}\*\/$\n?)/mg;
3022
+ break;
3023
+ case "{{{\n": // monospaced block
3024
+ this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\}\}\}$\n?)/mg;
3025
+ break;
3026
+ case "//{{{\n": // plugin
3027
+ this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\/\/\}\}\}$\n?)/mg;
3028
+ break;
3029
+ case "<!--{{{-->\n": //template
3030
+ this.lookaheadRegExp = /<!--\{\{\{-->\n*((?:^[^\n]*\n)+?)(\n*^<!--\}\}\}-->$\n?)/mg;
3031
+ break;
3032
+ default:
3033
+ break;
3034
+ }
3035
+ config.formatterHelpers.enclosedTextHelper.call(this,w);
2496
3036
  }
2497
3037
  },
2498
3038
 
2499
3039
  {
2500
- name: "wikifyCommentForTemplate",
2501
- match: "^<!---\\n",
2502
- termRegExp: /(^--->\n)/mg,
2503
- handler: function(w)
3040
+ name: "wikifyComment",
3041
+ match: "^(?:/\\*\\*\\*|<!---)\\n",
3042
+ handler: function(w)
2504
3043
  {
2505
- w.subWikifyTerm(w.output,this.termRegExp);
3044
+ var termRegExp = (w.matchText == "/***\n") ? (/(^\*\*\*\/\n)/mg) : (/(^--->\n)/mg);
3045
+ w.subWikifyTerm(w.output,termRegExp);
2506
3046
  }
2507
3047
  },
2508
3048
 
@@ -2547,20 +3087,15 @@ config.formatters = [
2547
3087
  }
2548
3088
  },
2549
3089
 
2550
- {
2551
- name: "unWikiLink",
2552
- match: config.textPrimitives.unWikiLink+config.textPrimitives.wikiLink,
2553
- handler: function(w)
2554
- {
2555
- w.outputText(w.output,w.matchStart+1,w.nextMatch);
2556
- }
2557
- },
2558
-
2559
3090
  {
2560
3091
  name: "wikiLink",
2561
- match: config.textPrimitives.wikiLink,
3092
+ match: config.textPrimitives.unWikiLink+"?"+config.textPrimitives.wikiLink,
2562
3093
  handler: function(w)
2563
3094
  {
3095
+ if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink) {
3096
+ w.outputText(w.output,w.matchStart+1,w.nextMatch);
3097
+ return;
3098
+ }
2564
3099
  if(w.matchStart > 0) {
2565
3100
  var preRegExp = new RegExp(config.textPrimitives.anyLetterStrict,"mg");
2566
3101
  preRegExp.lastIndex = w.matchStart-1;
@@ -2570,7 +3105,7 @@ config.formatters = [
2570
3105
  return;
2571
3106
  }
2572
3107
  }
2573
- if(w.autoLinkWikiWords == true || store.isShadowTiddler(w.matchText)) {
3108
+ if(w.autoLinkWikiWords || store.isShadowTiddler(w.matchText)) {
2574
3109
  var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler);
2575
3110
  w.outputText(link,w.matchStart,w.nextMatch);
2576
3111
  } else {
@@ -2645,81 +3180,77 @@ config.formatters = [
2645
3180
  },
2646
3181
 
2647
3182
  {
2648
- name: "boldByChar",
2649
- match: "''",
2650
- termRegExp: /('')/mg,
2651
- element: "strong",
2652
- handler: config.formatterHelpers.createElementAndWikify
2653
- },
2654
-
2655
- {
2656
- name: "italicByChar",
2657
- match: "//",
2658
- termRegExp: /(\/\/)/mg,
2659
- element: "em",
2660
- handler: config.formatterHelpers.createElementAndWikify
2661
- },
2662
-
2663
- {
2664
- name: "underlineByChar",
2665
- match: "__",
2666
- termRegExp: /(__)/mg,
2667
- element: "u",
2668
- handler: config.formatterHelpers.createElementAndWikify
2669
- },
2670
-
2671
- {
2672
- name: "strikeByChar",
2673
- match: "--(?!\\s|$)",
2674
- termRegExp: /((?!\s)--|(?=\n\n))/mg,
2675
- element: "strike",
2676
- handler: config.formatterHelpers.createElementAndWikify
2677
- },
2678
-
2679
- {
2680
- name: "superscriptByChar",
2681
- match: "\\^\\^",
2682
- termRegExp: /(\^\^)/mg,
2683
- element: "sup",
2684
- handler: config.formatterHelpers.createElementAndWikify
2685
- },
2686
-
2687
- {
2688
- name: "subscriptByChar",
2689
- match: "~~",
2690
- termRegExp: /(~~)/mg,
2691
- element: "sub",
2692
- handler: config.formatterHelpers.createElementAndWikify
3183
+ name: "characterFormat",
3184
+ match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{",
3185
+ handler: function(w)
3186
+ {
3187
+ switch(w.matchText) {
3188
+ case "''":
3189
+ w.subWikifyTerm(w.output.appendChild(document.createElement("strong")),/('')/mg);
3190
+ break;
3191
+ case "//":
3192
+ w.subWikifyTerm(createTiddlyElement(w.output,"em"),/(\/\/)/mg);
3193
+ break;
3194
+ case "__":
3195
+ w.subWikifyTerm(createTiddlyElement(w.output,"u"),/(__)/mg);
3196
+ break;
3197
+ case "^^":
3198
+ w.subWikifyTerm(createTiddlyElement(w.output,"sup"),/(\^\^)/mg);
3199
+ break;
3200
+ case "~~":
3201
+ w.subWikifyTerm(createTiddlyElement(w.output,"sub"),/(~~)/mg);
3202
+ break;
3203
+ case "--":
3204
+ w.subWikifyTerm(createTiddlyElement(w.output,"strike"),/(--)/mg);
3205
+ break;
3206
+ case "{{{":
3207
+ var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg;
3208
+ lookaheadRegExp.lastIndex = w.matchStart;
3209
+ var lookaheadMatch = lookaheadRegExp.exec(w.source);
3210
+ if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
3211
+ createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]);
3212
+ w.nextMatch = lookaheadRegExp.lastIndex;
3213
+ }
3214
+ break;
3215
+ }
3216
+ }
2693
3217
  },
2694
3218
 
2695
3219
  {
2696
- name: "monospacedByChar",
2697
- match: "\\{\\{\\{",
2698
- lookaheadRegExp: /\{\{\{((?:.|\n)*?)\}\}\}/mg,
3220
+ name: "customFormat",
3221
+ match: "@@|\\{\\{",
2699
3222
  handler: function(w)
2700
3223
  {
2701
- this.lookaheadRegExp.lastIndex = w.matchStart;
2702
- var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
2703
- if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
2704
- createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]);
2705
- w.nextMatch = this.lookaheadRegExp.lastIndex;
3224
+ switch(w.matchText) {
3225
+ case "@@":
3226
+ var e = createTiddlyElement(w.output,"span");
3227
+ var styles = config.formatterHelpers.inlineCssHelper(w);
3228
+ if(styles.length == 0)
3229
+ e.className = "marked";
3230
+ else
3231
+ config.formatterHelpers.applyCssHelper(e,styles);
3232
+ w.subWikifyTerm(e,/(@@)/mg);
3233
+ break;
3234
+ case "{{":
3235
+ lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
3236
+ lookaheadRegExp.lastIndex = w.matchStart;
3237
+ lookaheadMatch = lookaheadRegExp.exec(w.source);
3238
+ if(lookaheadMatch) {
3239
+ w.nextMatch = lookaheadRegExp.lastIndex;
3240
+ e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
3241
+ w.subWikifyTerm(e,/(\}\}\})/mg);
3242
+ }
3243
+ break;
2706
3244
  }
2707
3245
  }
2708
3246
  },
2709
3247
 
2710
3248
  {
2711
- name: "styleByChar",
2712
- match: "@@",
2713
- termRegExp: /(@@)/mg,
3249
+ name: "mdash",
3250
+ match: "--",
2714
3251
  handler: function(w)
2715
3252
  {
2716
- var e = createTiddlyElement(w.output,"span");
2717
- var styles = config.formatterHelpers.inlineCssHelper(w);
2718
- if(styles.length == 0)
2719
- e.className = "marked";
2720
- else
2721
- config.formatterHelpers.applyCssHelper(e,styles);
2722
- w.subWikifyTerm(e,this.termRegExp);
3253
+ createTiddlyElement(w.output,"span").innerHTML = "&mdash;";
2723
3254
  }
2724
3255
  },
2725
3256
 
@@ -2747,38 +3278,12 @@ config.formatters = [
2747
3278
  }
2748
3279
  },
2749
3280
 
2750
- {
2751
- name: "mdash",
2752
- match: "--",
2753
- handler: function(w)
2754
- {
2755
- createTiddlyElement(w.output,"span").innerHTML = "&mdash;";
2756
- }
2757
- },
2758
-
2759
3281
  {
2760
3282
  name: "htmlEntitiesEncoding",
2761
- match: "(?:(?:&#?[a-zA-Z0-9]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[a-zA-Z0-9]{2,8};)",
2762
- handler: function(w)
2763
- {
2764
- createTiddlyElement(w.output,"span").innerHTML = w.matchText;
2765
- }
2766
- },
2767
-
2768
- {
2769
- name: "customClasses",
2770
- match: "\\{\\{",
2771
- termRegExp: /(\}\}\})/mg,
2772
- lookaheadRegExp: /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg,
3283
+ match: "(?:(?:&#?[a-zA-Z0-9]{2,8};|.)(?:&#?(?:x0*(?:3[0-6][0-9a-fA-F]|1D[c-fC-F][0-9a-fA-F]|20[d-fD-F][0-9a-fA-F]|FE2[0-9a-fA-F])|0*(?:76[89]|7[7-9][0-9]|8[0-7][0-9]|761[6-9]|76[2-7][0-9]|84[0-3][0-9]|844[0-7]|6505[6-9]|6506[0-9]|6507[0-1]));)+|&#?[a-zA-Z0-9]{2,8};)",
2773
3284
  handler: function(w)
2774
3285
  {
2775
- this.lookaheadRegExp.lastIndex = w.matchStart;
2776
- var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
2777
- if(lookaheadMatch) {
2778
- var e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
2779
- w.nextMatch = this.lookaheadRegExp.lastIndex;
2780
- w.subWikifyTerm(e,this.termRegExp);
2781
- }
3286
+ createTiddlyElement(w.output,"span").innerHTML = w.matchText;
2782
3287
  }
2783
3288
  }
2784
3289
 
@@ -2793,13 +3298,14 @@ function getParser(tiddler,format)
2793
3298
  if(tiddler) {
2794
3299
  if(!format)
2795
3300
  format = tiddler.fields["wikiformat"];
3301
+ var i;
2796
3302
  if(format) {
2797
- for(var i in config.parsers) {
3303
+ for(i in config.parsers) {
2798
3304
  if(format == config.parsers[i].format)
2799
3305
  return config.parsers[i];
2800
3306
  }
2801
3307
  } else {
2802
- for(var i in config.parsers) {
3308
+ for(i in config.parsers) {
2803
3309
  if(tiddler.isTagged(config.parsers[i].formatTag))
2804
3310
  return config.parsers[i];
2805
3311
  }
@@ -2894,7 +3400,6 @@ Wikifier.prototype.subWikify = function(output,terminator)
2894
3400
 
2895
3401
  Wikifier.prototype.subWikifyUnterm = function(output)
2896
3402
  {
2897
- // subWikify() can be indirectly recursive, so we need to save the old output pointer
2898
3403
  var oldOutput = this.output;
2899
3404
  this.output = output;
2900
3405
  this.formatter.formatterRegExp.lastIndex = this.nextMatch;
@@ -2926,10 +3431,8 @@ Wikifier.prototype.subWikifyUnterm = function(output)
2926
3431
 
2927
3432
  Wikifier.prototype.subWikifyTerm = function(output,terminatorRegExp)
2928
3433
  {
2929
- // subWikify() can be indirectly recursive, so we need to save the old output pointer
2930
3434
  var oldOutput = this.output;
2931
3435
  this.output = output;
2932
- // Get the first matches for the formatter and terminator RegExps
2933
3436
  terminatorRegExp.lastIndex = this.nextMatch;
2934
3437
  var terminatorMatch = terminatorRegExp.exec(this.source);
2935
3438
  this.formatter.formatterRegExp.lastIndex = this.nextMatch;
@@ -2994,11 +3497,7 @@ Wikifier.prototype.outputText = function(place,startPos,endPos)
2994
3497
  config.macros.today.handler = function(place,macroName,params)
2995
3498
  {
2996
3499
  var now = new Date();
2997
- var text;
2998
- if(params[0])
2999
- text = now.formatString(params[0].trim());
3000
- else
3001
- text = now.toLocaleString();
3500
+ var text = params[0] ? now.formatString(params[0].trim()) : text = now.toLocaleString();
3002
3501
  createTiddlyElement(place,"span",null,null,text);
3003
3502
  };
3004
3503
 
@@ -3049,6 +3548,18 @@ config.macros.list.touched.handler = function(params)
3049
3548
  return store.getTouched();
3050
3549
  };
3051
3550
 
3551
+ config.macros.list.filter.handler = function(params)
3552
+ {
3553
+ var filter = params[1];
3554
+ var results = [];
3555
+ if(filter) {
3556
+ var tiddlers = store.filterTiddlers(filter);
3557
+ for(var t=0; t<tiddlers.length; t++)
3558
+ results.push(tiddlers[t].title);
3559
+ }
3560
+ return results;
3561
+ };
3562
+
3052
3563
  config.macros.allTags.handler = function(place,macroName,params)
3053
3564
  {
3054
3565
  var tags = store.getTags(params[0]);
@@ -3072,89 +3583,20 @@ config.macros.timeline.handler = function(place,macroName,params)
3072
3583
  var tiddlers = store.reverseLookup("tags","excludeLists",false,field);
3073
3584
  var lastDay = "";
3074
3585
  var last = params[1] ? tiddlers.length-Math.min(tiddlers.length,parseInt(params[1])) : 0;
3586
+ var dateFormat = params[2] ? params[2] : this.dateFormat;
3075
3587
  for(var t=tiddlers.length-1; t>=last; t--) {
3076
3588
  var tiddler = tiddlers[t];
3077
3589
  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
3078
3590
  if(theDay != lastDay) {
3079
- var theDateList = document.createElement("ul");
3080
- place.appendChild(theDateList);
3081
- createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
3591
+ var ul = document.createElement("ul");
3592
+ place.appendChild(ul);
3593
+ createTiddlyElement(ul,"li",null,"listTitle",tiddler[field].formatString(dateFormat));
3082
3594
  lastDay = theDay;
3083
3595
  }
3084
- var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink");
3085
- theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
3086
- }
3087
- };
3088
-
3089
- config.macros.search.handler = function(place,macroName,params)
3090
- {
3091
- var searchTimeout = null;
3092
- var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
3093
- var txt = createTiddlyElement(place,"input",null,"txtOptionInput");
3094
- if(params[0])
3095
- txt.value = params[0];
3096
- txt.onkeyup = this.onKeyPress;
3097
- txt.onfocus = this.onFocus;
3098
- txt.setAttribute("size",this.sizeTextbox);
3099
- txt.setAttribute("accessKey",this.accessKey);
3100
- txt.setAttribute("autocomplete","off");
3101
- txt.setAttribute("lastSearchText","");
3102
- if(config.browser.isSafari) {
3103
- txt.setAttribute("type","search");
3104
- txt.setAttribute("results","5");
3105
- } else {
3106
- txt.setAttribute("type","text");
3107
- }
3108
- };
3109
-
3110
- // Global because there's only ever one outstanding incremental search timer
3111
- config.macros.search.timeout = null;
3112
-
3113
- config.macros.search.doSearch = function(txt)
3114
- {
3115
- if(txt.value.length > 0) {
3116
- story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
3117
- txt.setAttribute("lastSearchText",txt.value);
3118
- }
3119
- };
3120
-
3121
- config.macros.search.onClick = function(e)
3122
- {
3123
- config.macros.search.doSearch(this.nextSibling);
3124
- return false;
3125
- };
3126
-
3127
- config.macros.search.onKeyPress = function(e)
3128
- {
3129
- if(!e) var e = window.event;
3130
- switch(e.keyCode) {
3131
- case 13: // Ctrl-Enter
3132
- case 10: // Ctrl-Enter on IE PC
3133
- config.macros.search.doSearch(this);
3134
- break;
3135
- case 27: // Escape
3136
- this.value = "";
3137
- clearMessage();
3138
- break;
3139
- }
3140
- if(this.value.length > 2) {
3141
- if(this.value != this.getAttribute("lastSearchText")) {
3142
- if(config.macros.search.timeout)
3143
- clearTimeout(config.macros.search.timeout);
3144
- var txt = this;
3145
- config.macros.search.timeout = setTimeout(function() {config.macros.search.doSearch(txt);},500);
3146
- }
3147
- } else {
3148
- if(config.macros.search.timeout)
3149
- clearTimeout(config.macros.search.timeout);
3596
+ createTiddlyElement(ul,"li",null,"listLink").appendChild(createTiddlyLink(place,tiddler.title,true));
3150
3597
  }
3151
3598
  };
3152
3599
 
3153
- config.macros.search.onFocus = function(e)
3154
- {
3155
- this.select();
3156
- };
3157
-
3158
3600
  config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3159
3601
  {
3160
3602
  params = paramString.parseParams("name",null,true,false,true);
@@ -3186,7 +3628,7 @@ config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramSt
3186
3628
  }
3187
3629
  };
3188
3630
 
3189
- config.macros.tiddler.renderText = function(place,text,tiddlerName,params)
3631
+ config.macros.tiddler.renderText = function(place,text,tiddlerName,params)
3190
3632
  {
3191
3633
  wikify(text,place,null,store.getTiddler(tiddlerName));
3192
3634
  };
@@ -3201,37 +3643,37 @@ config.macros.tag.handler = function(place,macroName,params)
3201
3643
  config.macros.tags.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3202
3644
  {
3203
3645
  params = paramString.parseParams("anon",null,true,false,false);
3204
- var theList = createTiddlyElement(place,"ul");
3646
+ var ul = createTiddlyElement(place,"ul");
3205
3647
  var title = getParam(params,"anon","");
3206
3648
  if(title && store.tiddlerExists(title))
3207
3649
  tiddler = store.getTiddler(title);
3208
3650
  var sep = getParam(params,"sep"," ");
3209
3651
  var lingo = config.views.wikified.tag;
3210
3652
  var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;
3211
- createTiddlyElement(theList,"li",null,"listTitle",prompt.format([tiddler.title]));
3653
+ createTiddlyElement(ul,"li",null,"listTitle",prompt.format([tiddler.title]));
3212
3654
  for(var t=0; t<tiddler.tags.length; t++) {
3213
- createTagButton(createTiddlyElement(theList,"li"),tiddler.tags[t],tiddler.title);
3655
+ createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title);
3214
3656
  if(t<tiddler.tags.length-1)
3215
- createTiddlyText(theList,sep);
3657
+ createTiddlyText(ul,sep);
3216
3658
  }
3217
3659
  };
3218
3660
 
3219
3661
  config.macros.tagging.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3220
3662
  {
3221
3663
  params = paramString.parseParams("anon",null,true,false,false);
3222
- var theList = createTiddlyElement(place,"ul");
3664
+ var ul = createTiddlyElement(place,"ul");
3223
3665
  var title = getParam(params,"anon","");
3224
3666
  if(title == "" && tiddler instanceof Tiddler)
3225
3667
  title = tiddler.title;
3226
3668
  var sep = getParam(params,"sep"," ");
3227
- theList.setAttribute("title",this.tooltip.format([title]));
3669
+ ul.setAttribute("title",this.tooltip.format([title]));
3228
3670
  var tagged = store.getTaggedTiddlers(title);
3229
3671
  var prompt = tagged.length == 0 ? this.labelNotTag : this.label;
3230
- createTiddlyElement(theList,"li",null,"listTitle",prompt.format([title,tagged.length]));
3672
+ createTiddlyElement(ul,"li",null,"listTitle",prompt.format([title,tagged.length]));
3231
3673
  for(var t=0; t<tagged.length; t++) {
3232
- createTiddlyLink(createTiddlyElement(theList,"li"),tagged[t].title,true);
3674
+ createTiddlyLink(createTiddlyElement(ul,"li"),tagged[t].title,true);
3233
3675
  if(t<tagged.length-1)
3234
- createTiddlyText(theList,sep);
3676
+ createTiddlyText(ul,sep);
3235
3677
  }
3236
3678
  };
3237
3679
 
@@ -3269,9 +3711,9 @@ config.macros.saveChanges.onClick = function(e)
3269
3711
  return false;
3270
3712
  };
3271
3713
 
3272
- config.macros.slider.onClickSlider = function(e)
3714
+ config.macros.slider.onClickSlider = function(ev)
3273
3715
  {
3274
- if(!e) var e = window.event;
3716
+ var e = ev ? ev : window.event;
3275
3717
  var n = this.nextSibling;
3276
3718
  var cookie = n.getAttribute("cookie");
3277
3719
  var isOpen = n.style.display != "none";
@@ -3286,11 +3728,11 @@ config.macros.slider.onClickSlider = function(e)
3286
3728
 
3287
3729
  config.macros.slider.createSlider = function(place,cookie,title,tooltip)
3288
3730
  {
3289
- var cookie = cookie ? cookie : "";
3731
+ var c = cookie ? cookie : "";
3290
3732
  var btn = createTiddlyButton(place,title,tooltip,this.onClickSlider);
3291
3733
  var panel = createTiddlyElement(null,"div",null,"sliderPanel");
3292
- panel.setAttribute("cookie",cookie);
3293
- panel.style.display = config.options[cookie] ? "block" : "none";
3734
+ panel.setAttribute("cookie",c);
3735
+ panel.style.display = config.options[c] ? "block" : "none";
3294
3736
  place.appendChild(panel);
3295
3737
  return panel;
3296
3738
  };
@@ -3305,132 +3747,173 @@ config.macros.slider.handler = function(place,macroName,params)
3305
3747
  wikify(text,panel,null,store.getTiddler(params[1]));
3306
3748
  };
3307
3749
 
3308
- config.macros.option.genericCreate = function(place,type,opt,className,desc)
3750
+ // <<gradient [[tiddler name]] vert|horiz rgb rgb rgb rgb... >>
3751
+ config.macros.gradient.handler = function(place,macroName,params,wikifier)
3309
3752
  {
3310
- var typeInfo = config.macros.option.types[type];
3311
- var c = document.createElement(typeInfo.elementType);
3312
- if(typeInfo.typeValue)
3313
- c.setAttribute("type",typeInfo.typeValue);
3314
- c[typeInfo.eventName] = typeInfo.onChange;
3315
- c.setAttribute("option",opt);
3316
- if(className)
3317
- c.className = className;
3318
- else
3319
- c.className = typeInfo.className;
3320
- if(config.optionsDesc[opt])
3321
- c.setAttribute("title",config.optionsDesc[opt]);
3322
- place.appendChild(c);
3323
- if(desc != "no")
3324
- createTiddlyText(place,config.optionsDesc[opt] ? config.optionsDesc[opt] : opt);
3325
- c[typeInfo.valueField] = config.options[opt];
3326
- return c;
3753
+ var panel = wikifier ? createTiddlyElement(place,"div",null,"gradient") : place;
3754
+ panel.style.position = "relative";
3755
+ panel.style.overflow = "hidden";
3756
+ panel.style.zIndex = "0";
3757
+ if(wikifier) {
3758
+ var styles = config.formatterHelpers.inlineCssHelper(wikifier);
3759
+ config.formatterHelpers.applyCssHelper(panel,styles);
3760
+ }
3761
+ var colours = [];
3762
+ for(var t=1; t<params.length; t++) {
3763
+ var c = new RGB(params[t]);
3764
+ if(c)
3765
+ colours.push(c);
3766
+ }
3767
+ drawGradient(panel,params[0] != "vert",colours);
3768
+ if(wikifier)
3769
+ wikifier.subWikify(panel,">>");
3770
+ if(document.all) {
3771
+ panel.style.height = "100%";
3772
+ panel.style.width = "100%";
3773
+ }
3327
3774
  };
3328
3775
 
3329
- config.macros.option.genericOnChange = function(e)
3776
+ config.macros.message.handler = function(place,macroName,params)
3330
3777
  {
3331
- var opt = this.getAttribute("option");
3332
- if(opt) {
3333
- var optType = opt.substr(0,3);
3334
- var handler = config.macros.option.types[optType];
3335
- if (handler.elementType && handler.valueField)
3336
- config.macros.option.propagateOption(opt,handler.valueField,this[handler.valueField],handler.elementType);
3778
+ if(params[0]) {
3779
+ var m = config;
3780
+ var p = params[0].split(".");
3781
+ for(var t=0; t<p.length; t++) {
3782
+ if(p[t] in m)
3783
+ m = m[p[t]];
3784
+ else
3785
+ break;
3337
3786
  }
3338
- return true;
3787
+ createTiddlyText(place,m.toString().format(params.splice(1)));
3788
+ }
3339
3789
  };
3340
3790
 
3341
- config.macros.option.types = {
3342
- 'txt': {
3343
- elementType: "input",
3344
- valueField: "value",
3345
- eventName: "onkeyup",
3346
- className: "txtOptionInput",
3347
- create: config.macros.option.genericCreate,
3348
- onChange: config.macros.option.genericOnChange
3349
- },
3350
- 'chk': {
3351
- elementType: "input",
3352
- valueField: "checked",
3353
- eventName: "onclick",
3354
- className: "chkOptionInput",
3355
- typeValue: "checkbox",
3356
- create: config.macros.option.genericCreate,
3357
- onChange: config.macros.option.genericOnChange
3791
+ config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3792
+ {
3793
+ if((tiddler instanceof Tiddler) && params[0]) {
3794
+ var value = store.getValue(tiddler,params[0]);
3795
+ if(value != undefined) {
3796
+ switch(params[1]) {
3797
+ case undefined:
3798
+ highlightify(value,place,highlightHack,tiddler);
3799
+ break;
3800
+ case "link":
3801
+ createTiddlyLink(place,value,true);
3802
+ break;
3803
+ case "wikified":
3804
+ wikify(value,place,highlightHack,tiddler);
3805
+ break;
3806
+ case "date":
3807
+ value = Date.convertFromYYYYMMDDHHMM(value);
3808
+ createTiddlyText(place,value.formatString(params[2] ? params[2] : config.views.wikified.dateFormat));
3809
+ break;
3810
+ }
3811
+ }
3358
3812
  }
3359
3813
  };
3360
3814
 
3361
- config.macros.option.propagateOption = function(opt,valueField,value,elementType)
3815
+ config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3362
3816
  {
3363
- config.options[opt] = value;
3364
- saveOptionCookie(opt);
3365
- var nodes = document.getElementsByTagName(elementType);
3366
- for(var t=0; t<nodes.length; t++) {
3367
- var optNode = nodes[t].getAttribute("option");
3368
- if(opt == optNode)
3369
- nodes[t][valueField] = value;
3817
+ var field = params[0];
3818
+ var rows = params[1] || 0;
3819
+ var defVal = params[2] || '';
3820
+ if((tiddler instanceof Tiddler) && field) {
3821
+ story.setDirty(tiddler.title,true);
3822
+ var e,v;
3823
+ if(field != "text" && !rows) {
3824
+ e = createTiddlyElement(null,"input");
3825
+ if(tiddler.isReadOnly())
3826
+ e.setAttribute("readOnly","readOnly");
3827
+ e.setAttribute("edit",field);
3828
+ e.setAttribute("type","text");
3829
+ e.value = store.getValue(tiddler,field) || defVal;
3830
+ e.setAttribute("size","40");
3831
+ e.setAttribute("autocomplete","off");
3832
+ place.appendChild(e);
3833
+ } else {
3834
+ var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
3835
+ var wrapper2 = createTiddlyElement(wrapper1,"div");
3836
+ e = createTiddlyElement(wrapper2,"textarea");
3837
+ if(tiddler.isReadOnly())
3838
+ e.setAttribute("readOnly","readOnly");
3839
+ e.value = v = store.getValue(tiddler,field) || defVal;
3840
+ rows = rows ? rows : 10;
3841
+ var lines = v.match(/\n/mg);
3842
+ var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
3843
+ if(lines != null && lines.length > rows)
3844
+ rows = lines.length + 5;
3845
+ rows = Math.min(rows,maxLines);
3846
+ e.setAttribute("rows",rows);
3847
+ e.setAttribute("edit",field);
3848
+ place.appendChild(wrapper1);
3370
3849
  }
3850
+ return e;
3851
+ }
3371
3852
  };
3372
3853
 
3373
- config.macros.option.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3854
+ config.macros.tagChooser.onClick = function(ev)
3374
3855
  {
3375
- params = paramString.parseParams("anon",null,true,false,false);
3376
- var opt = (params[1] && params[1].name == "anon") ? params[1].value : getParam(params,"name",null);
3377
- var className = (params[2] && params[2].name == "anon") ? params[2].value : getParam(params,"class",null);
3378
- var desc = getParam(params,"desc","no");
3379
- var type = opt.substr(0,3);
3380
- var h = config.macros.option.types[type];
3381
- if (h && h.create)
3382
- h.create(place,type,opt,className,desc);
3856
+ var e = ev ? ev : window.event;
3857
+ var lingo = config.views.editor.tagChooser;
3858
+ var popup = Popup.create(this);
3859
+ var tags = store.getTags();
3860
+ if(tags.length == 0)
3861
+ createTiddlyText(createTiddlyElement(popup,"li"),lingo.popupNone);
3862
+ for(var t=0; t<tags.length; t++) {
3863
+ var tag = createTiddlyButton(createTiddlyElement(popup,"li"),tags[t][0],lingo.tagTooltip.format([tags[t][0]]),config.macros.tagChooser.onTagClick);
3864
+ tag.setAttribute("tag",tags[t][0]);
3865
+ tag.setAttribute("tiddler",this.getAttribute("tiddler"));
3866
+ }
3867
+ Popup.show();
3868
+ e.cancelBubble = true;
3869
+ if(e.stopPropagation) e.stopPropagation();
3870
+ return false;
3383
3871
  };
3384
3872
 
3385
- config.macros.options.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3873
+ config.macros.tagChooser.onTagClick = function(ev)
3386
3874
  {
3387
- params = paramString.parseParams("anon",null,true,false,false);
3388
- var showUnknown = getParam(params,"showUnknown","no");
3389
- var wizard = new Wizard();
3390
- wizard.createWizard(place,this.wizardTitle);
3391
- wizard.addStep(this.step1Title,this.step1Html);
3392
- var markList = wizard.getElement("markList");
3393
- var chkUnknown = wizard.getElement("chkUnknown");
3394
- chkUnknown.checked = showUnknown == "yes";
3395
- chkUnknown.onchange = this.onChangeUnknown;
3396
- var listWrapper = document.createElement("div");
3397
- markList.parentNode.insertBefore(listWrapper,markList);
3398
- wizard.setValue("listWrapper",listWrapper);
3399
- this.refreshOptions(listWrapper,showUnknown == "yes");
3875
+ var e = ev ? ev : window.event;
3876
+ var tag = this.getAttribute("tag");
3877
+ var title = this.getAttribute("tiddler");
3878
+ if(!readOnly)
3879
+ story.setTiddlerTag(title,tag,0);
3880
+ return false;
3881
+ };
3882
+
3883
+ config.macros.tagChooser.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3884
+ {
3885
+ if(tiddler instanceof Tiddler) {
3886
+ var lingo = config.views.editor.tagChooser;
3887
+ var btn = createTiddlyButton(place,lingo.text,lingo.tooltip,this.onClick);
3888
+ btn.setAttribute("tiddler",tiddler.title);
3889
+ }
3400
3890
  };
3401
3891
 
3402
- config.macros.options.refreshOptions = function(listWrapper,showUnknown)
3403
- {
3404
- var opts = [];
3405
- for(var n in config.options) {
3406
- var opt = {};
3407
- opt.option = "";
3408
- opt.name = n;
3409
- opt.lowlight = !config.optionsDesc[n];
3410
- opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
3411
- if(!opt.lowlight || showUnknown)
3412
- opts.push(opt);
3413
- }
3414
- opts.sort(function(a,b) {return a.name.substr(3) < b.name.substr(3) ? -1 : (a.name.substr(3) == b.name.substr(3) ? 0 : +1);});
3415
- var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
3416
- for(n=0; n<opts.length; n++) {
3417
- var type = opts[n].name.substr(0,3);
3418
- var h = config.macros.option.types[type];
3419
- if (h && h.create) {
3420
- h.create(opts[n].colElements['option'],type,opts[n].name,null,"no");
3421
- }
3422
- }
3892
+ config.macros.refreshDisplay.handler = function(place)
3893
+ {
3894
+ createTiddlyButton(place,this.label,this.prompt,this.onClick);
3423
3895
  };
3424
3896
 
3425
- config.macros.options.onChangeUnknown = function(e)
3897
+ config.macros.refreshDisplay.onClick = function(e)
3426
3898
  {
3427
- var wizard = new Wizard(this);
3428
- var listWrapper = wizard.getValue("listWrapper");
3429
- removeChildren(listWrapper);
3430
- config.macros.options.refreshOptions(listWrapper,this.checked);
3899
+ refreshAll();
3431
3900
  return false;
3432
3901
  };
3433
3902
 
3903
+ config.macros.annotations.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3904
+ {
3905
+ var title = tiddler ? tiddler.title : null;
3906
+ var a = title ? config.annotations[title] : null;
3907
+ if(!tiddler || !title || !a)
3908
+ return;
3909
+ var text = a.format([title]);
3910
+ wikify(text,createTiddlyElement(place,"div",null,"annotation"),null,tiddler);
3911
+ };
3912
+
3913
+ //--
3914
+ //-- NewTiddler and NewJournal macros
3915
+ //--
3916
+
3434
3917
  config.macros.newTiddler.createNewTiddlerButton = function(place,title,params,label,prompt,accessKey,newFocus,isJournal)
3435
3918
  {
3436
3919
  var tags = [];
@@ -3455,7 +3938,7 @@ config.macros.newTiddler.createNewTiddlerButton = function(place,title,params,la
3455
3938
  if(customFields !== "")
3456
3939
  btn.setAttribute("customFields",customFields);
3457
3940
  var text = getParam(params,"text");
3458
- if(text !== undefined)
3941
+ if(text !== undefined)
3459
3942
  btn.setAttribute("newText",text);
3460
3943
  return btn;
3461
3944
  };
@@ -3499,48 +3982,89 @@ config.macros.newJournal.handler = function(place,macroName,params,wikifier,para
3499
3982
  {
3500
3983
  if(!readOnly) {
3501
3984
  params = paramString.parseParams("anon",null,true,false,false);
3502
- var title = params[1] && params[1].name == "anon" ? params[1].value : "";
3985
+ var title = params[1] && params[1].name == "anon" ? params[1].value : config.macros.timeline.dateFormat;
3503
3986
  title = getParam(params,"title",title);
3504
3987
  config.macros.newTiddler.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"text",true);
3505
3988
  }
3506
3989
  };
3507
3990
 
3508
- config.macros.sparkline.handler = function(place,macroName,params)
3991
+ //--
3992
+ //-- Search macro
3993
+ //--
3994
+
3995
+ config.macros.search.handler = function(place,macroName,params)
3509
3996
  {
3510
- var data = [];
3511
- var min = 0;
3512
- var max = 0;
3513
- for(var t=0; t<params.length; t++) {
3514
- var v = parseInt(params[t]);
3515
- if(v < min)
3516
- min = v;
3517
- if(v > max)
3518
- max = v;
3519
- data.push(v);
3997
+ var searchTimeout = null;
3998
+ var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
3999
+ var txt = createTiddlyElement(place,"input",null,"txtOptionInput");
4000
+ if(params[0])
4001
+ txt.value = params[0];
4002
+ txt.onkeyup = this.onKeyPress;
4003
+ txt.onfocus = this.onFocus;
4004
+ txt.setAttribute("size",this.sizeTextbox);
4005
+ txt.setAttribute("accessKey",this.accessKey);
4006
+ txt.setAttribute("autocomplete","off");
4007
+ txt.setAttribute("lastSearchText","");
4008
+ if(config.browser.isSafari) {
4009
+ txt.setAttribute("type","search");
4010
+ txt.setAttribute("results","5");
4011
+ } else {
4012
+ txt.setAttribute("type","text");
3520
4013
  }
3521
- if(data.length < 1)
3522
- return;
3523
- var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
3524
- box.title = data.join(",");
3525
- var w = box.offsetWidth;
3526
- var h = box.offsetHeight;
3527
- box.style.paddingRight = (data.length * 2 - w) + "px";
3528
- box.style.position = "relative";
3529
- for(var d=0; d<data.length; d++) {
3530
- var tick = document.createElement("img");
3531
- tick.border = 0;
3532
- tick.className = "sparktick";
3533
- tick.style.position = "absolute";
3534
- tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
3535
- tick.style.left = d*2 + "px";
3536
- tick.style.width = "2px";
3537
- var v = Math.floor(((data[d] - min)/(max-min)) * h);
3538
- tick.style.top = (h-v) + "px";
3539
- tick.style.height = v + "px";
3540
- box.appendChild(tick);
4014
+ };
4015
+
4016
+ // Global because there's only ever one outstanding incremental search timer
4017
+ config.macros.search.timeout = null;
4018
+
4019
+ config.macros.search.doSearch = function(txt)
4020
+ {
4021
+ if(txt.value.length > 0) {
4022
+ story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
4023
+ txt.setAttribute("lastSearchText",txt.value);
4024
+ }
4025
+ };
4026
+
4027
+ config.macros.search.onClick = function(e)
4028
+ {
4029
+ config.macros.search.doSearch(this.nextSibling);
4030
+ return false;
4031
+ };
4032
+
4033
+ config.macros.search.onKeyPress = function(ev)
4034
+ {
4035
+ var e = ev ? ev : window.event;
4036
+ switch(e.keyCode) {
4037
+ case 13: // Ctrl-Enter
4038
+ case 10: // Ctrl-Enter on IE PC
4039
+ config.macros.search.doSearch(this);
4040
+ break;
4041
+ case 27: // Escape
4042
+ this.value = "";
4043
+ clearMessage();
4044
+ break;
4045
+ }
4046
+ if(this.value.length > 2) {
4047
+ if(this.value != this.getAttribute("lastSearchText")) {
4048
+ if(config.macros.search.timeout)
4049
+ clearTimeout(config.macros.search.timeout);
4050
+ var txt = this;
4051
+ config.macros.search.timeout = setTimeout(function() {config.macros.search.doSearch(txt);},500);
4052
+ }
4053
+ } else {
4054
+ if(config.macros.search.timeout)
4055
+ clearTimeout(config.macros.search.timeout);
3541
4056
  }
3542
4057
  };
3543
4058
 
4059
+ config.macros.search.onFocus = function(e)
4060
+ {
4061
+ this.select();
4062
+ };
4063
+
4064
+ //--
4065
+ //-- Tabs macro
4066
+ //--
4067
+
3544
4068
  config.macros.tabs.handler = function(place,macroName,params)
3545
4069
  {
3546
4070
  var cookie = params[0];
@@ -3599,157 +4123,9 @@ config.macros.tabs.switchTab = function(tabset,tab)
3599
4123
  }
3600
4124
  };
3601
4125
 
3602
- // <<gradient [[tiddler name]] vert|horiz rgb rgb rgb rgb... >>
3603
- config.macros.gradient.handler = function(place,macroName,params,wikifier)
3604
- {
3605
- var terminator = ">>";
3606
- var panel;
3607
- if(wikifier)
3608
- panel = createTiddlyElement(place,"div",null,"gradient");
3609
- else
3610
- panel = place;
3611
- panel.style.position = "relative";
3612
- panel.style.overflow = "hidden";
3613
- panel.style.zIndex = "0";
3614
- var t;
3615
- if(wikifier) {
3616
- var styles = config.formatterHelpers.inlineCssHelper(wikifier);
3617
- config.formatterHelpers.applyCssHelper(panel,styles);
3618
- }
3619
- var colours = [];
3620
- for(t=1; t<params.length; t++) {
3621
- var c = new RGB(params[t]);
3622
- if(c)
3623
- colours.push(c);
3624
- }
3625
- drawGradient(panel,params[0] != "vert",colours);
3626
- if(wikifier)
3627
- wikifier.subWikify(panel,terminator);
3628
- if(document.all) {
3629
- panel.style.height = "100%";
3630
- panel.style.width = "100%";
3631
- }
3632
- };
3633
-
3634
- config.macros.message.handler = function(place,macroName,params)
3635
- {
3636
- if(params[0]) {
3637
- var m = config;
3638
- var p = params[0].split(".");
3639
- for(var t=0; t<p.length; t++) {
3640
- if(p[t] in m)
3641
- m = m[p[t]];
3642
- else
3643
- break;
3644
- }
3645
- createTiddlyText(place,m.toString().format(params.splice(1)));
3646
- }
3647
- };
3648
-
3649
- config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3650
- {
3651
- if((tiddler instanceof Tiddler) && params[0]) {
3652
- var value = store.getValue(tiddler,params[0]);
3653
- if(value != undefined) {
3654
- switch(params[1]) {
3655
- case undefined:
3656
- highlightify(value,place,highlightHack,tiddler);
3657
- break;
3658
- case "link":
3659
- createTiddlyLink(place,value,true);
3660
- break;
3661
- case "wikified":
3662
- wikify(value,place,highlightHack,tiddler);
3663
- break;
3664
- case "date":
3665
- value = Date.convertFromYYYYMMDDHHMM(value);
3666
- createTiddlyText(place,value.formatString(params[2] ? params[2] : config.views.wikified.dateFormat));
3667
- break;
3668
- }
3669
- }
3670
- }
3671
- };
3672
-
3673
- config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3674
- {
3675
- var field = params[0];
3676
- var rows = params[1];
3677
- if((tiddler instanceof Tiddler) && field) {
3678
- story.setDirty(tiddler.title,true);
3679
- if(field != "text" && !rows) {
3680
- var e = createTiddlyElement(null,"input");
3681
- if(tiddler.isReadOnly())
3682
- e.setAttribute("readOnly","readOnly");
3683
- e.setAttribute("edit",field);
3684
- e.setAttribute("type","text");
3685
- var v = store.getValue(tiddler,field);
3686
- if(!v)
3687
- v = "";
3688
- e.value = v;
3689
- e.setAttribute("size","40");
3690
- e.setAttribute("autocomplete","off");
3691
- place.appendChild(e);
3692
- } else {
3693
- var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
3694
- var wrapper2 = createTiddlyElement(wrapper1,"div");
3695
- var e = createTiddlyElement(wrapper2,"textarea");
3696
- if(tiddler.isReadOnly())
3697
- e.setAttribute("readOnly","readOnly");
3698
- var v = store.getValue(tiddler,field);
3699
- if(!v)
3700
- v = "";
3701
- e.value = v;
3702
- var rows = rows ? rows : 10;
3703
- var lines = v.match(/\n/mg);
3704
- var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
3705
- if(lines != null && lines.length > rows)
3706
- rows = lines.length + 5;
3707
- rows = Math.min(rows,maxLines);
3708
- e.setAttribute("rows",rows);
3709
- e.setAttribute("edit",field);
3710
- place.appendChild(wrapper1);
3711
- }
3712
- }
3713
- };
3714
-
3715
- config.macros.tagChooser.onClick = function(e)
3716
- {
3717
- if(!e) var e = window.event;
3718
- var lingo = config.views.editor.tagChooser;
3719
- var popup = Popup.create(this);
3720
- var tags = store.getTags();
3721
- if(tags.length == 0)
3722
- createTiddlyText(createTiddlyElement(popup,"li"),lingo.popupNone);
3723
- for(var t=0; t<tags.length; t++) {
3724
- var theTag = createTiddlyButton(createTiddlyElement(popup,"li"),tags[t][0],lingo.tagTooltip.format([tags[t][0]]),config.macros.tagChooser.onTagClick);
3725
- theTag.setAttribute("tag",tags[t][0]);
3726
- theTag.setAttribute("tiddler",this.getAttribute("tiddler"));
3727
- }
3728
- Popup.show();
3729
- e.cancelBubble = true;
3730
- if(e.stopPropagation) e.stopPropagation();
3731
- return false;
3732
- };
3733
-
3734
- config.macros.tagChooser.onTagClick = function(e)
3735
- {
3736
- if(!e) var e = window.event;
3737
- var tag = this.getAttribute("tag");
3738
- var title = this.getAttribute("tiddler");
3739
- if(!readOnly)
3740
- story.setTiddlerTag(title,tag,0);
3741
- return false;
3742
- };
3743
-
3744
- config.macros.tagChooser.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3745
- {
3746
- if(tiddler instanceof Tiddler) {
3747
- var title = tiddler.title;
3748
- var lingo = config.views.editor.tagChooser;
3749
- var btn = createTiddlyButton(place,lingo.text,lingo.tooltip,this.onClick);
3750
- btn.setAttribute("tiddler",title);
3751
- }
3752
- };
4126
+ //--
4127
+ //-- Tiddler toolbar
4128
+ //--
3753
4129
 
3754
4130
  // Create a toolbar command button
3755
4131
  config.macros.toolbar.createCommand = function(place,commandName,tiddler,theClass)
@@ -3805,18 +4181,18 @@ config.macros.toolbar.getCommandTooltip = function(command,tiddler)
3805
4181
  return tiddler.isReadOnly() && command.readOnlyTooltip ? command.readOnlyTooltip : command.tooltip;
3806
4182
  };
3807
4183
 
3808
- config.macros.toolbar.onClickCommand = function(e)
4184
+ config.macros.toolbar.onClickCommand = function(ev)
3809
4185
  {
3810
- if(!e) var e = window.event;
4186
+ var e = ev ? ev : window.event;
3811
4187
  e.cancelBubble = true;
3812
4188
  if (e.stopPropagation) e.stopPropagation();
3813
4189
  var command = config.commands[this.getAttribute("commandName")];
3814
4190
  return command.handler(e,this,this.getAttribute("tiddler"));
3815
4191
  };
3816
4192
 
3817
- config.macros.toolbar.onClickPopup = function(e)
4193
+ config.macros.toolbar.onClickPopup = function(ev)
3818
4194
  {
3819
- if(!e) var e = window.event;
4195
+ var e = ev ? ev : window.event;
3820
4196
  e.cancelBubble = true;
3821
4197
  if (e.stopPropagation) e.stopPropagation();
3822
4198
  var popup = Popup.create(this);
@@ -3843,7 +4219,7 @@ config.macros.toolbar.invokeCommand = function(place,theClass,event)
3843
4219
  }
3844
4220
  };
3845
4221
 
3846
- config.macros.toolbar.onClickMore = function(e)
4222
+ config.macros.toolbar.onClickMore = function(ev)
3847
4223
  {
3848
4224
  var e = this.nextSibling;
3849
4225
  e.style.display = "inline";
@@ -3882,27 +4258,6 @@ config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramSt
3882
4258
  }
3883
4259
  };
3884
4260
 
3885
- config.macros.refreshDisplay.handler = function(place)
3886
- {
3887
- createTiddlyButton(place,this.label,this.prompt,this.onClick);
3888
- };
3889
-
3890
- config.macros.refreshDisplay.onClick = function(e)
3891
- {
3892
- refreshAll();
3893
- return false;
3894
- };
3895
-
3896
- config.macros.annotations.handler = function(place,macroName,params,wikifier,paramString,tiddler)
3897
- {
3898
- var title = tiddler ? tiddler.title : null;
3899
- var a = title ? config.annotations[title] : null;
3900
- if(!tiddler || !title || !a)
3901
- return;
3902
- var text = a.format([title]);
3903
- wikify(text,createTiddlyElement(place,"div",null,"annotation"),null,tiddler);
3904
- };
3905
-
3906
4261
  //--
3907
4262
  //-- Menu and toolbar commands
3908
4263
  //--
@@ -4136,21 +4491,25 @@ Tiddler.prototype.isTouched = function()
4136
4491
  return changeCount > 0;
4137
4492
  };
4138
4493
 
4139
- // Format the text for storage in an RSS item
4140
- Tiddler.prototype.saveToRss = function(url)
4494
+ // Return the tiddler as an RSS item
4495
+ Tiddler.prototype.toRssItem = function(uri)
4141
4496
  {
4142
4497
  var s = [];
4143
- s.push("<item>");
4144
4498
  s.push("<title" + ">" + this.title.htmlEncode() + "</title" + ">");
4145
4499
  s.push("<description>" + wikifyStatic(this.text,null,this).htmlEncode() + "</description>");
4146
4500
  for(var t=0; t<this.tags.length; t++)
4147
4501
  s.push("<category>" + this.tags[t] + "</category>");
4148
- s.push("<link>" + url + "#" + encodeURIComponent(String.encodeTiddlyLink(this.title)) + "</link>");
4502
+ s.push("<link>" + uri + "#" + encodeURIComponent(String.encodeTiddlyLink(this.title)) + "</link>");
4149
4503
  s.push("<pubDate>" + this.modified.toGMTString() + "</pubDate>");
4150
- s.push("</item>");
4151
4504
  return s.join("\n");
4152
4505
  };
4153
4506
 
4507
+ // Format the text for storage in an RSS item
4508
+ Tiddler.prototype.saveToRss = function(uri)
4509
+ {
4510
+ return "<item>\n" + this.toRssItem(uri) + "\n</item>";
4511
+ };
4512
+
4154
4513
  // Change the text and other attributes of a tiddler
4155
4514
  Tiddler.prototype.set = function(title,text,modifier,modified,tags,created,fields)
4156
4515
  {
@@ -4239,15 +4598,15 @@ Tiddler.prototype.changed = function()
4239
4598
 
4240
4599
  Tiddler.prototype.getSubtitle = function()
4241
4600
  {
4242
- var theModifier = this.modifier;
4243
- if(!theModifier)
4244
- theModifier = config.messages.subtitleUnknown;
4245
- var theModified = this.modified;
4246
- if(theModified)
4247
- theModified = theModified.toLocaleString();
4601
+ var modifier = this.modifier;
4602
+ if(!modifier)
4603
+ modifier = config.messages.subtitleUnknown;
4604
+ var modified = this.modified;
4605
+ if(modified)
4606
+ modified = modified.toLocaleString();
4248
4607
  else
4249
- theModified = config.messages.subtitleUnknown;
4250
- return config.messages.tiddlerLinkTooltip.format([this.title,theModifier,theModified]);
4608
+ modified = config.messages.subtitleUnknown;
4609
+ return config.messages.tiddlerLinkTooltip.format([this.title,modifier,modified]);
4251
4610
  };
4252
4611
 
4253
4612
  Tiddler.prototype.isReadOnly = function()
@@ -4280,10 +4639,7 @@ Tiddler.prototype.getServerType = function()
4280
4639
  Tiddler.prototype.getAdaptor = function()
4281
4640
  {
4282
4641
  var serverType = this.getServerType();
4283
- if(serverType)
4284
- return new config.adaptors[serverType];
4285
- else
4286
- return null;
4642
+ return serverType ? new config.adaptors[serverType] : null;
4287
4643
  };
4288
4644
 
4289
4645
  //--
@@ -4302,7 +4658,8 @@ function TiddlyWiki()
4302
4658
  this.setDirty(false);
4303
4659
  };
4304
4660
  this.fetchTiddler = function(title) {
4305
- return tiddlers[title];
4661
+ var t = tiddlers[title];
4662
+ return t instanceof Tiddler ? t : null;
4306
4663
  };
4307
4664
  this.deleteTiddler = function(title) {
4308
4665
  delete this.slices[title];
@@ -4408,17 +4765,38 @@ TiddlyWiki.prototype.getTiddler = function(title)
4408
4765
 
4409
4766
  TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
4410
4767
  {
4411
- var tiddler = this.fetchTiddler(title);
4412
- if(tiddler)
4413
- return tiddler.text;
4414
- if(!title)
4768
+ if(!title)
4415
4769
  return defaultText;
4416
- var pos = title.indexOf(config.textPrimitives.sliceSeparator);
4770
+ var pos = title.indexOf(config.textPrimitives.sectionSeparator);
4771
+ var section = null;
4772
+ if(pos != -1) {
4773
+ section = title.substr(pos + config.textPrimitives.sectionSeparator.length);
4774
+ title = title.substr(0,pos);
4775
+ }
4776
+ pos = title.indexOf(config.textPrimitives.sliceSeparator);
4417
4777
  if(pos != -1) {
4418
4778
  var slice = this.getTiddlerSlice(title.substr(0,pos),title.substr(pos + config.textPrimitives.sliceSeparator.length));
4419
4779
  if(slice)
4420
4780
  return slice;
4421
4781
  }
4782
+ var tiddler = this.fetchTiddler(title);
4783
+ if(tiddler) {
4784
+ if(!section)
4785
+ return tiddler.text;
4786
+ var re = new RegExp("(^!{1,6}" + section.escapeRegExp() + ")","mg");
4787
+ re.lastIndex = 0;
4788
+ var match = re.exec(tiddler.text);
4789
+ if(match) {
4790
+ var t = tiddler.text.substr(match.index+match[1].length);
4791
+ var re2 = /^!/mg;
4792
+ re2.lastIndex = 0;
4793
+ match = re2.exec(t); //# search for the next heading
4794
+ if(match)
4795
+ t = t.substr(0,match.index);
4796
+ return t;
4797
+ }
4798
+ return defaultText;
4799
+ }
4422
4800
  if(this.isShadowTiddler(title))
4423
4801
  return config.shadowTiddlers[title];
4424
4802
  if(defaultText != undefined)
@@ -4635,9 +5013,9 @@ TiddlyWiki.prototype.allTiddlersAsHtml = function()
4635
5013
  };
4636
5014
 
4637
5015
  // Return an array of tiddlers matching a search regular expression
4638
- TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
5016
+ TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag,match)
4639
5017
  {
4640
- var candidates = this.reverseLookup("tags",excludeTag,false);
5018
+ var candidates = this.reverseLookup("tags",excludeTag,!!match);
4641
5019
  var results = [];
4642
5020
  for(var t=0; t<candidates.length; t++) {
4643
5021
  if((candidates[t].title.search(searchRegExp) != -1) || (candidates[t].text.search(searchRegExp) != -1))
@@ -4649,26 +5027,28 @@ TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
4649
5027
  return results;
4650
5028
  };
4651
5029
 
4652
- // Return an array of all the tags in use. Each member of the array is another array where [0] is the name of the tag and [1] is the number of occurances
5030
+ // Returns a list of all tags in use
5031
+ // excludeTag - if present, excludes tags that are themselves tagged with excludeTag
5032
+ // Returns an array of arrays where [tag][0] is the name of the tag and [tag][1] is the number of occurances
4653
5033
  TiddlyWiki.prototype.getTags = function(excludeTag)
4654
5034
  {
4655
5035
  var results = [];
4656
5036
  this.forEachTiddler(function(title,tiddler) {
4657
5037
  for(var g=0; g<tiddler.tags.length; g++) {
4658
5038
  var tag = tiddler.tags[g];
4659
- if(excludeTag) {
4660
- var t = store.fetchTiddler(tag);
4661
- if(t && t.isTagged(excludeTag))
4662
- return false;
4663
- }
4664
- var f = false;
5039
+ var n = true;
4665
5040
  for(var c=0; c<results.length; c++) {
4666
5041
  if(results[c][0] == tag) {
4667
- f = true;
5042
+ n = false;
4668
5043
  results[c][1]++;
4669
5044
  }
4670
5045
  }
4671
- if(!f)
5046
+ if(n && excludeTag) {
5047
+ var t = store.fetchTiddler(tag);
5048
+ if(t && t.isTagged(excludeTag))
5049
+ n = false;
5050
+ }
5051
+ if(n)
4672
5052
  results.push([tag,1]);
4673
5053
  }
4674
5054
  });
@@ -4799,6 +5179,62 @@ TiddlyWiki.prototype.getSaver = function()
4799
5179
  return this.saver;
4800
5180
  };
4801
5181
 
5182
+ // Filter a list of tiddlers
5183
+ TiddlyWiki.prototype.filterTiddlers = function(filter)
5184
+ {
5185
+ var results = [];
5186
+ if(filter) {
5187
+ var tiddler;
5188
+ var re = /([^ \[\]]+)|(?:\[([ \w]+)\[([^\]]+)\]\])|(?:\[\[([^\]]+)\]\])/mg;
5189
+ var match = re.exec(filter);
5190
+ while(match) {
5191
+ if(match[1] || match[4]) {
5192
+ var title = match[1] ? match[1] : match[4];
5193
+ tiddler = this.fetchTiddler(title);
5194
+ if(tiddler) {
5195
+ results.pushUnique(tiddler);
5196
+ } else if(store.isShadowTiddler(title)) {
5197
+ tiddler = new Tiddler();
5198
+ tiddler.set(title,store.getTiddlerText(title));
5199
+ results.pushUnique(tiddler);
5200
+ }
5201
+ } else if(match[2]) {
5202
+ switch(match[2]) {
5203
+ case "tag":
5204
+ this.forEachTiddler(function(title,tiddler) {
5205
+ if(tiddler.isTagged(match[3]))
5206
+ results.pushUnique(tiddler);
5207
+ });
5208
+ break;
5209
+ case "sort":
5210
+ results = this.sortTiddlers(results,match[3]);
5211
+ break;
5212
+ }
5213
+ }
5214
+ match = re.exec(filter);
5215
+ }
5216
+ }
5217
+ return results;
5218
+ };
5219
+
5220
+ // Sort a list of tiddlers
5221
+ TiddlyWiki.prototype.sortTiddlers = function(tiddlers,field)
5222
+ {
5223
+ var asc = +1;
5224
+ switch(field.substr(0,1)) {
5225
+ case "-":
5226
+ asc = -1;
5227
+ // Note: this fall-through is intentional
5228
+ case "+":
5229
+ field = field.substr(1);
5230
+ break;
5231
+ }
5232
+ if(TiddlyWiki.standardFieldAccess[field])
5233
+ tiddlers.sort(function(a,b) {return a[field] < b[field] ? -asc : (a[field] == b[field] ? 0 : asc);});
5234
+ else
5235
+ tiddlers.sort(function(a,b) {return a.fields[field] < b.fields[field] ? -asc : (a.fields[field] == b.fields[field] ? 0 : +asc);});
5236
+ return tiddlers;
5237
+ };
4802
5238
  // Returns true if path is a valid field name (path),
4803
5239
  // i.e. a sequence of identifiers, separated by '.'
4804
5240
  TiddlyWiki.isValidFieldName = function(name)
@@ -4944,19 +5380,20 @@ TiddlyWiki.prototype.forEachField = function(tiddler,callback,onlyExtendedFields
4944
5380
  var t = this.resolveTiddler(tiddler);
4945
5381
  if(!t)
4946
5382
  return undefined;
4947
- for(var n in t.fields) {
4948
- var result = callback(t,n,t.fields[n]);
5383
+ var n,result;
5384
+ for(n in t.fields) {
5385
+ result = callback(t,n,t.fields[n]);
4949
5386
  if(result)
4950
5387
  return result;
4951
5388
  }
4952
5389
  if(onlyExtendedFields)
4953
5390
  return undefined;
4954
- for(var n in TiddlyWiki.standardFieldAccess) {
5391
+ for(n in TiddlyWiki.standardFieldAccess) {
4955
5392
  if(n == "tiddler")
4956
5393
  // even though the "title" field can also be referenced through the name "tiddler"
4957
5394
  // we only visit this field once.
4958
5395
  continue;
4959
- var result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
5396
+ result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
4960
5397
  if(result)
4961
5398
  return result;
4962
5399
  }
@@ -4994,8 +5431,9 @@ Story.prototype.displayTiddlers = function(srcElement,titles,template,animate,un
4994
5431
  this.displayTiddler(srcElement,titles[t],template,animate,unused,customFields);
4995
5432
  };
4996
5433
 
4997
- Story.prototype.displayTiddler = function(srcElement,title,template,animate,unused,customFields,toggle)
5434
+ Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle)
4998
5435
  {
5436
+ var title = (tiddler instanceof Tiddler)? tiddler.title : tiddler;
4999
5437
  var place = document.getElementById(this.container);
5000
5438
  var tiddlerElem = document.getElementById(this.idPrefix + title);
5001
5439
  if(tiddlerElem) {
@@ -5062,7 +5500,7 @@ Story.prototype.loadMissingTiddler = function(title,fields,tiddlerElem)
5062
5500
  var serverType = tiddler.getServerType();
5063
5501
  var host = tiddler.fields['server.host'];
5064
5502
  var workspace = tiddler.fields['server.workspace'];
5065
- if(!serverType | !host)
5503
+ if(!serverType || !host)
5066
5504
  return null;
5067
5505
  var sm = new SyncMachine(serverType,{
5068
5506
  start: function() {
@@ -5072,9 +5510,10 @@ Story.prototype.loadMissingTiddler = function(title,fields,tiddlerElem)
5072
5510
  return this.openWorkspace(workspace,"getTiddler");
5073
5511
  },
5074
5512
  getTiddler: function() {
5075
- return this.getTiddler(title,"gotTiddler");
5513
+ return this.getTiddler(title,"onGetTiddler");
5076
5514
  },
5077
- gotTiddler: function(tiddler) {
5515
+ onGetTiddler: function(context) {
5516
+ var tiddler = context.tiddler;
5078
5517
  if(tiddler && tiddler.text) {
5079
5518
  var downloaded = new Date();
5080
5519
  if(!tiddler.created)
@@ -5179,15 +5618,15 @@ Story.prototype.addCustomFields = function(place,customFields)
5179
5618
  }
5180
5619
  };
5181
5620
 
5182
- Story.prototype.refreshAllTiddlers = function()
5621
+ Story.prototype.refreshAllTiddlers = function(force)
5183
5622
  {
5184
5623
  var place = document.getElementById(this.container);
5185
5624
  var e = place.firstChild;
5186
5625
  if(!e)
5187
5626
  return;
5188
- this.refreshTiddler(e.getAttribute("tiddler"),e.getAttribute("template"),true);
5189
- while((e = e.nextSibling) != null)
5190
- this.refreshTiddler(e.getAttribute("tiddler"),e.getAttribute("template"),true);
5627
+ this.refreshTiddler(e.getAttribute("tiddler"),force ? null : e.getAttribute("template"),true);
5628
+ while((e = e.nextSibling) != null)
5629
+ this.refreshTiddler(e.getAttribute("tiddler"),force ? null : e.getAttribute("template"),true);
5191
5630
  };
5192
5631
 
5193
5632
  Story.prototype.onTiddlerMouseOver = function(e)
@@ -5202,9 +5641,9 @@ Story.prototype.onTiddlerMouseOut = function(e)
5202
5641
  removeClass(this,"selected");
5203
5642
  };
5204
5643
 
5205
- Story.prototype.onTiddlerDblClick = function(e)
5644
+ Story.prototype.onTiddlerDblClick = function(ev)
5206
5645
  {
5207
- if(!e) var e = window.event;
5646
+ var e = ev ? ev : window.event;
5208
5647
  var theTarget = resolveTarget(e);
5209
5648
  if(theTarget && theTarget.nodeName.toLowerCase() != "input" && theTarget.nodeName.toLowerCase() != "textarea") {
5210
5649
  if(document.selection && document.selection.empty)
@@ -5218,18 +5657,18 @@ Story.prototype.onTiddlerDblClick = function(e)
5218
5657
  }
5219
5658
  };
5220
5659
 
5221
- Story.prototype.onTiddlerKeyPress = function(e)
5660
+ Story.prototype.onTiddlerKeyPress = function(ev)
5222
5661
  {
5223
- if(!e) var e = window.event;
5662
+ var e = ev ? ev : window.event;
5224
5663
  clearMessage();
5225
- var consume = false;
5664
+ var consume = false;
5226
5665
  var title = this.getAttribute("tiddler");
5227
5666
  var target = resolveTarget(e);
5228
5667
  switch(e.keyCode) {
5229
5668
  case 9: // Tab
5230
5669
  if(config.options.chkInsertTabs && target.tagName.toLowerCase() == "textarea") {
5231
5670
  replaceSelection(target,String.fromCharCode(9));
5232
- consume = true;
5671
+ consume = true;
5233
5672
  }
5234
5673
  if(config.isOpera) {
5235
5674
  target.onblur = function() {
@@ -5246,7 +5685,7 @@ Story.prototype.onTiddlerKeyPress = function(e)
5246
5685
  config.macros.toolbar.invokeCommand(this,"defaultCommand",e);
5247
5686
  consume = true;
5248
5687
  }
5249
- break;
5688
+ break;
5250
5689
  case 27: // Escape
5251
5690
  blurElement(this);
5252
5691
  config.macros.toolbar.invokeCommand(this,"cancelCommand",e);
@@ -5379,14 +5818,11 @@ Story.prototype.search = function(text,useCaseSensitive,useRegExp)
5379
5818
  this.closeAllTiddlers();
5380
5819
  highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
5381
5820
  var matches = store.search(highlightHack,"title","excludeSearch");
5382
- var titles = [];
5383
- for(var t=0;t<matches.length;t++)
5384
- titles.push(matches[t].title);
5385
- this.displayTiddlers(null,titles);
5821
+ this.displayTiddlers(null,matches);
5386
5822
  highlightHack = null;
5387
5823
  var q = useRegExp ? "/" : "'";
5388
5824
  if(matches.length > 0)
5389
- displayMessage(config.macros.search.successMsg.format([titles.length.toString(),q + text + q]));
5825
+ displayMessage(config.macros.search.successMsg.format([matches.length.toString(),q + text + q]));
5390
5826
  else
5391
5827
  displayMessage(config.macros.search.failureMsg.format([q + text + q]));
5392
5828
  };
@@ -5436,6 +5872,8 @@ Story.prototype.saveTiddler = function(title,minorUpdate)
5436
5872
  var fields = {};
5437
5873
  this.gatherSaveFields(tiddlerElem,fields);
5438
5874
  var newTitle = fields.title ? fields.title : title;
5875
+ if(!store.tiddlerExists(newTitle))
5876
+ newTitle = newTitle.trim();
5439
5877
  if(store.tiddlerExists(newTitle) && newTitle != title) {
5440
5878
  if(!confirm(config.messages.overwriteWarning.format([newTitle.toString()])))
5441
5879
  return null;
@@ -5451,11 +5889,11 @@ Story.prototype.saveTiddler = function(title,minorUpdate)
5451
5889
  if(!store.tiddlerExists(newTitle))
5452
5890
  minorUpdate = false;
5453
5891
  var newDate = new Date();
5454
- var extendedFields = store.tiddlerExists(newTitle) ? store.fetchTiddler(newTitle).fields : {};
5892
+ var extendedFields = store.tiddlerExists(newTitle) ? store.fetchTiddler(newTitle).fields : (newTitle!=title && store.tiddlerExists(title) ? store.fetchTiddler(title).fields : {});
5455
5893
  for(var n in fields) {
5456
5894
  if(!TiddlyWiki.isStandardField(n))
5457
5895
  extendedFields[n] = fields[n];
5458
- }
5896
+ }
5459
5897
  var tiddler = store.saveTiddler(title,newTitle,fields.text,minorUpdate ? undefined : config.options.txtUserName,minorUpdate ? undefined : newDate,fields.tags,extendedFields);
5460
5898
  autoSaveChanges(null,[tiddler]);
5461
5899
  return newTitle;
@@ -5476,6 +5914,63 @@ Story.prototype.permaView = function()
5476
5914
  window.location.hash = t;
5477
5915
  };
5478
5916
 
5917
+
5918
+ Story.prototype.switchTheme = function(theme)
5919
+ {
5920
+ if(safeMode)
5921
+ return;
5922
+
5923
+ isAvailable = function(title) {
5924
+ var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
5925
+ if(s!=-1)
5926
+ title = title.substr(0,s);
5927
+ return store.tiddlerExists(title) || store.isShadowTiddler(title);
5928
+ };
5929
+
5930
+ getSlice = function(theme,slice) {
5931
+ var r = store.getTiddlerSlice(theme,slice);
5932
+ if(r && r.indexOf(config.textPrimitives.sectionSeparator)==0)
5933
+ r = theme + r;
5934
+ return isAvailable(r) ? r : slice;
5935
+ };
5936
+
5937
+ replaceNotification = function(i,name,newName) {
5938
+ if(name==newName)
5939
+ return name;
5940
+ if(store.namedNotifications[i].name == name) {
5941
+ store.namedNotifications[i].name = newName;
5942
+ return newName;
5943
+ }
5944
+ return name;
5945
+ };
5946
+
5947
+ for(var i=0; i<config.notifyTiddlers.length; i++) {
5948
+ var name = config.notifyTiddlers[i].name;
5949
+ switch(name) {
5950
+ case "PageTemplate":
5951
+ config.refreshers.pageTemplate = replaceNotification(i,config.refreshers.pageTemplate,getSlice(theme,name));
5952
+ break;
5953
+ case "StyleSheet":
5954
+ removeStyleSheet(config.refreshers.styleSheet);
5955
+ config.refreshers.styleSheet = replaceNotification(i,config.refreshers.styleSheet,getSlice(theme,name));
5956
+ break;
5957
+ case "ColorPalette":
5958
+ config.refreshers.colorPalette = replaceNotification(i,config.refreshers.colorPalette,getSlice(theme,name));
5959
+ break;
5960
+ default:
5961
+ break;
5962
+ }
5963
+ }
5964
+ config.tiddlerTemplates[DEFAULT_VIEW_TEMPLATE] = getSlice(theme,"ViewTemplate");
5965
+ config.tiddlerTemplates[DEFAULT_EDIT_TEMPLATE] = getSlice(theme,"EditTemplate");
5966
+ if(!startingUp) {
5967
+ refreshAll();
5968
+ story.refreshAllTiddlers(true);
5969
+ config.options.txtTheme = theme;
5970
+ saveOptionCookie("txtTheme");
5971
+ }
5972
+ };
5973
+
5479
5974
  //--
5480
5975
  //-- Backstage
5481
5976
  //--
@@ -5529,11 +6024,11 @@ var backstage = {
5529
6024
  else
5530
6025
  this.hide();
5531
6026
  },
5532
-
5533
- isVisible: function () {
6027
+
6028
+ isVisible: function() {
5534
6029
  return this.area ? this.area.style.display == "block" : false;
5535
6030
  },
5536
-
6031
+
5537
6032
  show: function() {
5538
6033
  this.area.style.display = "block";
5539
6034
  if(anim && config.options.chkAnimate) {
@@ -5627,7 +6122,7 @@ var backstage = {
5627
6122
  removeChildren(backstage.panelBody);
5628
6123
  return backstage.panelBody;
5629
6124
  },
5630
-
6125
+
5631
6126
  showPanel: function() {
5632
6127
  backstage.panel.style.display = "block";
5633
6128
  if(anim && config.options.chkAnimate) {
@@ -5641,7 +6136,7 @@ var backstage = {
5641
6136
  }
5642
6137
  return backstage.panelBody;
5643
6138
  },
5644
-
6139
+
5645
6140
  hidePanel: function() {
5646
6141
  backstage.currTabName = null;
5647
6142
  backstage.currTabElem = null;
@@ -5773,8 +6268,7 @@ config.macros.importTiddlers.onOpen = function(e)
5773
6268
  wizard.setValue("adaptor",adaptor);
5774
6269
  wizard.setValue("serverType",serverType);
5775
6270
  wizard.setValue("host",url);
5776
- var context = {};
5777
- var ret = adaptor.openHost(url,context,wizard,config.macros.importTiddlers.onOpenHost);
6271
+ var ret = adaptor.openHost(url,null,wizard,config.macros.importTiddlers.onOpenHost);
5778
6272
  if(ret !== true)
5779
6273
  displayMessage(ret);
5780
6274
  wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusOpenHost);
@@ -5796,6 +6290,18 @@ config.macros.importTiddlers.onGetWorkspaceList = function(context,wizard)
5796
6290
  {
5797
6291
  if(context.status !== true)
5798
6292
  displayMessage("Error in importTiddlers.onGetWorkspaceList: " + context.statusText);
6293
+ wizard.setValue("context",context);
6294
+ var workspace = wizard.getValue("feedWorkspace");
6295
+ if(!workspace && context.workspaces.length==1)
6296
+ workspace = context.workspaces[0].title;
6297
+ if(workspace) {
6298
+ var ret = context.adaptor.openWorkspace(workspace,context,wizard,config.macros.importTiddlers.onOpenWorkspace);
6299
+ if(ret !== true)
6300
+ displayMessage(ret);
6301
+ wizard.setValue("workspace",workspace);
6302
+ wizard.setButtons([{caption: config.macros.importTiddlers.cancelLabel, tooltip: config.macros.importTiddlers.cancelPrompt, onClick: config.macros.importTiddlers.onCancel}],config.macros.importTiddlers.statusOpenWorkspace);
6303
+ return;
6304
+ }
5799
6305
  wizard.addStep(config.macros.importTiddlers.step2Title,config.macros.importTiddlers.step2Html);
5800
6306
  var s = wizard.getElement("selWorkspace");
5801
6307
  s.onchange = config.macros.importTiddlers.onWorkspaceChange;
@@ -5813,7 +6319,6 @@ config.macros.importTiddlers.onGetWorkspaceList = function(context,wizard)
5813
6319
  }
5814
6320
  }
5815
6321
  }
5816
- var workspace = wizard.getValue("feedWorkspace");
5817
6322
  if(workspace) {
5818
6323
  t = wizard.getElement("txtWorkspace");
5819
6324
  t.value = workspace;
@@ -5836,7 +6341,7 @@ config.macros.importTiddlers.onChooseWorkspace = function(e)
5836
6341
  var adaptor = wizard.getValue("adaptor");
5837
6342
  var workspace = wizard.getElement("txtWorkspace").value;
5838
6343
  wizard.setValue("workspace",workspace);
5839
- var context = {};
6344
+ var context = wizard.getValue("context");
5840
6345
  var ret = adaptor.openWorkspace(workspace,context,wizard,config.macros.importTiddlers.onOpenWorkspace);
5841
6346
  if(ret !== true)
5842
6347
  displayMessage(ret);
@@ -5967,7 +6472,7 @@ config.macros.importTiddlers.onGetTiddler = function(context,wizard)
5967
6472
  store.setValue(tiddler.title,'server',null);
5968
6473
  }
5969
6474
  store.resumeNotifications();
5970
- if(!context.isSynchronous)
6475
+ if(!context.isSynchronous)
5971
6476
  store.notify(tiddler.title,true);
5972
6477
  var remainingImports = wizard.getValue("remainingImports")-1;
5973
6478
  wizard.setValue("remainingImports",remainingImports);
@@ -6022,7 +6527,7 @@ config.macros.sync.startSync = function(place)
6022
6527
  ]);
6023
6528
  };
6024
6529
 
6025
- config.macros.sync.getSyncableTiddlers = function ()
6530
+ config.macros.sync.getSyncableTiddlers = function()
6026
6531
  {
6027
6532
  var list = [];
6028
6533
  store.forEachTiddler(function(title,tiddler) {
@@ -6096,9 +6601,10 @@ config.macros.sync.createSyncTask = function(syncItem)
6096
6601
  return this.openWorkspace(st.serverWorkspace,"getTiddlerList");
6097
6602
  },
6098
6603
  getTiddlerList: function() {
6099
- return this.getTiddlerList("gotTiddlerList");
6604
+ return this.getTiddlerList("onGetTiddlerList");
6100
6605
  },
6101
- gotTiddlerList: function(tiddlers) {
6606
+ onGetTiddlerList: function(context) {
6607
+ var tiddlers = context.tiddlers;
6102
6608
  for(var t=0; t<st.syncItems.length; t++) {
6103
6609
  var si = st.syncItems[t];
6104
6610
  var f = tiddlers.findByField("title",si.title);
@@ -6115,7 +6621,8 @@ config.macros.sync.createSyncTask = function(syncItem)
6115
6621
  getTiddler: function(title) {
6116
6622
  return this.getTiddler(title,"onGetTiddler");
6117
6623
  },
6118
- onGetTiddler: function(tiddler) {
6624
+ onGetTiddler: function(context) {
6625
+ var tiddler = context.tiddler;
6119
6626
  var syncItem = st.syncItems.findByField("title",tiddler.title);
6120
6627
  if(syncItem !== null) {
6121
6628
  syncItem = st.syncItems[syncItem];
@@ -6127,11 +6634,12 @@ config.macros.sync.createSyncTask = function(syncItem)
6127
6634
  putTiddler: function(tiddler) {
6128
6635
  return this.putTiddler(tiddler,"onPutTiddler");
6129
6636
  },
6130
- onPutTiddler: function(tiddler) {
6131
- var syncItem = st.syncItems.findByField("title",tiddler.title);
6637
+ onPutTiddler: function(context) {
6638
+ var title = context.title;
6639
+ var syncItem = st.syncItems.findByField("title",title);
6132
6640
  if(syncItem !== null) {
6133
6641
  syncItem = st.syncItems[syncItem];
6134
- store.resetTiddler(tiddler.title);
6642
+ store.resetTiddler(title);
6135
6643
  syncItem.syncStatus = config.macros.sync.syncStatusList.putToServer;
6136
6644
  config.macros.sync.updateSyncStatus(syncItem);
6137
6645
  }
@@ -6193,17 +6701,17 @@ function SyncMachine(serverType,steps)
6193
6701
  this.steps = steps;
6194
6702
  }
6195
6703
 
6196
- SyncMachine.prototype.go = function(step,varargs)
6704
+ SyncMachine.prototype.go = function(step,context)
6197
6705
  {
6198
- if(!step)
6199
- step = "start";
6200
- var h = this.steps[step];
6706
+ var r = context ? context.status : null;
6707
+ if(typeof r == "string") {
6708
+ this.invokeError(r);
6709
+ return r;
6710
+ }
6711
+ var h = this.steps[step ? step : "start"];
6201
6712
  if(!h)
6202
6713
  return null;
6203
- var a = [];
6204
- for(var t=1; t<arguments.length; t++)
6205
- a.push(arguments[t]);
6206
- var r = h.apply(this,a);
6714
+ r = h.call(this,context);
6207
6715
  if(typeof r == "string")
6208
6716
  this.invokeError(r);
6209
6717
  return r;
@@ -6218,45 +6726,25 @@ SyncMachine.prototype.invokeError = function(message)
6218
6726
  SyncMachine.prototype.openHost = function(host,nextStep)
6219
6727
  {
6220
6728
  var me = this;
6221
- return me.adaptor.openHost(host,null,null,function(context) {
6222
- if(typeof context.status == "string")
6223
- me.invokeError(context.status);
6224
- else
6225
- me.go(nextStep);
6226
- });
6729
+ return me.adaptor.openHost(host,null,null,function(context) {me.go(nextStep,context);});
6227
6730
  };
6228
6731
 
6229
6732
  SyncMachine.prototype.getWorkspaceList = function(nextStep)
6230
6733
  {
6231
6734
  var me = this;
6232
- return me.adaptor.getWorkspaceList(null,null,function(context) {
6233
- if(typeof context.status == "string")
6234
- me.invokeError(context.status);
6235
- else
6236
- me.go(nextStep,context.workspaces);
6237
- });
6735
+ return me.adaptor.getWorkspaceList(null,null,function(context) {me.go(nextStep,context);});
6238
6736
  };
6239
6737
 
6240
6738
  SyncMachine.prototype.openWorkspace = function(workspace,nextStep)
6241
6739
  {
6242
6740
  var me = this;
6243
- return me.adaptor.openWorkspace(workspace,null,null,function(context) {
6244
- if(typeof context.status == "string")
6245
- me.invokeError(context.status);
6246
- else
6247
- me.go(nextStep);
6248
- });
6741
+ return me.adaptor.openWorkspace(workspace,null,null,function(context) {me.go(nextStep,context);});
6249
6742
  };
6250
6743
 
6251
6744
  SyncMachine.prototype.getTiddlerList = function(nextStep)
6252
6745
  {
6253
6746
  var me = this;
6254
- return me.adaptor.getTiddlerList(null,null,function(context) {
6255
- if(typeof context.status == "string")
6256
- me.invokeError(context.status);
6257
- else
6258
- me.go(nextStep,context.tiddlers);
6259
- });
6747
+ return me.adaptor.getTiddlerList(null,null,function(context) {me.go(nextStep,context);});
6260
6748
  };
6261
6749
 
6262
6750
  SyncMachine.prototype.generateTiddlerInfo = function(tiddler)
@@ -6267,23 +6755,13 @@ SyncMachine.prototype.generateTiddlerInfo = function(tiddler)
6267
6755
  SyncMachine.prototype.getTiddler = function(title,nextStep)
6268
6756
  {
6269
6757
  var me = this;
6270
- return me.adaptor.getTiddler(title,null,null,function(context) {
6271
- if(typeof context.status == "string")
6272
- me.invokeError(context.status);
6273
- else
6274
- me.go(nextStep,context.tiddler);
6275
- });
6758
+ return me.adaptor.getTiddler(title,null,null,function(context) {me.go(nextStep,context);});
6276
6759
  };
6277
6760
 
6278
6761
  SyncMachine.prototype.putTiddler = function(tiddler,nextStep)
6279
6762
  {
6280
6763
  var me = this;
6281
- return me.adaptor.putTiddler(tiddler,null,null,function(context) {
6282
- if(typeof context.status == "string")
6283
- me.invokeError(context.status);
6284
- else
6285
- me.go(nextStep,tiddler);
6286
- });
6764
+ return me.adaptor.putTiddler(tiddler,null,null,function(context) {me.go(nextStep,context);});
6287
6765
  };
6288
6766
 
6289
6767
  //--
@@ -6431,7 +6909,7 @@ config.refreshers = {
6431
6909
  refreshTiddlyLink(e,title);
6432
6910
  return true;
6433
6911
  },
6434
-
6912
+
6435
6913
  tiddler: function(e,changeList)
6436
6914
  {
6437
6915
  var title = e.getAttribute("tiddler");
@@ -6464,7 +6942,13 @@ config.refreshers = {
6464
6942
  if(macro && macro.refresh)
6465
6943
  macro.refresh(e,params);
6466
6944
  return true;
6467
- }
6945
+ },
6946
+ styleSheet: "StyleSheet",
6947
+ defaultStyleSheet: "StyleSheet",
6948
+ pageTemplate: "PageTemplate",
6949
+ defaultPageTemplate: "PageTemplate",
6950
+ colorPalette: "ColorPalette",
6951
+ defaultColorPalette: "ColorPalette"
6468
6952
  };
6469
6953
 
6470
6954
  function refreshElements(root,changeList)
@@ -6518,9 +7002,18 @@ function refreshPageTemplate(title)
6518
7002
  stash.appendChild(nodes[t]);
6519
7003
  }
6520
7004
  var wrapper = document.getElementById("contentWrapper");
6521
- if(!title)
6522
- title = "PageTemplate";
6523
- var html = store.getRecursiveTiddlerText(title,null,10);
7005
+
7006
+ isAvailable = function(title) {
7007
+ var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
7008
+ if(s!=-1)
7009
+ title = title.substr(0,s);
7010
+ return store.tiddlerExists(title) || store.isShadowTiddler(title);
7011
+ };
7012
+ if(!title || !isAvailable(title))
7013
+ title = config.refreshers.pageTemplate;
7014
+ if(!isAvailable(title))
7015
+ title = config.refreshers.defaultPageTemplate; //# this one is always avaialable
7016
+ html = store.getRecursiveTiddlerText(title,null,10);
6524
7017
  wrapper.innerHTML = html;
6525
7018
  applyHtmlMacros(wrapper);
6526
7019
  refreshElements(wrapper);
@@ -6560,9 +7053,7 @@ function getPageTitle()
6560
7053
 
6561
7054
  function refreshStyles(title,doc)
6562
7055
  {
6563
- if(!doc)
6564
- doc = document;
6565
- setStylesheet(title == null ? "" : store.getRecursiveTiddlerText(title,"",10),title,doc);
7056
+ setStylesheet(title == null ? "" : store.getRecursiveTiddlerText(title,"",10),title,doc ? doc : document);
6566
7057
  }
6567
7058
 
6568
7059
  function refreshColorPalette(title)
@@ -6577,12 +7068,12 @@ function refreshAll()
6577
7068
  refreshDisplay();
6578
7069
  refreshStyles("StyleSheetLayout");
6579
7070
  refreshStyles("StyleSheetColors");
6580
- refreshStyles("StyleSheet");
7071
+ refreshStyles(config.refreshers.styleSheet);
6581
7072
  refreshStyles("StyleSheetPrint");
6582
7073
  }
6583
7074
 
6584
7075
  //--
6585
- //-- Options cookie stuff
7076
+ //-- Options stuff
6586
7077
  //--
6587
7078
 
6588
7079
  config.optionHandlers = {
@@ -6637,6 +7128,133 @@ function decodeCookie(s)
6637
7128
  return s.replace(re,function($0) {return String.fromCharCode(eval($0.replace(/[&#;]/g,"")));});
6638
7129
  }
6639
7130
 
7131
+
7132
+ config.macros.option.genericCreate = function(place,type,opt,className,desc)
7133
+ {
7134
+ var typeInfo = config.macros.option.types[type];
7135
+ var c = document.createElement(typeInfo.elementType);
7136
+ if(typeInfo.typeValue)
7137
+ c.setAttribute("type",typeInfo.typeValue);
7138
+ c[typeInfo.eventName] = typeInfo.onChange;
7139
+ c.setAttribute("option",opt);
7140
+ if(className)
7141
+ c.className = className;
7142
+ else
7143
+ c.className = typeInfo.className;
7144
+ if(config.optionsDesc[opt])
7145
+ c.setAttribute("title",config.optionsDesc[opt]);
7146
+ place.appendChild(c);
7147
+ if(desc != "no")
7148
+ createTiddlyText(place,config.optionsDesc[opt] ? config.optionsDesc[opt] : opt);
7149
+ c[typeInfo.valueField] = config.options[opt];
7150
+ return c;
7151
+ };
7152
+
7153
+ config.macros.option.genericOnChange = function(e)
7154
+ {
7155
+ var opt = this.getAttribute("option");
7156
+ if(opt) {
7157
+ var optType = opt.substr(0,3);
7158
+ var handler = config.macros.option.types[optType];
7159
+ if (handler.elementType && handler.valueField)
7160
+ config.macros.option.propagateOption(opt,handler.valueField,this[handler.valueField],handler.elementType);
7161
+ }
7162
+ return true;
7163
+ };
7164
+
7165
+ config.macros.option.types = {
7166
+ 'txt': {
7167
+ elementType: "input",
7168
+ valueField: "value",
7169
+ eventName: "onkeyup",
7170
+ className: "txtOptionInput",
7171
+ create: config.macros.option.genericCreate,
7172
+ onChange: config.macros.option.genericOnChange
7173
+ },
7174
+ 'chk': {
7175
+ elementType: "input",
7176
+ valueField: "checked",
7177
+ eventName: "onclick",
7178
+ className: "chkOptionInput",
7179
+ typeValue: "checkbox",
7180
+ create: config.macros.option.genericCreate,
7181
+ onChange: config.macros.option.genericOnChange
7182
+ }
7183
+ };
7184
+
7185
+ config.macros.option.propagateOption = function(opt,valueField,value,elementType)
7186
+ {
7187
+ config.options[opt] = value;
7188
+ saveOptionCookie(opt);
7189
+ var nodes = document.getElementsByTagName(elementType);
7190
+ for(var t=0; t<nodes.length; t++) {
7191
+ var optNode = nodes[t].getAttribute("option");
7192
+ if(opt == optNode)
7193
+ nodes[t][valueField] = value;
7194
+ }
7195
+ };
7196
+
7197
+ config.macros.option.handler = function(place,macroName,params,wikifier,paramString,tiddler)
7198
+ {
7199
+ params = paramString.parseParams("anon",null,true,false,false);
7200
+ var opt = (params[1] && params[1].name == "anon") ? params[1].value : getParam(params,"name",null);
7201
+ var className = (params[2] && params[2].name == "anon") ? params[2].value : getParam(params,"class",null);
7202
+ var desc = getParam(params,"desc","no");
7203
+ var type = opt.substr(0,3);
7204
+ var h = config.macros.option.types[type];
7205
+ if (h && h.create)
7206
+ h.create(place,type,opt,className,desc);
7207
+ };
7208
+
7209
+ config.macros.options.handler = function(place,macroName,params,wikifier,paramString,tiddler)
7210
+ {
7211
+ params = paramString.parseParams("anon",null,true,false,false);
7212
+ var showUnknown = getParam(params,"showUnknown","no");
7213
+ var wizard = new Wizard();
7214
+ wizard.createWizard(place,this.wizardTitle);
7215
+ wizard.addStep(this.step1Title,this.step1Html);
7216
+ var markList = wizard.getElement("markList");
7217
+ var chkUnknown = wizard.getElement("chkUnknown");
7218
+ chkUnknown.checked = showUnknown == "yes";
7219
+ chkUnknown.onchange = this.onChangeUnknown;
7220
+ var listWrapper = document.createElement("div");
7221
+ markList.parentNode.insertBefore(listWrapper,markList);
7222
+ wizard.setValue("listWrapper",listWrapper);
7223
+ this.refreshOptions(listWrapper,showUnknown == "yes");
7224
+ };
7225
+
7226
+ config.macros.options.refreshOptions = function(listWrapper,showUnknown)
7227
+ {
7228
+ var opts = [];
7229
+ for(var n in config.options) {
7230
+ var opt = {};
7231
+ opt.option = "";
7232
+ opt.name = n;
7233
+ opt.lowlight = !config.optionsDesc[n];
7234
+ opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
7235
+ if(!opt.lowlight || showUnknown)
7236
+ opts.push(opt);
7237
+ }
7238
+ opts.sort(function(a,b) {return a.name.substr(3) < b.name.substr(3) ? -1 : (a.name.substr(3) == b.name.substr(3) ? 0 : +1);});
7239
+ var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
7240
+ for(n=0; n<opts.length; n++) {
7241
+ var type = opts[n].name.substr(0,3);
7242
+ var h = config.macros.option.types[type];
7243
+ if (h && h.create) {
7244
+ h.create(opts[n].colElements['option'],type,opts[n].name,null,"no");
7245
+ }
7246
+ }
7247
+ };
7248
+
7249
+ config.macros.options.onChangeUnknown = function(e)
7250
+ {
7251
+ var wizard = new Wizard(this);
7252
+ var listWrapper = wizard.getValue("listWrapper");
7253
+ removeChildren(listWrapper);
7254
+ config.macros.options.refreshOptions(listWrapper,this.checked);
7255
+ return false;
7256
+ };
7257
+
6640
7258
  //--
6641
7259
  //-- Saving
6642
7260
  //--
@@ -6765,7 +7383,6 @@ function saveChanges(onlyIfDirty,tiddlers)
6765
7383
 
6766
7384
  function saveBackup(localPath,original)
6767
7385
  {
6768
- // Save the backup
6769
7386
  if(config.options.chkSaveBackups) {
6770
7387
  var backupPath = getBackupPath(localPath);
6771
7388
  var backup = config.browser.isIE ? ieCopyFile(backupPath,localPath) : saveFile(backupPath,original);
@@ -6852,19 +7469,22 @@ function getLocalPath(origPath)
6852
7469
  return localPath;
6853
7470
  }
6854
7471
 
6855
- function getBackupPath(localPath)
7472
+ function getBackupPath(localPath,title,extension)
6856
7473
  {
6857
- var backSlash = true;
7474
+ var slash = "\\";
6858
7475
  var dirPathPos = localPath.lastIndexOf("\\");
6859
7476
  if(dirPathPos == -1) {
6860
7477
  dirPathPos = localPath.lastIndexOf("/");
6861
- backSlash = false;
7478
+ slash = "/";
6862
7479
  }
6863
7480
  var backupFolder = config.options.txtBackupFolder;
6864
7481
  if(!backupFolder || backupFolder == "")
6865
7482
  backupFolder = ".";
6866
- var backupPath = localPath.substr(0,dirPathPos) + (backSlash ? "\\" : "/") + backupFolder + localPath.substr(dirPathPos);
6867
- backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + "." + (new Date()).convertToYYYYMMDDHHMMSSMMM() + ".html";
7483
+ var backupPath = localPath.substr(0,dirPathPos) + slash + backupFolder + localPath.substr(dirPathPos);
7484
+ backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + ".";
7485
+ if(title)
7486
+ backupPath += title.replace(/[\\\/\*\?\":<> ]/g,"_") + ".";
7487
+ backupPath += (new Date()).convertToYYYYMMDDHHMMSSMMM() + "." + (extension ? extension : "html");
6868
7488
  return backupPath;
6869
7489
  }
6870
7490
 
@@ -6890,8 +7510,9 @@ function generateRss()
6890
7510
  // The body
6891
7511
  var tiddlers = store.getTiddlers("modified","excludeLists");
6892
7512
  var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
6893
- for (var t=tiddlers.length-1; t>=n; t--)
6894
- s.push(tiddlers[t].saveToRss(u));
7513
+ for (var t=tiddlers.length-1; t>=n; t--) {
7514
+ s.push("<item>\n" + tiddlers[t].toRssItem(u) + "\n</item>");
7515
+ }
6895
7516
  // And footer
6896
7517
  s.push("</channel>");
6897
7518
  s.push("</rss>");
@@ -6905,10 +7526,7 @@ function generateRss()
6905
7526
 
6906
7527
  function convertUTF8ToUnicode(u)
6907
7528
  {
6908
- if(window.netscape == undefined)
6909
- return manualConvertUTF8ToUnicode(u);
6910
- else
6911
- return mozConvertUTF8ToUnicode(u);
7529
+ return window.netscape == undefined ? manualConvertUTF8ToUnicode(u) : mozConvertUTF8ToUnicode(u);
6912
7530
  }
6913
7531
 
6914
7532
  function manualConvertUTF8ToUnicode(utf)
@@ -6975,10 +7593,7 @@ function mozConvertUnicodeToUTF8(s)
6975
7593
  } // fallback
6976
7594
  var u = converter.ConvertFromUnicode(s);
6977
7595
  var fin = converter.Finish();
6978
- if(fin.length > 0)
6979
- return u + fin;
6980
- else
6981
- return u;
7596
+ return fin.length > 0 ? u + fin : u;
6982
7597
  }
6983
7598
 
6984
7599
  function convertUriToUTF8(uri,charSet)
@@ -6996,9 +7611,7 @@ function convertUriToUTF8(uri,charSet)
6996
7611
 
6997
7612
  function saveFile(fileUrl,content)
6998
7613
  {
6999
- var r = null;
7000
- if(!r)
7001
- r = mozillaSaveFile(fileUrl,content);
7614
+ var r = mozillaSaveFile(fileUrl,content);
7002
7615
  if(!r)
7003
7616
  r = ieSaveFile(fileUrl,content);
7004
7617
  if(!r)
@@ -7008,9 +7621,7 @@ function saveFile(fileUrl,content)
7008
7621
 
7009
7622
  function loadFile(fileUrl)
7010
7623
  {
7011
- var r = null;
7012
- if((r == null) || (r == false))
7013
- r = mozillaLoadFile(fileUrl);
7624
+ var r = mozillaLoadFile(fileUrl);
7014
7625
  if((r == null) || (r == false))
7015
7626
  r = ieLoadFile(fileUrl);
7016
7627
  if((r == null) || (r == false))
@@ -7018,9 +7629,39 @@ function loadFile(fileUrl)
7018
7629
  return r;
7019
7630
  }
7020
7631
 
7632
+ function ieCreatePath(path)
7633
+ {
7634
+ try {
7635
+ var fso = new ActiveXObject("Scripting.FileSystemObject");
7636
+ } catch(ex) {
7637
+ return null;
7638
+ }
7639
+
7640
+ var pos = path.lastIndexOf("\\");
7641
+ if(pos!=-1)
7642
+ path = path.substring(0, pos+1);
7643
+
7644
+ var scan = [];
7645
+ scan.push(path);
7646
+ var i = 0;
7647
+ do {
7648
+ var parent = fso.GetParentFolderName(scan[i++]);
7649
+ if (fso.FolderExists(parent))
7650
+ break;
7651
+ scan.push(parent);
7652
+ } while(true);
7653
+
7654
+ for(i=scan.length-1;i>=0;i--) {
7655
+ if (!fso.FolderExists(scan[i]))
7656
+ fso.CreateFolder(scan[i]);
7657
+ }
7658
+ return true;
7659
+ }
7660
+
7021
7661
  // Returns null if it can't do it, false if there's an error, true if it saved OK
7022
7662
  function ieSaveFile(filePath,content)
7023
7663
  {
7664
+ ieCreatePath(filePath);
7024
7665
  try {
7025
7666
  var fso = new ActiveXObject("Scripting.FileSystemObject");
7026
7667
  } catch(ex) {
@@ -7048,6 +7689,7 @@ function ieLoadFile(filePath)
7048
7689
 
7049
7690
  function ieCopyFile(dest,source)
7050
7691
  {
7692
+ ieCreatePath(dest);
7051
7693
  try {
7052
7694
  var fso = new ActiveXObject("Scripting.FileSystemObject");
7053
7695
  fso.GetFile(source).Copy(dest);
@@ -7151,7 +7793,7 @@ function javaLoadFile(filePath)
7151
7793
  }
7152
7794
 
7153
7795
  //--
7154
- //-- Server adaptor for talking to static files
7796
+ //-- Server adaptor for talking to static TiddlyWiki files
7155
7797
  //--
7156
7798
 
7157
7799
  function FileAdaptor()
@@ -7161,78 +7803,116 @@ function FileAdaptor()
7161
7803
  return this;
7162
7804
  }
7163
7805
 
7164
- FileAdaptor.NotLoadedError = "TiddlyWiki file has not been loaded";
7165
7806
  FileAdaptor.serverType = 'file';
7166
7807
 
7167
- // Open the specified host/server
7808
+ FileAdaptor.prototype.setContext = function(context,userParams,callback)
7809
+ {
7810
+ if(!context) context = {};
7811
+ context.userParams = userParams;
7812
+ if(callback) context.callback = callback;
7813
+ context.adaptor = this;
7814
+ if(!context.host)
7815
+ context.host = this.host;
7816
+ context.host = FileAdaptor.fullHostName(context.host);
7817
+ if(!context.workspace)
7818
+ context.workspace = this.workspace;
7819
+ return context;
7820
+ };
7821
+
7822
+ FileAdaptor.fullHostName = function(host)
7823
+ {
7824
+ if(!host)
7825
+ return '';
7826
+ if(!host.match(/:\/\//))
7827
+ host = 'http://' + host;
7828
+ return host;
7829
+ };
7830
+
7831
+ FileAdaptor.minHostName = function(host)
7832
+ {
7833
+ return host ? host.replace(/^http:\/\//,'').replace(/\/$/,'') : '';
7834
+ };
7835
+
7836
+ // Open the specified host
7168
7837
  FileAdaptor.prototype.openHost = function(host,context,userParams,callback)
7169
7838
  {
7170
7839
  this.host = host;
7171
- if(!context)
7172
- context = {};
7173
- context.adaptor = this;
7174
- context.callback = callback;
7175
- context.userParams = userParams;
7176
- var ret = loadRemoteFile(host,FileAdaptor.openHostCallback,context);
7177
- return typeof(ret) == "string" ? ret : true;
7840
+ context = this.setContext(context,userParams,callback);
7841
+ context.status = true;
7842
+ if(callback)
7843
+ window.setTimeout(function() {callback(context,userParams);},10);
7844
+ return true;
7178
7845
  };
7179
7846
 
7180
- FileAdaptor.openHostCallback = function(status,context,responseText,url,xhr)
7847
+ FileAdaptor.loadTiddlyWikiCallback = function(status,context,responseText,url,xhr)
7181
7848
  {
7182
- var adaptor = context.adaptor;
7183
7849
  context.status = status;
7184
7850
  if(!status) {
7185
7851
  context.statusText = "Error reading file: " + xhr.statusText;
7186
7852
  } else {
7187
- // Load the content into a TiddlyWiki() object
7188
- adaptor.store = new TiddlyWiki();
7189
- if(!adaptor.store.importTiddlyWiki(responseText))
7853
+ context.adaptor.store = new TiddlyWiki();
7854
+ if(!context.adaptor.store.importTiddlyWiki(responseText))
7190
7855
  context.statusText = config.messages.invalidFileError.format([url]);
7191
7856
  }
7192
- context.callback(context,context.userParams);
7857
+ context.complete(context,context.userParams);
7193
7858
  };
7194
7859
 
7195
- // Gets the list of workspaces on a given server
7860
+ // Get the list of workspaces on a given server
7196
7861
  FileAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
7197
7862
  {
7198
- if(!context)
7199
- context = {};
7863
+ context = this.setContext(context,userParams,callback);
7200
7864
  context.workspaces = [{title:"(default)"}];
7201
7865
  context.status = true;
7202
- window.setTimeout(function() {callback(context,userParams);},10);
7866
+ if(callback)
7867
+ window.setTimeout(function() {callback(context,userParams);},10);
7203
7868
  return true;
7204
7869
  };
7205
7870
 
7206
7871
  // Open the specified workspace
7207
7872
  FileAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
7208
7873
  {
7209
- if(!context)
7210
- context = {};
7874
+ this.workspace = workspace;
7875
+ context = this.setContext(context,userParams,callback);
7211
7876
  context.status = true;
7212
- window.setTimeout(function() {callback(context,userParams);},10);
7877
+ if(callback)
7878
+ window.setTimeout(function() {callback(context,userParams);},10);
7213
7879
  return true;
7214
7880
  };
7215
7881
 
7216
7882
  // Gets the list of tiddlers within a given workspace
7217
- FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback)
7218
- {
7219
- if(!this.store)
7220
- return FileAdaptor.NotLoadedError;
7221
- if(!context)
7222
- context = {};
7223
- context.tiddlers = [];
7224
- this.store.forEachTiddler(function(title,tiddler)
7225
- {
7226
- var t = new Tiddler(title);
7227
- t.text = tiddler.text;
7228
- t.modified = tiddler.modified;
7229
- t.modifier = tiddler.modifier;
7230
- t.fields['server.page.revision'] = tiddler.modified.convertToYYYYMMDDHHMM();
7231
- t.tags = tiddler.tags;
7232
- context.tiddlers.push(t);
7233
- });
7883
+ FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
7884
+ {
7885
+ context = this.setContext(context,userParams,callback);
7886
+ if(!context.filter)
7887
+ context.filter = filter;
7888
+ context.complete = FileAdaptor.getTiddlerListComplete;
7889
+ if(this.store) {
7890
+ var ret = context.complete(context,context.userParams);
7891
+ } else {
7892
+ ret = loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context);
7893
+ if(typeof ret != "string")
7894
+ ret = true;
7895
+ }
7896
+ return ret;
7897
+ };
7898
+
7899
+ FileAdaptor.getTiddlerListComplete = function(context,userParams)
7900
+ {
7901
+ if(context.filter) {
7902
+ context.tiddlers = context.adaptor.store.filterTiddlers(context.filter);
7903
+ } else {
7904
+ context.tiddlers = [];
7905
+ context.adaptor.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);});
7906
+ }
7907
+ for(var i=0; i<context.tiddlers.length; i++) {
7908
+ context.tiddlers[i].fields['server.type'] = FileAdaptor.serverType;
7909
+ context.tiddlers[i].fields['server.host'] = FileAdaptor.minHostName(context.host);
7910
+ context.tiddlers[i].fields['server.page.revision'] = context.tiddlers[i].modified.convertToYYYYMMDDHHMM();
7911
+ }
7234
7912
  context.status = true;
7235
- window.setTimeout(function() {callback(context,userParams);},10);
7913
+ if(context.callback) {
7914
+ window.setTimeout(function() {context.callback(context,userParams);},10);
7915
+ }
7236
7916
  return true;
7237
7917
  };
7238
7918
 
@@ -7243,23 +7923,28 @@ FileAdaptor.prototype.generateTiddlerInfo = function(tiddler)
7243
7923
  return info;
7244
7924
  };
7245
7925
 
7246
- // Retrieves a tiddler from a given workspace on a given server
7926
+ // Retrieve a tiddler from a given workspace on a given server
7247
7927
  FileAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
7248
7928
  {
7249
- if(!this.store)
7250
- return FileAdaptor.NotLoadedError;
7251
- if(!context)
7252
- context = {};
7253
- context.tiddler = this.store.fetchTiddler(title);
7254
- if(context.tiddler) {
7255
- context.tiddler.fields['server.type'] = FileAdaptor.serverType;
7256
- context.tiddler.fields['server.host'] = this.host;
7257
- context.tiddler.fields['server.page.revision'] = context.tiddler.modified.convertToYYYYMMDDHHMM();
7258
- }
7929
+ context = this.setContext(context,userParams,callback);
7930
+ context.title = title;
7931
+ context.complete = FileAdaptor.getTiddlerComplete;
7932
+ return context.adaptor.store ?
7933
+ context.complete(context,context.userParams) :
7934
+ loadRemoteFile(context.host,FileAdaptor.loadTiddlyWikiCallback,context);
7935
+ };
7936
+
7937
+ FileAdaptor.getTiddlerComplete = function(context,userParams)
7938
+ {
7939
+ var t = context.adaptor.store.fetchTiddler(context.title);
7940
+ t.fields['server.type'] = FileAdaptor.serverType;
7941
+ t.fields['server.host'] = FileAdaptor.minHostName(context.host);
7942
+ t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM();
7943
+ context.tiddler = t;
7259
7944
  context.status = true;
7260
7945
  if(context.allowSynchronous) {
7261
7946
  context.isSynchronous = true;
7262
- callback(context,userParams);
7947
+ context.callback(context,userParams);
7263
7948
  } else {
7264
7949
  window.setTimeout(function() {callback(context,userParams);},10);
7265
7950
  }
@@ -7288,6 +7973,7 @@ var httpStatus = {
7288
7973
  OK: 200,
7289
7974
  ContentCreated: 201,
7290
7975
  NoContent: 204,
7976
+ MultiStatus: 207,
7291
7977
  Unauthorized: 401,
7292
7978
  Forbidden: 403,
7293
7979
  NotFound: 404,
@@ -7296,14 +7982,17 @@ var httpStatus = {
7296
7982
 
7297
7983
  function doHttp(type,url,data,contentType,username,password,callback,params,headers)
7298
7984
  {
7299
- // Get an xhr object
7300
7985
  var x = getXMLHttpRequest();
7301
7986
  if(!x)
7302
7987
  return "Can't create XMLHttpRequest object";
7303
- // Install callback
7304
7988
  x.onreadystatechange = function() {
7305
- if (x.readyState == 4 && callback && (x.status !== undefined)) {
7306
- if([0, httpStatus.OK, httpStatus.ContentCreated, httpStatus.NoContent].contains(x.status))
7989
+ try {
7990
+ var status = x.status;
7991
+ } catch(ex) {
7992
+ status = false;
7993
+ }
7994
+ if (x.readyState == 4 && callback && (status !== undefined)) {
7995
+ if([0, httpStatus.OK, httpStatus.ContentCreated, httpStatus.NoContent, httpStatus.MultiStatus].contains(status))
7307
7996
  callback(true,params,x.responseText,url,x);
7308
7997
  else
7309
7998
  callback(false,params,null,url,x);
@@ -7311,23 +8000,22 @@ function doHttp(type,url,data,contentType,username,password,callback,params,head
7311
8000
  x = null;
7312
8001
  }
7313
8002
  };
7314
- // Send request
7315
8003
  if(window.Components && window.netscape && window.netscape.security && document.location.protocol.indexOf("http") == -1)
7316
8004
  window.netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
7317
8005
  try {
7318
8006
  url = url + (url.indexOf("?") < 0 ? "?" : "&") + "nocache=" + Math.random();
7319
8007
  x.open(type,url,true,username,password);
7320
- if (data)
8008
+ if(data)
7321
8009
  x.setRequestHeader("Content-Type", contentType ? contentType : "application/x-www-form-urlencoded");
7322
- if (x.overrideMimeType)
8010
+ if(x.overrideMimeType)
7323
8011
  x.setRequestHeader("Connection", "close");
7324
8012
  if(headers) {
7325
- for(n in headers)
8013
+ for(var n in headers)
7326
8014
  x.setRequestHeader(n,headers[n]);
7327
8015
  }
7328
8016
  x.setRequestHeader("X-Requested-With", "TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + (version.beta ? " (beta " + version.beta + ")" : ""));
7329
8017
  x.send(data);
7330
- } catch (ex) {
8018
+ } catch(ex) {
7331
8019
  return exceptionText(ex);
7332
8020
  }
7333
8021
  return x;
@@ -7351,34 +8039,36 @@ function getXMLHttpRequest()
7351
8039
  //-- TiddlyWiki-specific utility functions
7352
8040
  //--
7353
8041
 
7354
- function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey)
8042
+ function createTiddlyButton(parent,text,tooltip,action,className,id,accessKey,attribs)
7355
8043
  {
7356
- var theButton = document.createElement("a");
7357
- if(theAction) {
7358
- theButton.onclick = theAction;
7359
- theButton.setAttribute("href","javascript:;");
8044
+ var btn = document.createElement("a");
8045
+ if(action) {
8046
+ btn.onclick = action;
8047
+ btn.setAttribute("href","javascript:;");
7360
8048
  }
7361
- if(theTooltip)
7362
- theButton.setAttribute("title",theTooltip);
7363
- if(theText)
7364
- theButton.appendChild(document.createTextNode(theText));
7365
- if(theClass)
7366
- theButton.className = theClass;
7367
- else
7368
- theButton.className = "button";
7369
- if(theId)
7370
- theButton.id = theId;
7371
- if(theParent)
7372
- theParent.appendChild(theButton);
7373
- if(theAccessKey)
7374
- theButton.setAttribute("accessKey",theAccessKey);
7375
- return theButton;
8049
+ if(tooltip)
8050
+ btn.setAttribute("title",tooltip);
8051
+ if(text)
8052
+ btn.appendChild(document.createTextNode(text));
8053
+ btn.className = className ? className : "button";
8054
+ if(id)
8055
+ btn.id = id;
8056
+ if(attribs) {
8057
+ for(var n in attribs) {
8058
+ btn.setAttribute(n,attribs[n]);
8059
+ }
8060
+ }
8061
+ if(parent)
8062
+ parent.appendChild(btn);
8063
+ if(accessKey)
8064
+ btn.setAttribute("accessKey",accessKey);
8065
+ return btn;
7376
8066
  }
7377
8067
 
7378
- function createTiddlyLink(place,title,includeText,theClass,isStatic,linkedFromTiddler,noToggle)
8068
+ function createTiddlyLink(place,title,includeText,className,isStatic,linkedFromTiddler,noToggle)
7379
8069
  {
7380
8070
  var text = includeText ? title : null;
7381
- var i = getTiddlyLinkInfo(title,theClass);
8071
+ var i = getTiddlyLinkInfo(title,className);
7382
8072
  var btn = isStatic ? createExternalLink(place,store.getTiddlerText("SiteUrl",null) + "#" + title) : createTiddlyButton(place,text,i.subTitle,onClickTiddlerLink,i.classes);
7383
8073
  btn.setAttribute("refresh","link");
7384
8074
  btn.setAttribute("tiddlyLink",title);
@@ -7421,47 +8111,51 @@ function getTiddlyLinkInfo(title,currClasses)
7421
8111
  classes.remove("shadow");
7422
8112
  }
7423
8113
  }
7424
- if(config.annotations[title])
8114
+ if(typeof config.annotations[title]=="string")
7425
8115
  subTitle = config.annotations[title];
7426
8116
  return {classes: classes.join(" "),subTitle: subTitle};
7427
8117
  }
7428
8118
 
7429
8119
  function createExternalLink(place,url)
7430
8120
  {
7431
- var theLink = document.createElement("a");
7432
- theLink.className = "externalLink";
7433
- theLink.href = url;
7434
- theLink.title = config.messages.externalLinkTooltip.format([url]);
8121
+ var link = document.createElement("a");
8122
+ link.className = "externalLink";
8123
+ link.href = url;
8124
+ link.title = config.messages.externalLinkTooltip.format([url]);
7435
8125
  if(config.options.chkOpenInNewWindow)
7436
- theLink.target = "_blank";
7437
- place.appendChild(theLink);
7438
- return theLink;
8126
+ link.target = "_blank";
8127
+ place.appendChild(link);
8128
+ return link;
7439
8129
  }
7440
8130
 
7441
8131
  // Event handler for clicking on a tiddly link
7442
- function onClickTiddlerLink(e)
8132
+ function onClickTiddlerLink(ev)
7443
8133
  {
7444
- if(!e) e = window.event;
7445
- var theTarget = resolveTarget(e);
7446
- var theLink = theTarget;
8134
+ var e = ev ? ev : window.event;
8135
+ var target = resolveTarget(e);
8136
+ var link = target;
7447
8137
  var title = null;
7448
8138
  var fields = null;
7449
8139
  var noToggle = null;
7450
8140
  do {
7451
- title = theLink.getAttribute("tiddlyLink");
7452
- fields = theLink.getAttribute("tiddlyFields");
7453
- noToggle = theLink.getAttribute("noToggle");
7454
- theLink = theLink.parentNode;
7455
- } while(title == null && theLink != null);
7456
- if(!fields && !store.isShadowTiddler(title))
7457
- fields = String.encodeHashMap(config.defaultCustomFields);
8141
+ title = link.getAttribute("tiddlyLink");
8142
+ fields = link.getAttribute("tiddlyFields");
8143
+ noToggle = link.getAttribute("noToggle");
8144
+ link = link.parentNode;
8145
+ } while(title == null && link != null);
8146
+ if(!store.isShadowTiddler(title)) {
8147
+ var f = fields ? fields.decodeHashMap() : {};
8148
+ fields = String.encodeHashMap(merge(f,config.defaultCustomFields,true));
8149
+ }
7458
8150
  if(title) {
7459
8151
  var toggling = e.metaKey || e.ctrlKey;
7460
8152
  if(config.options.chkToggleLinks)
7461
8153
  toggling = !toggling;
7462
8154
  if(noToggle)
7463
8155
  toggling = false;
7464
- story.displayTiddler(theTarget,title,null,true,null,fields,toggling);
8156
+ if(store.getTiddler(title))
8157
+ fields = null;
8158
+ story.displayTiddler(target,title,null,true,null,fields,toggling);
7465
8159
  }
7466
8160
  clearMessage();
7467
8161
  return false;
@@ -7470,18 +8164,17 @@ function onClickTiddlerLink(e)
7470
8164
  // Create a button for a tag with a popup listing all the tiddlers that it tags
7471
8165
  function createTagButton(place,tag,excludeTiddler)
7472
8166
  {
7473
- var theTag = createTiddlyButton(place,tag,config.views.wikified.tag.tooltip.format([tag]),onClickTag);
7474
- theTag.setAttribute("tag",tag);
8167
+ var btn = createTiddlyButton(place,tag,config.views.wikified.tag.tooltip.format([tag]),onClickTag);
8168
+ btn.setAttribute("tag",tag);
7475
8169
  if(excludeTiddler)
7476
- theTag.setAttribute("tiddler",excludeTiddler);
7477
- return theTag;
8170
+ btn.setAttribute("tiddler",excludeTiddler);
8171
+ return btn;
7478
8172
  }
7479
8173
 
7480
8174
  // Event handler for clicking on a tiddler tag
7481
- function onClickTag(e)
8175
+ function onClickTag(ev)
7482
8176
  {
7483
- if(!e) var e = window.event;
7484
- var theTarget = resolveTarget(e);
8177
+ var e = ev ? ev : window.event;
7485
8178
  var popup = Popup.create(this);
7486
8179
  var tag = this.getAttribute("tag");
7487
8180
  var title = this.getAttribute("tiddler");
@@ -7515,21 +8208,18 @@ function onClickTag(e)
7515
8208
  }
7516
8209
 
7517
8210
  // Event handler for 'open all' on a tiddler popup
7518
- function onClickTagOpenAll(e)
8211
+ function onClickTagOpenAll(ev)
7519
8212
  {
7520
- if(!e) var e = window.event;
8213
+ var e = ev ? ev : window.event;
7521
8214
  var tag = this.getAttribute("tag");
7522
8215
  var tagged = store.getTaggedTiddlers(tag);
7523
- var titles = [];
7524
- for(var t=0; t<tagged.length; t++)
7525
- titles.push(tagged[t].title);
7526
- story.displayTiddlers(this,titles);
8216
+ story.displayTiddlers(this,tagged);
7527
8217
  return false;
7528
8218
  }
7529
8219
 
7530
- function onClickError(e)
8220
+ function onClickError(ev)
7531
8221
  {
7532
- if(!e) var e = window.event;
8222
+ var e = ev ? ev : window.event;
7533
8223
  var popup = Popup.create(this);
7534
8224
  var lines = this.getAttribute("errorText").split("\n");
7535
8225
  for(var t=0; t<lines.length; t++)
@@ -7564,9 +8254,9 @@ function createTiddlyPopup(place,caption,tooltip,tiddler)
7564
8254
  }
7565
8255
  }
7566
8256
 
7567
- function onClickTiddlyPopup(e)
8257
+ function onClickTiddlyPopup(ev)
7568
8258
  {
7569
- if(!e) var e = window.event;
8259
+ var e = ev ? ev : window.event;
7570
8260
  var tiddler = this.tiddler;
7571
8261
  if(tiddler.text) {
7572
8262
  var popup = Popup.create(this,"div","popupTiddler");
@@ -7626,6 +8316,8 @@ function glyph(name)
7626
8316
  return "";
7627
8317
  return g.codes[name][b];
7628
8318
  }
8319
+
8320
+
7629
8321
  //-
7630
8322
  //- Animation engine
7631
8323
  //-
@@ -7639,7 +8331,7 @@ function Animator()
7639
8331
  }
7640
8332
 
7641
8333
  // Start animation engine
7642
- Animator.prototype.startAnimating = function() // Variable number of arguments
8334
+ Animator.prototype.startAnimating = function() //# Variable number of arguments
7643
8335
  {
7644
8336
  for(var t=0; t<arguments.length; t++)
7645
8337
  this.animations.push(arguments[t]);
@@ -7666,7 +8358,6 @@ Animator.prototype.doAnimate = function(me)
7666
8358
  }
7667
8359
  };
7668
8360
 
7669
- // Map a 0..1 value to 0..1, but slow down at the start and end
7670
8361
  Animator.slowInSlowOut = function(progress)
7671
8362
  {
7672
8363
  return(1-((Math.cos(progress * Math.PI)+1)/2));
@@ -7829,10 +8520,9 @@ Popup.create = function(root,elem,theClass)
7829
8520
  return popup;
7830
8521
  };
7831
8522
 
7832
- Popup.onDocumentClick = function(e)
8523
+ Popup.onDocumentClick = function(ev)
7833
8524
  {
7834
- if (!e) var e = window.event;
7835
- var target = resolveTarget(e);
8525
+ var e = ev ? ev : window.event;
7836
8526
  if(e.eventPhase == undefined)
7837
8527
  Popup.remove();
7838
8528
  else if(e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET)
@@ -7868,7 +8558,7 @@ Popup.place = function(root,popup,offset)
7868
8558
  popup.style.left = popupLeft + "px";
7869
8559
  popup.style.top = popupTop + "px";
7870
8560
  popup.style.display = "block";
7871
- }
8561
+ };
7872
8562
 
7873
8563
  Popup.remove = function()
7874
8564
  {
@@ -8309,7 +8999,15 @@ Array.prototype.remove = function(item)
8309
8999
  this.splice(p,1);
8310
9000
  };
8311
9001
 
8312
- // Get characters from the right end of a string
9002
+ if(!Array.prototype.map){
9003
+ Array.prototype.map = function(fn, thisObj) {
9004
+ var scope = thisObj || window;
9005
+ var a = [];
9006
+ for ( var i=0, j=this.length; i < j; ++i ) {
9007
+ a.push(fn.call(scope, this[i], i, this));
9008
+ }
9009
+ return a;
9010
+ };}// Get characters from the right end of a string
8313
9011
  String.prototype.right = function(n)
8314
9012
  {
8315
9013
  return n < this.length ? this.slice(this.length-n) : this;
@@ -8498,13 +9196,15 @@ String.prototype.readBracketedList = function(unique)
8498
9196
  {
8499
9197
  var p = this.parseParams("list",null,false,true);
8500
9198
  var n = [];
8501
- for(var t=1; t<p.length; t++)
8502
- n.pushUnique(p[t].value,unique);
9199
+ for(var t=1; t<p.length; t++) {
9200
+ if(p[t].value)
9201
+ n.pushUnique(p[t].value,unique);
9202
+ }
8503
9203
  return n;
8504
9204
  };
8505
9205
 
8506
9206
  // Returns array with start and end index of chunk between given start and end marker, or undefined.
8507
- String.prototype.getChunkRange = function(start,end)
9207
+ String.prototype.getChunkRange = function(start,end)
8508
9208
  {
8509
9209
  var s = this.indexOf(start);
8510
9210
  if(s != -1) {
@@ -8578,7 +9278,7 @@ String.zeroPad = function(n,d)
8578
9278
  return s;
8579
9279
  };
8580
9280
 
8581
- String.prototype.startsWith = function(prefix)
9281
+ String.prototype.startsWith = function(prefix)
8582
9282
  {
8583
9283
  return !prefix || this.substring(0,prefix.length) == prefix;
8584
9284
  };
@@ -8635,7 +9335,7 @@ Date.prototype.getWeek = function()
8635
9335
  var d = dt.getDay();
8636
9336
  if (d==0) d=7;// JavaScript Sun=0, ISO Sun=7
8637
9337
  dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo
8638
- var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
9338
+ var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
8639
9339
  return Math.floor(n/7)+1;
8640
9340
  };
8641
9341
 
@@ -8692,143 +9392,6 @@ Date.convertFromYYYYMMDDHHMM = function(d)
8692
9392
  parseInt(d.substr(10,2),10),0,0));
8693
9393
  };
8694
9394
 
8695
- //--
8696
- //-- Crypto functions and associated conversion routines
8697
- //--
8698
-
8699
- // Crypto "namespace"
8700
- function Crypto() {}
8701
-
8702
- // Convert a string to an array of big-endian 32-bit words
8703
- Crypto.strToBe32s = function(str)
8704
- {
8705
- var be = Array();
8706
- var len = Math.floor(str.length/4);
8707
- var i, j;
8708
- for(i=0, j=0; i<len; i++, j+=4) {
8709
- be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
8710
- }
8711
- while (j<str.length) {
8712
- be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
8713
- j++;
8714
- }
8715
- return be;
8716
- };
8717
-
8718
- // Convert an array of big-endian 32-bit words to a string
8719
- Crypto.be32sToStr = function(be)
8720
- {
8721
- var str = "";
8722
- for(var i=0;i<be.length*32;i+=8)
8723
- str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
8724
- return str;
8725
- };
8726
-
8727
- // Convert an array of big-endian 32-bit words to a hex string
8728
- Crypto.be32sToHex = function(be)
8729
- {
8730
- var hex = "0123456789ABCDEF";
8731
- var str = "";
8732
- for(var i=0;i<be.length*4;i++)
8733
- str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
8734
- return str;
8735
- };
8736
-
8737
- // Return, in hex, the SHA-1 hash of a string
8738
- Crypto.hexSha1Str = function(str)
8739
- {
8740
- return Crypto.be32sToHex(Crypto.sha1Str(str));
8741
- };
8742
-
8743
- // Return the SHA-1 hash of a string
8744
- Crypto.sha1Str = function(str)
8745
- {
8746
- return Crypto.sha1(Crypto.strToBe32s(str),str.length);
8747
- };
8748
-
8749
- // Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
8750
- Crypto.sha1 = function(x,blen)
8751
- {
8752
- // Add 32-bit integers, wrapping at 32 bits
8753
- add32 = function(a,b)
8754
- {
8755
- var lsw = (a&0xFFFF)+(b&0xFFFF);
8756
- var msw = (a>>16)+(b>>16)+(lsw>>16);
8757
- return (msw<<16)|(lsw&0xFFFF);
8758
- };
8759
- // Add five 32-bit integers, wrapping at 32 bits
8760
- add32x5 = function(a,b,c,d,e)
8761
- {
8762
- var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
8763
- var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
8764
- return (msw<<16)|(lsw&0xFFFF);
8765
- };
8766
- // Bitwise rotate left a 32-bit integer by 1 bit
8767
- rol32 = function(n)
8768
- {
8769
- return (n>>>31)|(n<<1);
8770
- };
8771
-
8772
- var len = blen*8;
8773
- // Append padding so length in bits is 448 mod 512
8774
- x[len>>5] |= 0x80 << (24-len%32);
8775
- // Append length
8776
- x[((len+64>>9)<<4)+15] = len;
8777
- var w = Array(80);
8778
-
8779
- var k1 = 0x5A827999;
8780
- var k2 = 0x6ED9EBA1;
8781
- var k3 = 0x8F1BBCDC;
8782
- var k4 = 0xCA62C1D6;
8783
-
8784
- var h0 = 0x67452301;
8785
- var h1 = 0xEFCDAB89;
8786
- var h2 = 0x98BADCFE;
8787
- var h3 = 0x10325476;
8788
- var h4 = 0xC3D2E1F0;
8789
-
8790
- for(var i=0;i<x.length;i+=16) {
8791
- var j,t;
8792
- var a = h0;
8793
- var b = h1;
8794
- var c = h2;
8795
- var d = h3;
8796
- var e = h4;
8797
- for(j = 0;j<16;j++) {
8798
- w[j] = x[i+j];
8799
- t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
8800
- e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
8801
- }
8802
- for(j=16;j<20;j++) {
8803
- w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
8804
- t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
8805
- e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
8806
- }
8807
- for(j=20;j<40;j++) {
8808
- w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
8809
- t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
8810
- e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
8811
- }
8812
- for(j=40;j<60;j++) {
8813
- w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
8814
- t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
8815
- e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
8816
- }
8817
- for(j=60;j<80;j++) {
8818
- w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
8819
- t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
8820
- e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
8821
- }
8822
-
8823
- h0 = add32(h0,a);
8824
- h1 = add32(h1,b);
8825
- h2 = add32(h2,c);
8826
- h3 = add32(h3,d);
8827
- h4 = add32(h4,e);
8828
- }
8829
- return Array(h0,h1,h2,h3,h4);
8830
- };
8831
-
8832
9395
  //--
8833
9396
  //-- RGB colour object
8834
9397
  //--
@@ -8923,7 +9486,7 @@ function createTiddlyCheckbox(theParent,caption,checked,onChange)
8923
9486
  return cb;
8924
9487
  }
8925
9488
 
8926
- function createTiddlyElement(theParent,theElement,theID,theClass,theText)
9489
+ function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
8927
9490
  {
8928
9491
  var e = document.createElement(theElement);
8929
9492
  if(theClass != null)
@@ -8932,6 +9495,11 @@ function createTiddlyElement(theParent,theElement,theID,theClass,theText)
8932
9495
  e.setAttribute("id",theID);
8933
9496
  if(theText != null)
8934
9497
  e.appendChild(document.createTextNode(theText));
9498
+ if(attribs){
9499
+ for(var n in attribs){
9500
+ e.setAttribute(n,attribs[n]);
9501
+ }
9502
+ }
8935
9503
  if(theParent != null)
8936
9504
  theParent.appendChild(e);
8937
9505
  return e;
@@ -9015,6 +9583,14 @@ function resolveTarget(e)
9015
9583
  return obj;
9016
9584
  }
9017
9585
 
9586
+ // Prevent an event from bubbling
9587
+ function stopEvent(e){
9588
+ var ev = e? e : window.event;
9589
+ ev.cancelBubble = true;
9590
+ if (ev.stopPropagation) ev.stopPropagation();
9591
+ return false;
9592
+ }
9593
+
9018
9594
  // Return the content of an element as plain text with no formatting
9019
9595
  function getPlainText(e)
9020
9596
  {
@@ -9125,6 +9701,8 @@ function removeNode(e)
9125
9701
  // Remove any event handlers or non-primitve custom attributes
9126
9702
  function scrubNode(e)
9127
9703
  {
9704
+ if(!config.browser.isIE)
9705
+ return;
9128
9706
  var att = e.attributes;
9129
9707
  if(att) {
9130
9708
  for(var t=0; t<att.length; t++) {
@@ -9171,6 +9749,13 @@ function setStylesheet(s,id,doc)
9171
9749
  }
9172
9750
  }
9173
9751
 
9752
+ function removeStyleSheet(id)
9753
+ {
9754
+ var e = document.getElementById(id);
9755
+ if(e)
9756
+ e.parentNode.removeChild(e);
9757
+ }
9758
+
9174
9759
  // Force the browser to do a document reflow when needed to workaround browser bugs
9175
9760
  function forceReflow()
9176
9761
  {
@@ -9207,7 +9792,7 @@ function replaceSelection(e,text)
9207
9792
  // Returns the text of the given (text) node, possibly merging subsequent text nodes
9208
9793
  function getNodeText(e)
9209
9794
  {
9210
- var t = "";
9795
+ var t = "";
9211
9796
  while(e && e.nodeName == "#text") {
9212
9797
  t += e.nodeValue;
9213
9798
  e = e.nextSibling;
@@ -9351,94 +9936,6 @@ TW21Saver.prototype.externalizeTiddler = function(store,tiddler)
9351
9936
  }
9352
9937
  };
9353
9938
 
9354
- //--
9355
- //-- Deprecated code
9356
- //--
9357
-
9358
- // @Deprecated: Use createElementAndWikify and this.termRegExp instead
9359
- config.formatterHelpers.charFormatHelper = function(w)
9360
- {
9361
- w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
9362
- };
9363
-
9364
- // @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
9365
- config.formatterHelpers.monospacedByLineHelper = function(w)
9366
- {
9367
- var lookaheadRegExp = new RegExp(this.lookahead,"mg");
9368
- lookaheadRegExp.lastIndex = w.matchStart;
9369
- var lookaheadMatch = lookaheadRegExp.exec(w.source);
9370
- if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
9371
- var text = lookaheadMatch[1];
9372
- if(config.browser.isIE)
9373
- text = text.replace(/\n/g,"\r");
9374
- createTiddlyElement(w.output,"pre",null,null,text);
9375
- w.nextMatch = lookaheadRegExp.lastIndex;
9376
- }
9377
- };
9378
-
9379
- // @Deprecated: Use <br> or <br /> instead of <<br>>
9380
- config.macros.br.handler = function(place)
9381
- {
9382
- createTiddlyElement(place,"br");
9383
- };
9384
-
9385
- // Find an entry in an array. Returns the array index or null
9386
- // @Deprecated: Use indexOf instead
9387
- Array.prototype.find = function(item)
9388
- {
9389
- var i = this.indexOf(item);
9390
- return i == -1 ? null : i;
9391
- };
9392
-
9393
- // Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
9394
- // @Deprecated: Use store.getLoader().internalizeTiddler instead
9395
- Tiddler.prototype.loadFromDiv = function(divRef,title)
9396
- {
9397
- return store.getLoader().internalizeTiddler(store,this,title,divRef);
9398
- };
9399
-
9400
- // Format the text for storage in an HTML DIV
9401
- // @Deprecated Use store.getSaver().externalizeTiddler instead.
9402
- Tiddler.prototype.saveToDiv = function()
9403
- {
9404
- return store.getSaver().externalizeTiddler(store,this);
9405
- };
9406
-
9407
- // @Deprecated: Use store.allTiddlersAsHtml() instead
9408
- function allTiddlersAsHtml()
9409
- {
9410
- return store.allTiddlersAsHtml();
9411
- }
9412
-
9413
- // @Deprecated: Use refreshPageTemplate instead
9414
- function applyPageTemplate(title)
9415
- {
9416
- refreshPageTemplate(title);
9417
- }
9418
-
9419
- // @Deprecated: Use story.displayTiddlers instead
9420
- function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
9421
- {
9422
- story.displayTiddlers(srcElement,titles,template,animate);
9423
- }
9424
-
9425
- // @Deprecated: Use story.displayTiddler instead
9426
- function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
9427
- {
9428
- story.displayTiddler(srcElement,title,template,animate);
9429
- }
9430
-
9431
- // @Deprecated: Use functions on right hand side directly instead
9432
- var createTiddlerPopup = Popup.create;
9433
- var scrollToTiddlerPopup = Popup.show;
9434
- var hideTiddlerPopup = Popup.remove;
9435
-
9436
- // @Deprecated: Use right hand side directly instead
9437
- var regexpBackSlashEn = new RegExp("\\\\n","mg");
9438
- var regexpBackSlash = new RegExp("\\\\","mg");
9439
- var regexpBackSlashEss = new RegExp("\\\\s","mg");
9440
- var regexpNewLine = new RegExp("\n","mg");
9441
- var regexpCarriageReturn = new RegExp("\r","mg");
9442
9939
  //--
9443
9940
  //-- End of scripts
9444
9941
  //--
@@ -9451,7 +9948,6 @@ if(useJavaSaver)
9451
9948
  //]]>
9452
9949
  </script>
9453
9950
  <!--POST-SCRIPT-START-->
9454
-
9455
9951
  <!--POST-SCRIPT-END-->
9456
9952
  </body>
9457
9953
  </html>