mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-26 01:50:28 +00:00
13212 lines
568 KiB
HTML
13212 lines
568 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|||
|
<head>
|
|||
|
<script id="versionArea" type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
var version = {title: "TiddlyWiki", major: 2, minor: 6, revision: 5, date: new Date("October 6, 2011"), extensions: {}};
|
|||
|
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
|
|||
|
<meta name="copyright" content="
|
|||
|
TiddlyWiki created by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)
|
|||
|
|
|||
|
Copyright (c) Jeremy Ruston 2004-2007
|
|||
|
Copyright (c) UnaMesa Association 2007-2011
|
|||
|
|
|||
|
Redistribution and use in source and binary forms, with or without modification,
|
|||
|
are permitted provided that the following conditions are met:
|
|||
|
|
|||
|
Redistributions of source code must retain the above copyright notice, this
|
|||
|
list of conditions and the following disclaimer.
|
|||
|
|
|||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
|||
|
list of conditions and the following disclaimer in the documentation and/or other
|
|||
|
materials provided with the distribution.
|
|||
|
|
|||
|
Neither the name of the UnaMesa Association nor the names of its contributors may be
|
|||
|
used to endorse or promote products derived from this software without specific
|
|||
|
prior written permission.
|
|||
|
|
|||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND ANY
|
|||
|
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|||
|
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
|||
|
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|||
|
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|||
|
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|||
|
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
|||
|
DAMAGE.
|
|||
|
|
|||
|
" />
|
|||
|
<!--PRE-HEAD-START-->
|
|||
|
<!--{{{-->
|
|||
|
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
|
|||
|
<!--}}}-->
|
|||
|
|
|||
|
<!--PRE-HEAD-END-->
|
|||
|
<title>
|
|||
|
|
|||
|
</title>
|
|||
|
<style id="styleArea" type="text/css">
|
|||
|
#saveTest {display:none;}
|
|||
|
#messageArea {display:none;}
|
|||
|
#copyright {display:none;}
|
|||
|
#storeArea {display:none;}
|
|||
|
#storeArea div {padding:0.5em; margin:1em 0em 0em 0em; border-color:#fff #666 #444 #ddd; border-style:solid; border-width:2px; overflow:auto;}
|
|||
|
#shadowArea {display:none;}
|
|||
|
#javascriptWarning {width:100%; text-align:center; font-weight:bold; background-color:#dd1100; color:#fff; padding:1em 0em;}
|
|||
|
|
|||
|
</style>
|
|||
|
<!--POST-HEAD-START-->
|
|||
|
|
|||
|
<!--POST-HEAD-END-->
|
|||
|
</head>
|
|||
|
<body onload="main();" onunload="if(window.unload) unload();">
|
|||
|
<!--PRE-BODY-START-->
|
|||
|
|
|||
|
<!--PRE-BODY-END-->
|
|||
|
<div id="copyright">
|
|||
|
Welcome to TiddlyWiki created by Jeremy Ruston; Copyright © 2004-2007 Jeremy Ruston, Copyright © 2007-2011 UnaMesa Association
|
|||
|
</div>
|
|||
|
<noscript>
|
|||
|
|
|||
|
</noscript>
|
|||
|
<div id="saveTest"></div>
|
|||
|
<div id="backstageCloak"></div>
|
|||
|
<div id="backstageButton"></div>
|
|||
|
<div id="backstageArea"><div id="backstageToolbar"></div></div>
|
|||
|
<div id="backstage">
|
|||
|
<div id="backstagePanel"></div>
|
|||
|
</div>
|
|||
|
<div id="contentWrapper"></div>
|
|||
|
<div id="contentStash"></div>
|
|||
|
<div id="shadowArea">
|
|||
|
<div title="ColorPalette">
|
|||
|
<pre>Background: #fff
|
|||
|
Foreground: #000
|
|||
|
PrimaryPale: #8cf
|
|||
|
PrimaryLight: #18f
|
|||
|
PrimaryMid: #04b
|
|||
|
PrimaryDark: #014
|
|||
|
SecondaryPale: #ffc
|
|||
|
SecondaryLight: #fe8
|
|||
|
SecondaryMid: #db4
|
|||
|
SecondaryDark: #841
|
|||
|
TertiaryPale: #eee
|
|||
|
TertiaryLight: #ccc
|
|||
|
TertiaryMid: #999
|
|||
|
TertiaryDark: #666
|
|||
|
Error: #f88
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div title="EditTemplate">
|
|||
|
<pre><!--{{{-->
|
|||
|
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
|
|||
|
<div class='title' macro='view title'></div>
|
|||
|
<div class='editor' macro='edit title'></div>
|
|||
|
<div macro='annotations'></div>
|
|||
|
<div class='editor' macro='edit text'></div>
|
|||
|
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
|
|||
|
<!--}}}--></pre>
|
|||
|
</div>
|
|||
|
<div title="GettingStarted">
|
|||
|
<pre>To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
|
|||
|
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
|
|||
|
* [[MainMenu]]: The menu (usually on the left)
|
|||
|
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
|
|||
|
You'll also need to enter your username for signing your edits: <<option txtUserName>></pre>
|
|||
|
</div>
|
|||
|
<div title="ImportTiddlers">
|
|||
|
<pre><<importTiddlers>></pre>
|
|||
|
</div>
|
|||
|
<div title="MarkupPreHead">
|
|||
|
<pre><!--{{{-->
|
|||
|
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
|
|||
|
<!--}}}-->
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div title="OptionsPanel">
|
|||
|
<pre>These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser
|
|||
|
|
|||
|
Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])
|
|||
|
|
|||
|
<<option txtUserName>>
|
|||
|
<<option chkSaveBackups>> [[SaveBackups]]
|
|||
|
<<option chkAutoSave>> [[AutoSave]]
|
|||
|
<<option chkRegExpSearch>> [[RegExpSearch]]
|
|||
|
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
|
|||
|
<<option chkAnimate>> [[EnableAnimations]]
|
|||
|
|
|||
|
----
|
|||
|
Also see [[AdvancedOptions]]</pre>
|
|||
|
</div>
|
|||
|
<div title="PageTemplate">
|
|||
|
<pre><!--{{{-->
|
|||
|
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
|
|||
|
<div class='headerShadow'>
|
|||
|
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
|
|||
|
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
|
|||
|
</div>
|
|||
|
<div class='headerForeground'>
|
|||
|
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
|
|||
|
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
|
|||
|
<div id='sidebar'>
|
|||
|
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
|
|||
|
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
|
|||
|
</div>
|
|||
|
<div id='displayArea'>
|
|||
|
<div id='messageArea'></div>
|
|||
|
<div id='tiddlerDisplay'></div>
|
|||
|
</div>
|
|||
|
<!--}}}--></pre>
|
|||
|
</div>
|
|||
|
<div title="StyleSheetColors">
|
|||
|
<pre>/*{{{*/
|
|||
|
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
|
|||
|
|
|||
|
a {color:[[ColorPalette::PrimaryMid]];}
|
|||
|
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
|
|||
|
a img {border:0;}
|
|||
|
|
|||
|
h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
|
|||
|
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
|
|||
|
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}
|
|||
|
|
|||
|
.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
|
|||
|
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
|
|||
|
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}
|
|||
|
|
|||
|
.header {background:[[ColorPalette::PrimaryMid]];}
|
|||
|
.headerShadow {color:[[ColorPalette::Foreground]];}
|
|||
|
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
|
|||
|
.headerForeground {color:[[ColorPalette::Background]];}
|
|||
|
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}
|
|||
|
|
|||
|
.tabSelected {color:[[ColorPalette::PrimaryDark]];
|
|||
|
background:[[ColorPalette::TertiaryPale]];
|
|||
|
border-left:1px solid [[ColorPalette::TertiaryLight]];
|
|||
|
border-top:1px solid [[ColorPalette::TertiaryLight]];
|
|||
|
border-right:1px solid [[ColorPalette::TertiaryLight]];
|
|||
|
}
|
|||
|
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
|
|||
|
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
|
|||
|
.tabContents .button {border:0;}
|
|||
|
|
|||
|
#sidebar {}
|
|||
|
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
|
|||
|
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
|
|||
|
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
|
|||
|
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
|
|||
|
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}
|
|||
|
|
|||
|
.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
|
|||
|
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
|
|||
|
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
|
|||
|
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
|
|||
|
border:1px solid [[ColorPalette::PrimaryMid]];}
|
|||
|
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
|
|||
|
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
|
|||
|
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
|
|||
|
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
|
|||
|
border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
|
|||
|
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
|
|||
|
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
|
|||
|
border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}
|
|||
|
|
|||
|
.wizard .notChanged {background:transparent;}
|
|||
|
.wizard .changedLocally {background:#80ff80;}
|
|||
|
.wizard .changedServer {background:#8080ff;}
|
|||
|
.wizard .changedBoth {background:#ff8080;}
|
|||
|
.wizard .notFound {background:#ffff80;}
|
|||
|
.wizard .putToServer {background:#ff80ff;}
|
|||
|
.wizard .gotFromServer {background:#80ffff;}
|
|||
|
|
|||
|
#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
|
|||
|
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}
|
|||
|
|
|||
|
.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}
|
|||
|
|
|||
|
.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
|
|||
|
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
|
|||
|
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
|
|||
|
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
|
|||
|
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
|
|||
|
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
|
|||
|
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
|
|||
|
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.tiddler .defaultCommand {font-weight:bold;}
|
|||
|
|
|||
|
.shadow .title {color:[[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.title {color:[[ColorPalette::SecondaryDark]];}
|
|||
|
.subtitle {color:[[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.toolbar {color:[[ColorPalette::PrimaryMid]];}
|
|||
|
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
|
|||
|
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
|
|||
|
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}
|
|||
|
|
|||
|
.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
|
|||
|
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
|
|||
|
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
|
|||
|
.tagging .button, .tagged .button {border:none;}
|
|||
|
|
|||
|
.footer {color:[[ColorPalette::TertiaryLight]];}
|
|||
|
.selected .footer {color:[[ColorPalette::TertiaryMid]];}
|
|||
|
|
|||
|
.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
|
|||
|
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
|
|||
|
.lowlight {background:[[ColorPalette::TertiaryLight]];}
|
|||
|
|
|||
|
.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}
|
|||
|
|
|||
|
.imageLink, #displayArea .imageLink {background:transparent;}
|
|||
|
|
|||
|
.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}
|
|||
|
|
|||
|
.viewer .listTitle {list-style-type:none; margin-left:-2em;}
|
|||
|
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
|
|||
|
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
|
|||
|
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
|
|||
|
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
|
|||
|
.viewer code {color:[[ColorPalette::SecondaryDark]];}
|
|||
|
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}
|
|||
|
|
|||
|
.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}
|
|||
|
|
|||
|
.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
|
|||
|
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
|
|||
|
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
|
|||
|
.readOnly {background:[[ColorPalette::TertiaryPale]];}
|
|||
|
|
|||
|
#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
|
|||
|
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
|
|||
|
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
|
|||
|
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
|
|||
|
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
|
|||
|
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
|
|||
|
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
|
|||
|
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
|
|||
|
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
|
|||
|
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:alpha(opacity=60);}
|
|||
|
/*}}}*/</pre>
|
|||
|
</div>
|
|||
|
<div title="StyleSheetLayout">
|
|||
|
<pre>/*{{{*/
|
|||
|
* html .tiddler {height:1%;}
|
|||
|
|
|||
|
body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}
|
|||
|
|
|||
|
h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
|
|||
|
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
|
|||
|
h4,h5,h6 {margin-top:1em;}
|
|||
|
h1 {font-size:1.35em;}
|
|||
|
h2 {font-size:1.25em;}
|
|||
|
h3 {font-size:1.1em;}
|
|||
|
h4 {font-size:1em;}
|
|||
|
h5 {font-size:.9em;}
|
|||
|
|
|||
|
hr {height:1px;}
|
|||
|
|
|||
|
a {text-decoration:none;}
|
|||
|
|
|||
|
dt {font-weight:bold;}
|
|||
|
|
|||
|
ol {list-style-type:decimal;}
|
|||
|
ol ol {list-style-type:lower-alpha;}
|
|||
|
ol ol ol {list-style-type:lower-roman;}
|
|||
|
ol ol ol ol {list-style-type:decimal;}
|
|||
|
ol ol ol ol ol {list-style-type:lower-alpha;}
|
|||
|
ol ol ol ol ol ol {list-style-type:lower-roman;}
|
|||
|
ol ol ol ol ol ol ol {list-style-type:decimal;}
|
|||
|
|
|||
|
.txtOptionInput {width:11em;}
|
|||
|
|
|||
|
#contentWrapper .chkOptionInput {border:0;}
|
|||
|
|
|||
|
.externalLink {text-decoration:underline;}
|
|||
|
|
|||
|
.indent {margin-left:3em;}
|
|||
|
.outdent {margin-left:3em; text-indent:-3em;}
|
|||
|
code.escaped {white-space:nowrap;}
|
|||
|
|
|||
|
.tiddlyLinkExisting {font-weight:bold;}
|
|||
|
.tiddlyLinkNonExisting {font-style:italic;}
|
|||
|
|
|||
|
/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
|
|||
|
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}
|
|||
|
|
|||
|
#mainMenu .tiddlyLinkExisting,
|
|||
|
#mainMenu .tiddlyLinkNonExisting,
|
|||
|
#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
|
|||
|
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}
|
|||
|
|
|||
|
.header {position:relative;}
|
|||
|
.header a:hover {background:transparent;}
|
|||
|
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
|
|||
|
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0; top:0;}
|
|||
|
|
|||
|
.siteTitle {font-size:3em;}
|
|||
|
.siteSubtitle {font-size:1.2em;}
|
|||
|
|
|||
|
#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}
|
|||
|
|
|||
|
#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
|
|||
|
#sidebarOptions {padding-top:0.3em;}
|
|||
|
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
|
|||
|
#sidebarOptions input {margin:0.4em 0.5em;}
|
|||
|
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
|
|||
|
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
|
|||
|
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
|
|||
|
#sidebarTabs .tabContents {width:15em; overflow:hidden;}
|
|||
|
|
|||
|
.wizard {padding:0.1em 1em 0 2em;}
|
|||
|
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
|
|||
|
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
|
|||
|
.wizardStep {padding:1em 1em 1em 1em;}
|
|||
|
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
|
|||
|
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
|
|||
|
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
|
|||
|
.wizard .button {padding:0.1em 0.2em;}
|
|||
|
|
|||
|
#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
|
|||
|
.messageToolbar {display:block; text-align:right; padding:0.2em;}
|
|||
|
#messageArea a {text-decoration:underline;}
|
|||
|
|
|||
|
.tiddlerPopupButton {padding:0.2em;}
|
|||
|
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}
|
|||
|
|
|||
|
.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
|
|||
|
.popup .popupMessage {padding:0.4em;}
|
|||
|
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
|
|||
|
.popup li.disabled {padding:0.4em;}
|
|||
|
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
|
|||
|
.listBreak {font-size:1px; line-height:1px;}
|
|||
|
.listBreak div {margin:2px 0;}
|
|||
|
|
|||
|
.tabset {padding:1em 0 0 0.5em;}
|
|||
|
.tab {margin:0 0 0 0.25em; padding:2px;}
|
|||
|
.tabContents {padding:0.5em;}
|
|||
|
.tabContents ul, .tabContents ol {margin:0; padding:0;}
|
|||
|
.txtMainTab .tabContents li {list-style:none;}
|
|||
|
.tabContents li.listLink { margin-left:.75em;}
|
|||
|
|
|||
|
#contentWrapper {display:block;}
|
|||
|
#splashScreen {display:none;}
|
|||
|
|
|||
|
#displayArea {margin:1em 17em 0 14em;}
|
|||
|
|
|||
|
.toolbar {text-align:right; font-size:.9em;}
|
|||
|
|
|||
|
.tiddler {padding:1em 1em 0;}
|
|||
|
|
|||
|
.missing .viewer,.missing .title {font-style:italic;}
|
|||
|
|
|||
|
.title {font-size:1.6em; font-weight:bold;}
|
|||
|
|
|||
|
.missing .subtitle {display:none;}
|
|||
|
.subtitle {font-size:1.1em;}
|
|||
|
|
|||
|
.tiddler .button {padding:0.2em 0.4em;}
|
|||
|
|
|||
|
.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
|
|||
|
.isTag .tagging {display:block;}
|
|||
|
.tagged {margin:0.5em; float:right;}
|
|||
|
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
|
|||
|
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
|
|||
|
.tagClear {clear:both;}
|
|||
|
|
|||
|
.footer {font-size:.9em;}
|
|||
|
.footer li {display:inline;}
|
|||
|
|
|||
|
.annotation {padding:0.5em; margin:0.5em;}
|
|||
|
|
|||
|
* html .viewer pre {width:99%; padding:0 0 1em 0;}
|
|||
|
.viewer {line-height:1.4em; padding-top:0.5em;}
|
|||
|
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
|
|||
|
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
|
|||
|
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}
|
|||
|
|
|||
|
.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
|
|||
|
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
|
|||
|
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
|
|||
|
table.listView th, table.listView td, table.listView tr {padding:0 3px 0 3px;}
|
|||
|
|
|||
|
.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
|
|||
|
.viewer code {font-size:1.2em; line-height:1.4em;}
|
|||
|
|
|||
|
.editor {font-size:1.1em;}
|
|||
|
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
|
|||
|
.editorFooter {padding:0.25em 0; font-size:.9em;}
|
|||
|
.editorFooter .button {padding-top:0; padding-bottom:0;}
|
|||
|
|
|||
|
.fieldsetFix {border:0; padding:0; margin:1px 0px;}
|
|||
|
|
|||
|
.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
|
|||
|
.zoomer div {padding:1em;}
|
|||
|
|
|||
|
* html #backstage {width:99%;}
|
|||
|
* html #backstageArea {width:99%;}
|
|||
|
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
|
|||
|
#backstageToolbar {position:relative;}
|
|||
|
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
|
|||
|
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
|
|||
|
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
|
|||
|
#backstage {position:relative; width:100%; z-index:50;}
|
|||
|
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
|
|||
|
.backstagePanelFooter {padding-top:0.2em; float:right;}
|
|||
|
.backstagePanelFooter a {padding:0.2em 0.4em;}
|
|||
|
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
|
|||
|
|
|||
|
.whenBackstage {display:none;}
|
|||
|
.backstageVisible .whenBackstage {display:block;}
|
|||
|
/*}}}*/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div title="StyleSheetLocale">
|
|||
|
<pre>/***
|
|||
|
StyleSheet for use when a translation requires any css style changes.
|
|||
|
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
|
|||
|
***/
|
|||
|
/*{{{*/
|
|||
|
body {font-size:0.8em;}
|
|||
|
#sidebarOptions {font-size:1.05em;}
|
|||
|
#sidebarOptions a {font-style:normal;}
|
|||
|
#sidebarOptions .sliderPanel {font-size:0.95em;}
|
|||
|
.subtitle {font-size:0.8em;}
|
|||
|
.viewer table.listView {font-size:0.95em;}
|
|||
|
/*}}}*/</pre>
|
|||
|
</div>
|
|||
|
<div title="StyleSheetPrint">
|
|||
|
<pre>/*{{{*/
|
|||
|
@media print {
|
|||
|
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
|
|||
|
#displayArea {margin: 1em 1em 0em;}
|
|||
|
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
|
|||
|
}
|
|||
|
/*}}}*/</pre>
|
|||
|
</div>
|
|||
|
<div title="ViewTemplate">
|
|||
|
<pre><!--{{{-->
|
|||
|
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
|
|||
|
<div class='title' macro='view title'></div>
|
|||
|
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
|
|||
|
<div class='tagging' macro='tagging'></div>
|
|||
|
<div class='tagged' macro='tags'></div>
|
|||
|
<div class='viewer' macro='view text wikified'></div>
|
|||
|
<div class='tagClear'></div>
|
|||
|
<!--}}}--></pre>
|
|||
|
</div>
|
|||
|
|
|||
|
</div>
|
|||
|
<!--POST-SHADOWAREA-->
|
|||
|
<div id="storeArea">
|
|||
|
<div created="201102111106" creator="psd" modified="201102111306" modifier="blaine" tags="systemServer" title="AbegoSoftwareServer">
|
|||
|
<pre>|''URL:''|http://tiddlywiki.abego-software.de/|
|
|||
|
|''Description:''|UdoBorkowski's Extensions for TiddlyWiki|
|
|||
|
|''Author:''|UdoBorkowski|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031801" modifier="jermolene" tags="help" title="Advanced download options">
|
|||
|
<pre>When you click on the [[download|Download]] button, the website will detect your browser and operating system, and trigger a download for either an empty ~TiddlyWiki file or, if you're running [[Safari]] or [[Opera]], a zip file which also includes the TiddlySaver file. This is version <<version>> of ~TiddlyWiki.
|
|||
|
|
|||
|
Advanced users may find these download options helpful (right click the link and select "Save as" to download):
|
|||
|
*[[An empty TiddlyWiki file|http://www.tiddlywiki.com/empty.html]]
|
|||
|
*[[A zip file containing an empty TiddlyWiki file plus a TiddlySaver file|http://www.tiddlywiki.com/empty.zip]]
|
|||
|
*[[A copy of this website (TiddlyWiki.com) minus images|#]]
|
|||
|
*[[The TiddlySaver.jar file on its own|http://www.tiddlywiki.com/TiddlySaver.jar]]
|
|||
|
Finally, these links may be useful:
|
|||
|
*[[Downloading]] instructions for the main browsers
|
|||
|
*A list of supported [[Browsers]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="examples" title="AnotherExampleStyleSheet">
|
|||
|
<pre>This tiddler shows some more complex effects that can be obtained with cunning use of CSS. Not all of these will work properly on all browsers because of differences in CSS implementation, but they should fail gracefully.
|
|||
|
|
|||
|
You can have special formatting for a specific, named tiddler like this:
|
|||
|
{{{
|
|||
|
#tiddlerHelloThere .title {
|
|||
|
background-color: #99aaee;
|
|||
|
}
|
|||
|
}}}
|
|||
|
|
|||
|
Or for the first displayed tiddler:
|
|||
|
{{{
|
|||
|
div.tiddler:first-child .title {
|
|||
|
font-size: 28pt;
|
|||
|
}
|
|||
|
}}}
|
|||
|
|
|||
|
Or just for the first line of every tiddler:
|
|||
|
{{{
|
|||
|
.viewer:first-line {
|
|||
|
background-color: #999999;
|
|||
|
}
|
|||
|
}}}
|
|||
|
|
|||
|
Or just for the first letter of every tiddler:
|
|||
|
{{{
|
|||
|
.viewer:first-letter {
|
|||
|
float: left;
|
|||
|
font-size: 28pt;
|
|||
|
font-weight: bold;
|
|||
|
}
|
|||
|
}}}
|
|||
|
|
|||
|
Or just for tiddlers tagged with a particular tag (note that this won't work for tags that contain spaces):
|
|||
|
{{{
|
|||
|
div[tags~="welcome"].tiddler .viewer {
|
|||
|
background-color: #ffccaa;
|
|||
|
}
|
|||
|
|
|||
|
div[tags~="features"].tiddler .viewer {
|
|||
|
background-color: #88aaff;
|
|||
|
}
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features options" title="AutoSave">
|
|||
|
<pre>If you check this box in the InterfaceOptions, TiddlyWiki will automatically SaveChanges every time you edit a tiddler. In that way there's a lot less chance of you losing any information.
|
|||
|
|
|||
|
However, if you also have the SaveBackups checkbox ticked, you'll end up with a lot of archived files. You may prefer to select either one or the other.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211427" modifier="colmbritton" tags="features" title="BackstageArea">
|
|||
|
<pre>One of the great strengths of TiddlyWiki is the way that its interface can be customised by editting various shadow tiddlers. However, a problem that has consistently emerged is the difficulty of reconciling the needs of authors, who need access to the full array of TiddlyWiki features, and the needs of ordinary readers, who generally benefit from seeing a restricted set of functionality more suited to their needs.
|
|||
|
|
|||
|
The new backstage area in release 2.2 offers a solution to this conundrum by providing a consistent way of accessing authoring functionality that is independent of the interface customisations (so, even if you blast away the contents of your PageTemplate, you can still access the backstage area).
|
|||
|
|
|||
|
The backstage area is only available when a TiddlyWiki is edittable - typically meaning that it's been opened off of a {{{file://}}} URL. It appears as an unobtrusive link in the topright corner of the page. Clicking it reveals the backstage toolbar consisting of commands like {{{saveChanges}}} and drop-down tasks like ImportTiddlers, SyncMacro, PluginManager and Tweak (which provides access to the new [[options macro]]).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111425" creator="matt" modified="201102151515" modifier="psd" tags="formatting" title="Basic Formatting">
|
|||
|
<pre>|Style|Formatting|h
|
|||
|
|''bold''|{{{''bold''}}} - two single-quotes, not a double-quote|
|
|||
|
|//italics//|{{{//italics//}}}|
|
|||
|
|''//bold italics//''|{{{''//bold italics//''}}}|
|
|||
|
|__underline__|{{{__underline__}}}|
|
|||
|
|--strikethrough--|{{{--Strikethrough--}}}|
|
|||
|
|super^^script^^|{{{super^^script^^}}}|
|
|||
|
|sub~~script~~|{{{sub~~script~~}}}|
|
|||
|
|@@Highlight@@|{{{@@Highlight@@}}}|
|
|||
|
|{{{plain text}}}|{{{ {{{PlainText No ''Formatting''}}} }}}|
|
|||
|
|/%this text will be invisible%/hidden text|{{{/%this text will be invisible%/}}}|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="BidiXTWServer">
|
|||
|
<pre>|''URL:''|http://tiddlywiki.bidix.info/|
|
|||
|
|''Description:''|Repository for BidiX's TiddlyWiki Extensions|
|
|||
|
|''Author:''|BidiX|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161206" modifier="colmbritton" tags="systemServer" title="BobsPluginsServer">
|
|||
|
<pre>|''URL:''|http://bob.mcelrath.org/plugins.html|
|
|||
|
|''Description:''|Bob ~McElrath's Plugins|
|
|||
|
|''Author:''|~BobMcElrath|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110311138" modifier="jermolene" tags="features" title="Browsers">
|
|||
|
<pre>Here is a table of web browsers that work with ~TiddlyWiki:
|
|||
|
|
|||
|
|!Browser |!Version |!Allows changes to be saved locally?|
|
|||
|
|InternetExplorer |6.0+ |Yes |
|
|||
|
|FireFox |1.0+ |Yes |
|
|||
|
|[[Safari]] |1.0+ |Yes, using TiddlySaver plugin|
|
|||
|
|[[Opera]] |? |Yes, using TiddlySaver plugin|
|
|||
|
|Netscape Navigator |7.0+ |Yes |
|
|||
|
|[[Camino]] |1.0+ |Yes |
|
|||
|
|[[Chrome]] |All |Yes, using TiddlySaver plugin|
|
|||
|
|[[iPhone]] |All |Yes, using [[iTW|http://www.apple.com/webapps/productivity/itwatiddlywikiforiphone.html]]|
|
|||
|
|[[Wii]] |All |No |
|
|||
|
|
|||
|
See also the [[TiddlyWiki apps available for smartphones|MobileDevices]].
|
|||
|
|
|||
|
Please [[let us know|http://groups.google.com/group/TiddlyWiki]] of any additions or corrections.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111426" creator="matt" modified="201111031822" modifier="jermolene" tags="formatting" title="CSS Formatting">
|
|||
|
<pre>!!Inline Styles
|
|||
|
Apply CSS properties inline:
|
|||
|
{{{
|
|||
|
@@color:#4bbbbb;Some random text@@
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
@@color:#4bbbbb;Some random text@@
|
|||
|
!!CSS classes
|
|||
|
CSS classes can be applied to text blocks or runs. This form creates an HTML {{{<span>}}}:
|
|||
|
{{{
|
|||
|
{{customClassName{Some random text}}}
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
{{customClassName{Some random text}}}
|
|||
|
This form generates an HTML {{{<div>}}}:
|
|||
|
{{{
|
|||
|
{{customClassName{
|
|||
|
Some random text
|
|||
|
}}}
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
{{customClassName{
|
|||
|
Some random text
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102211414" creator="matt" modifier="matt" title="CamelCase">
|
|||
|
<pre>CamelCase (camel case or camel-case)—also known as medial capitals—is the practice of writing compound words or phrases in which the elements are joined without spaces.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="browsers" title="Camino">
|
|||
|
<pre>The Mozilla-based [[Camino browser|http://www.caminobrowser.org/]] on Macintosh OS X works well with TiddlyWiki, including the ability to SaveChanges.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="CancelTiddlerCommand">
|
|||
|
<pre>Abandons any pending edits to the current tiddler, and switches it the default view. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar cancelTiddler>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="troubleshooting" title="CharacterEncoding">
|
|||
|
<pre>When you upload a TiddlyWiki to a web server, if doesn't load properly, it may be a CharacterEncoding issue.
|
|||
|
|
|||
|
TiddlyWiki uses Unicode ~UTF-8 encoding and won't load properly if your host is serving it as ~ISO-8859-1. You should be able to check this by loading another page on the server in FireFox and selecting 'Page Info' on the 'Tools' menu.
|
|||
|
|
|||
|
If this is the case, it should be reasonably easy to sort out. We recommend that you contact your server host and ask them to serve it in ~UTF-8 mode. If you are more technically hands-on, you may be able to [[solve the issue yourself|http://www.w3.org/International/questions/qa-htaccess-charset]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="browsers issues" title="Chrome">
|
|||
|
<pre>~TiddlyWiki works well in Google Chrome and Chromium using [[TiddlySaver]].
|
|||
|
However, due to Chrome's [[lack of Java support on Mac OS and Linux|http://groups.google.com/group/tiddlywiki/browse_thread/thread/1f0e299198573e89]], it currently cannot save on those platforms.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="CloseOthersCommand">
|
|||
|
<pre>Closes all other open tiddlers, except for any that are being editted. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar closeOthers>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="CloseTiddlerCommand">
|
|||
|
<pre>Closes the current tiddler, regardless of whether it is being editted. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar closeTiddler>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111426" creator="matt" modified="201102161148" modifier="colmbritton" tags="formatting" title="Code Formatting">
|
|||
|
<pre>Text such as computer code that should be displayed without wiki processing and preserving line breaks:
|
|||
|
&#123;&#123;&#123;
|
|||
|
Some plain text including WikiLinks
|
|||
|
&#125;&#125;&#125;
|
|||
|
Displays as:
|
|||
|
{{{
|
|||
|
Some plain text including WikiLinks
|
|||
|
}}}
|
|||
|
!See Also
|
|||
|
[[Suppressing Formatting]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201110201351" creator="jermolene" modifier="jermolene" title="ColorPalette">
|
|||
|
<pre>Background: #fff
|
|||
|
Foreground: #000
|
|||
|
PrimaryPale: #aef
|
|||
|
PrimaryLight: #8ad
|
|||
|
PrimaryMid: #38c
|
|||
|
PrimaryDark: #026
|
|||
|
SecondaryPale: #ffc
|
|||
|
SecondaryLight: #fe8
|
|||
|
SecondaryMid: #db4
|
|||
|
SecondaryDark: #841
|
|||
|
TertiaryPale: #eee
|
|||
|
TertiaryLight: #ccc
|
|||
|
TertiaryMid: #999
|
|||
|
TertiaryDark: #666
|
|||
|
QuaternaryPale: #cf8
|
|||
|
QuaternaryLight: #8f1
|
|||
|
QuaternaryMid: #4b0
|
|||
|
QuaternaryDark: #140
|
|||
|
Error: #f88
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111436" creator="matt" modified="201102151510" modifier="matt" tags="shadow" title="ColorPalette shadows">
|
|||
|
<pre>This tiddler determines the colour scheme used within the TiddlyWiki. When a new space is created the random color palette macro determines the default, however these can be overwritten directly in the ColorPalette tiddler.
|
|||
|
|
|||
|
{{{
|
|||
|
Background: #e0e3f5
|
|||
|
Foreground: #090d1e
|
|||
|
PrimaryPale: #b9c2e8
|
|||
|
PrimaryLight: #7485d2
|
|||
|
PrimaryMid: #384fb1
|
|||
|
PrimaryDark: #0c1126
|
|||
|
SecondaryPale: #cbe8b9
|
|||
|
SecondaryLight: #98d274
|
|||
|
SecondaryMid: #67b138
|
|||
|
SecondaryDark: #16260c
|
|||
|
TertiaryPale: #e8bab9
|
|||
|
TertiaryLight: #d27574
|
|||
|
TertiaryMid: #b13a38
|
|||
|
TertiaryDark: #260c0c
|
|||
|
Error: #f88
|
|||
|
ColorPaletteParameters: HSL([229|48], [0.5146822107288709],[0.1|0.8208696653333263])
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031650" modifier="jermolene" tags="community help" title="Community">
|
|||
|
<pre>[>img[tiddlywiki.org logo|http://trac.tiddlywiki.org/chrome/site/tworg_logo_med.jpg][http://www.tiddlywiki.org]]~TiddlyWiki today is the result of the efforts of dozens of people around the world generously contributing their time and skill, and offering considerable help and support.
|
|||
|
|
|||
|
The community has several hubs for different activities:
|
|||
|
* The DiscussionForums on Google Groups
|
|||
|
* The ~TiddlyWiki IRC room at irc://irc.freenode.net/TiddlyWiki
|
|||
|
* TiddlyWiki code at http://github.com/TiddlyWiki/tiddlywiki
|
|||
|
* TiddlyWiki issue tracker at https://github.com/TiddlyWiki/tiddlywiki/issues
|
|||
|
* The community wiki at http://tiddlywiki.org/
|
|||
|
|
|||
|
The community welcomes [[contributions|Contribute]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="includeNew" title="Configuration">
|
|||
|
<pre>PageTemplate
|
|||
|
|>|>|SiteTitle - SiteSubtitle|
|
|||
|
|MainMenu|DefaultTiddlers<br><br><br><br>ViewTemplate<br><br>EditTemplate|SideBarOptions|
|
|||
|
|~|~|OptionsPanel|
|
|||
|
|~|~|AdvancedOptions|
|
|||
|
|~|~|<<tiddler Configuration.SideBarTabs>>|
|
|||
|
|
|||
|
''StyleSheet:'' StyleSheetColors - StyleSheetLayout - StyleSheetPrint
|
|||
|
|
|||
|
InterfaceOptions
|
|||
|
|
|||
|
SiteUrl
|
|||
|
|
|||
|
Extensive StartupParameters to control the startup beahviour of ~TiddlyWiki through specially crafted ~URLs
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="Configuration.SideBarTabs">
|
|||
|
<pre>SideBarTabs
|
|||
|
|[[Timeline|TabTimeline]]|[[All|TabAll]]|[[Tags|TabTags]]|>|>|[[More|TabMore]] |
|
|||
|
|>|>||[[Missing|TabMoreMissing]]|[[Orphans|TabMoreOrphans]]|[[Shadowed|TabMoreShadowed]]|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="ContentsSlider">
|
|||
|
<pre>@@margin-left:.5em;<<slider chkContents SideBarTabs "contents »" "show
|
|||
|
lists of tiddlers contained in this document">>@@
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="Contribute">
|
|||
|
<pre>~TiddlyWiki has an enthusiastic and friendly [[Community|Help and Support]] of people around the world helping to grow and improve it. But there's always more to do and we welcome any offers of assistance. There are many ways that you can help:
|
|||
|
* Testing and [[reporting bugs|http://trac.tiddlywiki.org/wiki/ReportingBugs]] against the core code. Clear, easily reproducible bug reports are incredibly useful and really help the team improve the quality of ~TiddlyWiki
|
|||
|
* [[Contributing code|http://trac.tiddlywiki.org/wiki/ContributingCode]]
|
|||
|
* [[Making translations|http://trac.tiddlywiki.org/wiki/Translations]]
|
|||
|
* Documentation needs planning, writing and editing, particularly user guide information at http://www.tiddlywiki.org
|
|||
|
If you would like to make a financial contribution, ~TiddlyWiki is owned by the not-for-profit [[UnaMesa Foundation|http://www.unamesa.org/]] which welcomes donations.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="CustomMarkup">
|
|||
|
<pre>Sometimes it's necessary to include custom HTML markup in the {{{<head>}}} of a TiddlyWiki file - typically for compatibility with ad serving software, external libraries, or for custom meta tags. The CustomMarkup operation defines four shadow tiddlers whose contents are spliced into the saved HTML file. (If you do a view/source you'll see the markers referred to below).
|
|||
|
|!Title |!Location |!Marker |
|
|||
|
|MarkupPreHead |Start of the {{{<head>}}} section |{{{<!--PRE-HEAD-START-->}}} |
|
|||
|
|MarkupPostHead |End of the {{{<head>}}} section |{{{<!--POST-HEAD-START-->}}} |
|
|||
|
|MarkupPreBody |Start of the {{{<body>}}} section |{{{<!--PRE-BODY-START-->}}} |
|
|||
|
|MarkupPostBody |End of the {{{<body>}}} section |{{{<!--POST-BODY-START-->}}} |
|
|||
|
MarkupPreHead is the only one with shadow content: a link to the default location of the RSS feed.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="features" title="CustomStyleSheet">
|
|||
|
<pre>You can skin TiddlyWiki with a special StyleSheet tiddler containing your own CSS style sheet declarations. Unlike hacking the HTML directly, the StyleSheet tiddler withstands upgrading to a new version of the TiddlyWiki code (see HowToUpgrade). You can also use the NestedStyleSheets feature to structure your CSS declarations.
|
|||
|
|
|||
|
The ExampleStyleSheet shows some of the basic options you can control (see AnotherExampleStyleSheet for more complex examples). SaveChanges and then click refresh in your browser to see StyleSheet changes. Any errors in your CSS syntax will be caught and displayed, but they shouldn't stop TiddlyWiki from working.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031733" modifier="jermolene" title="Customisation">
|
|||
|
<pre>You can customise the appearance and behaviour of TiddlyWiki to almost any degree you want:
|
|||
|
* Install [[Plugins]] to extend the core functionality
|
|||
|
* Use the ColorPalette to change the basic colour scheme
|
|||
|
* Use built in [[Formatting|Basic Formatting]] techniques
|
|||
|
* Create a CustomStyleSheet for finer grained control over the appearance
|
|||
|
* Customise the PageTemplate, ViewTemplate or EditTemplate to change the composition of the page and the layout of individual tiddlers
|
|||
|
* Further SpecialTiddlers
|
|||
|
* Use off-the-shelf themes from [[TiddlyThemes|http://tiddlythemes.com/]]
|
|||
|
* Visit the [[Configuration]] summary to see all the special configuration tiddlers
|
|||
|
* Use TiddlyBookmarklets for low level hacking of TiddlyWiki documents
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102161139" creator="colmbritton" modified="201102211415" modifier="matt" title="Date Formats">
|
|||
|
<pre>Several [[Macros|MacrosContent]] including the [[Today Macro|today macro]] take a [[Date Format String|Date Formats]] as an optional argument. This string can be a combination of ordinary text, with some special characters that get substituted by parts of the date:
|
|||
|
* {{{DDD}}} - day of week in full (eg, "Monday")
|
|||
|
* {{{ddd}}} - short day of week (eg, "Mon")
|
|||
|
* {{{DD}}} - day of month
|
|||
|
* {{{0DD}}} - adds a leading zero
|
|||
|
* {{{DDth}}} - adds a suffix
|
|||
|
* {{{WW}}} - ~ISO-8601 week number of year
|
|||
|
* {{{0WW}}} - adds a leading zero
|
|||
|
* {{{MMM}}} - month in full (eg, "July")
|
|||
|
* {{{mmm}}} - short month (eg, "Jul")
|
|||
|
* {{{MM}}} - month number
|
|||
|
* {{{0MM}}} - adds leading zero
|
|||
|
* {{{YYYY}}} - full year
|
|||
|
* {{{YY}}} - two digit year
|
|||
|
* {{{wYYYY}}} - full year with respect to week number
|
|||
|
* {{{wYY}}} two digit year with respect to week number
|
|||
|
* {{{hh}}} - hours
|
|||
|
* {{{0hh}}} - adds a leading zero
|
|||
|
* {{{hh12}}} - hours in 12 hour clock
|
|||
|
* {{{0hh12}}} - hours in 12 hour clock with leading zero
|
|||
|
* {{{mm}}} - minutes
|
|||
|
* {{{0mm}}} - minutes with leading zero
|
|||
|
* {{{ss}}} - seconds
|
|||
|
* {{{0ss}}} - seconds with leading zero
|
|||
|
* {{{am}}} or {{{pm}}} - lower case AM/PM indicator
|
|||
|
* {{{AM}}} or {{{PM}}} - upper case AM/PM indicator
|
|||
|
|
|||
|
!!!!Examples
|
|||
|
{{{DDth MMM YYYY}}} - 16th February 2011
|
|||
|
{{{DDth mmm hh:mm:ss}}} - 16th Feb 2011 11:38:42
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" title="DefaultTiddlers">
|
|||
|
<pre>HelloThere GettingStarted [[TiddlyWiki Browser Compatibility]] Raves Examples
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111436" creator="matt" modified="201102151510" modifier="matt" tags="shadow" title="DefaultTiddlers shadows">
|
|||
|
<pre>This tiddler contains a list of tiddlers that are opened automatically when you load the tiddlywiki.
|
|||
|
The default is:
|
|||
|
{{{
|
|||
|
[[GettingStarted]]
|
|||
|
}}}
|
|||
|
|
|||
|
An example could be:
|
|||
|
{{{
|
|||
|
[[HelloThere]]
|
|||
|
[[Reference]]
|
|||
|
[[Features]]
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="DeleteTiddlerCommand">
|
|||
|
<pre>Deletes the current tiddler. A confirmation dialogue is displayed unless disabled with the ConfirmBeforeDeleting checkbox in AdvancedOptions. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar deleteTiddler>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201111031824" modifier="jermolene" tags="community help" title="DeveloperDocumentation">
|
|||
|
<pre>TiddlyWiki developer documentation is being built up at http://tiddlywikidev.tiddlyspace.com/.
|
|||
|
|
|||
|
Michael Mahemoff has written a very helpful outline of the architecture of ~TiddlyWiki: [[Part 1|http://softwareas.com/tiddlywiki-internals-1-of-3-architectural-concepts]], [[Part 2|http://softwareas.com/tiddlywiki-internals-2-of-3-list-of-javascript-files]] and [[Part 3|http://softwareas.com/tiddlywiki-internals-3-of-3-key-javascript-classes-and-files]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201110201351" modifier="jermolene" tags="community help" title="DiscussionForums">
|
|||
|
<pre>There are two Google Group discussion forums for discussions about ~TiddlyWiki, whether basic entry level questions or more complex development challenges. They are the best places to ask questions about ~TiddlyWiki, and to connect with other enthusiasts:
|
|||
|
* A ~TiddlyWiki group for general discussion, bug reports and announcements at http://groups.google.com/group/TiddlyWiki
|
|||
|
* A ~TiddlyWikiDev group for discussion about ~TiddlyWiki development at http://groups.google.com/group/TiddlyWikiDev
|
|||
|
!~Non-English resources
|
|||
|
There are a number of resources for non-English language speakers:
|
|||
|
* ~TiddlyWikiFR, in French, at http://groups.google.com/group/TiddlyWikiFR
|
|||
|
* ~TiddlyWiki 華語支援論壇, in Chinese, at http://groups.google.com/group/TiddlyWiki-zh
|
|||
|
* A guide to [[TiddlyWiki in Japanese|http://www.geocities.jp/potto372/tiddlywiki/tiddlywikinote.html]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031824" modifier="jermolene" tags="gettingstarted" title="Download">
|
|||
|
<pre><<download>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111121" creator="psd" modified="201111031807" modifier="jermolene" tags="systemConfig" title="DownloadTiddlyWikiPlugin">
|
|||
|
<pre>/***
|
|||
|
|''Name:''|DownloadTiddlyWikiPlugin|
|
|||
|
|''Description:''|Download TiddlyWiki according to browser type|
|
|||
|
|''Version:''|0.0.8|
|
|||
|
|''Date:''|Aug 26, 2008|
|
|||
|
|''Source:''|http://www.tiddlywiki.com/#DownloadTiddlyWikiPlugin|
|
|||
|
|''License:''|[[BSD open source license]]|
|
|||
|
|''~CoreVersion:''|2.4.1|
|
|||
|
***/
|
|||
|
|
|||
|
//{{{
|
|||
|
if(!version.extensions.DownloadTiddlyWikiPlugin) {
|
|||
|
version.extensions.DownloadTiddlyWikiPlugin = {installed:true};
|
|||
|
|
|||
|
config.macros.download = {};
|
|||
|
|
|||
|
merge(config.macros.download,{
|
|||
|
label: "download",
|
|||
|
prompt: "Download TiddlyWiki",
|
|||
|
className: "chunkyButton"});
|
|||
|
|
|||
|
config.macros.download.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var span = createTiddlyElement(place,"span",null,this.className);
|
|||
|
createTiddlyButton(span,params[0]||this.label,params[1]||this.prompt,this.onClick);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.download.onClick = function(ev)
|
|||
|
{
|
|||
|
// display the tiddler containing the instructions
|
|||
|
var e = ev || window.event;
|
|||
|
var title = "Downloading";
|
|||
|
var url = config.browser.isSafari || config.browser.isOpera ? 'http://www.tiddlywiki.com/empty.zip' :'http://www.tiddlywiki.com/empty.download';
|
|||
|
if(config.browser.isOpera || config.browser.isWindows) {
|
|||
|
story.displayTiddler(target,title);
|
|||
|
window.setTimeout(function() {document.location.href = url;},300);
|
|||
|
} else {
|
|||
|
// put an iframe in the target instructions tiddler to start the download
|
|||
|
var html = '<html><iframe src="' + url + '" style="display:none"></html>';
|
|||
|
var tiddler = store.getTiddler(title);
|
|||
|
var oldText = tiddler.text;
|
|||
|
tiddler.text = html + tiddler.text;
|
|||
|
var target = resolveTarget(e);
|
|||
|
story.closeTiddler(title,true);
|
|||
|
story.displayTiddler(target,title);
|
|||
|
tiddler.text = oldText;
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
} //# end of 'install only once'
|
|||
|
//}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031807" modifier="jermolene" tags="instructions" title="Downloading">
|
|||
|
<pre>The following downloading guidelines have been created to cover the vast majority of browsers and operating systems.
|
|||
|
|
|||
|
If you are still having trouble downloading ~TiddlyWiki after checking these guidelines, check the [[list of browsers|Browsers]] to make sure your browser and operating system are supported. And you can always [[turn to the community|Help and Support]] for help!
|
|||
|
!Downloading guidelines
|
|||
|
[[Firefox on Mac OS X|Downloading guidelines: Firefox on Mac OS X]]
|
|||
|
[[Firefox on Windows Vista|Downloading guidelines: Firefox on Windows Vista]]
|
|||
|
[[Firefox on Windows XP|Downloading guidelines: Firefox on Windows XP]]
|
|||
|
[[Firefox on Ubuntu|Downloading guidelines: Firefox on Ubuntu]]
|
|||
|
[[Internet Explorer on Windows Vista|Downloading guidelines: Internet Explorer on Windows Vista]]
|
|||
|
[[Internet Explorer on Windows XP|Downloading guidelines: Internet Explorer on Windows XP]]
|
|||
|
[[Safari on Mac OS X|Downloading guidelines: Safari on Mac OS X]]
|
|||
|
[[Opera on Mac OS X|Downloading guidelines: Opera on Mac OS X]]
|
|||
|
|
|||
|
For unusual or custom deployments, have a look at [[advanced download options|Advanced download options]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031757" modifier="jermolene" title="Downloading guidelines: Firefox on Mac OS X">
|
|||
|
<pre>Follow these easy steps to get started. Note that these guidelines are for Firefox v3.0.1 running on Mac OS X 10.5.4.
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or Documents folder. Make sure you keep the .html file extension and leave the "Save As: Hypertext" default option as it is.
|
|||
|
[img[images/step1mac.jpg]]
|
|||
|
!Step 2 - Download complete
|
|||
|
Empty ~TiddlyWiki files are very small, and download should be completed quickly. You can now either launch the file from the download pane (shown below, double click on the file name to launch), or open your finder to open the file from there.
|
|||
|
[img[images/step2mac.jpg]]
|
|||
|
!Step 3 - Open file
|
|||
|
You'll be asked if you're sure you want to open the file - click "Open".
|
|||
|
[img[images/step3mac.jpg]]
|
|||
|
!Step 4 - Grant authority
|
|||
|
When you try to save your changes for the first time, Firefox may ask you to grant access to the file system. You will need to 'Allow' this for ~TiddlyWiki changes to be saved, and we recommend you tick the 'Remember this decision' checkbox so this dialogue box doesn't appear each time.
|
|||
|
|
|||
|
[img[images/step4mac.jpg]]
|
|||
|
|
|||
|
!Step 5 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031758" modifier="jermolene" title="Downloading guidelines: Firefox on Ubuntu">
|
|||
|
<pre>Follow these easy steps to get started! Note that these guidelines are for Firefox v3.0.1 running on Ubuntu version 8.0.4 (Hardy Heron).
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or Documents folder. Make sure you keep the file type as HTML Document.
|
|||
|
|
|||
|
[img[images/step1ubuntu.png]]
|
|||
|
!Step 2 - Download complete
|
|||
|
Empty ~TiddlyWiki files are very small, and download should be completed quickly. You can now either launch the file from the download pane (shown below, double click on the file name to launch), or open your finder to open the file from there.
|
|||
|
|
|||
|
[img[images/step2ubuntu.png]]
|
|||
|
|
|||
|
!Step 3 - Grant authority
|
|||
|
When you try to save your changes for the first time, Firefox may ask you to grant access to the file system. You will need to 'Allow' this for ~TiddlyWiki changes to be saved, and we recommend you tick the 'Remember this decision' checkbox so this dialogue box doesn't appear each time.
|
|||
|
|
|||
|
[img[images/step3ubuntu.png]]
|
|||
|
|
|||
|
!Step 4 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031758" modifier="jermolene" title="Downloading guidelines: Firefox on Windows">
|
|||
|
<pre><<tiddler [[Downloading guidelines: Firefox on Windows Vista]]>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031809" modifier="jermolene" title="Downloading guidelines: Firefox on Windows Vista">
|
|||
|
<pre>Follow these steps to get started! These guidelines are for Firefox 3.0.1 running on Microsoft Windows Vista 6.0.0. Hopefully they will be helpful for your setup too.
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or Documents folder. Make sure you leave the "Save as type: HTML Document" default option as it is. Then click 'Save'.
|
|||
|
|
|||
|
[img[images/step1vistaff.jpg]]
|
|||
|
!Step 2 - Open file
|
|||
|
Click on the file name in the Download dialogue box. This will open your ~TiddlyWiki file, and you'll be able to start editing immediately - but you'll need to complete Step 3 below to save your changes.
|
|||
|
|
|||
|
[img[images/step2vistaff.jpg]]
|
|||
|
!Step 3 - Enable advanced features
|
|||
|
When you try to save changes for the first time in a browser session, this dialogue box will appear. These features will enable the saving mechanism. Tick the 'Remember this decision' checkbox and then click on 'Allow'.
|
|||
|
|
|||
|
[img[images/step3vistaff.jpg]]
|
|||
|
!Step 4 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031810" modifier="jermolene" title="Downloading guidelines: Firefox on Windows XP">
|
|||
|
<pre>Follow these steps to get started! These guidelines are for Firefox 3.0.1 running on Microsoft Windows XP, Service Pack 3. Hopefully they will be helpful for your setup too.
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or My Documents folder. Make sure you leave the "Save as type: Firefox Document" default option as it is. Then click 'Save'.
|
|||
|
|
|||
|
[img[images/step1xpff.jpg]]
|
|||
|
!Step 2 - Open file
|
|||
|
Double click on the file name in the Download dialogue box, shown below. This will open your ~TiddlyWiki file, and you'll be able to start editing immediately - but you'll need to complete Step 3 below to save your changes.
|
|||
|
|
|||
|
[img[images/step2xpff.jpg]]
|
|||
|
!Step 3 - Enable advanced features
|
|||
|
When you try to save changes for the first time in a browser session, this dialogue box will appear. These features will enable the saving mechanism. Tick the 'Remember this decision' checkbox and then click on 'Allow'.
|
|||
|
[img[images/step3xpff.jpg]]
|
|||
|
!Step 4 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031759" modifier="jermolene" title="Downloading guidelines: Internet Explorer on Windows">
|
|||
|
<pre><<tiddler [[Downloading guidelines: Internet Explorer on Windows Vista]]>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031759" modifier="jermolene" title="Downloading guidelines: Internet Explorer on Windows Vista">
|
|||
|
<pre>Follow these steps to get started! These guidelines are for Internet Explorer 7.0 running on Microsoft Windows Vista 6.0.0. Hopefully they will be helpful for your setup too.
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or Documents folder. Make sure you leave the "Save as type: HTML Document" default option as it is. Then click 'Save'.
|
|||
|
|
|||
|
[img[images/step1vista.jpg]]
|
|||
|
!Step 2 - Open folder
|
|||
|
Once the download has been completed, ''don't open the file yet'' - a minor modification is required before ~TiddlyWiki will work! Click on 'Open Folder'.
|
|||
|
|
|||
|
[img[images/step2vista.jpg]]
|
|||
|
!Step 3 - Modify properties
|
|||
|
In the folder, right click on the file name and select 'Properties' from the bottom of the contextual menu.
|
|||
|
|
|||
|
[img[images/step3vista.jpg]]
|
|||
|
!Step 4 - Unblock file
|
|||
|
In order to allow saving, you need to Unblock the file. Select 'Unblock' near the bottom of the dialogue box, then click on 'OK'. If the Unblock button doesn't appear, then you don't need to worry about it - click on OK and proceed to step 5.
|
|||
|
|
|||
|
[img[images/step4vista.jpg]]
|
|||
|
|
|||
|
!Step 5 - Open file
|
|||
|
Double click on the file name to open the file. Internet Explorer takes special care to block javascript from untrusted sources, so a screen will appear with a yellow bar at the top and a warning in red. Click on the yellow bar (this will make it turn blue, as shown below), and select 'Allow Blocked Content...'.
|
|||
|
|
|||
|
[img[images/step5vista.jpg]]
|
|||
|
|
|||
|
!Step 6 - Allow active content
|
|||
|
~TiddlyWiki contains 'active content' that, for example, allows search and tagging to function. Approve this active content by clicking on 'Yes'.
|
|||
|
[img[images/step6vista.jpg]]
|
|||
|
!Step 7 - Enable saving mechanism
|
|||
|
One final hurdle! When you save for the first time, you'll be prompted to allow the activity. Click on 'Yes'.
|
|||
|
[img[images/step7vista.jpg]]
|
|||
|
!Step 8 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031800" modifier="jermolene" title="Downloading guidelines: Internet Explorer on Windows XP">
|
|||
|
<pre>Follow these steps to get started! These guidelines are for Internet Explorer 7.0 running on Microsoft Windows XP, Service Pack 3. Hopefully they will be helpful for your setup too.
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download file
|
|||
|
You'll need to choose a name and location for your empty ~TiddlyWiki file - we recommend either your Desktop or My Documents folder. Make sure you leave the "Save as type: HTML Document" default option as it is. Then click 'Save'.
|
|||
|
|
|||
|
[img[images/step1xpie.jpg]]
|
|||
|
!Step 2 - Open folder
|
|||
|
Once the download has been completed, ''don't open the file yet'' - a minor modification is required before ~TiddlyWiki will work! ''Click on 'Open Folder'''.
|
|||
|
|
|||
|
[img[images/step2xpie.jpg]]
|
|||
|
!Step 3 - Modify properties
|
|||
|
In the folder, right click on the file name and select 'Properties' from the bottom of the contextual menu.
|
|||
|
|
|||
|
[img[images/step3xpie.jpg]]
|
|||
|
!Step 4 - Unblock file
|
|||
|
In order to allow saving, you need to Unblock the file. Select 'Unblock' near the bottom of the dialogue box, then click on 'OK'. If the Unblock button doesn't appear, then you don't need to worry about it - click on OK and proceed to step 5.
|
|||
|
|
|||
|
[img[images/step4xpie.jpg]]
|
|||
|
|
|||
|
!Step 5 - Open file
|
|||
|
Now you've unblocked the file, you can double click on the file name to open the file. Internet Explorer takes special care to block javascript from untrusted sources, so a screen will appear with a yellow bar at the top and a warning in red. Click on the yellow bar (this will make it turn blue, as shown below), and select 'Allow Blocked Content...'.
|
|||
|
|
|||
|
[img[images/step5xpie.jpg]]
|
|||
|
!Step 6 - Allow active content
|
|||
|
~TiddlyWiki contains 'active content' that, for example, allows animations to function. Approve this active content by clicking on 'Yes'.
|
|||
|
[img[images/step6xpie.jpg]]
|
|||
|
!Step 7 - Enable saving mechanism
|
|||
|
One final hurdle! When you save for the first time, you'll be prompted to allow the activity. Click on 'Yes'.
|
|||
|
[img[images/step7xpie.jpg]]
|
|||
|
!Step 8 - You're ready to start!
|
|||
|
You're now ready to start playing with your ~TiddlyWiki file - be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031800" modifier="jermolene" title="Downloading guidelines: Opera on Mac OS X">
|
|||
|
<pre>Follow these easy steps to get started! Note that these guidelines are for Opera 9.5.1 running on Mac OS X 10.5.4, but will apply to several other configurations (including most other versions of [[Opera]])
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Download files
|
|||
|
Download the zip file to a location of your choice.
|
|||
|
|
|||
|
[img[images/step1macopera.jpg]]
|
|||
|
!Step 2 - Check files
|
|||
|
Open the zip file, and then check in the resulting folder that you have automatically received two files:
|
|||
|
*empty.html (this is your ~TiddlyWiki file)
|
|||
|
*~TiddlySaver.jar (this is a java applet, which will make sure everything works in your chosen browser. Note a copy of this file ''must'' be kept in the same folder as any ~TiddlyWiki file you are using)
|
|||
|
[img[images/step2macopera.jpg]]
|
|||
|
You can download the TiddlySaver file on it's own from [[here|http://www.tiddlywiki.com/TiddlySaver.jar]] if you need it.
|
|||
|
|
|||
|
Open the empty.html file to get started.
|
|||
|
!Step 3 - Trust applet
|
|||
|
The ~TiddlySaver.jar applet has been signed by [[UnaMesa|http://www.unamesa.org]], who hold the rights to ~TiddlyWiki on behalf of the community. You can find out more about the applet itself [[here|TiddlySaver]], and you'll need to click on 'Trust' in order for the ~TiddlyWiki to work. If you've accidentally clicked on 'Don't Trust' previously, don't worry - just restart the browser and you should get asked again.
|
|||
|
|
|||
|
[img[images/step3macopera.jpg]]
|
|||
|
!Step 4 - You're done!
|
|||
|
Thanks to the applet, you now have the full functionality of ~TiddlyWiki at your disposal. Be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031800" modifier="jermolene" title="Downloading guidelines: Safari on Mac OS X">
|
|||
|
<pre>Follow these easy steps to get started! Note that these guidelines are for Safari 3.1.2 running on Mac OS X 10.5.4, but will apply to several other configurations (other versions of [[Safari]] and [[Opera]] too)
|
|||
|
|
|||
|
''If these guidelines aren't appropriate, check the [[other browser-specific guidelines|Downloading]] to find some that are right for you.''
|
|||
|
!Step 1 - Check downloaded files
|
|||
|
After [[Download]], check first that you have automatically received a zip file containing two files (the contents of the zip file may have been extracted automatically - if not, open the zip file):
|
|||
|
*empty.html (this is your ~TiddlyWiki file)
|
|||
|
*~TiddlySaver.jar (this is a java applet, which will make sure everything works in your chosen browser. Note a copy of this file ''must'' be kept in the same folder as any ~TiddlyWiki file you are using)
|
|||
|
[img[images/step1macsafari.jpg]]
|
|||
|
You can download the ~TiddlySaver.jar file on it's own from [[here|http://www.tiddlywiki.com/TiddlySaver.jar]] if you need it.
|
|||
|
|
|||
|
Double click the empty.html file to get started.
|
|||
|
!Step 2 - Open file
|
|||
|
The system will check you're happy to open the ~TiddlyWiki file. Click on 'Open'.
|
|||
|
|
|||
|
[img[images/step2macsafari.jpg]]
|
|||
|
!Step 3 - Trust applet
|
|||
|
The ~TiddlySaver.jar applet has been signed by [[UnaMesa|http://www.unamesa.org]], who hold the rights to ~TiddlyWiki on behalf of the community. You can find out more about the applet itself [[here|TiddlySaver]], and you'll need to click on 'Trust' in order for the ~TiddlyWiki to work. If you've accidentally clicked on 'Don't Trust' previously, don't worry - just restart the browser and you should get asked again.
|
|||
|
|
|||
|
[img[images/step3macsafari.jpg]]
|
|||
|
!Step 4 - You're done!
|
|||
|
Thanks to the applet, you now have the full functionality of ~TiddlyWiki at your disposal. Be sure to check out the guidelines in [[Getting Started|GettingStarted]]!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111437" creator="matt" modified="201102151511" modifier="matt" tags="shadow" title="EditTemplate shadows">
|
|||
|
<pre>This tiddler contains the markup used to display tiddlers in edit mode. It is designed to make it easy to change the layout/structure of the tiddler in edit mode.
|
|||
|
By default it contains the following markup:
|
|||
|
{{{
|
|||
|
<div class='toolbar'
|
|||
|
macro='toolbar [[ToolbarCommands::EditToolbar]] icons:yes'>
|
|||
|
</div>
|
|||
|
<div class='heading editorHeading'>
|
|||
|
<div class='editor title' macro='edit title'></div>
|
|||
|
<div class='tagClear'></div>
|
|||
|
</div>
|
|||
|
<div class='annotationsBox' macro='annotations'>
|
|||
|
<div class='editSpaceSiteIcon'
|
|||
|
macro='tiddlerOrigin height:16 width:16 label:no interactive:no'>
|
|||
|
</div>
|
|||
|
<div class="privacyEdit" macro='setPrivacy label:no interactive:no'></div>
|
|||
|
<div class='tagClear'></div>
|
|||
|
</div>
|
|||
|
<div class='editor' macro='edit text'></div>
|
|||
|
<div class='editorFooter'>
|
|||
|
<div class='tagTitle'>tags</div>
|
|||
|
<div class='editor' macro='edit tags'></div>
|
|||
|
<div class='tagAnnotation'>
|
|||
|
<span macro='message views.editor.tagPrompt'></span>
|
|||
|
<span macro='tagChooser excludeLists'></span>
|
|||
|
</div>
|
|||
|
</div>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="EditTiddlerCommand">
|
|||
|
<pre>Switches the current tiddler to the current edit view. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar editTiddler>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031824" modifier="jermolene" tags="gettingstarted" title="Editing">
|
|||
|
<pre>~TiddlyWiki is made up of chunks of information called tiddlers. You're reading a tiddler called 'Editing' right now.
|
|||
|
|
|||
|
When you open an empty ~TiddlyWiki file for the first time, you'll be presented with a tiddler called "~GettingStarted". This contains links to tiddlers to help you define the main attributes of your ~TiddlyWiki; the Title, SubTitle and MainMenu navigation (see [[Configuration]]).
|
|||
|
|
|||
|
You will notice that each tiddler has a command menu in it's top right corner (''close'', ''edit'', and so on). You can use this to switch the tiddler into edit mode, or if you prefer you can simply double click the tiddler when it is in view mode. When you are finished, click on ''done'', or ''cancel'' to discard your changes.
|
|||
|
|
|||
|
You can sign your edits with your username, which is currently set to <<option txtUserName>>. You can change it here, or in the right hand sidebar, where it can be found under [[options »|InterfaceOptions]].
|
|||
|
|
|||
|
There are two ways to make links between tiddlers. If you are linking to a tiddler which already exists, put the tiddler name in double square brackets (Double click here, and you'll see double square brackets around the word [[example]]). You can use this technique to point to (and create) a new tiddler, or alternatively just write the tiddler name by joining words starting with capital letters, LikeThis. When you save the tiddler and click on the link, you can then add content to your new tiddler.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111121" creator="psd" modified="201102111310" modifier="blaine" tags="systemConfig" title="ExamplePlugin">
|
|||
|
<pre>/***
|
|||
|
|''Name:''|ExamplePlugin|
|
|||
|
|''Description:''|To demonstrate how to write TiddlyWiki plugins|
|
|||
|
|''Version:''|2.0.3|
|
|||
|
|''Date:''|Sep 22, 2006|
|
|||
|
|''Source:''|http://www.tiddlywiki.com/#ExamplePlugin|
|
|||
|
|''Author:''|JeremyRuston (jeremy (at) osmosoft (dot) com)|
|
|||
|
|''License:''|[[BSD open source license]]|
|
|||
|
|''~CoreVersion:''|2.1.0|
|
|||
|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|
|||
|
***/
|
|||
|
|
|||
|
//{{{
|
|||
|
|
|||
|
// Uncomment the following line to see how the PluginManager deals with errors in plugins
|
|||
|
// deliberateError();
|
|||
|
|
|||
|
// Log a message
|
|||
|
pluginInfo.log.push("This is a test message from " + tiddler.title);
|
|||
|
|
|||
|
//}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="examples" title="ExampleStyleSheet">
|
|||
|
<pre>#displayArea {background-color: #ffccff; }
|
|||
|
#mainMenu {border: 1px solid #ffff88; }
|
|||
|
#commandPanel {background-color: #008800; }
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211428" modifier="colmbritton" tags="examples" title="ExampleSystemConfig">
|
|||
|
<pre>config.animFast = 0.12; // Speed for animations (lower == slower)
|
|||
|
config.animSlow = 0.01; // Speed for Easter Egg animations
|
|||
|
config.views.wikified.toolbarEdit.text = "Edit away, it won't get saved";
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111051455" modifier="jermolene" tags="community" title="Examples">
|
|||
|
<pre>See Dave Gifford's incredibly detailed catalogue of TiddlyWiki being used in the wild in his [[TiddlyWikiShowcase|http://giffmex.tiddlyspot.com/]].
|
|||
|
|
|||
|
Other notable or interesting examples:
|
|||
|
* Getting Things Done - [[MonkeyPirateTiddlyWiki|http://mptw.tiddlyspot.com/]], [[mGSD|http://mgsd.tiddlyspot.com/#mGSD]],[[D-Cubed|http://www.dcubed.ca/]], [[TeamTasks|http://www.hawksworx.com/playground/TeamTasks/]], [[TiddlyPackingList|http://tiddlypacking.tiddlyspace.com/]], [[tbGTD|http://tbgtd.tiddlyspot.com/]]
|
|||
|
* [[Open Notebook Science|http://pineda-krch.com/2008/10/31/starting-an-open-notebook-science-project/]] - [[Garrett Lisi's|http://www.telegraph.co.uk/earth/main.jhtml?CMP=ILC-mostviewedbox&xml=/earth/2007/11/14/scisurf114.xml]] [[Deferential Geometry|http://deferentialgeometry.org/]], ([[video|http://broadcast.oreilly.com/2008/09/lisi-on-a-wiki.html]])
|
|||
|
* Novels and creative writing - [[TiddlyWikiWrite|http://www.ljcohen.net/resources-wiki.html]], [[Gimcrack'd|http://gimcrackd.com/]], [[Singularity!|http://www.antipope.org/charlie/toughguide.html]], [[Liberty Hall Writers Wiki|http://wiki.libertyhallwriters.org/doku.php?id=tiddlywiki]], [[Bibliotheca Caelestis. Tiddlywikiroman|http://bc.etkbooks.com/opac/]] from Hartmut Abendschein, [[Die, Vampire! Die!|http://www.davidvanwert.com/wiki/dievampiredie.html]] from David Van Wert, [[Rose|http://www.emacswiki.org/alex/rose.html]] from Alex Schroeder
|
|||
|
* Education - [[South Australia|https://secure.ait.org/wiki/background.htm]], [[maths in Massachusetts|http://luceatlux.net/mcasmath10/]], [[The NoteStorm Christian database|http://giffmex.org/nsdb.html]]
|
|||
|
* Factbooks - [[Web campaigning in the US|http://mitpress.mit.edu/books/0262062585/WebCampaigningDigitalSupplement.html]], [[Bolivian politics|http://www.centellas.org/politics/politiddly.html]], [[Prince2 project management|http://www.microupdate.net/cms/doc/PrinceII.html]], [[Python Grimoire|http://the.taoofmac.com/space/Python/Grimoire]], [[Marc Bolan and T-Rex|http://videodrama.tiddlyspot.com/]]
|
|||
|
* Teaching - [[An Introduction to Chain Indexing|http://informationr.net/tdw/publ/chain_indexing/chain_indexing.html]], [[Reasoning Well|http://reasoningwell.tiddlyspot.com/]]
|
|||
|
* Role Playing Games - [[Making kickass campaign sites with TiddlyWiki|http://www.encounteraday.com/2009/05/20/making-kickass-campaign-sites-with-mptw/]]
|
|||
|
* Medicine - [[TiddlyManuals|http://tiddlymanuals.tiddlyspace.com/]], [[AMBIT|http://ambit.tiddlyspace.com/]]
|
|||
|
* Law - [[TiddLegal|http://tiddlegal.tiddlyspot.com/]], [[Courtrules|http://www.michlaw.net/courtrules.html]]
|
|||
|
* Activism - [[Climate Change 2.0|http://www.climate-change-two.net/]], [[TiddlyWiki for Left Wing Journalists and Researchers|http://leftclickblog.blogspot.com/2008/02/tiddlywiki-for-left-journoes-and.html]]
|
|||
|
* Homepage/Portfolio - [[Digimask|http://digimask.com/]], [[American Cryptogram Association|http://msig.med.utah.edu/RunningUtes/cryptogram/aca.html]], [[Nykyri.net|http://www.nykyri.net/]]
|
|||
|
* Blog - [[UdiGrudi|http://udigrudi.net/]], [[LumpyMilk|http://lumpymilk.tiddlyspot.com/]], [[Veminra|http://veminra.tiddlyspace.com/]]
|
|||
|
* Mobile - [[iTW optimised for the iPhone|http://itw.bidix.info/]], [[iPhone|http://iphone.tiddlyspace.com/]], [[Android|http://android.tiddlyspace.com]]
|
|||
|
* Tools - [[TiddlyFolio|http://tiddlyfolio.tiddlyspot.com/]] (an electronic wallet), [[TiddlySlidy|http://tiddlyslidy.com/#TiddlySlidy]] (presentations using TiddlyWiki), [[TiddlyPocketBooks|http://tiddlypocketbook.com/]] (printable pocket books), [[TiddlyTweets|http://osmosoft.com/tiddlytweets/]] (a tweet archiver), [[Project Cecily|http://osmosoft.com/cecily/]] (a zooming user interface for TiddlyWiki)
|
|||
|
* As a component of other products:
|
|||
|
** [[Dido|http://projects.csail.mit.edu/exhibit/Dido/]] - a tiddlywikified database application
|
|||
|
** [[KNote|http://www.smartgoldfish.com/download.html]] - a notetakingprogram (desktopapplikation)
|
|||
|
** [[Twine|http://gimcrackd.com/etc/src/]] - a program for creating interactive stories
|
|||
|
** [[CkEditor + TW|http://simonmcmanus.wordpress.com/2010/06/28/installing-ckeditor-with-standalone-tiddlywiki/]] - wysiwyg and TW on local disk (with an [[updated version from Måns Mårtensson|http://måns.dk/TW/tw265CKeditor.zip]])
|
|||
|
|
|||
|
Also, see TiddlyWikiAdaptations
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="Feedback">
|
|||
|
<pre>If you've any comments, corrections or observations about TiddlyWiki, the best way to get our attention is to post to the [[Community]] groups -- or write a blog entry.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031801" modifier="jermolene" tags="browsers issues" title="FireFox">
|
|||
|
<pre>~TiddlyWiki works well in ~FireFox v1.0 and above. If you're experiencing problems, make sure you've followed the [[downloading guidelines|Downloading]].
|
|||
|
|
|||
|
When saving ~TiddlyWiki in ~FireFox for the first time, you can run into problems if you accidentally click 'Deny' on the dialog, and select //Remember this decision//.
|
|||
|
|
|||
|
To reverse the effects, first locate the file {{{prefs.js}}} in your ~FireFox profile directory:
|
|||
|
* Under Windows you'll find it at something like {{{C:\Documents and Settings\Jeremy\Application Data\Mozilla\Firefox\Profiles\o3dhupu6.default\prefs.js}}}, where {{{Jeremy}}} is the name of your windows profile and {{{o3dhupu6}}} will be a similar string of gobbledegook.
|
|||
|
* On the Mac it'll be at {{{~/Library/Application Support/Firefox/Profiles/o3dhupu6.default/prefs.js}}}
|
|||
|
* On Linux you can find this file at {{{~/.mozilla/firefox/o3dhupu6.default/prefs.js}}}.
|
|||
|
|
|||
|
Open the file in a text editor and find the line {{{user_pref("capability.principal.codebase.p0.denied", "UniversalXPConnect");}}} and simply replace the word {{{denied}}} with {{{granted}}}.
|
|||
|
//(Thanks to ~JonScully for figuring out this fix)//
|
|||
|
|
|||
|
Firefox users should be aware that GreaseMonkey can break TiddlyWiki. There's also a rather unpredictable FireFoxKeyboardIssue.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="browsers issues" title="FireFoxKeyboardIssue">
|
|||
|
<pre>Under FireFox, TiddlyWiki can get into a state where it ignores the arrow keys on the keyboard but accepts ordinary alphanumeric input. The triggers for this behaviour are unclear, but it doesn't just affect TiddlyWiki. The solution appears to be to locate the file {{{compreg.dat}}} in your FireFox profile folder and rename it to {{{compreg.dat.old}}}.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="tips" title="FlickrBadge">
|
|||
|
<pre>Here's one way to get a Flickr badge in TiddlyWiki:
|
|||
|
|
|||
|
<html>
|
|||
|
<a href="http://www.flickr.com" style="text-align:center;">www.<strong style="color:#3993ff">flick<span style="color:#ff1c92">r</span></strong>.com</a><br>
|
|||
|
<iframe style="background-color:#ffffff; border-color:#ffffff; border:none;" width="113" height="151" frameborder="0" scrolling="no" src="http://www.flickr.com/apps/badge/badge_iframe.gne?zg_bg_color=ffffff&zg_person_id=35468148136%40N01" title="Flickr Badge"></iframe>
|
|||
|
</html>
|
|||
|
|
|||
|
Here's the HTML code to insert in a tiddler:
|
|||
|
{{{
|
|||
|
<html>
|
|||
|
<a href="http://www.flickr.com" style="text-align:center;">www.<strong style="color:#3993ff">flick<span style="color:#ff1c92">r</span></strong>.com</a><br>
|
|||
|
<iframe style="background-color:#ffffff; border-color:#ffffff; border:none;" width="113" height="151" frameborder="0" scrolling="no" src="http://www.flickr.com/apps/badge/badge_iframe.gne?zg_bg_color=ffffff&zg_person_id=35468148136%40N01" title="Flickr Badge"></iframe>
|
|||
|
</html>
|
|||
|
}}}
|
|||
|
|
|||
|
You'll need to know your Flickr person ID, which should replace the value "35468148136%40N01" in the HTML. There's a useful [[Flickr idGettr|http://eightface.com/code/idgettr/]] to help with this.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features options" title="GenerateAnRssFeed">
|
|||
|
<pre>A new feature for the ThirdVersion of TiddlyWiki is the ability to generate an RssFeed of its content. You can flick it on with a new addition to the InterfaceOptions. If enabled, it automatically saves an RSS 2.0 format file with the last few changed tiddlers in it. It's given the same filename as the TiddlyWiki file but with the ".xml" extension. Like all TiddlyWiki features, it's experimental, and will probably be a bit temperamental in your feedreader until the bugs are ironed out.
|
|||
|
|
|||
|
Note that you must set the tiddler SiteUrl to be the URL where your TiddlyWiki will be published. (Don't put leading spaces or line breaks before or after the URL).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031801" modifier="jermolene" tags="instructions" title="GettingStarted">
|
|||
|
<pre>Once you've successfully [[downloaded|Downloading]] ~TiddlyWiki, you can find out how to:
|
|||
|
* [[Edit your tiddlers|Editing]]
|
|||
|
* [[Save changes|SaveChanges]]
|
|||
|
* [[Search]] for content
|
|||
|
* Use [[tagging|Tags]] to organise your tiddlers
|
|||
|
* [[Customise|Customisation]] TiddlyWiki's appearance and behaviour
|
|||
|
* Use apps to run TiddlyWiki on a [[MobileDevice|MobileDevices]]
|
|||
|
See the full [[Reference Guide|Reference]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102161540" creator="colmbritton" modifier="colmbritton" tags="shadow" title="GettingStarted shadows">
|
|||
|
<pre>The GettingStarted shadow tiddler contains information about how to start using your TiddlyWiki.
|
|||
|
You can change it to include anything you desire.
|
|||
|
|
|||
|
For example a lot of tiddlywiki authors use it to explain what their wiki is about. This is a particularly useful approach because by default the GettingStarted tiddler is in the [[DefaultTiddlers|DefaultTiddlers shadows]] tiddler, thus opens automatically upon loading of the page.
|
|||
|
|
|||
|
By default it is also part of the [[MainMenu|MainMenu shadows]] tiddler so is included on the left side of the menu bar above.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="issues" title="GreaseMonkey">
|
|||
|
<pre>Several popular GreaseMonkey scripts can cause some or all features of TiddlyWiki to stop working - the default Linkify script seems to be particularly troublesome. There doesn't seem to be a //solid// way to disable GreaseMonkey from within TiddlyWiki (which is technically entirely understandable but does lead to a fairly grim user experience).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161205" modifier="colmbritton" tags="concepts" title="GuerillaWiki">
|
|||
|
<pre>TiddlyWiki makes a great GuerillaWiki in situations where it's not practical to use a traditional wiki.
|
|||
|
|
|||
|
For instance, in a corporate setting, persuading an over-worked IT department to install you a Wiki server for you isn't always going to be possible overnight. And your PC is locked down so you can't install a conventional Wiki yourself. But, equally, you can't go and use one of the public hosted Wiki services because your Information Security department would not allow all that corporate data to flow into an outside server.
|
|||
|
|
|||
|
TiddlyWiki slices through those barriers by being usable on virtually all ~PCs.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111428" creator="matt" modified="201102151515" modifier="psd" tags="formatting" title="HTML Entities Formatting">
|
|||
|
<pre>HTML entities can be used to easily type special characters:
|
|||
|
{{{
|
|||
|
Here is a quote symbol: &quot;
|
|||
|
And a pound sign: &pound;
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
Here is a quote symbol: &quot;
|
|||
|
And a pound sign: &pound;
|
|||
|
!Notes
|
|||
|
For a full list of available HTML references see:
|
|||
|
http://www.w3schools.com/tags/ref_entities.asp
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111429" creator="matt" modified="201102151518" modifier="psd" tags="formatting" title="HTML Formatting">
|
|||
|
<pre>Raw HTML text can be included in a tiddler:
|
|||
|
{{{
|
|||
|
<html>
|
|||
|
This is some <strong>HTML</strong> formatting
|
|||
|
</html>
|
|||
|
}}}
|
|||
|
<html>
|
|||
|
This is some <strong>HTML</strong> formatting
|
|||
|
</html>
|
|||
|
!Notes
|
|||
|
* only static HTML elements that are valid within a {{{<div>}}} work correctly
|
|||
|
* {{{document.write}}} cannot be used to generate dynamic content
|
|||
|
* External {{{<script>}}} elements cannot be used within {{{<html>}}} blocks
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111427" creator="matt" modified="201102151516" modifier="psd" tags="formatting" title="Headings Formatting">
|
|||
|
<pre>{{{
|
|||
|
!Heading Level 1
|
|||
|
!!Heading Level 2
|
|||
|
!!!Heading Level 3
|
|||
|
!!!!Heading Level 4
|
|||
|
!!!!!Heading Level 5
|
|||
|
!!!!!!Heading Level 6
|
|||
|
}}}
|
|||
|
Display as:
|
|||
|
!Heading Level 1
|
|||
|
!!Heading Level 2
|
|||
|
!!!Heading Level 3
|
|||
|
!!!!Heading Level 4
|
|||
|
!!!!!Heading Level 5
|
|||
|
!!!!!!Heading Level 6
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111301652" modifier="jermolene" tags="gettingstarted welcome" title="HelloThere">
|
|||
|
<pre>Welcome to TiddlyWiki, a reusable non-linear personal web notebook. It's a unique [[wiki|WikiWikiWeb]] that people [[love using|Raves]] to keep ideas and information organised. It was originally created by JeremyRuston and is now a thriving [[open source|OpenSourceLicense]] project with a busy [[Community]] of independent developers.
|
|||
|
|
|||
|
TiddlyWiki is written in [[HTML]], [[CSS]] and JavaScript to run on any reasonably modern [[browser|Browsers]] without needing any ServerSide logic. It allows anyone to create personal SelfContained hypertext documents that can be published to a WebServer, sent by email, stored in a DropBox or kept on a USB thumb drive to make a WikiOnAStick. Because it doesn't need to be installed and configured it makes a great GuerillaWiki. This is revision <<version>> of TiddlyWiki, and is published under an OpenSourceLicense.
|
|||
|
|
|||
|
Unlike most wikis, TiddlyWiki doesn't directly support group collaboration; it is a wiki in the sense of elevating linking be a part of the punctuation of writing. You can easily publish a TiddlyWiki you have created by placing the single file on a web server (for instance the homepage hosting provided by many ISPs). If you need full group collaboration features, there are several HostedOptions to choose from.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031657" modifier="jermolene" tags="community gettingstarted help" title="Help and Support">
|
|||
|
<pre>TiddlyWiki is an [[OpenSourceLicense|open source]] product, with most help and support being provided by the [[Community]]. The best way to get help with a specific problem is the TiddlyWiki DiscussionForums (it's worth searching the group archives to see if anyone else has already solved the same problem).
|
|||
|
|
|||
|
There are a number of other useful resources for learning about TiddlyWiki:
|
|||
|
|
|||
|
* [[TiddlerToddler|http://tiddlertoddler.tiddlyspot.com/]] from Julie Starr
|
|||
|
* [[TwHelp|http://twhelp.tiddlyspot.com/]] from Morris Gray
|
|||
|
|
|||
|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="features options" title="HideEditingFeatures">
|
|||
|
<pre>This is an [[advanced option|AdvancedOptions]] that lets you choose whether editting features are shown when a TiddlyWiki file is viewed over {{{http:}}} (as opposed to {{{file:}}}).
|
|||
|
|
|||
|
To publish a TiddlyWiki with the editting features hidden you'll need to create a tiddler tagged with 'systemConfig' and include in it the line:
|
|||
|
|
|||
|
{{{
|
|||
|
config.options.chkHttpReadOnly = true;
|
|||
|
}}}
|
|||
|
|
|||
|
End users can then override the setting using the AdvancedOptions panel.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201110201351" creator="jermolene" modifier="jermolene" title="History">
|
|||
|
<pre>Released in September 2004, the [[first version|firstversion.html]] was pretty basic, weighing in at 52KB.
|
|||
|
|
|||
|
Released in December 2004, the [[second version|secondversion.html]] of TiddlyWiki grew 50% over the FirstVersion to 76KB. It added IncrementalSearch, the ReferencesButton, the PermalinkCommand, PermaView, [[closeAll macro]], smooth scrolling, an improved sidebar, an animation for the CloseTiddlerCommand and a tiny Easter egg in homage for Macintosh OS X. It also introduced a new site design.
|
|||
|
|
|||
|
After that, there's a nearly complete archive of old versions of TiddlyWiki at:
|
|||
|
* http://www.tiddlywiki.com/archive/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111428" creator="matt" modified="201102151518" modifier="psd" tags="formatting" title="Horizontal Rule Formatting">
|
|||
|
<pre>Four dashes on a line by themselves are used to introduce a horizontal rule:
|
|||
|
{{{
|
|||
|
Before the rule
|
|||
|
----
|
|||
|
After the rule
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
Before the rule
|
|||
|
----
|
|||
|
After the rule
|
|||
|
|
|||
|
The HTML tag {{{<hr>}}} can be used as an alternative syntax:
|
|||
|
|
|||
|
{{{
|
|||
|
Before the rule<hr>After the rule
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
Before the rule<hr>After the rule
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111508" creator="jermolene" modified="201111031717" modifier="jermolene" title="HostedOptions">
|
|||
|
<pre>There are several ways that you can have your TiddlyWiki data hosted online, making it easier to access and share your information.
|
|||
|
|
|||
|
!~TiddlySpot
|
|||
|
[<img[http://tiddlyspot.com/_ts/images/banner-logo.png][TiddlySpot|http://tiddlyspot.com]] ~TiddlySpot lets you put TiddlyWiki documents on the Web, and edit them directly in your browser. It doesn't yet offer full support for simultaneous editing by multiple users.
|
|||
|
|
|||
|
!~DropBox
|
|||
|
Many people use [[DropBox|http://dropbox.com]] to synchronise their TiddlyWiki documents to make them available on multiple computers. The ~DropBox iPhone/iPad application also permits read only access to TiddlyWiki documents. See [[A Personal Knowledgebase Solution: Tiddlywiki and Dropbox|http://www.broowaha.com/articles/7671/a-personal-knowledgebase-solution-tiddlywiki-and-dropbox]]
|
|||
|
|
|||
|
!~TiddlyWeb & ~TiddlySpace
|
|||
|
[<img[TiddlySpace|http://tiddlyspace.com/bags/frontpage_public/tiddlers/shinyspace.png][http://tiddlyspace.com]] [[TiddlySpace|http://tiddlyspace.com]] is a full hosted service for TiddlyWiki that allows multiple people to edit the same wiki at the same time. It is particularly focussed on sharing tiddlers.
|
|||
|
|
|||
|
~TiddlySpace is built on top of [[TiddlyWeb|http://tiddlyweb.com]], a flexible architecture for putting tiddlers on the web.
|
|||
|
|
|||
|
!~GieWiki
|
|||
|
[[GieWiki|http://code.google.com/p/giewiki/]] by Poul Staugaard is a new serverside for TiddlyWiki that focusses on making TiddlyWiki behave like a real wiki, with preview and versioning of tiddlers, any number of pages in any hierachy, an auto-generated sitemap, comments on tiddlers, fine-grained access control, image upload, recent changes etc. You can see a default instance at http://giewiki.appspot.com/.
|
|||
|
|
|||
|
!ccTiddly
|
|||
|
[[ccTiddly|http://tiddlywiki.org/#ccTiddly]] is an older serverside written in PHP to use [[MySQL|http://en.wikipedia.org/wiki/MySQL]] for storage. It is no longer under active development, but remains a popular choice for basic TiddlyWiki hosting needs.
|
|||
|
|
|||
|
!~TiddlyCouch
|
|||
|
[[TiddlyCouch|http://bijl.iriscouch.com/bijl-ctw/_design/tiddlycouch/_list/tiddlywiki/tiddlers]] is an experimental integration of TiddlyWiki with CouchDB.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="instructions" title="HowToUpgrade">
|
|||
|
<pre>The core TiddlyWiki code is regularly updated with bug fixes and new features. If you're using an earlier revision of TiddlyWiki, you should consider upgrading to the latest version.
|
|||
|
|
|||
|
The steps you need to take depend on which version of TiddlyWiki you are upgrading from. From version 2.4.0 onwards, you can upgrade to the latest version using the 'Upgrade' tab in the BackstageArea, as described below. If you're using an earlier version of TiddlyWiki, you'll need to follow [[these instructions|HowToUpgradeOlderTiddlyWikis]] instead.
|
|||
|
|
|||
|
! Upgrading from ~TiddlyWiki 2.4.0+ to the most recent version
|
|||
|
* Open the BackstageArea by clicking the 'backstage' button at the top right
|
|||
|
* Click on the 'Upgrade' tab
|
|||
|
* Click on the 'Upgrade' button, and follow the prompts
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="instructions" title="HowToUpgradeOlderTiddlyWikis">
|
|||
|
<pre>The steps you need to take depend on which version of TiddlyWiki you are upgrading from. From version 2.4.0 onwards, you can upgrade to the latest version using the 'Upgrade' tab in the BackstageArea, as described in HowToUpgrade. If you're using an earlier version of TiddlyWiki, you'll need to follow these instructions instead:
|
|||
|
! Upgrading from TiddlyWiki earlier than version 2.4.0 to the latest version
|
|||
|
* Download a fresh, empty version of TiddlyWiki by right-clicking on [[this link|http://www.tiddlywiki.com/empty.html]], selecting 'Save target' or 'Save link' and saving it in a convenient location as (say) "mynewtiddlywiki.html"
|
|||
|
* Open the new TiddlyWiki file in your browser
|
|||
|
* Choose ''import'' from the BackstageArea at the top of the window (you may need to click the 'backstage' button at the upper right to show the BackstageArea)
|
|||
|
* Click the ''browse'' button and select your original TiddlyWiki file (say, "mytiddlywiki.html") from the file browser
|
|||
|
* Click the ''open'' button on the import wizard; a list of all of your tiddlers is displayed
|
|||
|
* Click on the top-left checkbox to select all the tiddlers in the list
|
|||
|
* Scroll down to the bottom of the wizard and ensure that the checkbox labelled //Keep these tiddlers linked to this server...// is ''clear''
|
|||
|
* Click the ''import'' button
|
|||
|
The most likely cause of the upgrade process not working properly is that one of the [[Plugins]] you're using is not compatible with a change in the new release. If so, you can repeat the process omitting the troublesome plugins.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111621" modifier="jermolene" tags="formatting" title="HtmlEntities">
|
|||
|
<pre>Entities in HTML documents allow characters to be entered that can't easily be typed on an ordinary keyboard. They take the form of an ampersand (&), an identifying string, and a terminating semi-colon (;). There's a complete reference [[here|http://www.htmlhelp.com/reference/html40/entities/]]; some of the more common and useful ones are shown below.
|
|||
|
|
|||
|
|>|>|>|>|>|>| !HTML Entities |
|
|||
|
| &amp;nbsp; | &nbsp; | no-break space | &nbsp;&nbsp; | &amp;apos; | &apos; | single quote, apostrophe |
|
|||
|
| &amp;ndash; | &ndash; | en dash |~| &amp;quot; | " | quotation mark |
|
|||
|
| &amp;mdash; | &mdash; | em dash |~| &amp;prime; | &prime; | prime; minutes; feet |
|
|||
|
| &amp;hellip; | &hellip; | horizontal ellipsis |~| &amp;Prime; | &Prime; | double prime; seconds; inches |
|
|||
|
| &amp;copy; | &copy; | Copyright symbol |~| &amp;lsquo; | &lsquo; | left single quote |
|
|||
|
| &amp;reg; | &reg; | Registered symbol |~| &amp;rsquo; | &rsquo; | right single quote |
|
|||
|
| &amp;trade; | &trade; | Trademark symbol |~| &amp;ldquo; | &ldquo; | left double quote |
|
|||
|
| &amp;dagger; | &dagger; | dagger |~| &amp;rdquo; | &rdquo; | right double quote |
|
|||
|
| &amp;Dagger; | &Dagger; | double dagger |~| &amp;laquo; | &laquo; | left angle quote |
|
|||
|
| &amp;para; | &para; | paragraph sign |~| &amp;raquo; | &raquo; | right angle quote |
|
|||
|
| &amp;sect; | &sect; | section sign |~| &amp;times; | &times; | multiplication symbol |
|
|||
|
| &amp;uarr; | &uarr; | up arrow |~| &amp;darr; | &darr; | down arrow |
|
|||
|
| &amp;larr; | &larr; | left arrow |~| &amp;rarr; | &rarr; | right arrow |
|
|||
|
| &amp;lArr; | &lArr; | double left arrow |~| &amp;rArr; | &rArr; | double right arrow |
|
|||
|
| &amp;harr; | &harr; | left right arrow |~| &amp;hArr; | &hArr; | double left right arrow |
|
|||
|
|
|||
|
The table below shows how accented characters can be built up by subsituting a base character into the various accent entities in place of the underscore ('_'):
|
|||
|
|
|||
|
|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>| !Accented Characters |
|
|||
|
| grave accent | &amp;_grave; | &Agrave; | &agrave; | &Egrave; | &egrave; | &Igrave; | &igrave; | &Ograve; | &ograve; | &Ugrave; | &ugrave; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |
|
|||
|
| acute accent | &amp;_acute; | &Aacute; | &aacute; | &Eacute; | &eacute; | &Iacute; | &iacute; | &Oacute; | &oacute; | &Uacute; | &uacute; | &nbsp; | &nbsp; | &Yacute; | &yacute; | &nbsp; | &nbsp; |
|
|||
|
| circumflex accent | &amp;_circ; | &Acirc; | &acirc; | &Ecirc; | &ecirc; | &Icirc; | &icirc; | &Ocirc; | &ocirc; | &Ucirc; | &ucirc; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |
|
|||
|
| umlaut mark | &amp;_uml; | &Auml; | &auml; | &Euml; | &euml; | &Iuml; | &iuml; | &Ouml; | &ouml; | &Uuml; | &uuml; | &nbsp; | &nbsp; | &Yuml; | &yuml; | &nbsp; | &nbsp; |
|
|||
|
| tilde | &amp;_tilde; | &Atilde; | &atilde; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Otilde; | &otilde; | &nbsp; | &nbsp; | &Ntilde; | &ntilde; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |
|
|||
|
| ring | &amp;_ring; | &Aring; | &aring; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |
|
|||
|
| slash | &amp;_slash; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Oslash; | &oslash; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |
|
|||
|
| cedilla | &amp;_cedil; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &Ccedil; | &ccedil; |
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111430" creator="matt" modified="201102151519" modifier="psd" tags="formatting" title="Image Formatting">
|
|||
|
<pre>!Simple Images
|
|||
|
{{{
|
|||
|
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
!Tooltips for Images
|
|||
|
{{{
|
|||
|
[img[tooltip|http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
[img[tooltip|http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
!Image Links
|
|||
|
{{{
|
|||
|
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg][http://www.flickr.com/photos/jermy/10134618/]]
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
[img[http://wikitext.tiddlyspace.com/fractalveg.jpg][http://www.flickr.com/photos/jermy/10134618/]]
|
|||
|
!Floating Images with Text
|
|||
|
{{{
|
|||
|
[<img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
}}}
|
|||
|
[<img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]Displays as.
|
|||
|
{{{
|
|||
|
@@clear:both;display:block; @@
|
|||
|
}}}
|
|||
|
Will then clear the float.
|
|||
|
@@clear:both;display:block;Like this@@
|
|||
|
{{{
|
|||
|
[>img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]
|
|||
|
}}}
|
|||
|
[>img[http://wikitext.tiddlyspace.com/fractalveg.jpg]]Displays as.@@clear:both;display:block; @@
|
|||
|
!See Also
|
|||
|
[[Image Macro]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201103011514" creator="psd" modified="201110201351" modifier="jermolene" title="Importing Tiddlers">
|
|||
|
<pre>To import tiddlers from another ~TiddlyWiki file, or from an external website, follow these instructions.
|
|||
|
#If the tiddler is on an external site, first copy the URL of the site which includes the tiddler you'd like to download into your clipboard (eg http://www.tiddlytools.com)
|
|||
|
#Open your local ~TiddlyWiki file from your computer.
|
|||
|
#Click on the 'Backstage' link that you can see at the very top right hand side of the page.
|
|||
|
#In the menu, click on 'Import'. You will then see a window that looks like this - and you can follow the guidance from there. Note that you may need to grant authorisation to your ~TiddlyWiki file to import tiddlers - this is fine and expected.
|
|||
|
To import tiddlers from another ~TiddlyWiki file, or from an external website, follow these instructions.
|
|||
|
#If the tiddler is on an external site, first copy the URL of the site which includes the tiddler you'd like to download into your clipboard (eg http://www.tiddlytools.com)
|
|||
|
#Open your local ~TiddlyWiki file from your computer.
|
|||
|
#Click on the 'Backstage' link that you can see at the very top right hand side of the page.
|
|||
|
#In the menu, click on 'Import'. You will then see a window that looks like this - and you can follow the guidance from there. Note that you may need to grant authorisation to your ~TiddlyWiki file to import tiddlers - this is fine and expected.
|
|||
|
<<importTiddlers>>
|
|||
|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="IncrementalSearch">
|
|||
|
<pre>When you type more than three characters in the search box at the upper right, any matching tiddlers are automatically displayed with the text highlighted. There's a couple of minor issues: the highlights don't get removed when you clear the search, and occasionally, on some browsers, keystrokes get missed if you type quickly so you may need to click the 'search' button to manually trigger the search.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="InstallingPlugins">
|
|||
|
<pre>[[Plugins]] are just tiddlers containing ~JavaScript code that is tagged with <<tag systemConfig>>. TiddlyWiki executes any [[Plugins]] as it loads; they can add [[Macros]] or otherwise extend and enhance the base code.
|
|||
|
|
|||
|
The recommended way to install a plugin into your own copy of TiddlyWiki is to use ImportTiddlers (there are instructions for ManuallyInstallIngPlugins when required).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="features options" title="InterfaceOptions">
|
|||
|
<pre>InterfaceOptions are displayed when you click the 'options' button on the right in your TiddlyWiki file. They are saved in a cookie on your browser, making them sticky between visits:
|
|||
|
<<<
|
|||
|
<<tiddler OptionsPanel>>
|
|||
|
<<<
|
|||
|
* The user name for edits should be set //before// starting to edit things
|
|||
|
* SaveBackups gives the option of whether to generate backup files
|
|||
|
* AutoSave gives the option of automatically saving every time a change is made
|
|||
|
* RegExpSearch allows more complex search expressions
|
|||
|
* CaseSensitiveSearch does as its name implies
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031802" modifier="jermolene" tags="browsers issues" title="InternetExplorer">
|
|||
|
<pre>TiddlyWiki works on InternetExplorer 6.x and above under Windows. It also allows you to SaveChanges, albeit there are some annoying XP ServicePack2Problems and VistaIssues to work around. If you're having problems, make sure you've followed the appropriate [[downloading guidelines|Downloading]].
|
|||
|
|
|||
|
Known problems with ~TiddlyWiki under InternetExplorer:
|
|||
|
* [[Gradient|GradientMacro]] fills sometimes appear in the wrong place until you move the mouse over the tiddler
|
|||
|
* Horizontal gradients don't work correctly
|
|||
|
* Links to tiddlers with multiple consecutive spaces in their titles is broken
|
|||
|
* Runs of spaces within tiddlers get conflated into a single space when you edit a tiddler. This is particularly annoying when using MonospacedText blocks
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201110201351" creator="jermolene" modifier="jermolene" title="JavaScript">
|
|||
|
<pre>JavaScript is the programming language that powers the [[Web]]. In the browser it is used to script behaviours that breathe life into the static world of [[HTML]] and [[CSS]], and it is increasingly being selected as a ServerSide programming language.
|
|||
|
|
|||
|
TiddlyWiki relies on JavaScript, and can't function properly without it. An alternative is to use a ServerSide adaptation like TiddlyWeb or TiddlySpace that can provide a static HTML view of TiddlyWiki content that doesn't require JavaScript in the browser.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="welcome" title="JeremyRuston">
|
|||
|
<pre>Jeremy is the original creator of TiddlyWiki (nowadays, it's more of a [[group effort|Community]]). He works at [[BT|http://www.btplc.com/]] where he is Head of Open Source Innovation. He runs the [[Osmosoft]] team, and generally tries to help BT be better at understanding and participating in open source.
|
|||
|
|
|||
|
I can be reached at {{{jeremy (at) osmosoft (dot) com}}}, and I regularly read and reply to messages on the [[TiddlyWiki Google Groups|Community]]. I (occasionally) write on my TiddlySpace at http://jermolene.com/ and you can also find me on [[Flickr|http://www.flickr.com/photos/jermy/]], [[del.icio.us|http://del.icio.us/jeremyruston]] and [[twitter|http://twitter.com/Jermolene]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="JumpCommand">
|
|||
|
<pre>Offers a popup menu to jump directly to any of the currently open tiddlers. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar jump>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110311634" modifier="jermolene" tags="features" title="KeyboardShortcuts">
|
|||
|
<pre>Access keys are shortcuts to common functions accessed by typing a letter with either the 'alt' (PC) or 'control-alt' (Mac) key:
|
|||
|
|!PC|!Mac|!Function|
|
|||
|
|~Alt-F|~Ctrl-Alt-F|Search|
|
|||
|
|~Alt-J|~Ctrl-Alt-J|NewJournal|
|
|||
|
|~Alt-N|~Ctrl-Alt-N|NewTiddler|
|
|||
|
|~Alt-S|~Ctrl-Alt-S|SaveChanges|
|
|||
|
These access keys are provided by the associated internal [[Macros]] for the functions above. The macro needs to be used in an open tiddler (or the MainMenu or SideBar) in order for the access keys to work.
|
|||
|
|
|||
|
While editing a tiddler:
|
|||
|
* ~Control-Enter or ~Control-Return accepts your changes and switches out of editing mode (use ~Shift-Control-Enter or ~Shift-Control-Return to stop the date and time being updated for MinorChanges)
|
|||
|
* Escape abandons your changes and reverts the tiddler to its previous state
|
|||
|
|
|||
|
In the search box:
|
|||
|
* Escape clears the search term
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201102111310" modifier="blaine" title="Licence">
|
|||
|
<pre>~TiddlyWiki is published under a BSD licence, and is owned by the not-for-profit [[UnaMesa Foundation|http://www.unamesa.org/]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="LikeThis">
|
|||
|
<pre>You've clicked on an example link! Click close to close this tiddler.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111431" creator="matt" modified="201102151519" modifier="psd" tags="formatting" title="Line Break Formatting">
|
|||
|
<pre>Line breaks can be forced explicitly:
|
|||
|
{{{
|
|||
|
Some text with a<br>line break in the middle
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
Some text with a<br>line break in the middle
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102161121" creator="psd" modifier="psd" tags="formatting" title="Link Formatting">
|
|||
|
<pre>!Wiki Links
|
|||
|
Any words or phrases that are CamelCase or compound words - in which the elements are joined without spaces - will result in them becoming links to tiddlers with that name.
|
|||
|
|
|||
|
For example,
|
|||
|
{{{
|
|||
|
WikiWord
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
WikiWord
|
|||
|
|
|||
|
To stop this happening the words must be escaped:
|
|||
|
{{{
|
|||
|
~WikiWord
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
~WikiWord
|
|||
|
|
|||
|
Alternatively, a tiddler can be linked to using square brackets to encompass the whole tiddler title:
|
|||
|
{{{
|
|||
|
[[tiddler name]]
|
|||
|
}}}
|
|||
|
!Pretty Links
|
|||
|
Optionally, custom text can be added, separated by a pipe character (|)
|
|||
|
{{{
|
|||
|
[[alternative link text|tiddler name]]
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
[[link to our WikiWord tiddler|WikiWord]]
|
|||
|
!External Links
|
|||
|
Writing the URL in the text results in a link to that external site:
|
|||
|
{{{
|
|||
|
http://osmosoft.com
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
http://osmosoft.com
|
|||
|
Similar to pretty links alternative text can be used to link to external sites:
|
|||
|
{{{
|
|||
|
[[Visit the Osmosoft site|http://osmosoft.com]]
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
[[Visit the Osmosoft site|http://osmosoft.com]]
|
|||
|
!Links to Other Spaces
|
|||
|
Link to a space by preceding it with {{{@}}}:
|
|||
|
{{{
|
|||
|
@about
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
@about
|
|||
|
|
|||
|
Suppress space linking with {{{~}}}:
|
|||
|
{{{
|
|||
|
~@about
|
|||
|
}}}
|
|||
|
~@about
|
|||
|
Link to a tiddler within another space:
|
|||
|
{{{
|
|||
|
TiddlyWiki@glossary
|
|||
|
[[TiddlySpace API]]@glossary
|
|||
|
[[Information about the HTTP interface|TiddlySpace API]]@glossary
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
TiddlyWiki@glossary
|
|||
|
[[TiddlySpace API]]@glossary
|
|||
|
[[Information about the HTTP interface|TiddlySpace API]]@glossary
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211414" modifier="psd" tags="features" title="LinkToFolders">
|
|||
|
<pre>[[Link Formatting]] allows for links that open local or network folders. Depending on your browser and operating system, the folders are opened in Windows Explorer, the OS X Finder, or the browser itself.
|
|||
|
|
|||
|
Edit this tiddler to see [[this link to a Windows network share|file://///server/share/folder/path/name]], [[this link to a Windows drive-mapped folder|file:///c:/folder/path/name]] and [[this link to a Unix-style folder|file:///folder/path/name]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111432" creator="matt" modified="201102151519" modifier="psd" tags="formatting" title="List Formatting">
|
|||
|
<pre>!Ordered Lists
|
|||
|
Lists can be ordered with numbers and letters:
|
|||
|
{{{
|
|||
|
#List item one
|
|||
|
##List item two
|
|||
|
###List item three
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
#List item one
|
|||
|
##List item two
|
|||
|
###List item three
|
|||
|
!Unordered Lists
|
|||
|
Lists can be unordered:
|
|||
|
{{{
|
|||
|
*Unordered List Level 1
|
|||
|
**Unordered List Level 2
|
|||
|
***Unordered List Level 3
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
*Unordered List Level 1
|
|||
|
**Unordered List Level 2
|
|||
|
***Unordered List Level 3
|
|||
|
!Definition Lists
|
|||
|
Definition lists can also be created:
|
|||
|
{{{
|
|||
|
;Title 1
|
|||
|
:Definition of title 1
|
|||
|
;Title 2
|
|||
|
:Definition of title 2
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
;Title 1
|
|||
|
:Definition of title 1
|
|||
|
;Title 2
|
|||
|
:Definition of title 2
|
|||
|
|
|||
|
See also [[Tagging Macro]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111446" creator="colmbritton" modified="201102111532" modifier="colmbritton" title="MacrosContent">
|
|||
|
<pre>[[allTags|allTags macro]]
|
|||
|
[[closeAll|closeAll macro]]
|
|||
|
[[list|list macro]]
|
|||
|
[[newJournal|newJournal macro]]
|
|||
|
[[newTiddler|newTiddler macro]]
|
|||
|
[[permaview|permaview macro]]
|
|||
|
[[saveChanges|saveChanges macro]]
|
|||
|
[[search|search macro]]
|
|||
|
[[slider|slider macro]]
|
|||
|
[[tabs|tabs macro]]
|
|||
|
[[tag|tag macro]]
|
|||
|
[[tagging|tagging macro]]
|
|||
|
[[tags|tags macro]]
|
|||
|
[[tiddler|tiddler macro]]
|
|||
|
[[timeline|timeline macro]]
|
|||
|
[[today|today macro]]
|
|||
|
[[version|version macro]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" title="MainMenu">
|
|||
|
<pre>HelloThere
|
|||
|
|
|||
|
GettingStarted
|
|||
|
[[Customisation]]
|
|||
|
[[Examples]]
|
|||
|
|
|||
|
[[Reference]]
|
|||
|
[[Help and Support]]
|
|||
|
[[Community]]
|
|||
|
[[RSS|RssFeed]]
|
|||
|
|
|||
|
<<tiddler Download>>
|
|||
|
|
|||
|
^^[img[favicon.ico]] TiddlyWiki <<version>>
|
|||
|
© 2011 [[UnaMesa|http://www.unamesa.org/]]^^
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111611" creator="matt" modified="201102151511" modifier="matt" tags="shadow" title="MainMenu shadows">
|
|||
|
<pre>This tiddler contains a list of the tiddlers that appear in the MainMenu. In the default TiddlySpace theme the MainMenu appears in the horizontal bar at the top of the page and in the default TiddlyWiki theme the MainMenu is on the left.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161204" modifier="psd" title="ManuallyInstallIngPlugins">
|
|||
|
<pre>In some situations it can be useful to use the clipboard insead of InstallingPlugins using ImportTiddlers.
|
|||
|
|
|||
|
# Open a new browser window and navigate to the TiddlyWiki site containing the macro you want
|
|||
|
# Double click the tiddler, or click the {{{source}}} button (on other sites it will sometimes be a {{{view}}} or {{{edit}}} button)
|
|||
|
# The entire text of the tiddler should be selected; if not select it manually with ~Control-A or ~Command-A
|
|||
|
# Copy the entire text of the tiddler to the clipboard
|
|||
|
# Open your TiddlyWiki file in a new browser window
|
|||
|
# Click {{{new tiddler}}} to create a new blank tiddler
|
|||
|
## Paste the contents of the clipboard into it's body
|
|||
|
## Set the title as appropriate
|
|||
|
## Add the tag {{{systemConfig}}}
|
|||
|
# Click {{{done}}} on the tiddler
|
|||
|
# SaveChanges
|
|||
|
# Reload your TiddlyWiki in the browser
|
|||
|
The plugin should now be available for use.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111102" creator="psd" modified="201102151018" modifier="psd" tags="excludeLists" title="MarkupPreHead">
|
|||
|
<pre><!--{{{-->
|
|||
|
<link rel="shortcut icon" href="/recipes/tiddlywiki-com_public/tiddlers/favicon.ico" />
|
|||
|
<link href="/index.xml" rel="alternate"
|
|||
|
type="application/rss+xml" title="tiddlywiki.com's RSS feed" />
|
|||
|
<!--}}}-->
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="MartinsPluginsServer">
|
|||
|
<pre>|''URL:''|http://www.martinswiki.com/ |
|
|||
|
|''Description:''|Martin Buddens's Plugins |
|
|||
|
|''Author:''|MartinBudden |
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201111141221" creator="jermolene" modified="201111141228" modifier="jermolene" tags="niche" title="Mathematics">
|
|||
|
<pre>There are several ways to incorporate mathematical formulae into TiddlyWiki, both of which let you to type ordinary LaTeX into a tiddler:
|
|||
|
1. Use the [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] library via Bob McElrath's [[TiddlyJsMath|http://bob.mcelrath.org/tiddlyjsmath.html]] plugin
|
|||
|
2. Use the [[MathJax|http://www.mathjax.org/]] library via [[PluginMathJax|http://math-template.tiddlyspace.com/#%5B%5BPluginMathJax%20v1.3%5D%5D]]
|
|||
|
|
|||
|
An alternative is to use a service like [[CodeCogs|http://www.codecogs.com/latex/eqneditor.php]] that enables you to generate images of equations from LaTeX source that can be manually inserted into TiddlyWiki. Some examples of this technique are http://twmath.tiddlyspot.com/ and http://twequation.tiddlyspot.com/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111261322" modifier="jermolene" tags="concepts" title="MicroContent">
|
|||
|
<pre>MicroContent and MicroCopy being fashionable words for self-contained fragments of content that are smaller than an entire pages.
|
|||
|
|
|||
|
Usually MicroContent is presented through some kind of aggregation that reduces the perceptual shock and resource cost of context switching (eg the way that blogs aggregating several entries onto a page, or Flickr presents a bunch of photos in an album). TiddlyWiki aggregates MicroContent items called [[tiddlers|Tiddler]] into pages that are loaded in one gulp and progressively displayed as the user clicks hypertext links to read them.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="MinorChanges">
|
|||
|
<pre>Sometimes it's useful to stop a minor change to a tiddler from causing it to rise to the top of the timeline. This can be done by pressing the Shift key while clicking the 'done' toolbar button, or with the ~Shift-Control-Enter key. This behaviour can be switched to become the default with one of the AdvancedOptions.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="MissingTiddlers">
|
|||
|
<pre>The 'Missing' option on the MoreTab shows you the names of tiddlers that you've referred to but not gone ahead to define. It can be useful during writing sessions to keep track of things you need to come back and fill out.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201103221319" creator="jermolene" modified="201110311131" modifier="jermolene" title="MobileDevices">
|
|||
|
<pre>TiddlyWiki sites on the Internet work well on the iPhone, iPad and Android devices but the browsers on those devices do not allow documents to be saved.
|
|||
|
|
|||
|
To work around this limitation, you can use these apps:
|
|||
|
|
|||
|
* [[AndTidWiki|https://market.android.com/details?id=de.mgsimon.android.andtidwiki]] for Android Devices
|
|||
|
* [[TWMobile|http://itunes.apple.com/gb/app/twmobile/id381945222?mt=8]] for iPad
|
|||
|
* [[TWEdit|http://itunes.apple.com/gb/app/twedit/id409607956?mt=8]] for iPhone, iPad and iPod Touch
|
|||
|
* [[tiddlyNotes|http://itunes.apple.com/us/app/tiddlynotes-lite/id465933435?mt=8]] for iPhone, iPad and iPod Touch
|
|||
|
|
|||
|
Note that these applications are produced by independent third parties, and are not associated with tiddlywiki.com or UnaMesa.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="MonkeyPirateTWServer">
|
|||
|
<pre>|''URL:''|http://mptw.tiddlyspot.com/|
|
|||
|
|''Description:''|a tiddlywiki distribution and plugins|
|
|||
|
|''Author:''|SimonBaird|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="MoreTab">
|
|||
|
<pre>The functions of 'Timeline' and 'All' tabs have been around since the FirstVersion of TiddlyWiki. The purpose of the 'More' tab is to bring together some other, more specialised lists of tiddlers that can be useful during writing sessions. Currently, it offers lists of OrphanTiddlers and MissingTiddlers.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="NestedStyleSheets">
|
|||
|
<pre>Within a CustomStyleSheet, you can include the text of another tiddler by including it in double square brackets. For example, if the tiddler MyFavouriteColour contains {{{#ff763e}}}, and the StyleSheet tiddler contained:
|
|||
|
|
|||
|
{{{
|
|||
|
#mainMenu {background-color:[[MyFavouriteColour]];}
|
|||
|
}}}
|
|||
|
|
|||
|
Then, the effect is that each CSS declaration will be set to {{{background-color: #ff763e;}}}.
|
|||
|
|
|||
|
In practice, for small bits of text like a colour, it makes sense to use TiddlerSlicing format to reference a chunk of text within a tiddler. See ColorPalette and StyleSheetColors for an example.
|
|||
|
|
|||
|
Of course, you can use this mechanism to redirect any part of a stylesheet, not just colours. And you can nest references for more complex effects.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="NestedTemplates">
|
|||
|
<pre>A PageTemplate, ViewTemplate or EditTemplate can include the text of another tiddler by including it in double square brackets. For example:
|
|||
|
|
|||
|
{{{
|
|||
|
<div>
|
|||
|
[[MyHeader]]
|
|||
|
</div>
|
|||
|
}}}
|
|||
|
|
|||
|
You can also use TiddlerSlicing format to include a smaller chunk of the text of a tiddler.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="concepts" title="OpenSourceLicense">
|
|||
|
<pre>TiddlyWiki is published under a BSD OpenSourceLicense that gives you the freedom to use it pretty much however you want, including for commercial purposes, as long as you keep the copyright notice. (You can see the full license text by doing a 'view source' in your browser).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031802" modifier="jermolene" tags="browsers" title="Opera">
|
|||
|
<pre>~TiddlyWiki works with all recent versions of Opera, and can save changes using the TiddlySaver Java applet. If you're experiencing problems, make sure you've followed the appropriate [[downloading guidelines|Downloading]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="OrphanTiddlers">
|
|||
|
<pre>The 'Orphans' option on the MoreTab shows you the names of tiddlers that aren't linked to from any other tiddlers - in other words, tiddlers that there is no way for readers to find other than searching for them.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" title="Osmosoft">
|
|||
|
<pre>Osmosoft Limited was founded by JeremyRuston in 2005, and acquired by [[BT|http://btplc.com]] in 2007.
|
|||
|
|
|||
|
Osmosoft is now a small team within [[BT|http://www.btplc.com/]] that focuses on showing the value of open source working methods. It does this through working with the community on the ongoing development of TiddlyWiki, TiddlyWeb and TiddlySpace, and applying them to solve problems within BT.
|
|||
|
|
|||
|
See http://www.osmosoft.com/ for more details.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211431" modifier="colmbritton" tags="features" title="ParameterParser">
|
|||
|
<pre>The ParameterParser is used in several places in TiddlyWiki:
|
|||
|
* to process the StartupParameters after the '#' in a TiddlyWiki URL
|
|||
|
* to process the DefaultTiddlers list
|
|||
|
* to process the parameters to Macros
|
|||
|
* to process tag lists when editing a tiddler
|
|||
|
It supports a list of parameters each of the form "name:value". For example:
|
|||
|
{{{
|
|||
|
name:John location:"Isle of Wight" [[dietary needs]]:none really:'yes, really'
|
|||
|
}}}
|
|||
|
Names and values that need to contain spaces may be quoted with single- or double-quotes or double-square brackets. The parser is generally tolerant of additional spaces.
|
|||
|
|
|||
|
When processing macro parameters, names and values may also be quoted with double-braces which causes them to be evaluated as a [[JavaScript|http://en.wikipedia.org/wiki/JavaScript]] expression. For example:
|
|||
|
{{{
|
|||
|
title:{{window.title}}
|
|||
|
}}}
|
|||
|
|
|||
|
The ParameterParser will cope with either the name or the value being omitted, and will substitute a specified default. This is how the StartupParameters work; the default parameter name is specified as 'open'.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161207" modifier="colmbritton" tags="systemServer" title="PeachTWServer">
|
|||
|
<pre>|''URL:''|http://bradleymeck.tiddlyspot.com/|
|
|||
|
|''Description:''|Resources that are Ripe for the Picking|
|
|||
|
|''Author:''|~BradleyMeck|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="formatting" title="PeriodicTable">
|
|||
|
<pre>|Standard Periodic Table (ref. Wikipedia)|c
|
|||
|
|| !1 | !2 |!| !3 | !4 | !5 | !6 | !7 | !8 | !9 | !10 | !11 | !12 | !13 | !14 | !15 | !16 | !17 | !18 |
|
|||
|
|!1|bgcolor(#a0ffa0): @@color(red):H@@ |>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>||bgcolor(#c0ffff): @@color(red):He@@ |
|
|||
|
|!2|bgcolor(#ff6666): Li |bgcolor(#ffdead): Be |>|>|>|>|>|>|>|>|>|>||bgcolor(#cccc99): B |bgcolor(#a0ffa0): C |bgcolor(#a0ffa0): @@color(red):N@@ |bgcolor(#a0ffa0): @@color(red):O@@ |bgcolor(#ffff99): @@color(red):F@@ |bgcolor(#c0ffff): @@color(red):Ne@@ |
|
|||
|
|!3|bgcolor(#ff6666): Na |bgcolor(#ffdead): Mg |>|>|>|>|>|>|>|>|>|>||bgcolor(#cccccc): Al |bgcolor(#cccc99): Si |bgcolor(#a0ffa0): P |bgcolor(#a0ffa0): S |bgcolor(#ffff99): @@color(red):Cl@@ |bgcolor(#c0ffff): @@color(red):Ar@@ |
|
|||
|
|!4|bgcolor(#ff6666): K |bgcolor(#ffdead): Ca ||bgcolor(#ffc0c0): Sc |bgcolor(#ffc0c0): Ti |bgcolor(#ffc0c0): V |bgcolor(#ffc0c0): Cr |bgcolor(#ffc0c0): Mn |bgcolor(#ffc0c0): Fe |bgcolor(#ffc0c0): Co |bgcolor(#ffc0c0): Ni |bgcolor(#ffc0c0): Cu |bgcolor(#ffc0c0): Zn |bgcolor(#cccccc): Ga |bgcolor(#cccc99): Ge |bgcolor(#cccc99): As |bgcolor(#a0ffa0): Se |bgcolor(#ffff99): @@color(green):Br@@ |bgcolor(#c0ffff): @@color(red):Kr@@ |
|
|||
|
|!5|bgcolor(#ff6666): Rb |bgcolor(#ffdead): Sr ||bgcolor(#ffc0c0): Y |bgcolor(#ffc0c0): Zr |bgcolor(#ffc0c0): Nb |bgcolor(#ffc0c0): Mo |bgcolor(#ffc0c0): Tc |bgcolor(#ffc0c0): Ru |bgcolor(#ffc0c0): Rh |bgcolor(#ffc0c0): Pd |bgcolor(#ffc0c0): Ag |bgcolor(#ffc0c0): Cd |bgcolor(#cccccc): In |bgcolor(#cccccc): Sn |bgcolor(#cccc99): Sb |bgcolor(#cccc99): Te |bgcolor(#ffff99): I |bgcolor(#c0ffff): @@color(red):Xe@@ |
|
|||
|
|!6|bgcolor(#ff6666): Cs |bgcolor(#ffdead): Ba |bgcolor(#ffbfff):^^*1^^|bgcolor(#ffc0c0): Lu |bgcolor(#ffc0c0): Hf |bgcolor(#ffc0c0): Ta |bgcolor(#ffc0c0): W |bgcolor(#ffc0c0): Re |bgcolor(#ffc0c0): Os |bgcolor(#ffc0c0): Ir |bgcolor(#ffc0c0): Pt |bgcolor(#ffc0c0): Au |bgcolor(#ffc0c0): @@color(green):Hg@@ |bgcolor(#cccccc): Tl |bgcolor(#cccccc): Pb |bgcolor(#cccccc): Bi |bgcolor(#cccc99): Po |bgcolor(#ffff99): At |bgcolor(#c0ffff): @@color(red):Rn@@ |
|
|||
|
|!7|bgcolor(#ff6666): Fr |bgcolor(#ffdead): Ra |bgcolor(#ff99cc):^^*2^^|bgcolor(#ffc0c0): Lr |bgcolor(#ffc0c0): Rf |bgcolor(#ffc0c0): Db |bgcolor(#ffc0c0): Sq |bgcolor(#ffc0c0): Bh |bgcolor(#ffc0c0): Hs |bgcolor(#ffc0c0): Mt |bgcolor(#ffc0c0): Ds |bgcolor(#ffc0c0): Rg |bgcolor(#ffc0c0): @@color(green):Uub@@ |bgcolor(#cccccc): Uut |bgcolor(#cccccc): Uuq |bgcolor(#cccccc): Uup |bgcolor(#cccccc): Uuh |bgcolor(#fcfecc): @@color(#cccccc):Uus@@ |bgcolor(#ecfefc): @@color(#cccccc):Uuo@@ |
|
|||
|
|
|||
|
| !Lanthanides^^*1^^|bgcolor(#ffbfff): La |bgcolor(#ffbfff): Ce |bgcolor(#ffbfff): Pr |bgcolor(#ffbfff): Nd |bgcolor(#ffbfff): Pm |bgcolor(#ffbfff): Sm |bgcolor(#ffbfff): Eu |bgcolor(#ffbfff): Gd |bgcolor(#ffbfff): Tb |bgcolor(#ffbfff): Dy |bgcolor(#ffbfff): Ho |bgcolor(#ffbfff): Er |bgcolor(#ffbfff): Tm |bgcolor(#ffbfff): Yb |
|
|||
|
| !Actinides^^*2^^|bgcolor(#ff99cc): Ac |bgcolor(#ff99cc): Th |bgcolor(#ff99cc): Pa |bgcolor(#ff99cc): U |bgcolor(#ff99cc): Np |bgcolor(#ff99cc): Pu |bgcolor(#ff99cc): Am |bgcolor(#ff99cc): Cm |bgcolor(#ff99cc): Bk |bgcolor(#ff99cc): Cf |bgcolor(#ff99cc): Es |bgcolor(#ff99cc): Fm |bgcolor(#ff99cc): Md |bgcolor(#ff99cc): No |
|
|||
|
|
|||
|
*Chemical Series of the Periodic Table
|
|||
|
**@@bgcolor(#ff6666): Alkali metals@@
|
|||
|
**@@bgcolor(#ffdead): Alkaline earth metals@@
|
|||
|
**@@bgcolor(#ffbfff): Lanthanides@@
|
|||
|
**@@bgcolor(#ff99cc): Actinides@@
|
|||
|
**@@bgcolor(#ffc0c0): Transition metals@@
|
|||
|
**@@bgcolor(#cccccc): Poor metals@@
|
|||
|
**@@bgcolor(#cccc99): Metalloids@@
|
|||
|
**@@bgcolor(#a0ffa0): Nonmetals@@
|
|||
|
**@@bgcolor(#ffff99): Halogens@@
|
|||
|
**@@bgcolor(#c0ffff): Noble gases@@
|
|||
|
|
|||
|
*State at standard temperature and pressure
|
|||
|
**those in @@color(red):red@@ are gases
|
|||
|
**those in @@color(green):green@@ are liquids
|
|||
|
**those in black are solids
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="features" title="PermaView">
|
|||
|
<pre>PermaView is a button in the right-hand sidebar that sets the browser address bar to a URL embodying all the currently open tiddlers in the order that they are currently shown. To use it, arrange the open tiddlers that you want, click the permaview button, copy the URL from the browser address bar, and then paste it into an email, web page or whatever.
|
|||
|
|
|||
|
On some browsers, PermaView can be unreliable if any of the tiddler titles include characters that have special meanings in URLs (like "+" and "\") or are outside the basic ANSI character set.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211407" modifier="psd" tags="commands" title="PermalinkCommand">
|
|||
|
<pre>Changes the browser address bar to a permalink to the current tiddler. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar permalink>>
|
|||
|
}}}
|
|||
|
|
|||
|
On some browsers, the PermalinkCommand can be unreliable if the tiddler title includes characters that have special meanings in ~URLs (like "+" and "\") or are outside the basic ANSI character set.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="PersistentOptions">
|
|||
|
<pre>TiddlyWiki now has the ability to save options in the TiddlyWiki document itself (in addition to the ability to save options in cookies). Persistent options are stored in the [[SystemSettings]] tiddler. Persistent options are sometimes called "baked" options, since the value of the cookie is "baked" into the TiddlyWiki.
|
|||
|
|
|||
|
As an example, let's look at the {{{chkAnimate}}} option; this is currently stored as a cookie. You can get its value to be persistent by adding it to the [[SystemSettings]] tiddler. If there is no SystemSettings tiddler, you need to create it. Then add, for example:
|
|||
|
<<<
|
|||
|
chkAnimate: true
|
|||
|
<<<
|
|||
|
This has two effects, it makes the {{{chkAnimate}}} option persistent, and it gives the option a value (in this case {{{true}}}, it could equally well have been {{{false}}}).
|
|||
|
|
|||
|
The option can still be changed in the normal way (by ticking the box in the options panel); it can also be changed by editing the value in the [[SystemSettings]] tiddler. If the option is removed from the [[SystemSettings]] tiddler, then its value will be retained, but it will stored in a cookie.
|
|||
|
|
|||
|
!!Under the hood
|
|||
|
The "source" of an option is controlled by the {{{config.optionsSource[optionName]}}} variable. This can take one of two values:
|
|||
|
# {{{null}}} - the option is stored in a cookie, this is the ''default''.
|
|||
|
# {{{setting}}} - the option is stored in the [[SystemSettings]] tiddler.
|
|||
|
The {{{config.optionsSource[]}}} variable is controlled by the values in the [[SystemSettings]] tiddler. If the option exists in [[SystemSettings]], then {{{config.optionsSource[optionName]}}} is set to {{{setting}}}, and the option is persisted.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="formatting" title="PlainText">
|
|||
|
<pre>Sometimes text can inadvertently match TiddlyWiki formatting instructions - particularly program code, or text pasted from elsewhere. In these situations you can either use MonospacedText or you can accomplish the same thing without the monospaced effect like this:
|
|||
|
{{{
|
|||
|
This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>
|
|||
|
<nowiki>This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>></nowiki>
|
|||
|
"""This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>"""
|
|||
|
}}}
|
|||
|
Which displays as:
|
|||
|
This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>
|
|||
|
<nowiki>This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>></nowiki>
|
|||
|
"""This is AnotherLink, this is a copyright symbol &copy; and this site is called <<tiddler SiteTitle>>"""
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" title="PluginFormat">
|
|||
|
<pre>It is recommended that [[Plugins]] start with some standard information in TiddlerSlicing format. For example, see the ExamplePlugin:
|
|||
|
{{{
|
|||
|
|''Name:''|ExamplePlugin|
|
|||
|
|''Description:''|To demonstrate how to write TiddlyWiki plugins|
|
|||
|
|''Version:''|2.0.2|
|
|||
|
|''Date:''|Jul 12, 2006|
|
|||
|
|''Source:''|http://www.tiddlywiki.com/#ExamplePlugin|
|
|||
|
|''Author:''|JeremyRuston (jeremy (at) osmosoft (dot) com)|
|
|||
|
|''License:''|[[BSD open source license]]|
|
|||
|
|''~CoreVersion:''|2.1.0|
|
|||
|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|
|||
|
}}}
|
|||
|
At the moment, only ~CoreVersion affects how [[Plugins]] are processed: if the ~CoreVersion is specified for a plugin, TiddlyWiki will only execute the plugin if the core code version matches or exceeds the version specified. For example, if you specify a ~CoreVersion of 2.2, version 2.1.x of TiddlyWiki will refuse to execute the plugin.
|
|||
|
|
|||
|
To indicate an error, plugins should just {{{throw}}} an exception. The text of the exception will be displayed in the PluginManager.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102211429" modifier="colmbritton" tags="formatting" title="PluginFormatting">
|
|||
|
<pre>To make plugins, stylesheets and templates easier to read, you can use special alternative formatting for monospaced blocks.
|
|||
|
|
|||
|
In [[JavaScript|http://en.wikipedia.org/wiki/JavaScript]] code:
|
|||
|
{{{
|
|||
|
//{{{
|
|||
|
var id = document.getElementById("mainMenu");
|
|||
|
//}}}
|
|||
|
}}}
|
|||
|
In HTML templates:
|
|||
|
{{{
|
|||
|
<!--{{{-->
|
|||
|
<div id="MainMenu">
|
|||
|
</div>
|
|||
|
<!--}}}-->
|
|||
|
}}}
|
|||
|
In CSS stylesheets
|
|||
|
{{{
|
|||
|
/*{{{*/
|
|||
|
div {color: #ff0000;}
|
|||
|
/*}}}*/
|
|||
|
}}}
|
|||
|
It will be displayed as:
|
|||
|
//{{{
|
|||
|
var id = document.getElementById("mainMenu");
|
|||
|
//}}}
|
|||
|
|
|||
|
<!--{{{-->
|
|||
|
<div id="MainMenu">
|
|||
|
</div>
|
|||
|
<!--}}}-->
|
|||
|
|
|||
|
/*{{{*/
|
|||
|
div {color: #ff0000;}
|
|||
|
/*}}}*/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111613" creator="matt" modified="201102151511" modifier="matt" tags="shadow" title="PluginManager shadows">
|
|||
|
<pre>This tiddler contains the command to display the plugin manager:
|
|||
|
{{{
|
|||
|
<<plugins>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201111031825" modifier="jermolene" tags="community concepts gettingstarted" title="Plugins">
|
|||
|
<pre>~TiddlyWiki can be extended by [[installing plugins|InstallingPlugins]] that implement a wide variety of features (including [[Macros]], [[themes|http://tiddlythemes.com/]] or tweaks).
|
|||
|
|
|||
|
Community member Dave Gifford oversees an extensive catalogue of available plugins at [[TiddlyVault|http://tiddlyvault.tiddlyspot.com/]], and Eric Shulman maintains his own impressive collection of plugins at [[TiddlyTools|http://www.tiddlytools.com]]. More recently, Saq Imtiaz has built a service which lists plugins from all around the web in a single place, at [[plugins.tiddlywiki.org|http://plugins.tiddlywiki.org/]]
|
|||
|
|
|||
|
When you've chosen the plugin you'd like to import, follow the directions in ImportTiddlers (just make sure to tag the plugin {{{systemConfig}}}).
|
|||
|
|
|||
|
See http://tiddlywikidev.tiddlyspace.com/ for information on writing plugins for TiddlyWiki.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161208" modifier="colmbritton" tags="systemServer" title="PrinceTiddlyWikiExtensionsServer">
|
|||
|
<pre>|''URL:''|http://ptw.sourceforge.net/ptwe.html|
|
|||
|
|''Description:''|~BramChen's Extensions for TiddlyWiki|
|
|||
|
|''Author:''|~BramChen|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201110201351" modifier="jermolene" tags="community help" title="PublicationsAndArticles">
|
|||
|
<pre>~TiddlyWiki has appeared in a number of publications and articles:
|
|||
|
* A [[book about TiddlyWiki|http://www.flickr.com/photos/philhawksworth/1933329531/]] published in Taiwain
|
|||
|
* A [[guide|http://www.broowaha.com/articles/7671/a-personal-knowledgebase-solution-tiddlywiki-and-dropbox]] on using ~TiddlyWiki with ~DropBox.
|
|||
|
* [[Wikify Yourself|http://eriwen.com/tools/wikify-yourself/]] - Why every programmer should have a Tiddlywiki
|
|||
|
* Mike Mahemoff has created a [[screencast|http://softwareas.com/tiddlywiki-screencast-forum-in-15-minutes]] showing how to create a multi-user forum with ~TiddlyWiki in 15 minutes.
|
|||
|
* Pao-hsu Shih, a professor at Taipai University in Taiwan, has written an [[Introduction to TiddlyWiki|http://www.wunan.com.tw/bookdetail.asp?no=8852]] in Chinese
|
|||
|
* Dmitri Popov discusses ~TiddlyWiki in [[Writer for Writers and Advanced Users|http://www.lulu.com/content/221513]]
|
|||
|
* Jeremy Wagstaff's [[The Power of Tiddly|http://www.loosewireblog.com/2007/11/the-power-of-ti.html]]
|
|||
|
* Eric Shulman talking about TiddlyWiki at TiddlyWest, a meeting of TiddlyWiki enthusiasts in San Francisco in 2008:
|
|||
|
** http://blip.tv/play/gtQ9vexsAg
|
|||
|
** http://blip.tv/play/gtQ9ve0NAg
|
|||
|
** http://blip.tv/play/gtQ9ve0vAg
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111432" creator="matt" modified="201102151517" modifier="psd" tags="formatting" title="Quotations Formatting">
|
|||
|
<pre>!Block Quotations
|
|||
|
Blocks of text can be displayed as quotations:
|
|||
|
{{{
|
|||
|
<<<
|
|||
|
Steve Jobs: "computers are like a bicycle for our minds"
|
|||
|
<<<
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<<
|
|||
|
Steve Jobs: "computers are like a bicycle for our minds"
|
|||
|
<<<
|
|||
|
!Nested Quotations
|
|||
|
Quotes can be displayed on multi-levels:
|
|||
|
{{{
|
|||
|
> blockquote, level 1
|
|||
|
>> blockquote, level 2
|
|||
|
>>> blockquote, level 3
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
> blockquote, level 1
|
|||
|
>> blockquote, level 2
|
|||
|
>>> blockquote, level 3
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="welcome" title="Raves">
|
|||
|
<pre>~TiddlyWiki has received many favourable reviews:
|
|||
|
* "~TiddlyWiki offers a glimpse of how things are changing in terms of how people think about software... a new beginning for simple software." -- //Jeremy Wagstaff, [[WSJ.com|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/53c7b7686b9bb5c2/122f1b2146d2ba6d?q=wsj&rnum=1]]//
|
|||
|
* "The original ~TiddlyWiki by Jeremy Ruston is, without a doubt, one of the most amazing dynamic web apps I've ever seen (sorry Gmail.)" -- [[Lifehacker.com recommendation|http://www.lifehacker.com/software/productivity/getting-things-done-tiddlywiki-102953.php]]
|
|||
|
* "It's blowing my mind." -- //Evan Williams, founder of Blogger, Twitter and Odeo, [[EvHead|http://evhead.com/2005/05/tiddlywiki-reusable-non-linear.asp]]//
|
|||
|
* "What I love most about ~TiddlyWiki is that it is quite easy to use but incredibly flexible." -- //Ed Sim of Dawntreader Ventures, [[BeyondVC|http://www.beyondvc.com/2005/10/tiddlywiki.html]]//
|
|||
|
* "~TiddlyWiki is completely blowing my mind... Completely tripped out. Try it and you'll see what I mean." -- //Russell Beattie of Yahoo!, [[Russell Beattie's Notebook|http://www.russellbeattie.com/notebook/1008896.html]]//
|
|||
|
* "OK, this is the first wiki interface I’ve seen that has real potential. Dunno quite why exactly, but this blows my mind." -- //Jason Kottke, [[Kottke's Remaindered Links|http://www.kottke.org/remainder/04/09/6574.html]]//
|
|||
|
There is also the [[The Great TiddlyWiki Viral Mass Interview Challenge|http://interview.tiddlyspace.com/]], a community project to record the impact that TiddlyWiki has had on the people that use it and build it.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102161206" modifier="colmbritton" tags="systemServer" title="RedMountainVistaServer">
|
|||
|
<pre>|''URL:''|http://solo.dc3.com/tw/|
|
|||
|
|''Description:''|Bob Denny's extensions to TiddlyWiki|
|
|||
|
|''Author:''|~BobDenny|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111458" creator="colmbritton" modified="201110201344" modifier="jermolene" title="Reference">
|
|||
|
<pre>|!Formatting|!Macros|!Shadow tiddlers|!Miscellaneous|
|
|||
|
|<<tiddler WikiTextContent>>|<<tiddler MacrosContent>>|<<tiddler ShadowTiddlersContent>>|<<tiddler ReferenceContent>>|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201110201344" creator="jermolene" modifier="jermolene" tags="gettingstarted instructions" title="ReferenceContent">
|
|||
|
<pre>InterfaceOptions
|
|||
|
SaveChanges
|
|||
|
ToolbarButtons
|
|||
|
SafeMode
|
|||
|
KeyboardShortcuts
|
|||
|
StartupParameters
|
|||
|
SpecialTags
|
|||
|
SpecialTiddlers
|
|||
|
PermaView
|
|||
|
HtmlEntities
|
|||
|
[[Tags]]
|
|||
|
IncrementalSearch
|
|||
|
RegExpSearch
|
|||
|
SaveEmptyTemplate
|
|||
|
CustomStyleSheet
|
|||
|
NestedStyleSheets
|
|||
|
NestedTemplates
|
|||
|
TiddlerSlicing
|
|||
|
CustomMarkup
|
|||
|
MobileDevices
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="ReferencesButton">
|
|||
|
<pre>Since the FirstVersion of TiddlyWiki, the ReferencesButton has been implemented as a canned search for the name of the current tiddler. That approach was a bit disruptive because of the way that a search operation wipes the current reading state of the document.
|
|||
|
|
|||
|
The new implementation offers a popup menu of the names of all the referring tiddlers. It can be consulted without disturbing any tiddlers that are currently open.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="ReferencesCommand">
|
|||
|
<pre>Offers a popup menu displaying the tiddlers that link to the current one. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar references>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111106" creator="psd" modified="201110201351" modifier="jermolene" tags="features options" title="RegExpSearch">
|
|||
|
<pre>RegExpSearch is an [[advanced option|AdvancedOptions]] uses [[JavaScript|http://en.wikipedia.org/wiki/JavaScript]]'s [[RegExp syntax|http://www.programmershelp.co.uk/docs/javascript/regexp.html#1193188]] to allow flexible searches.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="features" title="RssFeed">
|
|||
|
<pre>TiddlyWiki's RSS feed is available [[here|http://www.tiddlywiki.com/index.xml]]. You can generate an RSS feed for your own TiddlyWiki using the GenerateAnRssFeed option.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="browsers issues" title="Safari">
|
|||
|
<pre>Safari can SaveChanges using the TiddlySaver Java applet.
|
|||
|
|
|||
|
There are still some issues with Safari:
|
|||
|
* Permalinks with Unicode characters in them (like [[this one|http://avm.free.fr/tidlipo.html#AdaptationFran%C3%A7aise]]) don't work properly
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="features" title="SafeMode">
|
|||
|
<pre>SafeMode can be selected by putting {{{#start:safe}}} (see StartupParameters) on the end of the TiddlyWiki URL. It stops TiddlyWiki from executing any [[Plugins]], modifying shadow tiddlers, or reading/writing cookies. It can be useful for tracking down problems caused by rogue [[Plugins]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="features options" title="SaveBackups">
|
|||
|
<pre>This is one of the InterfaceOptions you can use to customize TiddlyWiki. It determines whether TiddlyWiki creates a backup file each time you SaveChanges. I'd suggest keeping it switched on for safety!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031825" modifier="jermolene" tags="features gettingstarted instructions" title="SaveChanges">
|
|||
|
<pre>If you've followed the appropriate [[Downloading]] guidelines, then you can save your changes as you go along. (AutoSave makes this easy).
|
|||
|
|
|||
|
It's important to save changes using ~TiddlyWiki's built in saving functionality (rather than the browser's 'Save As' function - [[here's why|SaveUnpredictabilities]]). Your local version of ~TiddlyWiki will have a button on the right hand side that says 'save changes' - that's the button you'll need to use.
|
|||
|
|
|||
|
It's worthwhile configuring your backup settings. You can edit the AdvancedOptions to decide when backups are made and where they're saved.
|
|||
|
|
|||
|
If you're still experiencing problems, the following links will help:
|
|||
|
*General guidance on FireFox, InternetExplorer, [[Opera]], [[Camino]] or [[Safari]]
|
|||
|
* if you're using InternetExplorer on Windows you might run into XP ServicePack2Problems or VistaIssues
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="features options" title="SaveEmptyTemplate">
|
|||
|
<pre>This causes a blank, template TiddlyWiki to be saved alongside your file when you SaveChanges. It's intended to help people who are distributing TiddlyWikiAdaptations, and isn't needed when you're an end-user of TiddlyWiki.
|
|||
|
|
|||
|
The template TiddlyWiki is called 'empty.html'.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="commands" title="SaveTiddlerCommand">
|
|||
|
<pre>Saves any pending edits to the current tiddler, and switches it to the default view. It is used with the ToolbarMacro like this:
|
|||
|
{{{
|
|||
|
<<toolbar saveTiddler>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="issues troubleshooting" title="SaveUnpredictabilities">
|
|||
|
<pre>Several people have reported problems with reusing TiddlyWiki when they have used the File/Save command of their browser to save it. The issue is that some browsers (notably FireFox) don't save the text of the HTML file exactly as it appears on the server, but rather save a snapshot of the current state of the page. In the case of a highly dynamic page like TiddlyWiki, this leads to all sorts of peculiarness...
|
|||
|
|
|||
|
TiddlyWiki now displays a warning if it thinks that it has been saved wrongly.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031649" modifier="jermolene" title="Search">
|
|||
|
<pre>The default version of ~TiddlyWiki includes basic search functionality. When a search term is entered, all tiddlers that contain this term are opened, with the search term highlighted wherever it appears.
|
|||
|
|
|||
|
However, using the [[plugin architecture|Plugins]] of ~TiddlyWiki, the [[community|Help and Support]] has written a number of search plugins which can be installed on your local ~TiddlyWiki files easily. The most popular search plugins are:
|
|||
|
*Eric Shulman's ~SearchOptionsPlugin - a highly configurable plugin that produces a list of tiddler titles with options for advanced searches. Available at http://www.TiddlyTools.com/#SearchOptionsPlugin
|
|||
|
*Udo Borkowski's ~YourSearchPlugin - opens the search results in a large iFrame in the same style as Google (result, then synopsis). Available at http://tiddlywiki.abego-software.de/
|
|||
|
*Frederik Dohr's ~SimpleSearchPlugin (which this site is using) - copy and paste the code on [[this page|http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/SimpleSearchPlugin.js]] into a new tiddler, tag the tiddler with systemConfig, and save / re-open your ~TiddlyWiki.
|
|||
|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="concepts features" title="SelfContained">
|
|||
|
<pre>One of the neatest features of TiddlyWiki is that it is entirely self-contained in a single HTML file - even including graphics like the GradientMacro. The file contains the actual hypertext document, and the ~JavaScript, ~CascadingStyleSheets and HTML necessary to both view and edit it. This means that it is trivial to host a TiddlyWiki on a website, or to distribute one by email. And anyone with a reasonably recent web browser will be able to read and edit it.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031648" modifier="jermolene" tags="community concepts" title="ServerSide">
|
|||
|
<pre>Out of the box, ~TiddlyWiki doesn't have a Server Side back end. In many applications that's a great strength because it means that you can work with ~TiddlyWiki without having to be connected to the Internet or, because it's SelfContained, installing any software.
|
|||
|
|
|||
|
In other applications, a ~ServerSide can be very useful, particularly if you want to edit a ~TiddlyWiki while it's online, or you need lots of people to be able to edit a ~TiddlyWiki at the same time. The development [[Community]] has come up with several ~ServerSide implementations that are suitable for a range of applications, listed under HostedOptions.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="instructions issues troubleshooting" title="ServicePack2Problems">
|
|||
|
<pre>Internet Explorer Windows XP ~SP2 seems to have a magical ability to keep track of html files that have been downloaded from the internet and saved on an NTFS drive. By storing additional data in an [[alternate data stream|http://www.microsoft.com/technet/sysinternals/FileAndDisk/Streams.mspx]], it manages to keep them in the 'Internet' zone regardless of attempts to rename or modify the file. But, in order to be able to SaveChanges, TiddlyWiki needs to run in the 'My Computer' zone.
|
|||
|
|
|||
|
The solution is to right-click on the TiddlyWiki html file and choose //Properties//. If the file is blocked, you'll see an 'Unblock' button on the resulting property sheet that removes the protection and allows the file to open in the 'My Computer' zone. Then open the file in Internet Explorer - it might put up its information bar asking you whether you want to run it. You need to 'Allow blocked content' to let TiddlyWiki do its stuff.
|
|||
|
<<<
|
|||
|
If you find yourself running into the information bar frequently, you can disable it by visiting the "Options" dialog and, on the "Advanced" tab make sure that "Allow active content to run in files on My Computer" is checked.
|
|||
|
|
|||
|
Alternatively, you can rename the file to {{{*.hta}}} which has the added bonus of automatically granting all necessary save permissions.
|
|||
|
<<<
|
|||
|
This is all a bit frustrating. An easy alternative is to use FireFox, which seems to do the trick on all platforms.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="concepts terminology" title="ShadowTiddlers">
|
|||
|
<pre>ShadowTiddlers are special tiddlers that have default values that take over if they are undefined or deleted. For example, PageTemplate and StyleSheetColors are both shadow tiddlers.
|
|||
|
|
|||
|
ShadowTiddlers make it harder to render a TiddlyWiki inoperative by accidentally deleting something important. You can see a list of shadow tiddlers in the Shadowed tab under the More tab in the right hand column. When you create a tiddler with the same title you override the underlying shadow tiddler.
|
|||
|
----
|
|||
|
<<list shadowed>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111446" creator="colmbritton" modified="201102151536" modifier="matt" title="ShadowTiddlersContent">
|
|||
|
<pre>[[ColorPalette|ColorPalette shadows]]
|
|||
|
[[DefaultTiddlers|DefaultTiddlers shadows]]
|
|||
|
[[EditTemplate|EditTemplate shadows]]
|
|||
|
[[GettingStarted|GettingStarted shadows]]
|
|||
|
[[MainMenu|MainMenu shadows]]
|
|||
|
[[PageTemplate|PageTemplate shadows]]
|
|||
|
[[PluginManager|PluginManager shadows]]
|
|||
|
[[SideBarOptions|SideBarOptions shadows]]
|
|||
|
[[SiteSubtitle|SiteSubtitle shadows]]
|
|||
|
[[SiteTitle|SiteTitle shadows]]
|
|||
|
[[StyleSheet|StyleSheet shadows]]
|
|||
|
[[TabAll|TabAll shadows]]
|
|||
|
[[TabMoreMissing|TabMoreMissing shadows]]
|
|||
|
[[TabMoreOrphans|TabMoreOrphans shadows]]
|
|||
|
[[TabMoreShadowed|TabMoreShadowed shadows]]
|
|||
|
[[TabTimeline|TabTimeline shadows]]
|
|||
|
[[ViewTemplate|ViewTemplate shadows]]
|
|||
|
[[WindowTitle|WindowTitle shadows]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201111031637" creator="jermolene" modified="201111031638" modifier="jermolene" tags="excludeSearch" title="SideBarOptions">
|
|||
|
<pre><<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111438" creator="matt" modified="201102151511" modifier="matt" tags="shadow" title="SideBarOptions shadows">
|
|||
|
<pre>This tiddler contains the commands that produce the buttons contained in the slider above the timeline on the right.
|
|||
|
In ~TiddlySpace they are displayed on the right hand side of the menu bar.
|
|||
|
By default it is set to:
|
|||
|
{{{
|
|||
|
<<closeAll>><<permaview>><<newTiddler>>
|
|||
|
}}}
|
|||
|
|
|||
|
You can edit it to include anything else you want.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111121" creator="psd" modified="201102111310" modifier="blaine" tags="systemConfig" title="SimpleSearchPlugin">
|
|||
|
<pre>/***
|
|||
|
|''Name''|SimpleSearchPlugin|
|
|||
|
|''Description''|displays search results as a simple list of matching tiddlers|
|
|||
|
|''Authors''|FND|
|
|||
|
|''Version''|0.4.1|
|
|||
|
|''Status''|stable|
|
|||
|
|''Source''|http://devpad.tiddlyspot.com/#SimpleSearchPlugin|
|
|||
|
|''CodeRepository''|http://svn.tiddlywiki.org/Trunk/contributors/FND/plugins/SimpleSearchPlugin.js|
|
|||
|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|
|||
|
|''Keywords''|search|
|
|||
|
!Revision History
|
|||
|
!!v0.2.0 (2008-08-18)
|
|||
|
* initial release
|
|||
|
!!v0.3.0 (2008-08-19)
|
|||
|
* added Open All button (renders Classic Search option obsolete)
|
|||
|
* sorting by relevance (title matches before content matches)
|
|||
|
!!v0.4.0 (2008-08-26)
|
|||
|
* added tag matching
|
|||
|
!To Do
|
|||
|
* tag matching optional
|
|||
|
* animations for container creation and removal
|
|||
|
* when clicking on search results, do not scroll to the respective tiddler (optional)
|
|||
|
* use template for search results
|
|||
|
!Code
|
|||
|
***/
|
|||
|
//{{{
|
|||
|
if(!version.extensions.SimpleSearchPlugin) { //# ensure that the plugin is only installed once
|
|||
|
version.extensions.SimpleSearchPlugin = { installed: true };
|
|||
|
|
|||
|
if(!config.extensions) { config.extensions = {}; }
|
|||
|
|
|||
|
config.extensions.SimpleSearchPlugin = {
|
|||
|
heading: "Search Results",
|
|||
|
containerId: "searchResults",
|
|||
|
btnCloseLabel: "close",
|
|||
|
btnCloseTooltip: "dismiss search results",
|
|||
|
btnCloseId: "search_close",
|
|||
|
btnOpenLabel: "Open all",
|
|||
|
btnOpenTooltip: "open all search results",
|
|||
|
btnOpenId: "search_open",
|
|||
|
|
|||
|
displayResults: function(matches, query) {
|
|||
|
story.refreshAllTiddlers(true); // update highlighting within story tiddlers
|
|||
|
var el = document.getElementById(this.containerId);
|
|||
|
query = '"""' + query + '"""'; // prevent WikiLinks
|
|||
|
if(el) {
|
|||
|
removeChildren(el);
|
|||
|
} else { //# fallback: use displayArea as parent
|
|||
|
var container = document.getElementById("displayArea");
|
|||
|
el = document.createElement("div");
|
|||
|
el.id = this.containerId;
|
|||
|
el = container.insertBefore(el, container.firstChild);
|
|||
|
}
|
|||
|
var msg = "!" + this.heading + "\n";
|
|||
|
if(matches.length > 0) {
|
|||
|
msg += "''" + config.macros.search.successMsg.format([matches.length.toString(), query]) + ":''\n";
|
|||
|
this.results = [];
|
|||
|
for(var i = 0 ; i < matches.length; i++) {
|
|||
|
this.results.push(matches[i].title);
|
|||
|
msg += "* [[" + matches[i].title + "]]\n";
|
|||
|
}
|
|||
|
} else {
|
|||
|
msg += "''" + config.macros.search.failureMsg.format([query]) + "''"; // XXX: do not use bold here!?
|
|||
|
}
|
|||
|
createTiddlyButton(el, this.btnCloseLabel, this.btnCloseTooltip, config.extensions.SimpleSearchPlugin.closeResults, "button", this.btnCloseId);
|
|||
|
wikify(msg, el);
|
|||
|
if(matches.length > 0) { // XXX: redundant!?
|
|||
|
createTiddlyButton(el, this.btnOpenLabel, this.btnOpenTooltip, config.extensions.SimpleSearchPlugin.openAll, "button", this.btnOpenId);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
closeResults: function() {
|
|||
|
var el = document.getElementById(config.extensions.SimpleSearchPlugin.containerId);
|
|||
|
removeNode(el);
|
|||
|
config.extensions.SimpleSearchPlugin.results = null;
|
|||
|
highlightHack = null;
|
|||
|
},
|
|||
|
|
|||
|
openAll: function(ev) {
|
|||
|
story.displayTiddlers(null, config.extensions.SimpleSearchPlugin.results);
|
|||
|
return false;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.shadowTiddlers.StyleSheetSimpleSearch = "/*{{{*/\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.containerId + " {\n" +
|
|||
|
"\toverflow: auto;\n" +
|
|||
|
"\tpadding: 5px 1em 10px;\n" +
|
|||
|
"\tbackground-color: [[ColorPalette::TertiaryPale]];\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.containerId + " h1 {\n" +
|
|||
|
"\tmargin-top: 0;\n" +
|
|||
|
"\tborder: none;\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.containerId + " ul {\n" +
|
|||
|
"\tmargin: 0.5em;\n" +
|
|||
|
"\tpadding-left: 1.5em;\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button {\n" +
|
|||
|
"\tdisplay: block;\n" +
|
|||
|
"\tborder-color: [[ColorPalette::TertiaryDark]];\n" +
|
|||
|
"\tpadding: 5px;\n" +
|
|||
|
"\tbackground-color: [[ColorPalette::TertiaryLight]];\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.containerId + " .button:hover {\n" +
|
|||
|
"\tborder-color: [[ColorPalette::SecondaryMid]];\n" +
|
|||
|
"\tbackground-color: [[ColorPalette::SecondaryLight]];\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.btnCloseId + " {\n" +
|
|||
|
"\tfloat: right;\n" +
|
|||
|
"\tmargin: -5px -1em 5px 5px;\n" +
|
|||
|
"}\n\n" +
|
|||
|
"#" + config.extensions.SimpleSearchPlugin.btnOpenId + " {\n" +
|
|||
|
"\tfloat: left;\n" +
|
|||
|
"\tmargin-top: 5px;\n" +
|
|||
|
"}\n" +
|
|||
|
"/*}}}*/";
|
|||
|
store.addNotification("StyleSheetSimpleSearch", refreshStyles);
|
|||
|
|
|||
|
// override Story.search()
|
|||
|
Story.prototype.search = function(text, useCaseSensitive, useRegExp) {
|
|||
|
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(), useCaseSensitive ? "mg" : "img");
|
|||
|
var matches = store.search(highlightHack, null, "excludeSearch");
|
|||
|
var q = useRegExp ? "/" : "'";
|
|||
|
config.extensions.SimpleSearchPlugin.displayResults(matches, q + text + q);
|
|||
|
};
|
|||
|
|
|||
|
// override TiddlyWiki.search() to sort by relevance
|
|||
|
TiddlyWiki.prototype.search = function(searchRegExp, sortField, excludeTag, match) {
|
|||
|
var candidates = this.reverseLookup("tags", excludeTag, !!match);
|
|||
|
var primary = [];
|
|||
|
var secondary = [];
|
|||
|
var tertiary = [];
|
|||
|
for(var t = 0; t < candidates.length; t++) {
|
|||
|
if(candidates[t].title.search(searchRegExp) != -1) {
|
|||
|
primary.push(candidates[t]);
|
|||
|
} else if(candidates[t].tags.join(" ").search(searchRegExp) != -1) {
|
|||
|
secondary.push(candidates[t]);
|
|||
|
} else if(candidates[t].text.search(searchRegExp) != -1) {
|
|||
|
tertiary.push(candidates[t]);
|
|||
|
}
|
|||
|
}
|
|||
|
var results = primary.concat(secondary).concat(tertiary);
|
|||
|
if(sortField) {
|
|||
|
results.sort(function(a, b) {
|
|||
|
return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);
|
|||
|
});
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
} //# end of "install only once"
|
|||
|
//}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111102" creator="psd" modified="201102111310" modifier="blaine" tags="excludeLists excludeSearch" title="SiteTitle">
|
|||
|
<pre>TiddlyWiki
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111613" creator="matt" modified="201102151512" modifier="matt" tags="shadow" title="SiteTitle shadows">
|
|||
|
<pre>In the SiteTitle tiddler you can define the title of your TiddlyWiki. When you first create a TiddlyWiki it defaults to
|
|||
|
{{{
|
|||
|
TiddlyWiki
|
|||
|
}}}
|
|||
|
However you can edit it to display anything that you choose.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" title="SiteUrl">
|
|||
|
<pre>http://tiddlywiki.com/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102211429" modifier="colmbritton" tags="features" title="SpecialTags">
|
|||
|
<pre>TiddlyWiki defines a small number of SpecialTags that are used to indicate that tiddlers should be treated differently in some way:
|
|||
|
* ''excludeSearch'': excludes a tiddler from search results
|
|||
|
* ''excludeLists'': excludes a tiddler from the lists in the sidebar tabs
|
|||
|
* ''systemConfig'': marks tiddlers that contain [[JavaScript|http://en.wikipedia.org/wiki/JavaScript]] that should be executed once TiddlyWiki has loaded
|
|||
|
* ''excludeMissing'': excludes a tiddler from the processing that generates the MissingTiddlers list. Use it when you have a tiddler that contains links to missing tiddlers and you don't want those missing links to appear in the MissingTiddlers list
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111633" modifier="blaine" tags="features instructions" title="SpecialTiddlers">
|
|||
|
<pre>~TiddlyWiki uses several "special tiddlers" to perform a number of essential functions as follows:
|
|||
|
*[[Configuration]] tiddlers configure the layout of the page, including the MainMenu, the SiteTitle, the SiteSubtitle and other features.
|
|||
|
*A tiddler called DefaultTiddlers is used to list the tiddlers that are shown at startup.
|
|||
|
*A tiddler called SaveChanges is automatically displayed if there's a problem with saving. Any of them can be edited with the changes taking effect immediately.
|
|||
|
* MoreTab, MissingTiddlers, OrphanTiddlers
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102161201" modifier="colmbritton" tags="features" title="StartupParameters">
|
|||
|
<pre>TiddlyWiki obtains its StartupParameters from the //location// portion of it's URL (the bit after the '#'). At it's simplest, the StartupParameters can list the names of the tiddlers to be opened when the TiddlyWiki is opened:
|
|||
|
{{{
|
|||
|
http://www.tiddlywiki.com/#HelloThere JeremyRuston
|
|||
|
}}}
|
|||
|
In fact, that usage is equivalent to:
|
|||
|
{{{
|
|||
|
http://www.tiddlywiki.com/#open:HelloThere open:JeremyRuston
|
|||
|
}}}
|
|||
|
The complete list of commands is:
|
|||
|
|!Command |!Description |!Example |
|
|||
|
|open:title |Opens the tiddler with the specified title |http://www.tiddlywiki.com/#open:HelloThere |
|
|||
|
|start:safe |Switches to SafeMode |http://www.tiddlywiki.com/#start:safe |
|
|||
|
|search:text |Performs a search for the specified text |http://www.tiddlywiki.com/#search:jeremy |
|
|||
|
|tag:text |Displays tiddlers tagged with the specified tag |http://www.tiddlywiki.com/#tag:news |
|
|||
|
|newTiddler:title |Opens a new tiddler with the specified title in edit mode |http://www.tiddlywiki.com/#newTiddler:"This is a new tiddler" |
|
|||
|
|newJournal:titleFormat |Opens a new tiddler with the specified [[Date Format String|Date Formats]] |http://www.tiddlywiki.com/#newJournal:"YYYY MMM DD" |
|
|||
|
|
|||
|
See the details of the underlying ParameterParser for more details.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031825" modifier="jermolene" title="StyleSheet">
|
|||
|
<pre>/***
|
|||
|
This fixes a problem with the tabs slider
|
|||
|
***/
|
|||
|
/*{{{*/
|
|||
|
#sidebarTabs .button {
|
|||
|
margin:0em 0.2em;
|
|||
|
padding:0.2em 0.3em;
|
|||
|
display:block;
|
|||
|
}
|
|||
|
/*}}}*/
|
|||
|
/***
|
|||
|
This is a sample style definition to demonstrate [[CustomCssClass|CSS Formatting]] formatting
|
|||
|
***/
|
|||
|
/*{{{*/
|
|||
|
.wrappingClass {color: #666; background: #bbb;}
|
|||
|
/*}}}*/
|
|||
|
/***
|
|||
|
Prettyify
|
|||
|
***/
|
|||
|
/*{{{*/
|
|||
|
body {
|
|||
|
font-size: 0.92em;
|
|||
|
margin-bottom: 4em;
|
|||
|
}
|
|||
|
|
|||
|
.tiddler .viewer {
|
|||
|
font-size: 1.1em;
|
|||
|
}
|
|||
|
|
|||
|
#contentWrapper .chunkyButton {
|
|||
|
width: auto;
|
|||
|
}
|
|||
|
|
|||
|
#contentWrapper span.chunkyButton {
|
|||
|
border: none;
|
|||
|
}
|
|||
|
|
|||
|
#contentWrapper span.chunkyButton a.button, #contentWrapper span.chunkyButton a:active.button {
|
|||
|
font-weight: bold;
|
|||
|
font-size: 1.3em;
|
|||
|
color: [[ColorPalette::Background]];
|
|||
|
background-color: [[ColorPalette::QuaternaryMid]];
|
|||
|
text-align: center;
|
|||
|
padding: 0.5em 1em;
|
|||
|
border-radius: 1ex;
|
|||
|
border-style: none !important;
|
|||
|
}
|
|||
|
|
|||
|
#contentWrapper span.chunkyButton a.button:hover {
|
|||
|
background-color: [[ColorPalette::QuaternaryDark]];
|
|||
|
color: [[ColorPalette::Background]];
|
|||
|
border-style: none !important;
|
|||
|
}
|
|||
|
|
|||
|
/*}}}*/
|
|||
|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="matt" modified="201102151512" modifier="matt" tags="shadow" title="StyleSheet shadows">
|
|||
|
<pre>The StyleSheet tiddler allows you to customise the look and feel of your TiddlyWiki using CSS
|
|||
|
You can put simple one line tweaks in, like:
|
|||
|
{{{
|
|||
|
.mainMenu { color: red; }
|
|||
|
}}}
|
|||
|
|
|||
|
Or you can put in full ~StyleSheets, like that seen in TiddlySpace in the StyleSheetTiddlySpace
|
|||
|
{{{
|
|||
|
/*{{{*/
|
|||
|
[[StyleSheetTiddlySpace]]
|
|||
|
/*}}}*/
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102161122" creator="psd" modifier="psd" tags="formatting" title="Suppressing Formatting">
|
|||
|
<pre>Wiki markup rules can be suppressed for any given section of text by enclosing it in 3 ''double'' quotes:
|
|||
|
{{{
|
|||
|
"""//WikiWord//"""
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
"""//WikiWord//"""
|
|||
|
|
|||
|
WikiWords can also be suppressed by prefixing the WikiWord with ''~'':
|
|||
|
{{{
|
|||
|
~WikiWord
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
~WikiWord
|
|||
|
!!Also See
|
|||
|
[[Code formatting]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111614" creator="matt" modified="201102151513" modifier="matt" tags="shadow" title="TabAll shadows">
|
|||
|
<pre>The TabAll tiddler contains a command to list all of the tiddler in your TiddlyWiki.
|
|||
|
{{{
|
|||
|
<<list all>>
|
|||
|
}}}
|
|||
|
In TiddlyWiki this list appears as default in the {{{All}}} tab on the right-hand menu.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111614" creator="matt" modified="201102151514" modifier="matt" tags="shadow" title="TabMoreMissing shadows">
|
|||
|
<pre>The TabMoreMissing tiddler contains a command to list all of the tiddlers that have links to them but are undefined.
|
|||
|
{{{
|
|||
|
<<list missing>>
|
|||
|
}}}
|
|||
|
In TiddlyWiki this list appears as default in the {{{Missing}}} tab on the right-hand menu.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111615" creator="matt" modified="201102151514" modifier="matt" tags="shadow" title="TabMoreOrphans shadows">
|
|||
|
<pre>The TabMoreOrphans tiddler contains a command that lists all the tiddlers that are not linked to from any other tidder.
|
|||
|
{{{
|
|||
|
<<list orphans>>
|
|||
|
}}}
|
|||
|
In TiddlyWiki this list appears as default in the {{{Orphans}}} tab on the right-hand menu.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111615" creator="matt" modified="201102151514" modifier="matt" tags="shadow" title="TabMoreShadowed shadows">
|
|||
|
<pre>The TabMoreShadowed tiddler contains a command that displays a list of all tiddlers shadowed with default content in them
|
|||
|
{{{
|
|||
|
<<list shadowed>>
|
|||
|
}}}
|
|||
|
In TiddlyWiki this list appears as default in the {{{Shadows}}} tab on the right-hand menu.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111616" creator="matt" modified="201102151514" modifier="matt" tags="shadow" title="TabTimeline shadows">
|
|||
|
<pre>The TabTimeline tiddler contains a command to list in reverse chronological the tiddlers in your TiddlyWiki
|
|||
|
{{{
|
|||
|
<<timeline>>
|
|||
|
}}}
|
|||
|
In TiddlyWiki this list appears as default in the {{{Recent}}} tab on the right-hand menu.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111433" creator="matt" modified="201102151517" modifier="psd" tags="formatting" title="Tables Formatting">
|
|||
|
<pre>!Simple Tables
|
|||
|
{{{
|
|||
|
|North West|North|North East|
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|North West|North|North East|
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
!Cell Formatting
|
|||
|
*Insert a space before cell content to right justify cell
|
|||
|
*Insert a space after cell content to left justify cell
|
|||
|
*Insert spaces before and after cell content to centre justify cell
|
|||
|
*Insert an exclamation mark ({{{!}}}) as the first non-space character of a cell to turn it into a header cell
|
|||
|
For example:
|
|||
|
{{{
|
|||
|
|!First column|!Second column|!Third column|
|
|||
|
|left | centre | right|
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|!First column|!Second column|!Third column|
|
|||
|
|left | centre | right|
|
|||
|
!Table Headers and Footers
|
|||
|
* Mark a table row as a header by adding an 'h' to the end
|
|||
|
* Mark a table row as a footer by adding an 'f' to the end
|
|||
|
For example:
|
|||
|
{{{
|
|||
|
|North West|North|North East|h
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|f
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|North West|North|North East|h
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|f
|
|||
|
!Table Caption
|
|||
|
A caption can be added above or below a table by adding a special row marked with a 'c':
|
|||
|
{{{
|
|||
|
|A caption above the table|c
|
|||
|
|North West|North|North East|
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
}}}
|
|||
|
{{{
|
|||
|
|North West|North|North East|
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
|A caption below the table|c
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|A caption above the table|c
|
|||
|
|North West|North|North East|h
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|f
|
|||
|
|
|||
|
|North West|North|North East|h
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|f
|
|||
|
|A caption below the table|c
|
|||
|
!Mergine Table Cells
|
|||
|
A cell can be merged horizontally with the cell to its right by giving it the text {{{>}}}:
|
|||
|
{{{
|
|||
|
|North West|North|North East|
|
|||
|
|>|>|West and Here and East|
|
|||
|
|South West|South|South East|
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|North West|North|North East|
|
|||
|
|>|>|West and Here and East|
|
|||
|
|South West|South|South East|
|
|||
|
A cell can be merged vertically with the cell in the row above by giving it the text {{{~}}}:
|
|||
|
{{{
|
|||
|
|Westerly|North|North East|
|
|||
|
|~|Here|East|
|
|||
|
|~|South|South East|
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|Westerly|North|North East|
|
|||
|
|~|Here|East|
|
|||
|
|~|South|South East|
|
|||
|
!Table CSS Formatting
|
|||
|
A CSS class can be added to an entire table by adding a special row tagged with a 'k':
|
|||
|
{{{
|
|||
|
|myClass|k
|
|||
|
|North West|North|North East|
|
|||
|
|West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
}}}
|
|||
|
CSS properties can be added to a table cell by preceding the cell content with CSS name/value pairs. There are two alternative forms of syntax:
|
|||
|
{{{
|
|||
|
|color:red; North West|opacity:0.5;North|North East|
|
|||
|
|color(green):West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|color:red; North West|opacity:0.5;North|North East|
|
|||
|
|color(green):West|Here|East|
|
|||
|
|South West|South|South East|
|
|||
|
!Alternating Rows
|
|||
|
TiddlyWiki automatically assigns the classes {{{oddRow}}} and {{{evenRow}}} to table rows {{{<TR>}}} elements. These can then be styled via the StyleSheet:
|
|||
|
{{{
|
|||
|
.viewer tr.oddRow { background-color: #fff; }
|
|||
|
.viewer tr.evenRow { background-color: #ffc; }
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="features gettingstarted terminology" title="Tags">
|
|||
|
<pre>You can categorise a tiddler by assigning it with one or more special keywords called tags.
|
|||
|
|
|||
|
Tiddlers which have been assigned tags can be accessed using the tagging menu that appears at the top right of each tiddler (when in read mode). For instance, this tiddler is tagged with "features", "terminology" and "gettingstarted". If you click on these tag names in the tagging menu, you get access to all the other tiddlers that have been given the same tag.
|
|||
|
|
|||
|
You can see a whole list of tags by looking in the [[SideBarTabs]], and selecting the Tags tab.
|
|||
|
|
|||
|
This site uses the standard convention that the names of tags start with a lower case letter, and tiddlers with an upper case letter, but this is not actually enforced.
|
|||
|
|
|||
|
Tags can be tiddlers themselves, with their own tags, so you can have hierarchies of tiddlers. This is a surprisingly useful and powerful technique has been dubbed ~TagglyTagging by the [[Community]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="terminology concepts history" title="Tiddler">
|
|||
|
<pre>A 'tiddler' is the name given to a unit of MicroContent in TiddlyWiki.
|
|||
|
|
|||
|
Tiddlers are pervasive in TiddlyWiki. The MainMenu is defined by a tiddler, plugins are delivered in tiddlers, there are special StyleSheet tiddlers, and so on.
|
|||
|
|
|||
|
Other systems have analogous concepts with more prosaic names: like "items", "entries", "entities". Even though "tiddler" is a vaguely preposterous name it at least has the virtue of being confusingly distinctive rather than confusingly generic.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="formatting" title="TiddlerComments">
|
|||
|
<pre>To hide text within a tiddler so that it is not displayed you can wrap it in {{{/%}}} and {{{%/}}}. It can be a useful trick for hiding drafts or annotating complex markup. Edit this tiddler to see an example.
|
|||
|
/%This text is not displayed
|
|||
|
until you try to edit %/
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102161116" modifier="psd" title="TiddlerSlicing">
|
|||
|
<pre>TiddlerSlicing allows you to use special notation to pull out a chunk of specially marked text from within a tiddler. Each slice has a name and a value which can be specified anywhere within a tiddler in any of these formats:
|
|||
|
{{{
|
|||
|
theName: textSlice
|
|||
|
|theName:| textSlice |
|
|||
|
|theName| textSlice |
|
|||
|
}}}
|
|||
|
The name may contain any of the characters "a-ZA-Z_0-9", and may also be decorated with {{{''}}} or {{{//}}} markers for ''bold'' and //italic// formatting that are ignored. For example:
|
|||
|
{{{
|
|||
|
|''theName:''| textSlice |
|
|||
|
}}}
|
|||
|
Slices can be then be referenced by qualifying the parent tiddler name with the symbols "::" and the name of the slice. For example:
|
|||
|
{{{
|
|||
|
ColorPalette::PrimaryLight
|
|||
|
}}}
|
|||
|
TiddlerSlicing doesn't work eveywhere; at this point it is mainly intended to support the ColorPalette and similar usages.
|
|||
|
|
|||
|
Finally, here's an example of some more complex slice formatting:
|
|||
|
{{{
|
|||
|
version: 1.2.3.4
|
|||
|
Author: Joe Brown
|
|||
|
''Credits:'' ~ASmith ~BBrown ~CCalony
|
|||
|
//~SeeAlso:// The rise and fall of the M-perium
|
|||
|
|!Name|!Value|
|
|||
|
|Name:|TextSlice Tester|
|
|||
|
|URL:|http:\\sample.com\TestSliced |
|
|||
|
|''Type:''| Plugin |
|
|||
|
|//Source//| http:\\sample.com\TestSliced\src\text.js |
|
|||
|
}}}
|
|||
|
The slices defined in that example are:
|
|||
|
|version|1.2.3.4|
|
|||
|
|Author|Joe Brown|
|
|||
|
|Credits|~ASmith ~BBrown ~CCalony|
|
|||
|
|~SeeAlso|The rise and fall of the M-perium|
|
|||
|
|Name|TextSlice Tester|
|
|||
|
|URL|http:\\sample.com\TestSliced|
|
|||
|
|Type|Plugin|
|
|||
|
|Source|http:\\sample.com\TestSliced\src\text.js|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="community help" title="TiddlyBookmarklets">
|
|||
|
<pre>[[Bookmarklets|http://en.wikipedia.org/wiki/Bookmarklet]] can be useful for TiddlyWiki hackers. They are browser bookmarks that contain embedded ~JavaScript that can reach into the currently loaded TiddlyWiki page to manipulate them and extract data.
|
|||
|
|
|||
|
Drag these links to your bookmark/favourites bar, or right click on them and choose "add to bookmarks" or "add to favourites":
|
|||
|
* [[Scrub shadow tiddlers|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){for(var s in config.shadowTiddlers){store.removeTiddler(s);}refreshDisplay();}})()]] - deletes any overridden shadow tiddlers, reverting them to their default values. Handy when you’ve gone mad with PageTemplate customisations and your ~TiddlyWiki document won’t display properly
|
|||
|
* [[Scrub tiddler fields|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){store.forEachTiddler(function(title,tiddler){tiddler.fields={};});refreshDisplay();}})()]] - all the extended fields from a ~TiddlyWiki document, including that pesky “changecount” field
|
|||
|
* [[Rescue raw TiddlyWiki content|javascript:(function(){if(window.version&&window.version.title=='TiddlyWiki'){var w=window.open();w.document.open();w.document.write('<html><body><pre>');w.document.write(store.allTiddlersAsHtml().htmlEncode());w.document.write('</pre></body></html>');w.document.close();}})()]] - opens a new window containing the raw content of a ~TiddlyWiki. Handy when you’ve inadvertently been editing an online version of TiddlyWiki that isn’t letting you save changes in the usual way
|
|||
|
|
|||
|
If you're creating your own bookmarklets, this [[editor|http://subsimple.com/bookmarklets/jsbuilder.htm]] and these [[tips|http://subsimple.com/bookmarklets/tips.asp]] are useful resources.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031645" modifier="jermolene" tags="features" title="TiddlySaver">
|
|||
|
<pre>The ~TiddlySaver Java applet allows ~TiddlyWiki to save changes in a local version (from a file:// URL) of Safari, Opera and other browsers. It is a small file named [["TiddlySaver.jar"|TiddlySaver.jar]] that must be placed in the same directory as your ~TiddlyWiki file. As of August 2008, when an empty ~TiddlyWiki file is downloaded using either Safari or Opera, it is bundled with a copy of the ~TiddlySaver.jar file in a zip file - both files must be in the same directory ''whenever the ~TiddlyWiki file is opened'' in order to work.
|
|||
|
|
|||
|
[["TiddlySaver.jar"|TiddlySaver.jar]] is signed by [[UnaMesa Association|UnaMesa]]. The [[UnaMesa Association|UnaMesa]] certificate is signed by the ''Thawte Code Signing CA'' intermediate certificate which is chained to the ''Thawte Premium Server CA'' root certificate. You need to trust this certificate Chain to be able to use the applet.
|
|||
|
|
|||
|
Note that there is currently [[a bug|http://trac.tiddlywiki.org/ticket/172]] that prevents ~TiddlySaver from working if you have specified a backup directory in AdvancedOptions and the directory doesn't exist.
|
|||
|
|
|||
|
Thanks to Andrew Gregory for the original TiddlySaver code, and ~BidiX for arranging all the certificate magic.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="TiddlyStylesServer">
|
|||
|
<pre>|''URL:''|http://tiddlystyles.com/|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="TiddlyToolsServer">
|
|||
|
<pre>|''URL:''|http://www.tiddlytools.com/|
|
|||
|
|''Description:''|Small Tools for Big Ideas!|
|
|||
|
|''Author:''|EricShulman|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="concepts" title="TiddlyWiki">
|
|||
|
<pre>~TiddlyWiki is a complete [[wiki|WikiWikiWeb]] in a single HTML file. It contains the entire text of the wiki, and all the ~JavaScript, CSS and HTML goodness to be able to display it, and let you edit it or search it - without needing a server. Although, having said that, there are some fine ServerSide adaptations out there.
|
|||
|
|
|||
|
~TiddlyWiki was originally created by JeremyRuston and is now a thriving [[open source|OpenSourceLicense]] project with a busy [[Community]] of independent developers. [[Osmosoft]], part of [[BT|http://btplc.com]], is the leading contributor to the project.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201110041247" creator="jon" modified="201110241109" modifier="jon" tags="browsers issues" title="TiddlyWiki Browser Compatibility">
|
|||
|
<pre>Recent versions of Firefox and Chrome feature tighter default security settings that can interfere with the operation of TiddlyWiki. The main issue is new restrictions on the ability of TiddlyWiki running from a {{{file://}}} URI to access other servers.
|
|||
|
!!!Known Problems with Upgrading TiddlyWiki
|
|||
|
Versions of TiddlyWiki before and including 2.6.3 are known to have an issue with the upgrade function. To upgrade these versions you will need to download an empty latest version of TiddlyWiki and import your content into it using the [[import function|Import Tiddlers]] in the backstage.
|
|||
|
!!!Known Problems with Importing in TiddlyWiki
|
|||
|
* It is not possible to import from TiddlyWiki's on servers which are not [[CORS|http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing]] enabled. Popular sites such as [[TiddlyTools|http://tiddlytools.com]] are currently not CORS enabled. Fortunately this is fixable - webmasters can enable their sites to be CORS enabled by following the instructions [[here|http://enable-cors.org]] and if a website is not CORS enabled you can e-mail the owner to tell them the problem.
|
|||
|
* Some browsers will only allow you to import from other TiddlyWikis in the same directory as your TiddlyWiki. If you use Chrome you can enable this by modifying the Chrome shortcut to include the following parameter
|
|||
|
{{{
|
|||
|
--allow-file-access-from-files
|
|||
|
}}}
|
|||
|
* In Opera you can enable this by entering the following into your address bar and ticking the checkbox.
|
|||
|
{{{
|
|||
|
opera:config#UserPrefs|AllowFileXMLHttpRequest
|
|||
|
}}}
|
|||
|
* Note some browsers, do not support import / upgrade in any form.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031823" modifier="jermolene" tags="community history" title="TiddlyWikiAdaptations">
|
|||
|
<pre>Before TiddlyWiki supported [[Plugins]], several independent developers created their own extended adaptations to support new features. These can be considered forks of the original core code, and won't necessarily be based on the latest version. For that reason, the trend more recently has been for developers to release new features as [[Plugins]] that can be readily mixed and matched and upgraded to the latest version.
|
|||
|
|
|||
|
Here's a list of known adaptations - note that many of these are quite old, and the links may be dead (all working as at 10 July 2008):
|
|||
|
* Bram Chen's [[PrinceTiddlyWiki|http://ptw.sourceforge.net/]]
|
|||
|
* Jacques Turbé's [[TidliPo|http://avm.free.fr/tidlipo.html]] (in French)
|
|||
|
* Jároli József's [[MagyarTiddlyWiki|http://innen.hu/MagyarTiddlyWiki]] (in Hungarian)
|
|||
|
* Yoshimov's [[EncryptedTiddlyWiki|http://wiki.yoshimov.com/?page=EncryptedTiddlyWiki]] (in Japanese)
|
|||
|
* Nathan Bower's [[GTDTiddlyWiki|http://shared.snapgrid.com/gtd_tiddlywiki.html]]
|
|||
|
* Jonny ~LeRoy's [[TiddlyTagWiki|http://www.digitaldimsum.co.uk/tiddlywiki/]]
|
|||
|
* Christian Hauck's [[CompleXimple InDeed|http://www.christianhauck.net/html/14300.html]]
|
|||
|
* Tim Cuthbertson and Matt Giuca's [[TiddlyWikiCSS|http://codestar.lidonet.net/misc/tiddlywikicss.html]]
|
|||
|
* Patrick Curry and Gabriel Jeffrey's [[PhpTiddlyWiki|http://www.patrickcurry.com/tiddly/]]
|
|||
|
* Henrik Aasted Sorensen's [[server side adaptation|http://aasted.org/wiki]]
|
|||
|
* [[KamiWiki|http://rakusai.org/kamiwiki/]]
|
|||
|
* Kevem Buangga's [[TiddlyWikiClone|http://www.kevembuangga.com/hwk/hailiwiki.htm]]
|
|||
|
* Andre Nho's [[StickWiki|http://stickwiki.sourceforge.net/]]
|
|||
|
* [[MessageVault|http://www.kokogiak.com/gedankengang/2007/03/introducing-message-vault.html]], a personal password store built on some ~TiddlyWiki technology
|
|||
|
There's also some TiddlyWikiTools that extend ~TiddlyWiki.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111620" modifier="jermolene" tags="community" title="TiddlyWikiFiction">
|
|||
|
<pre>~TiddlyWiki has been used as the basis of a few experiments in hypertext fiction.
|
|||
|
*"[[Bibliotheca Caelestis. Tiddlywikiroman|http://bc.etkbooks.com/opac/]]" from Hartmut Abendschein
|
|||
|
*"[[Die, Vampire! Die!|http://www.davidvanwert.com/wiki/dievampiredie.html]]" from David Van Wert
|
|||
|
*"[[Rose|http://www.emacswiki.org/alex/rose.html]]" from Alex Schroeder
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="features options" title="ToggleLinks">
|
|||
|
<pre>If your press the command key on the Mac or the control key on the PC while clicking on a link to a tiddler, the tiddler will be opened as usual if it isn't already open, but if //is// open, it will be closed. It makes a handy way to review links without having to move the mouse around to re-close tiddlers.
|
|||
|
|
|||
|
You can make this behaviour the default under AdvancedOptions (you can override back to the normal behaviour with the same command/control key).
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="features" title="ToolbarButtons">
|
|||
|
<pre>A row of ToolbarButtons appears to the right of a tiddler title when the mouse is hovered over it. The buttons are:
|
|||
|
* ''close'' - close the current tiddler
|
|||
|
* ''edit'' - edit the current tiddler
|
|||
|
* ''fields'' - show the custom fields attached to the current tiddler
|
|||
|
* ''syncing'' - shows the server synchronisation status of the current tiddler
|
|||
|
* ''jump'' - jump straight to another open tiddler
|
|||
|
* ''permalink'' - puts a link direct to the current tiddler into the address bar
|
|||
|
* ''references'' - displays all the tiddlers that link to the current tiddler
|
|||
|
* ''done'' - save changes to a tiddler being editted
|
|||
|
* ''cancel'' - cancel changes to a tiddler being editted
|
|||
|
* ''delete'' - delete the current tiddler
|
|||
|
|
|||
|
The shadow tiddler ToolbarCommands allows these commands to customised and reordered.
|
|||
|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201110201351" modifier="jermolene" tags="community help" title="TutorialsAndGuides">
|
|||
|
<pre>The ~TiddlyWiki community have created several tutorials and guides. Here are some of the most popular ones:
|
|||
|
* Dave Gifford's [[TiddlyWiki for the Rest of Us|http://www.giffmex.org/twfortherestofus.html]]
|
|||
|
* Morris Gray's [[TW Help - TiddlyWiki help file for beginners|http://tiddlyspot.com/twhelp/]]
|
|||
|
* Julie Starr's [[Tiddler Toddler|http://tiddlertoddler.tiddlyspot.com/]], documenting the learning curve from a beginner's perspective
|
|||
|
* Screencasts from [[JimVentola|http://faculty.massasoit.mass.edu/jventola/videocasts/tidhelp2/tidhelp2.html]] and [[Phil Whitehouse|http://www.youtube.com/watch?v=ezNScBd7_h4]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" title="UnaMesa">
|
|||
|
<pre>[[UnaMesa|http://www.unamesa.org/]] is a non-profit organisation that owns and holds the IPR for TiddlyWiki in trust for the public.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="matt" modified="201102151515" modifier="matt" tags="shadow" title="ViewTemplate shadows">
|
|||
|
<pre>This tiddler contains the mark up to display tiddlers. You can change the mark up to create a custom view of a tiddler.
|
|||
|
|
|||
|
By default it contains the following markup:
|
|||
|
|
|||
|
{{{
|
|||
|
<div class='toolbar'
|
|||
|
macro='toolbar [[ToolbarCommands::ViewToolbar]] icons:yes height:16 width:16 more:popup'>
|
|||
|
</div>
|
|||
|
<div class='heading'>
|
|||
|
<span class='spaceSiteIcon'
|
|||
|
macro='tiddlerOrigin label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
|
|||
|
</span>
|
|||
|
<span class="titleBar">
|
|||
|
<div class='title' macro='view title text'></div>
|
|||
|
<div class="subtitle" macro='viewRevisions page:5'>
|
|||
|
last modified on
|
|||
|
<span macro="view modified date"></span>
|
|||
|
</div>
|
|||
|
</span>
|
|||
|
<span class='followPlaceHolder' macro='followTiddlers'></span>
|
|||
|
<span class='modifierIcon'
|
|||
|
macro='view modifier SiteIcon label:no spaceLink:yes height:48 width:48 preserveAspectRatio:yes'>
|
|||
|
</span>
|
|||
|
<div class='tagClear'></div>
|
|||
|
</div>
|
|||
|
<div class='content'>
|
|||
|
<div class='viewer' macro='view text wikified'></div>
|
|||
|
</div>
|
|||
|
<div class='tagInfo'>
|
|||
|
<div class='tidTags' macro='tags'></div>
|
|||
|
<div class='tagging' macro='tagging'></div>
|
|||
|
</div>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="browsers issues" title="VistaIssues">
|
|||
|
<pre>TiddlyWiki works fine under Internet Explorer on Windows Vista, although you may run into the blocking problem described in ServicePack2Problems.
|
|||
|
|
|||
|
Under Vista, TiddlyWiki will not save changes correctly if you are viewing the TiddlyWiki file in Vista's file preview pane.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="systemServer" title="VisualTWServer">
|
|||
|
<pre>|''URL:''|http://visualtw.ouvaton.org/VisualTW.html|
|
|||
|
|''Author:''|Pascal|
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" title="Wii">
|
|||
|
<pre>TiddlyWiki seems to [[work fine on the Wii browser|http://blog.deuceofalltrades.com/2007/02/wii-browser-meets-microcontent.html]], at least for browsing -- it doesn't appear that you can save or upload changes.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201110201351" modifier="jermolene" tags="concepts" title="WikiOnAStick">
|
|||
|
<pre>Putting ~TiddlyWiki on a USB stick lets you carry around a self contained notebook that you can update wherever there's a computer, whether it's a Mac, Linux or a PC.
|
|||
|
|
|||
|
To be even more independent you can [[install FireFox on the drive|http://portableapps.com/apps/internet/firefox_portable]] as well!
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111446" creator="colmbritton" modified="201102151540" modifier="matt" title="WikiTextContent">
|
|||
|
<pre>[[Basic|Basic Formatting]]
|
|||
|
[[CSS|CSS Formatting]]
|
|||
|
[[Code|Code Formatting]]
|
|||
|
[[HTML Entities|HTML Entities Formatting]]
|
|||
|
[[HTML|HTML Formatting]]
|
|||
|
[[Headings|Headings Formatting]]
|
|||
|
[[Horizontal Rules|Horizontal Rule Formatting]]
|
|||
|
[[Images|Image Formatting]]
|
|||
|
[[Line Breaks|Line Break Formatting]]
|
|||
|
[[Links|Link Formatting]]
|
|||
|
[[Lists|List Formatting]]
|
|||
|
[[Quotations|Quotations Formatting]]
|
|||
|
[[Suppressing|Suppressing Formatting]]
|
|||
|
[[Tables|Tables Formatting]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="concepts" title="WikiWikiWeb">
|
|||
|
<pre>A wiki (derived from the Hawaiian word for "fast") is a popular way of building collaborative websites. It's based on the two ideas of allowing users to easily edit any page and the use of special formatting to create links between pages. See Wikipedia for [[more details|http://en.wikipedia.org/wiki/Wiki]].
|
|||
|
|
|||
|
~TiddlyWiki is fundamentally different from a conventional Wiki because it is not based on separate, entire pages of content, but rather items of MicroContent referred to as [[Tiddlers|Tiddler]] that live together on the same page.
|
|||
|
|
|||
|
Out of the box, ~TiddlyWiki is also different because it doesn't support public editing - or indeed any persistent editing when viewed over the web. However, there are ServerSide editions, TiddlyWikiAdaptations and [[Plugins]] that provide these features in a wide range of different configurations.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111510" creator="blaine" modifier="blaine" title="WikiWord">
|
|||
|
<pre>A WikiWord is a word composed of a bunch of other words slammed together with each of their first letters capitalised. WikiWord notation in a conventional WikiWikiWeb is used to name individual pages while TiddlyWiki uses WikiWord titles for smaller chunks of MicroContent. Referring to a page with a WikiWord automatically creates a link to it. Clicking on a link jumps to that page or, if it doesn't exist, to an editor to create it. It's also easy to have NonWikiWordLinks, and there's a WikiWordEscape for situations where you don't want a WikiWord to be interpreted as a link.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111440" creator="matt" modified="201102151515" modifier="matt" tags="shadow" title="WindowTitle shadows">
|
|||
|
<pre>In this tiddler you put the text you wish to be displayed as the title of the page in the browser.
|
|||
|
By default it is set to:
|
|||
|
{{{
|
|||
|
<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>
|
|||
|
}}}
|
|||
|
which could display something like:
|
|||
|
{{{
|
|||
|
shadowtiddlers - a tiddlywiki
|
|||
|
}}}
|
|||
|
|
|||
|
You can change this at any time. For example:
|
|||
|
{{{
|
|||
|
Shadow Tiddlers Documentation | TiddlyWiki.com
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" tags="concepts" title="WritingStyle">
|
|||
|
<pre>I'm hoping that after using TiddlyWiki for a while a new WritingStyle will emerge that is appropriate for this medium. Jakob Neilsen wrote an article about [[writing styles|http://www.useit.com/alertbox/980906.html]] for MicroContent back in 1998 that still seems surprisingly relevant.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="allTags macro">
|
|||
|
<pre>At it's most basic this macro lists all the tags used in you tiddlywiki as dropdown lists of all the tiddlers which have that tag
|
|||
|
For example
|
|||
|
{{{
|
|||
|
<<allTags>>
|
|||
|
}}}
|
|||
|
|
|||
|
Displays as:
|
|||
|
<<allTags>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102281439" creator="jermolene" modifier="jermolene" title="anotherTiddlerToTransclude">
|
|||
|
<pre>Hello $1, welcome to $2
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="closeAll macro">
|
|||
|
<pre>To close all open tiddlers:
|
|||
|
{{{
|
|||
|
<<closeAll>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<closeAll>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" title="example">
|
|||
|
<pre>You just clicked on an example link, which was created by putting the word 'example' in double square brackets. You can now close this tiddler by clicking on the 'close' link above, and return to the guidelines.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111115" creator="jon" modifier="jon" title="favicon.ico">
|
|||
|
<pre>AAABAAEAEBAAAAAAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD////////////////////////////////////////////////a2tra2tra2tra2tr///////////+fn5+fn5+fn5+fn5+fn5+fn5/////////////a2tra2tra2tra2tr////MzMz////////////////////////////////////////a2tra2tra2tra2tr///////////+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5/////a2tra2tra2tra2tr////MzMz////////////////////////////////////////a2tra2tra2tra2tr///////////+fn5+fn5+fn5+fn5/////////////////////a2tra2tra2tra2tr////MzMz///+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5/////a2tra2tra2tra2tr///////////+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5/////////////////////////MzMz////////////////////////////////////////a2tra2tra2tra2tr///////////+fn5+fn5+fn5+fn5+fn5+fn5+fn5/////////////////////////////MzMz///+fn5+fn5+fn5+fn5+fn5+fn5+fn5+fn5/////a2tra2tra2tra2tr////////////////////////////////////////////////////////////////ETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPETQPVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfVXgfmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwvmbwv2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw/2fw8AAOLpAADg6QAAf18AAP//AAD//wAA//8AAP//AAD//wAAAIAAAP//AAD/fwAA//8AAACAAAD//wAA//8AAOHp
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111259" creator="blaine" modified="201102111310" modifier="blaine" title="iPhone">
|
|||
|
<pre>Community member ~BidiX has created an adaptation of the ~TiddlyWiki user interface [[specially for the iPhone|http://www.apple.com/webapps/productivity/itwatiddlywikiforiphone.html]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="list macro">
|
|||
|
<pre>!all
|
|||
|
To list all tiddlers
|
|||
|
{{{
|
|||
|
<<list all>>
|
|||
|
}}}
|
|||
|
!filter
|
|||
|
List tiddlers that match a certain [[filter|filters syntax]]. The following example lists all plugins.
|
|||
|
{{{
|
|||
|
<<list filter [tag[systemConfig]]>>
|
|||
|
}}}
|
|||
|
!Missing
|
|||
|
To list tiddlers that have links to them but are not defined:
|
|||
|
{{{
|
|||
|
<<list missing>>
|
|||
|
}}}
|
|||
|
!Orphans
|
|||
|
To list tiddlers that are not linked to from any other tiddlers:
|
|||
|
{{{
|
|||
|
<<list orphans>>
|
|||
|
}}}
|
|||
|
!Shadowed
|
|||
|
To list tiddlers shadowed with default contents:
|
|||
|
{{{
|
|||
|
<<list shadowed>>
|
|||
|
}}}
|
|||
|
!Touched
|
|||
|
Show tiddlers that have been modified locally:
|
|||
|
{{{
|
|||
|
<<list touched>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="newJournal macro">
|
|||
|
<pre>To create a new tiddler from the current date and time:
|
|||
|
{{{
|
|||
|
<<newJournal>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<newJournal>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="newTiddler macro">
|
|||
|
<pre>Using the following you get a new tiddler button:
|
|||
|
{{{
|
|||
|
<<newTiddler>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<newTiddler>>
|
|||
|
|
|||
|
Certain attributes can also be attached, such as a label, default text, tags and fields:
|
|||
|
{{{
|
|||
|
<<newTiddler label:WikiWord text:"text" tag:tag tag:tag accessKey:key focus:field>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<newTiddler label:WikiWord text:"text" tag:tag tag:tag accessKey:key focus:field>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102211421" creator="colmbritton" modified="201111031822" modifier="jermolene" tags="macro" title="options macro">
|
|||
|
<pre>The options macro, used predominately in the backstage, allows the user to set a number of cookie based options that affect the enabled features of the Tiddlywiki. These settings can be trivial, such as do you want animations enabled, or can be used for more complex things, such as enable regular expressions searches.
|
|||
|
It is used as below:
|
|||
|
{{{
|
|||
|
<<options>>
|
|||
|
}}}
|
|||
|
|
|||
|
Options can be used by plugin developers to add settings that can be used by their plugin.
|
|||
|
|
|||
|
Displays as:
|
|||
|
<<options>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="permaview macro">
|
|||
|
<pre>To create a permaview URL for all open tiddlers:
|
|||
|
{{{
|
|||
|
<<permaview>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<permaview>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="saveChanges macro">
|
|||
|
<pre>Using the following creates a save changes button
|
|||
|
{{{
|
|||
|
<<saveChanges>>
|
|||
|
}}}
|
|||
|
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<saveChanges>>
|
|||
|
|
|||
|
The button label can also be changed and a tooltip added:
|
|||
|
{{{
|
|||
|
<<saveChanges [label] [tip]>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<saveChanges [label] [tip]>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="search macro">
|
|||
|
<pre>Search fields can be created using:
|
|||
|
{{{
|
|||
|
<<search>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<search>>
|
|||
|
|
|||
|
A default search term can also be added:
|
|||
|
{{{
|
|||
|
<<search [term]>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
|
|||
|
<<search [term]>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="slider macro">
|
|||
|
<pre>The slider macro allows embedding tiddlers within another tiddler, with the option to toggle the visibility of the [[transclusion|transcluded]] content:
|
|||
|
{{{
|
|||
|
<<slider cookie tiddler label tooltip>>
|
|||
|
}}}
|
|||
|
* {{{cookie}}}: variable to save the state of the slider (e.g. {{{chkFooSlider}}})
|
|||
|
* {{{tiddler}}}: name of the tiddler to include in the slider
|
|||
|
* {{{label}}}: title text of the slider
|
|||
|
* {{{tooltip}}}: tooltip text of the slider
|
|||
|
|
|||
|
For example:
|
|||
|
{{{
|
|||
|
<<slider chkTestSlider [[OptionsPanel]] "Options" "Open advanced options">>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201102111310" modifier="blaine" title="systemServer">
|
|||
|
<pre>Tiddlers tagged {{{systemServer}}} wrap up all the connection details of a particular server so that they can be accessed quickly.
|
|||
|
|
|||
|
A list of available {{{systemServer}}} tiddlers is presented at the start of the ImportTiddlers macro. Selecting one of them pre-selects the relevant fields in the wizard. After a successful import operation, ImportTiddlers also offers the opportunity to automatically create a {{{systemServer}}} tiddler with the details of the server that was used. {{{systemServer}}} tiddlers are also used by the [[syncing]] command.
|
|||
|
|
|||
|
Here's an example {{{systemServer}}} tiddler:
|
|||
|
|
|||
|
<<<
|
|||
|
|''Description:''|My example server|
|
|||
|
|''Type:''|mediawiki|
|
|||
|
|''URL:''|http://www.myexampleserver.org/x/|
|
|||
|
|''Workspace:''|Main|
|
|||
|
|''~TiddlerFilter:''|[tags[important unpluggable]]|
|
|||
|
<<<
|
|||
|
|
|||
|
The fields are as follows:
|
|||
|
|
|||
|
|!Field |!Description |!Status |
|
|||
|
|Description |Brief description of the server |Optional |
|
|||
|
|Type |Type of server connection eg {{{file}}} or {{{mediawiki}}} |Optional - defaults to {{{file}}} |
|
|||
|
|URL |Host URL of the server |Mandatory |
|
|||
|
|Workspace |Name of the workspace |Optional |
|
|||
|
|TiddlerFilter |Specifies which tiddlers are to be imported |Optional |
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111531" creator="colmbritton" modified="201111031823" modifier="jermolene" tags="macro" title="tabs macro">
|
|||
|
<pre>The tab macro lets you create tab interfaces such as the one used for the timeline in the sidebar.
|
|||
|
You use it as follows:
|
|||
|
{{{
|
|||
|
<<tabs theCookieName
|
|||
|
nameOfFirstTab "HoverValueOfFirstTab" TiddlerToShowInTab(or content)
|
|||
|
nameOfSecondTab "HoverValueOfSecondTab" TiddlerToShowInTab(or content)
|
|||
|
...
|
|||
|
>>
|
|||
|
}}}
|
|||
|
''theCookieName'' is used to store the name of the tab you currently have open. It does this so that when you return the tiddler will still be displaying the last tab you had selected.
|
|||
|
|
|||
|
Example use of the tab macro:
|
|||
|
{{{
|
|||
|
<<tabs txtFavourite
|
|||
|
tags "First tab" "tags macro"
|
|||
|
tag "Second tab" "tag macro"
|
|||
|
>>
|
|||
|
}}}
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="tag macro">
|
|||
|
<pre>The tag macro generates a button with the named [[tag]] which when clicked provides a drop-down list of [[tiddlers]] tagged with the given tag along with an option to open all of the tagged tiddlers.
|
|||
|
{{{
|
|||
|
<<tag tagName [label] [tooltip]>>
|
|||
|
}}}
|
|||
|
For example
|
|||
|
{{{
|
|||
|
<<tag macro>>
|
|||
|
}}}
|
|||
|
Which displays
|
|||
|
<<tag macro>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="tagging macro">
|
|||
|
<pre>The tagging macro lists all the tiddlers that have a given tag. You set the tag you are looking for as the first parameter. E.g. to look for all tiddlers tagged with ''transclude'' you need to do the following:
|
|||
|
{{{
|
|||
|
<<tagging transclude>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<tagging transclude>>
|
|||
|
This macro also accepts a 2nd parameter which allows you to define a separator.
|
|||
|
{{{
|
|||
|
<<tagging transclude sep:____>> e.g. <<tagging transclude sep:---------->>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<tagging transclude sep:---------->>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="tags macro">
|
|||
|
<pre>To generate a list of [[tags]] applied to the current [[tiddler]]:
|
|||
|
{{{
|
|||
|
<<tags [tiddler]>>
|
|||
|
}}}
|
|||
|
|
|||
|
Note this will not display any tags that are themselves tagged excludeLists.
|
|||
|
For instance if there is a tiddler called "foo" tagged excludeLists and the tags macro is run on a tiddler with the tag foo, this tag will not be displayed.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102281441" modifier="jermolene" tags="macro" title="tiddler macro">
|
|||
|
<pre>The tiddler macro allows you to [[transclude|Tranclusion]] the text of other tidders, or sections of other tiddlers, into your current tiddler.
|
|||
|
!!Basic Usage
|
|||
|
The basic usage is:
|
|||
|
{{{
|
|||
|
<<tiddler tiddlerToTransclude>>
|
|||
|
}}}
|
|||
|
|
|||
|
This displays as:
|
|||
|
<<<
|
|||
|
<<tiddler tiddlerToTransclude>>
|
|||
|
<<<
|
|||
|
Have a look at the actual [[tiddlerToTransclude]] tiddler.
|
|||
|
!!Transcluding Sections and Slices
|
|||
|
Instead of transcluding an entire tiddler, you can also transclude individual [[slices|Tiddler Slices]] or [[sections|Tiddler Sections]]:
|
|||
|
{{{
|
|||
|
<<tiddler [[Title::sliceLabel]]>>
|
|||
|
<<tiddler [[Title##sectionHeading]]>>
|
|||
|
}}}
|
|||
|
!!Parameterised Transclusion
|
|||
|
Using the {{{with:}}} parameter, placeholders in the transcluded content can be replaced with a desired value. For example:
|
|||
|
{{{
|
|||
|
<<tiddler anotherTiddlerToTransclude with:"Jim" "Oz">>
|
|||
|
}}}
|
|||
|
Which displays as:
|
|||
|
<<<
|
|||
|
<<tiddler anotherTiddlerToTransclude with:"Jim" "Oz">>
|
|||
|
<<<
|
|||
|
Have a look at the actual [[anotherTiddlerToTransclude]].
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102161153" creator="colmbritton" modifier="colmbritton" title="tiddlerToTransclude">
|
|||
|
<pre>This text has been transcluded from another tidder.
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111328" creator="colmbritton" modifier="colmbritton" tags="excludeLists excludePublisher excludeSearch" tiddlyspaceinit_version="0.6" title="tiddlywiki-com-refSetupFlag">
|
|||
|
<pre>@@Please do not modify this tiddler; it was created automatically upon space creation.@@
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111102" creator="psd" modifier="psd" tags="excludeLists excludePublisher excludeSearch" tiddlyspaceinit_version="0.6" title="tiddlywiki-comSetupFlag">
|
|||
|
<pre>@@Please do not modify this tiddler; it was created automatically upon space creation.@@
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="timeline macro">
|
|||
|
<pre>To create a chronological list of recent edits:
|
|||
|
{{{
|
|||
|
<<timeline>>
|
|||
|
}}}
|
|||
|
It can accept 2 parameters. The first parameter can be either {{{modified}}} or {{{created}}}. This determines whether to list the tiddlers by last edited date or by creation date.
|
|||
|
It accepts a second parameter, an integer, which determines the number of tiddlers to list. This is particularly useful for option to use in spaces that have a large number of tiddlers.
|
|||
|
e.g.
|
|||
|
{{{
|
|||
|
<<timeline created 5>>>
|
|||
|
}}}
|
|||
|
displays as:
|
|||
|
<<timeline created 5>>
|
|||
|
{{{
|
|||
|
<<timeline modified 5>>
|
|||
|
}}}
|
|||
|
displays as:
|
|||
|
<<timeline modified 5>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="today macro">
|
|||
|
<pre>The date macro will display the current date and time:
|
|||
|
{{{
|
|||
|
<<today>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<today>>
|
|||
|
|
|||
|
This macro accepts one parameter - a date format. Such as:
|
|||
|
{{{
|
|||
|
<<today DD/MM/YYYY>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<today DD/MM/YYYY>>
|
|||
|
Read more about [[Date Formats]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111107" creator="psd" modified="201111031643" modifier="jermolene" tags="features translations" title="translations">
|
|||
|
<pre>~TiddlyWiki is available in 17 other languages languages.
|
|||
|
|
|||
|
Translations are packaged as plugins which are stored at https://github.com/TiddlyWiki/translations
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102111446" modifier="colmbritton" tags="macro" title="version macro">
|
|||
|
<pre>This is a simple macro that outputs the version of TiddlyWiki that is being used.
|
|||
|
{{{
|
|||
|
<<version>>
|
|||
|
}}}
|
|||
|
Displays as:
|
|||
|
<<version>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102111439" creator="colmbritton" modified="201102151557" modifier="psd" tags="macro" title="view macro">
|
|||
|
<pre>The view macro is a powerful macro that allows you to access fields on a given tiddler and format them.
|
|||
|
|
|||
|
The first parameter is the field to access (note tags does not work).
|
|||
|
The second parameter defines a [[view type|view macro types]] which defines how the value of that field should be rendered.
|
|||
|
|
|||
|
{{{
|
|||
|
<<view title link>>
|
|||
|
}}}
|
|||
|
renders the link of the current tiddler i.e. <<view title link>>
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
<div created="201102151603" creator="psd" modified="201102161143" modifier="colmbritton" title="view macro types">
|
|||
|
<pre>!Text
|
|||
|
Renders the field exactly how it is stored.
|
|||
|
For example
|
|||
|
{{{
|
|||
|
<<view modified text>>
|
|||
|
<<view title text>>
|
|||
|
}}}
|
|||
|
gives:
|
|||
|
* <<view modified text>>
|
|||
|
* <<view title text>>
|
|||
|
|
|||
|
!Link
|
|||
|
Renders the value of the field as a link
|
|||
|
{{{
|
|||
|
<<view title link>>
|
|||
|
}}}
|
|||
|
gives
|
|||
|
* <<view title link>>
|
|||
|
|
|||
|
!Date
|
|||
|
Applicable to the modified and created fields. Note a further parameter - a date format can be used.
|
|||
|
{{{
|
|||
|
<<view created date>>
|
|||
|
<<view modified date "YYYY">>
|
|||
|
}}}
|
|||
|
gives:
|
|||
|
* <<view created date>>
|
|||
|
* <<view modified date "YYYY">>
|
|||
|
See [[Date Formats]] for possible date format strings.
|
|||
|
|
|||
|
!Wikified
|
|||
|
Treats the string as wikitext.
|
|||
|
e.g.
|
|||
|
{{{
|
|||
|
<<view customfield wikified>>
|
|||
|
}}}
|
|||
|
|
|||
|
!TiddlySpace specific
|
|||
|
See [[TiddlySpace View Types]]
|
|||
|
</pre>
|
|||
|
</div>
|
|||
|
|
|||
|
|
|||
|
|
|||
|
</div>
|
|||
|
<!--POST-STOREAREA-->
|
|||
|
<!--POST-BODY-START-->
|
|||
|
|
|||
|
<!--POST-BODY-END-->
|
|||
|
<script id="jsArea" type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
|
|||
|
//
|
|||
|
// Please note:
|
|||
|
//
|
|||
|
// * This code is designed to be readable but for compactness it only includes brief comments. You can see fuller comments
|
|||
|
// in the project repository at https://github.com/TiddlyWiki/tiddlywiki
|
|||
|
//
|
|||
|
// * You should never need to modify this source code directly. TiddlyWiki is carefully designed to allow deep customisation
|
|||
|
// without changing the core code. Please consult the development group at http://groups.google.com/group/TiddlyWikiDev
|
|||
|
//
|
|||
|
// JSLint directives
|
|||
|
/*global jQuery:false, version:false */
|
|||
|
/*jslint bitwise:true, browser:true, confusion:true, eqeq:true, evil:true, forin:true, maxerr:100, plusplus:true, regexp:true, sloppy:true, sub:true, undef:true, unparam:true, vars:true, white:true */
|
|||
|
//--
|
|||
|
//-- Configuration repository
|
|||
|
//--
|
|||
|
|
|||
|
// Miscellaneous options
|
|||
|
var config = {
|
|||
|
numRssItems: 20, // Number of items in the RSS feed
|
|||
|
animDuration: 400, // Duration of UI animations in milliseconds
|
|||
|
cascadeFast: 20, // Speed for cascade animations (higher == slower)
|
|||
|
cascadeSlow: 60, // Speed for EasterEgg cascade animations
|
|||
|
cascadeDepth: 5, // Depth of cascade animation
|
|||
|
locale: "en" // W3C language tag
|
|||
|
};
|
|||
|
|
|||
|
// Hashmap of alternative parsers for the wikifier
|
|||
|
config.parsers = {};
|
|||
|
|
|||
|
// Adaptors
|
|||
|
config.adaptors = {};
|
|||
|
config.defaultAdaptor = null;
|
|||
|
|
|||
|
// Backstage tasks
|
|||
|
config.tasks = {};
|
|||
|
|
|||
|
// Annotations
|
|||
|
config.annotations = {};
|
|||
|
|
|||
|
// Custom fields to be automatically added to new tiddlers
|
|||
|
config.defaultCustomFields = {};
|
|||
|
|
|||
|
// Messages
|
|||
|
config.messages = {
|
|||
|
messageClose: {},
|
|||
|
dates: {},
|
|||
|
tiddlerPopup: {}
|
|||
|
};
|
|||
|
|
|||
|
// Options that can be set in the options panel and/or cookies
|
|||
|
config.options = {
|
|||
|
chkRegExpSearch: false,
|
|||
|
chkCaseSensitiveSearch: false,
|
|||
|
chkIncrementalSearch: true,
|
|||
|
chkAnimate: true,
|
|||
|
chkSaveBackups: true,
|
|||
|
chkAutoSave: false,
|
|||
|
chkGenerateAnRssFeed: false,
|
|||
|
chkSaveEmptyTemplate: false,
|
|||
|
chkOpenInNewWindow: true,
|
|||
|
chkToggleLinks: false,
|
|||
|
chkHttpReadOnly: true,
|
|||
|
chkForceMinorUpdate: false,
|
|||
|
chkConfirmDelete: true,
|
|||
|
chkInsertTabs: false,
|
|||
|
chkUsePreForStorage: true, // Whether to use <pre> format for storage
|
|||
|
chkDisplayInstrumentation: false,
|
|||
|
txtBackupFolder: "",
|
|||
|
txtEditorFocus: "text",
|
|||
|
txtMainTab: "tabTimeline",
|
|||
|
txtMoreTab: "moreTabAll",
|
|||
|
txtMaxEditRows: "30",
|
|||
|
txtFileSystemCharSet: "UTF-8",
|
|||
|
txtTheme: ""
|
|||
|
};
|
|||
|
config.optionsDesc = {};
|
|||
|
|
|||
|
config.optionsSource = {};
|
|||
|
|
|||
|
// Default tiddler templates
|
|||
|
var DEFAULT_VIEW_TEMPLATE = 1;
|
|||
|
var DEFAULT_EDIT_TEMPLATE = 2;
|
|||
|
config.tiddlerTemplates = {
|
|||
|
1: "ViewTemplate",
|
|||
|
2: "EditTemplate"
|
|||
|
};
|
|||
|
|
|||
|
// More messages (rather a legacy layout that should not really be like this)
|
|||
|
config.views = {
|
|||
|
wikified: {
|
|||
|
tag: {}
|
|||
|
},
|
|||
|
editor: {
|
|||
|
tagChooser: {}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Backstage tasks
|
|||
|
config.backstageTasks = ["save","sync","importTask","tweak","upgrade","plugins"];
|
|||
|
|
|||
|
// Extensions
|
|||
|
config.extensions = {};
|
|||
|
|
|||
|
// Macros; each has a 'handler' member that is inserted later
|
|||
|
config.macros = {
|
|||
|
today: {},
|
|||
|
version: {},
|
|||
|
search: {sizeTextbox: 15},
|
|||
|
tiddler: {},
|
|||
|
tag: {},
|
|||
|
tags: {},
|
|||
|
tagging: {},
|
|||
|
timeline: {},
|
|||
|
allTags: {},
|
|||
|
list: {
|
|||
|
all: {},
|
|||
|
missing: {},
|
|||
|
orphans: {},
|
|||
|
shadowed: {},
|
|||
|
touched: {},
|
|||
|
filter: {}
|
|||
|
},
|
|||
|
closeAll: {},
|
|||
|
permaview: {},
|
|||
|
saveChanges: {},
|
|||
|
slider: {},
|
|||
|
option: {},
|
|||
|
options: {},
|
|||
|
newTiddler: {},
|
|||
|
newJournal: {},
|
|||
|
tabs: {},
|
|||
|
gradient: {},
|
|||
|
message: {},
|
|||
|
view: {defaultView: "text"},
|
|||
|
edit: {},
|
|||
|
tagChooser: {},
|
|||
|
toolbar: {},
|
|||
|
plugins: {},
|
|||
|
refreshDisplay: {},
|
|||
|
importTiddlers: {},
|
|||
|
upgrade: {
|
|||
|
source: "http://tiddlywiki-releases.tiddlyspace.com/upgrade",
|
|||
|
backupExtension: "pre.core.upgrade"
|
|||
|
},
|
|||
|
sync: {},
|
|||
|
annotations: {}
|
|||
|
};
|
|||
|
|
|||
|
// Commands supported by the toolbar macro
|
|||
|
config.commands = {
|
|||
|
closeTiddler: {},
|
|||
|
closeOthers: {},
|
|||
|
editTiddler: {},
|
|||
|
saveTiddler: {hideReadOnly: true},
|
|||
|
cancelTiddler: {},
|
|||
|
deleteTiddler: {hideReadOnly: true},
|
|||
|
permalink: {},
|
|||
|
references: {type: "popup"},
|
|||
|
jump: {type: "popup"},
|
|||
|
syncing: {type: "popup"},
|
|||
|
fields: {type: "popup"}
|
|||
|
};
|
|||
|
|
|||
|
// Control of macro parameter evaluation
|
|||
|
config.evaluateMacroParameters = "all";
|
|||
|
|
|||
|
// Basic regular expressions
|
|||
|
config.textPrimitives = {
|
|||
|
upperLetter: "[A-Z\u00c0-\u00de\u0150\u0170]",
|
|||
|
lowerLetter: "[a-z0-9_\\-\u00df-\u00ff\u0151\u0171]",
|
|||
|
anyLetter: "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]",
|
|||
|
anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff\u0150\u0170\u0151\u0171]"
|
|||
|
};
|
|||
|
if(!((new RegExp("[\u0150\u0170]","g")).test("\u0150"))) {
|
|||
|
config.textPrimitives = {
|
|||
|
upperLetter: "[A-Z\u00c0-\u00de]",
|
|||
|
lowerLetter: "[a-z0-9_\\-\u00df-\u00ff]",
|
|||
|
anyLetter: "[A-Za-z0-9_\\-\u00c0-\u00de\u00df-\u00ff]",
|
|||
|
anyLetterStrict: "[A-Za-z0-9\u00c0-\u00de\u00df-\u00ff]"
|
|||
|
};
|
|||
|
}
|
|||
|
config.textPrimitives.sliceSeparator = "::";
|
|||
|
config.textPrimitives.sectionSeparator = "##";
|
|||
|
config.textPrimitives.urlPattern = "(?:file|http|https|mailto|ftp|irc|news|data):[^\\s'\"]+(?:/|\\b)";
|
|||
|
config.textPrimitives.unWikiLink = "~";
|
|||
|
config.textPrimitives.wikiLink = "(?:(?:" + config.textPrimitives.upperLetter + "+" +
|
|||
|
config.textPrimitives.lowerLetter + "+" +
|
|||
|
config.textPrimitives.upperLetter +
|
|||
|
config.textPrimitives.anyLetter + "*)|(?:" +
|
|||
|
config.textPrimitives.upperLetter + "{2,}" +
|
|||
|
config.textPrimitives.lowerLetter + "+))";
|
|||
|
|
|||
|
config.textPrimitives.cssLookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
|
|||
|
config.textPrimitives.cssLookaheadRegExp = new RegExp(config.textPrimitives.cssLookahead,"mg");
|
|||
|
|
|||
|
config.textPrimitives.brackettedLink = "\\[\\[([^\\]]+)\\]\\]";
|
|||
|
config.textPrimitives.titledBrackettedLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
|
|||
|
config.textPrimitives.tiddlerForcedLinkRegExp = new RegExp("(?:" + config.textPrimitives.titledBrackettedLink + ")|(?:" +
|
|||
|
config.textPrimitives.brackettedLink + ")|(?:" +
|
|||
|
config.textPrimitives.urlPattern + ")","mg");
|
|||
|
config.textPrimitives.tiddlerAnyLinkRegExp = new RegExp("("+ config.textPrimitives.wikiLink + ")|(?:" +
|
|||
|
config.textPrimitives.titledBrackettedLink + ")|(?:" +
|
|||
|
config.textPrimitives.brackettedLink + ")|(?:" +
|
|||
|
config.textPrimitives.urlPattern + ")","mg");
|
|||
|
|
|||
|
config.glyphs = {
|
|||
|
currBrowser: null,
|
|||
|
browsers: [],
|
|||
|
codes: {}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Shadow tiddlers
|
|||
|
//--
|
|||
|
|
|||
|
config.shadowTiddlers = {
|
|||
|
StyleSheet: "",
|
|||
|
MarkupPreHead: "",
|
|||
|
MarkupPostHead: "",
|
|||
|
MarkupPreBody: "",
|
|||
|
MarkupPostBody: "",
|
|||
|
TabTimeline: '<<timeline>>',
|
|||
|
TabAll: '<<list all>>',
|
|||
|
TabTags: '<<allTags excludeLists>>',
|
|||
|
TabMoreMissing: '<<list missing>>',
|
|||
|
TabMoreOrphans: '<<list orphans>>',
|
|||
|
TabMoreShadowed: '<<list shadowed>>',
|
|||
|
AdvancedOptions: '<<options>>',
|
|||
|
PluginManager: '<<plugins>>',
|
|||
|
SystemSettings: '',
|
|||
|
ToolbarCommands: '|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|\n|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|',
|
|||
|
WindowTitle: '<<tiddler SiteTitle>> - <<tiddler SiteSubtitle>>'
|
|||
|
};
|
|||
|
|
|||
|
// Browser detection... In a very few places, there's nothing else for it but to know what browser we're using.
|
|||
|
config.userAgent = navigator.userAgent.toLowerCase();
|
|||
|
config.browser = {
|
|||
|
isIE: config.userAgent.indexOf("msie") != -1 && config.userAgent.indexOf("opera") == -1,
|
|||
|
isGecko: navigator.product == "Gecko" && config.userAgent.indexOf("WebKit") == -1,
|
|||
|
ieVersion: /MSIE (\d.\d)/i.exec(config.userAgent), // config.browser.ieVersion[1], if it exists, will be the IE version string, eg "6.0"
|
|||
|
isSafari: config.userAgent.indexOf("applewebkit") != -1,
|
|||
|
isBadSafari: !((new RegExp("[\u0150\u0170]","g")).test("\u0150")),
|
|||
|
firefoxDate: /gecko\/(\d{8})/i.exec(config.userAgent), // config.browser.firefoxDate[1], if it exists, will be Firefox release date as "YYYYMMDD"
|
|||
|
isOpera: config.userAgent.indexOf("opera") != -1,
|
|||
|
isChrome: config.userAgent.indexOf('chrome') > -1,
|
|||
|
isLinux: config.userAgent.indexOf("linux") != -1,
|
|||
|
isUnix: config.userAgent.indexOf("x11") != -1,
|
|||
|
isMac: config.userAgent.indexOf("mac") != -1,
|
|||
|
isWindows: config.userAgent.indexOf("win") != -1
|
|||
|
};
|
|||
|
|
|||
|
merge(config.glyphs,{
|
|||
|
browsers: [
|
|||
|
function() {return config.browser.isIE;},
|
|||
|
function() {return true;}
|
|||
|
],
|
|||
|
codes: {
|
|||
|
downTriangle: ["\u25BC","\u25BE"],
|
|||
|
downArrow: ["\u2193","\u2193"],
|
|||
|
bentArrowLeft: ["\u2190","\u21A9"],
|
|||
|
bentArrowRight: ["\u2192","\u21AA"]
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
//--
|
|||
|
//-- Translateable strings
|
|||
|
//--
|
|||
|
|
|||
|
// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
|
|||
|
|
|||
|
merge(config.options,{
|
|||
|
txtUserName: "YourName"});
|
|||
|
|
|||
|
merge(config.tasks,{
|
|||
|
save: {text: "save", tooltip: "Save your changes to this TiddlyWiki"},
|
|||
|
sync: {text: "sync", tooltip: "Synchronise changes with other TiddlyWiki files and servers", content: '<<sync>>'},
|
|||
|
importTask: {text: "import", tooltip: "Import tiddlers and plugins from other TiddlyWiki files and servers", content: '<<importTiddlers>>'},
|
|||
|
tweak: {text: "tweak", tooltip: "Tweak the appearance and behaviour of TiddlyWiki", content: '<<options>>'},
|
|||
|
upgrade: {text: "upgrade", tooltip: "Upgrade TiddlyWiki core code", content: '<<upgrade>>'},
|
|||
|
plugins: {text: "plugins", tooltip: "Manage installed plugins", content: '<<plugins>>'}
|
|||
|
});
|
|||
|
|
|||
|
// Options that can be set in the options panel and/or cookies
|
|||
|
merge(config.optionsDesc,{
|
|||
|
txtUserName: "Username for signing your edits",
|
|||
|
chkRegExpSearch: "Enable regular expressions for searches",
|
|||
|
chkCaseSensitiveSearch: "Case-sensitive searching",
|
|||
|
chkIncrementalSearch: "Incremental key-by-key searching",
|
|||
|
chkAnimate: "Enable animations",
|
|||
|
chkSaveBackups: "Keep backup file when saving changes",
|
|||
|
chkAutoSave: "Automatically save changes",
|
|||
|
chkGenerateAnRssFeed: "Generate an RSS feed when saving changes",
|
|||
|
chkSaveEmptyTemplate: "Generate an empty template when saving changes",
|
|||
|
chkOpenInNewWindow: "Open external links in a new window",
|
|||
|
chkToggleLinks: "Clicking on links to open tiddlers causes them to close",
|
|||
|
chkHttpReadOnly: "Hide editing features when viewed over HTTP",
|
|||
|
chkForceMinorUpdate: "Don't update modifier username and date when editing tiddlers",
|
|||
|
chkConfirmDelete: "Require confirmation before deleting tiddlers",
|
|||
|
chkInsertTabs: "Use the tab key to insert tab characters instead of moving between fields",
|
|||
|
txtBackupFolder: "Name of folder to use for backups",
|
|||
|
txtMaxEditRows: "Maximum number of rows in edit boxes",
|
|||
|
txtTheme: "Name of the theme to use",
|
|||
|
txtFileSystemCharSet: "Default character set for saving changes (Firefox/Mozilla only)"});
|
|||
|
|
|||
|
merge(config.messages,{
|
|||
|
customConfigError: "Problems were encountered loading plugins. See PluginManager for details",
|
|||
|
pluginError: "Error: %0",
|
|||
|
pluginDisabled: "Not executed because disabled via 'systemConfigDisable' tag",
|
|||
|
pluginForced: "Executed because forced via 'systemConfigForce' tag",
|
|||
|
pluginVersionError: "Not executed because this plugin needs a newer version of TiddlyWiki",
|
|||
|
nothingSelected: "Nothing is selected. You must select one or more items first",
|
|||
|
savedSnapshotError: "It appears that this TiddlyWiki has been incorrectly saved. Please see http://www.tiddlywiki.com/#Download for details",
|
|||
|
subtitleUnknown: "(unknown)",
|
|||
|
undefinedTiddlerToolTip: "The tiddler '%0' doesn't yet exist",
|
|||
|
shadowedTiddlerToolTip: "The tiddler '%0' doesn't yet exist, but has a pre-defined shadow value",
|
|||
|
tiddlerLinkTooltip: "%0 - %1, %2",
|
|||
|
externalLinkTooltip: "External link to %0",
|
|||
|
noTags: "There are no tagged tiddlers",
|
|||
|
notFileUrlError: "You need to save this TiddlyWiki to a file before you can save changes",
|
|||
|
cantSaveError: "It's not possible to save changes. Possible reasons include:\n- your browser doesn't support saving (Firefox, Internet Explorer, Safari and Opera all work if properly configured)\n- the pathname to your TiddlyWiki file contains illegal characters\n- the TiddlyWiki HTML file has been moved or renamed",
|
|||
|
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
|
|||
|
backupSaved: "Backup saved",
|
|||
|
backupFailed: "Failed to save backup file",
|
|||
|
rssSaved: "RSS feed saved",
|
|||
|
rssFailed: "Failed to save RSS feed file",
|
|||
|
emptySaved: "Empty template saved",
|
|||
|
emptyFailed: "Failed to save empty template file",
|
|||
|
mainSaved: "Main TiddlyWiki file saved",
|
|||
|
mainFailed: "Failed to save main TiddlyWiki file. Your changes have not been saved",
|
|||
|
macroError: "Error in macro <<%0>>",
|
|||
|
macroErrorDetails: "Error while executing macro <<%0>>:\n%1",
|
|||
|
missingMacro: "No such macro",
|
|||
|
overwriteWarning: "A tiddler named '%0' already exists. Choose OK to overwrite it",
|
|||
|
unsavedChangesWarning: "WARNING! There are unsaved changes in TiddlyWiki\n\nChoose OK to save\nChoose CANCEL to discard",
|
|||
|
confirmExit: "--------------------------------\n\nThere are unsaved changes in TiddlyWiki. If you continue you will lose those changes\n\n--------------------------------",
|
|||
|
saveInstructions: "SaveChanges",
|
|||
|
unsupportedTWFormat: "Unsupported TiddlyWiki format '%0'",
|
|||
|
tiddlerSaveError: "Error when saving tiddler '%0'",
|
|||
|
tiddlerLoadError: "Error when loading tiddler '%0'",
|
|||
|
wrongSaveFormat: "Cannot save with storage format '%0'. Using standard format for save.",
|
|||
|
invalidFieldName: "Invalid field name %0",
|
|||
|
fieldCannotBeChanged: "Field '%0' cannot be changed",
|
|||
|
loadingMissingTiddler: "Attempting to retrieve the tiddler '%0' from the '%1' server at:\n\n'%2' in the workspace '%3'",
|
|||
|
upgradeDone: "The upgrade to version %0 is now complete\n\nClick 'OK' to reload the newly upgraded TiddlyWiki",
|
|||
|
invalidCookie: "Invalid cookie '%0'"});
|
|||
|
|
|||
|
merge(config.messages.messageClose,{
|
|||
|
text: "close",
|
|||
|
tooltip: "close this message area"});
|
|||
|
|
|||
|
config.messages.backstage = {
|
|||
|
open: {text: "backstage", tooltip: "Open the backstage area to perform authoring and editing tasks"},
|
|||
|
close: {text: "close", tooltip: "Close the backstage area"},
|
|||
|
prompt: "backstage: ",
|
|||
|
decal: {
|
|||
|
edit: {text: "edit", tooltip: "Edit the tiddler '%0'"}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.messages.listView = {
|
|||
|
tiddlerTooltip: "Click for the full text of this tiddler",
|
|||
|
previewUnavailable: "(preview not available)"
|
|||
|
};
|
|||
|
|
|||
|
config.messages.dates.months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November","December"];
|
|||
|
config.messages.dates.days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
|
|||
|
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
|
|||
|
config.messages.dates.shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
|
|||
|
// suffixes for dates, eg "1st","2nd","3rd"..."30th","31st"
|
|||
|
config.messages.dates.daySuffixes = ["st","nd","rd","th","th","th","th","th","th","th",
|
|||
|
"th","th","th","th","th","th","th","th","th","th",
|
|||
|
"st","nd","rd","th","th","th","th","th","th","th",
|
|||
|
"st"];
|
|||
|
config.messages.dates.am = "am";
|
|||
|
config.messages.dates.pm = "pm";
|
|||
|
|
|||
|
merge(config.messages.tiddlerPopup,{
|
|||
|
});
|
|||
|
|
|||
|
merge(config.views.wikified.tag,{
|
|||
|
labelNoTags: "no tags",
|
|||
|
labelTags: "tags: ",
|
|||
|
openTag: "Open tag '%0'",
|
|||
|
tooltip: "Show tiddlers tagged with '%0'",
|
|||
|
openAllText: "Open all",
|
|||
|
openAllTooltip: "Open all of these tiddlers",
|
|||
|
popupNone: "No other tiddlers tagged with '%0'"});
|
|||
|
|
|||
|
merge(config.views.wikified,{
|
|||
|
defaultText: "The tiddler '%0' doesn't yet exist. Double-click to create it",
|
|||
|
defaultModifier: "(missing)",
|
|||
|
shadowModifier: "(built-in shadow tiddler)",
|
|||
|
dateFormat: "DD MMM YYYY",
|
|||
|
createdPrompt: "created"});
|
|||
|
|
|||
|
merge(config.views.editor,{
|
|||
|
tagPrompt: "Type tags separated with spaces, [[use double square brackets]] if necessary, or add existing",
|
|||
|
defaultText: "Type the text for '%0'"});
|
|||
|
|
|||
|
merge(config.views.editor.tagChooser,{
|
|||
|
text: "tags",
|
|||
|
tooltip: "Choose existing tags to add to this tiddler",
|
|||
|
popupNone: "There are no tags defined",
|
|||
|
tagTooltip: "Add the tag '%0'"});
|
|||
|
|
|||
|
merge(config.messages,{
|
|||
|
sizeTemplates:
|
|||
|
[
|
|||
|
{unit: 1024*1024*1024, template: "%0\u00a0GB"},
|
|||
|
{unit: 1024*1024, template: "%0\u00a0MB"},
|
|||
|
{unit: 1024, template: "%0\u00a0KB"},
|
|||
|
{unit: 1, template: "%0\u00a0B"}
|
|||
|
]});
|
|||
|
|
|||
|
merge(config.macros.search,{
|
|||
|
label: "search",
|
|||
|
prompt: "Search this TiddlyWiki",
|
|||
|
placeholder: "",
|
|||
|
accessKey: "F",
|
|||
|
successMsg: "%0 tiddlers found matching %1",
|
|||
|
failureMsg: "No tiddlers found matching %0"});
|
|||
|
|
|||
|
merge(config.macros.tagging,{
|
|||
|
label: "tagging: ",
|
|||
|
labelNotTag: "not tagging",
|
|||
|
tooltip: "List of tiddlers tagged with '%0'"});
|
|||
|
|
|||
|
merge(config.macros.timeline,{
|
|||
|
dateFormat: "DD MMM YYYY"});
|
|||
|
|
|||
|
merge(config.macros.allTags,{
|
|||
|
tooltip: "Show tiddlers tagged with '%0'",
|
|||
|
noTags: "There are no tagged tiddlers"});
|
|||
|
|
|||
|
config.macros.list.all.prompt = "All tiddlers in alphabetical order";
|
|||
|
config.macros.list.missing.prompt = "Tiddlers that have links to them but are not defined";
|
|||
|
config.macros.list.orphans.prompt = "Tiddlers that are not linked to from any other tiddlers";
|
|||
|
config.macros.list.shadowed.prompt = "Tiddlers shadowed with default contents";
|
|||
|
config.macros.list.touched.prompt = "Tiddlers that have been modified locally";
|
|||
|
|
|||
|
merge(config.macros.closeAll,{
|
|||
|
label: "close all",
|
|||
|
prompt: "Close all displayed tiddlers (except any that are being edited)"});
|
|||
|
|
|||
|
merge(config.macros.permaview,{
|
|||
|
label: "permaview",
|
|||
|
prompt: "Link to an URL that retrieves all the currently displayed tiddlers"});
|
|||
|
|
|||
|
merge(config.macros.saveChanges,{
|
|||
|
label: "save changes",
|
|||
|
prompt: "Save all tiddlers to create a new TiddlyWiki",
|
|||
|
accessKey: "S"});
|
|||
|
|
|||
|
merge(config.macros.newTiddler,{
|
|||
|
label: "new tiddler",
|
|||
|
prompt: "Create a new tiddler",
|
|||
|
title: "New Tiddler",
|
|||
|
accessKey: "N"});
|
|||
|
|
|||
|
merge(config.macros.newJournal,{
|
|||
|
label: "new journal",
|
|||
|
prompt: "Create a new tiddler from the current date and time",
|
|||
|
accessKey: "J"});
|
|||
|
|
|||
|
merge(config.macros.options,{
|
|||
|
wizardTitle: "Tweak advanced options",
|
|||
|
step1Title: "These options are saved in cookies in your browser",
|
|||
|
step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Show unknown options</input>",
|
|||
|
unknownDescription: "//(unknown)//",
|
|||
|
listViewTemplate: {
|
|||
|
columns: [
|
|||
|
{name: 'Option', field: 'option', title: "Option", type: 'String'},
|
|||
|
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
|
|||
|
{name: 'Name', field: 'name', title: "Name", type: 'String'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
{className: 'lowlight', field: 'lowlight'}
|
|||
|
]}
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.plugins,{
|
|||
|
wizardTitle: "Manage plugins",
|
|||
|
step1Title: "Currently loaded plugins",
|
|||
|
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
|
|||
|
skippedText: "(This plugin has not been executed because it was added since startup)",
|
|||
|
noPluginText: "There are no plugins installed",
|
|||
|
confirmDeleteText: "Are you sure you want to delete these plugins:\n\n%0",
|
|||
|
removeLabel: "remove systemConfig tag",
|
|||
|
removePrompt: "Remove systemConfig tag",
|
|||
|
deleteLabel: "delete",
|
|||
|
deletePrompt: "Delete these tiddlers forever",
|
|||
|
listViewTemplate: {
|
|||
|
columns: [
|
|||
|
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
|
|||
|
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
|
|||
|
{name: 'Description', field: 'Description', title: "Description", type: 'String'},
|
|||
|
{name: 'Version', field: 'Version', title: "Version", type: 'String'},
|
|||
|
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
|
|||
|
{name: 'Forced', field: 'forced', title: "Forced", tag: 'systemConfigForce', type: 'TagCheckbox'},
|
|||
|
{name: 'Disabled', field: 'disabled', title: "Disabled", tag: 'systemConfigDisable', type: 'TagCheckbox'},
|
|||
|
{name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"},
|
|||
|
{name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'},
|
|||
|
{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"},
|
|||
|
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
{className: 'error', field: 'error'},
|
|||
|
{className: 'warning', field: 'warning'}
|
|||
|
]},
|
|||
|
listViewTemplateReadOnly: {
|
|||
|
columns: [
|
|||
|
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
|
|||
|
{name: 'Description', field: 'Description', title: "Description", type: 'String'},
|
|||
|
{name: 'Version', field: 'Version', title: "Version", type: 'String'},
|
|||
|
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
|
|||
|
{name: 'Executed', field: 'executed', title: "Loaded", type: 'Boolean', trueText: "Yes", falseText: "No"},
|
|||
|
{name: 'Startup Time', field: 'startupTime', title: "Startup Time", type: 'String'},
|
|||
|
{name: 'Error', field: 'error', title: "Status", type: 'Boolean', trueText: "Error", falseText: "OK"},
|
|||
|
{name: 'Log', field: 'log', title: "Log", type: 'StringList'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
{className: 'error', field: 'error'},
|
|||
|
{className: 'warning', field: 'warning'}
|
|||
|
]}
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.toolbar,{
|
|||
|
moreLabel: "more",
|
|||
|
morePrompt: "Show additional commands",
|
|||
|
lessLabel: "less",
|
|||
|
lessPrompt: "Hide additional commands",
|
|||
|
separator: "|"
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.refreshDisplay,{
|
|||
|
label: "refresh",
|
|||
|
prompt: "Redraw the entire TiddlyWiki display"
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.importTiddlers,{
|
|||
|
readOnlyWarning: "You cannot import into a read-only TiddlyWiki file. Try opening it from a file:// URL",
|
|||
|
wizardTitle: "Import tiddlers from another file or server",
|
|||
|
step1Title: "Step 1: Locate the server or TiddlyWiki file",
|
|||
|
step1Html: "Specify the type of the server: <select name='selTypes'><option value=''>Choose...</option></select><br>Enter the URL or pathname here: <input type='text' size=50 name='txtPath'><br>...or browse for a file: <input type='file' size=50 name='txtBrowse'><br><hr>...or select a pre-defined feed: <select name='selFeeds'><option value=''>Choose...</option></select>",
|
|||
|
openLabel: "open",
|
|||
|
openPrompt: "Open the connection to this file or server",
|
|||
|
statusOpenHost: "Opening the host",
|
|||
|
statusGetWorkspaceList: "Getting the list of available workspaces",
|
|||
|
step2Title: "Step 2: Choose the workspace",
|
|||
|
step2Html: "Enter a workspace name: <input type='text' size=50 name='txtWorkspace'><br>...or select a workspace: <select name='selWorkspace'><option value=''>Choose...</option></select>",
|
|||
|
cancelLabel: "cancel",
|
|||
|
cancelPrompt: "Cancel this import",
|
|||
|
statusOpenWorkspace: "Opening the workspace",
|
|||
|
statusGetTiddlerList: "Getting the list of available tiddlers",
|
|||
|
errorGettingTiddlerList: "Error getting list of tiddlers, click Cancel to try again",
|
|||
|
errorGettingTiddlerListHttp404: "Error retrieving tiddlers from url, please ensure the url exists. Click Cancel to try again.",
|
|||
|
errorGettingTiddlerListHttp: "Error retrieving tiddlers from url, please ensure this url exists and is <a href='http://enable-cors.org/'>CORS</a> enabled",
|
|||
|
errorGettingTiddlerListFile: "Error retrieving tiddlers from local file, please make sure the file is in the same directory as your TiddlyWiki. Click Cancel to try again.",
|
|||
|
step3Title: "Step 3: Choose the tiddlers to import",
|
|||
|
step3Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='true' name='chkSync'>Keep these tiddlers linked to this server so that you can synchronise subsequent changes</input><br><input type='checkbox' name='chkSave'>Save the details of this server in a 'systemServer' tiddler called:</input> <input type='text' size=25 name='txtSaveTiddler'>",
|
|||
|
importLabel: "import",
|
|||
|
importPrompt: "Import these tiddlers",
|
|||
|
confirmOverwriteText: "Are you sure you want to overwrite these tiddlers:\n\n%0",
|
|||
|
step4Title: "Step 4: Importing %0 tiddler(s)",
|
|||
|
step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
|
|||
|
doneLabel: "done",
|
|||
|
donePrompt: "Close this wizard",
|
|||
|
statusDoingImport: "Importing tiddlers",
|
|||
|
statusDoneImport: "All tiddlers imported",
|
|||
|
systemServerNamePattern: "%2 on %1",
|
|||
|
systemServerNamePatternNoWorkspace: "%1",
|
|||
|
confirmOverwriteSaveTiddler: "The tiddler '%0' already exists. Click 'OK' to overwrite it with the details of this server, or 'Cancel' to leave it unchanged",
|
|||
|
serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nThis tiddler was automatically created to record the details of this server",
|
|||
|
serverSaveModifier: "(System)",
|
|||
|
listViewTemplate: {
|
|||
|
columns: [
|
|||
|
{name: 'Selected', field: 'Selected', rowName: 'title', type: 'Selector'},
|
|||
|
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
|
|||
|
{name: 'Size', field: 'size', tiddlerLink: 'size', title: "Size", type: 'Size'},
|
|||
|
{name: 'Tags', field: 'tags', title: "Tags", type: 'Tags'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
]}
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.upgrade,{
|
|||
|
wizardTitle: "Upgrade TiddlyWiki core code",
|
|||
|
step1Title: "Update or repair this TiddlyWiki to the latest release",
|
|||
|
step1Html: "You are about to upgrade to the latest release of the TiddlyWiki core code (from <a href='%0' class='externalLink' target='_blank'>%1</a>). Your content will be preserved across the upgrade.<br><br>Note that core upgrades have been known to interfere with older plugins. If you run into problems with the upgraded file, see <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
|
|||
|
errorCantUpgrade: "Unable to upgrade this TiddlyWiki. You can only perform upgrades on TiddlyWiki files stored locally",
|
|||
|
errorNotSaved: "You must save changes before you can perform an upgrade",
|
|||
|
step2Title: "Confirm the upgrade details",
|
|||
|
step2Html_downgrade: "You are about to downgrade to TiddlyWiki version %0 from %1.<br><br>Downgrading to an earlier version of the core code is not recommended",
|
|||
|
step2Html_restore: "This TiddlyWiki appears to be already using the latest version of the core code (%0).<br><br>You can continue to upgrade anyway to ensure that the core code hasn't been corrupted or damaged",
|
|||
|
step2Html_upgrade: "You are about to upgrade to TiddlyWiki version %0 from %1",
|
|||
|
upgradeLabel: "upgrade",
|
|||
|
upgradePrompt: "Prepare for the upgrade process",
|
|||
|
statusPreparingBackup: "Preparing backup",
|
|||
|
statusSavingBackup: "Saving backup file",
|
|||
|
errorSavingBackup: "There was a problem saving the backup file",
|
|||
|
statusLoadingCore: "Loading core code",
|
|||
|
errorLoadingCore: "Error loading the core code",
|
|||
|
errorCoreFormat: "Error with the new core code",
|
|||
|
statusSavingCore: "Saving the new core code",
|
|||
|
statusReloadingCore: "Reloading the new core code",
|
|||
|
startLabel: "start",
|
|||
|
startPrompt: "Start the upgrade process",
|
|||
|
cancelLabel: "cancel",
|
|||
|
cancelPrompt: "Cancel the upgrade process",
|
|||
|
step3Title: "Upgrade cancelled",
|
|||
|
step3Html: "You have cancelled the upgrade process"
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.sync,{
|
|||
|
listViewTemplate: {
|
|||
|
columns: [
|
|||
|
{name: 'Selected', field: 'selected', rowName: 'title', type: 'Selector'},
|
|||
|
{name: 'Tiddler', field: 'tiddler', title: "Tiddler", type: 'Tiddler'},
|
|||
|
{name: 'Server Type', field: 'serverType', title: "Server type", type: 'String'},
|
|||
|
{name: 'Server Host', field: 'serverHost', title: "Server host", type: 'String'},
|
|||
|
{name: 'Server Workspace', field: 'serverWorkspace', title: "Server workspace", type: 'String'},
|
|||
|
{name: 'Status', field: 'status', title: "Synchronisation status", type: 'String'},
|
|||
|
{name: 'Server URL', field: 'serverUrl', title: "Server URL", text: "View", type: 'Link'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
],
|
|||
|
buttons: [
|
|||
|
{caption: "Sync these tiddlers", name: 'sync'}
|
|||
|
]},
|
|||
|
wizardTitle: "Synchronize with external servers and files",
|
|||
|
step1Title: "Choose the tiddlers you want to synchronize",
|
|||
|
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
|
|||
|
syncLabel: "sync",
|
|||
|
syncPrompt: "Sync these tiddlers",
|
|||
|
hasChanged: "Changed while unplugged",
|
|||
|
hasNotChanged: "Unchanged while unplugged",
|
|||
|
syncStatusList: {
|
|||
|
none: {text: "...", display:'none', className:'notChanged'},
|
|||
|
changedServer: {text: "Changed on server", display:null, className:'changedServer'},
|
|||
|
changedLocally: {text: "Changed while unplugged", display:null, className:'changedLocally'},
|
|||
|
changedBoth: {text: "Changed while unplugged and on server", display:null, className:'changedBoth'},
|
|||
|
notFound: {text: "Not found on server", display:null, className:'notFound'},
|
|||
|
putToServer: {text: "Saved update on server", display:null, className:'putToServer'},
|
|||
|
gotFromServer: {text: "Retrieved update from server", display:null, className:'gotFromServer'}
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
merge(config.macros.annotations,{
|
|||
|
});
|
|||
|
|
|||
|
merge(config.commands.closeTiddler,{
|
|||
|
text: "close",
|
|||
|
tooltip: "Close this tiddler"});
|
|||
|
|
|||
|
merge(config.commands.closeOthers,{
|
|||
|
text: "close others",
|
|||
|
tooltip: "Close all other tiddlers"});
|
|||
|
|
|||
|
merge(config.commands.editTiddler,{
|
|||
|
text: "edit",
|
|||
|
tooltip: "Edit this tiddler",
|
|||
|
readOnlyText: "view",
|
|||
|
readOnlyTooltip: "View the source of this tiddler"});
|
|||
|
|
|||
|
merge(config.commands.saveTiddler,{
|
|||
|
text: "done",
|
|||
|
tooltip: "Save changes to this tiddler"});
|
|||
|
|
|||
|
merge(config.commands.cancelTiddler,{
|
|||
|
text: "cancel",
|
|||
|
tooltip: "Undo changes to this tiddler",
|
|||
|
warning: "Are you sure you want to abandon your changes to '%0'?",
|
|||
|
readOnlyText: "done",
|
|||
|
readOnlyTooltip: "View this tiddler normally"});
|
|||
|
|
|||
|
merge(config.commands.deleteTiddler,{
|
|||
|
text: "delete",
|
|||
|
tooltip: "Delete this tiddler",
|
|||
|
warning: "Are you sure you want to delete '%0'?"});
|
|||
|
|
|||
|
merge(config.commands.permalink,{
|
|||
|
text: "permalink",
|
|||
|
tooltip: "Permalink for this tiddler"});
|
|||
|
|
|||
|
merge(config.commands.references,{
|
|||
|
text: "references",
|
|||
|
tooltip: "Show tiddlers that link to this one",
|
|||
|
popupNone: "No references"});
|
|||
|
|
|||
|
merge(config.commands.jump,{
|
|||
|
text: "jump",
|
|||
|
tooltip: "Jump to another open tiddler"});
|
|||
|
|
|||
|
merge(config.commands.syncing,{
|
|||
|
text: "syncing",
|
|||
|
tooltip: "Control synchronisation of this tiddler with a server or external file",
|
|||
|
currentlySyncing: "<div>Currently syncing via <span class='popupHighlight'>'%0'</span> to:</"+"div><div>host: <span class='popupHighlight'>%1</span></"+"div><div>workspace: <span class='popupHighlight'>%2</span></"+"div>", // Note escaping of closing <div> tag
|
|||
|
notCurrentlySyncing: "Not currently syncing",
|
|||
|
captionUnSync: "Stop synchronising this tiddler",
|
|||
|
chooseServer: "Synchronise this tiddler with another server:",
|
|||
|
currServerMarker: "\u25cf ",
|
|||
|
notCurrServerMarker: " "});
|
|||
|
|
|||
|
merge(config.commands.fields,{
|
|||
|
text: "fields",
|
|||
|
tooltip: "Show the extended fields of this tiddler",
|
|||
|
emptyText: "There are no extended fields for this tiddler",
|
|||
|
listViewTemplate: {
|
|||
|
columns: [
|
|||
|
{name: 'Field', field: 'field', title: "Field", type: 'String'},
|
|||
|
{name: 'Value', field: 'value', title: "Value", type: 'String'}
|
|||
|
],
|
|||
|
rowClasses: [
|
|||
|
],
|
|||
|
buttons: [
|
|||
|
]}});
|
|||
|
|
|||
|
merge(config.shadowTiddlers,{
|
|||
|
DefaultTiddlers: "[[GettingStarted]]",
|
|||
|
MainMenu: "[[GettingStarted]]",
|
|||
|
SiteTitle: "My TiddlyWiki",
|
|||
|
SiteSubtitle: "a reusable non-linear personal web notebook",
|
|||
|
SiteUrl: "",
|
|||
|
SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "options \u00bb" "Change TiddlyWiki advanced options">>',
|
|||
|
SideBarTabs: '<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>',
|
|||
|
TabMore: '<<tabs txtMoreTab "Missing" "Missing tiddlers" TabMoreMissing "Orphans" "Orphaned tiddlers" TabMoreOrphans "Shadowed" "Shadowed tiddlers" TabMoreShadowed>>'
|
|||
|
});
|
|||
|
|
|||
|
merge(config.annotations,{
|
|||
|
AdvancedOptions: "This shadow tiddler provides access to several advanced options",
|
|||
|
ColorPalette: "These values in this shadow tiddler determine the colour scheme of the ~TiddlyWiki user interface",
|
|||
|
DefaultTiddlers: "The tiddlers listed in this shadow tiddler will be automatically displayed when ~TiddlyWiki starts up",
|
|||
|
EditTemplate: "The HTML template in this shadow tiddler determines how tiddlers look while they are being edited",
|
|||
|
GettingStarted: "This shadow tiddler provides basic usage instructions",
|
|||
|
ImportTiddlers: "This shadow tiddler provides access to importing tiddlers",
|
|||
|
MainMenu: "This shadow tiddler is used as the contents of the main menu in the left-hand column of the screen",
|
|||
|
MarkupPreHead: "This tiddler is inserted at the top of the <head> section of the TiddlyWiki HTML file",
|
|||
|
MarkupPostHead: "This tiddler is inserted at the bottom of the <head> section of the TiddlyWiki HTML file",
|
|||
|
MarkupPreBody: "This tiddler is inserted at the top of the <body> section of the TiddlyWiki HTML file",
|
|||
|
MarkupPostBody: "This tiddler is inserted at the end of the <body> section of the TiddlyWiki HTML file immediately after the script block",
|
|||
|
OptionsPanel: "This shadow tiddler is used as the contents of the options panel slider in the right-hand sidebar",
|
|||
|
PageTemplate: "The HTML template in this shadow tiddler determines the overall ~TiddlyWiki layout",
|
|||
|
PluginManager: "This shadow tiddler provides access to the plugin manager",
|
|||
|
SideBarOptions: "This shadow tiddler is used as the contents of the option panel in the right-hand sidebar",
|
|||
|
SideBarTabs: "This shadow tiddler is used as the contents of the tabs panel in the right-hand sidebar",
|
|||
|
SiteSubtitle: "This shadow tiddler is used as the second part of the page title",
|
|||
|
SiteTitle: "This shadow tiddler is used as the first part of the page title",
|
|||
|
SiteUrl: "This shadow tiddler should be set to the full target URL for publication",
|
|||
|
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",
|
|||
|
StyleSheet: "This tiddler can contain custom CSS definitions",
|
|||
|
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",
|
|||
|
StyleSheetLocale: "This shadow tiddler contains CSS definitions related to the translation locale",
|
|||
|
StyleSheetPrint: "This shadow tiddler contains CSS definitions for printing",
|
|||
|
SystemSettings: "This tiddler is used to store configuration options for this TiddlyWiki document",
|
|||
|
TabAll: "This shadow tiddler contains the contents of the 'All' tab in the right-hand sidebar",
|
|||
|
TabMore: "This shadow tiddler contains the contents of the 'More' tab in the right-hand sidebar",
|
|||
|
TabMoreMissing: "This shadow tiddler contains the contents of the 'Missing' tab in the right-hand sidebar",
|
|||
|
TabMoreOrphans: "This shadow tiddler contains the contents of the 'Orphans' tab in the right-hand sidebar",
|
|||
|
TabMoreShadowed: "This shadow tiddler contains the contents of the 'Shadowed' tab in the right-hand sidebar",
|
|||
|
TabTags: "This shadow tiddler contains the contents of the 'Tags' tab in the right-hand sidebar",
|
|||
|
TabTimeline: "This shadow tiddler contains the contents of the 'Timeline' tab in the right-hand sidebar",
|
|||
|
ToolbarCommands: "This shadow tiddler determines which commands are shown in tiddler toolbars",
|
|||
|
ViewTemplate: "The HTML template in this shadow tiddler determines how tiddlers look"
|
|||
|
});
|
|||
|
//--
|
|||
|
//-- Main
|
|||
|
//--
|
|||
|
|
|||
|
var params = null; // Command line parameters
|
|||
|
var store = null; // TiddlyWiki storage
|
|||
|
var story = null; // Main story
|
|||
|
var formatter = null; // Default formatters for the wikifier
|
|||
|
var anim = typeof Animator == "function" ? new Animator() : null; // Animation engine
|
|||
|
var readOnly = false; // Whether we're in readonly mode
|
|||
|
var highlightHack = null; // Embarrassing hack department...
|
|||
|
var hadConfirmExit = false; // Don't warn more than once
|
|||
|
var safeMode = false; // Disable all plugins and cookies
|
|||
|
var showBackstage; // Whether to include the backstage area
|
|||
|
var installedPlugins = []; // Information filled in when plugins are executed
|
|||
|
var startingUp = false; // Whether we're in the process of starting up
|
|||
|
var pluginInfo,tiddler; // Used to pass information to plugins in loadPlugins()
|
|||
|
|
|||
|
// Whether to use the JavaSaver applet
|
|||
|
var useJavaSaver = (config.browser.isSafari || config.browser.isOpera) && (document.location.toString().substr(0,4) != "http");
|
|||
|
|
|||
|
if(!window || !window.console) {
|
|||
|
console = {tiddlywiki:true,log:function(message) {displayMessage(message);}};
|
|||
|
}
|
|||
|
|
|||
|
// Starting up
|
|||
|
function main()
|
|||
|
{
|
|||
|
var t10,t9,t8,t7,t6,t5,t4,t3,t2,t1,t0 = new Date();
|
|||
|
startingUp = true;
|
|||
|
var doc = jQuery(document);
|
|||
|
jQuery.noConflict();
|
|||
|
window.onbeforeunload = function(e) {if(window.confirmExit) return confirmExit();};
|
|||
|
params = getParameters();
|
|||
|
if(params)
|
|||
|
params = params.parseParams("open",null,false);
|
|||
|
store = new TiddlyWiki({config:config});
|
|||
|
invokeParamifier(params,"oninit");
|
|||
|
story = new Story("tiddlerDisplay","tiddler");
|
|||
|
addEvent(document,"click",Popup.onDocumentClick);
|
|||
|
saveTest();
|
|||
|
var s;
|
|||
|
for(s=0; s<config.notifyTiddlers.length; s++)
|
|||
|
store.addNotification(config.notifyTiddlers[s].name,config.notifyTiddlers[s].notify);
|
|||
|
t1 = new Date();
|
|||
|
loadShadowTiddlers();
|
|||
|
doc.trigger("loadShadows");
|
|||
|
t2 = new Date();
|
|||
|
store.loadFromDiv("storeArea","store",true);
|
|||
|
doc.trigger("loadTiddlers");
|
|||
|
loadOptions();
|
|||
|
t3 = new Date();
|
|||
|
invokeParamifier(params,"onload");
|
|||
|
t4 = new Date();
|
|||
|
readOnly = (window.location.protocol == "file:") ? false : config.options.chkHttpReadOnly;
|
|||
|
var pluginProblem = loadPlugins("systemConfig");
|
|||
|
doc.trigger("loadPlugins");
|
|||
|
t5 = new Date();
|
|||
|
formatter = new Formatter(config.formatters);
|
|||
|
invokeParamifier(params,"onconfig");
|
|||
|
story.switchTheme(config.options.txtTheme);
|
|||
|
showBackstage = showBackstage !== undefined ? showBackstage : !readOnly;
|
|||
|
t6 = new Date();
|
|||
|
var m;
|
|||
|
for(m in config.macros) {
|
|||
|
if(config.macros[m].init)
|
|||
|
config.macros[m].init();
|
|||
|
}
|
|||
|
t7 = new Date();
|
|||
|
store.notifyAll();
|
|||
|
t8 = new Date();
|
|||
|
restart();
|
|||
|
refreshDisplay();
|
|||
|
t9 = new Date();
|
|||
|
if(pluginProblem) {
|
|||
|
story.displayTiddler(null,"PluginManager");
|
|||
|
displayMessage(config.messages.customConfigError);
|
|||
|
}
|
|||
|
if(showBackstage)
|
|||
|
backstage.init();
|
|||
|
t10 = new Date();
|
|||
|
if(config.options.chkDisplayInstrumentation) {
|
|||
|
displayMessage("LoadShadows " + (t2-t1) + " ms");
|
|||
|
displayMessage("LoadFromDiv " + (t3-t2) + " ms");
|
|||
|
displayMessage("LoadPlugins " + (t5-t4) + " ms");
|
|||
|
displayMessage("Macro init " + (t7-t6) + " ms");
|
|||
|
displayMessage("Notify " + (t8-t7) + " ms");
|
|||
|
displayMessage("Restart " + (t9-t8) + " ms");
|
|||
|
displayMessage("Total: " + (t10-t0) + " ms");
|
|||
|
}
|
|||
|
startingUp = false;
|
|||
|
doc.trigger("startup");
|
|||
|
}
|
|||
|
|
|||
|
// Called on unload. All functions called conditionally since they themselves may have been unloaded.
|
|||
|
function unload()
|
|||
|
{
|
|||
|
if(window.checkUnsavedChanges)
|
|||
|
checkUnsavedChanges();
|
|||
|
if(window.scrubNodes)
|
|||
|
scrubNodes(document.body);
|
|||
|
}
|
|||
|
|
|||
|
// Restarting
|
|||
|
function restart()
|
|||
|
{
|
|||
|
invokeParamifier(params,"onstart");
|
|||
|
if(story.isEmpty()) {
|
|||
|
story.displayDefaultTiddlers();
|
|||
|
}
|
|||
|
window.scrollTo(0,0);
|
|||
|
}
|
|||
|
|
|||
|
function saveTest()
|
|||
|
{
|
|||
|
var s = document.getElementById("saveTest");
|
|||
|
if(s.hasChildNodes())
|
|||
|
alert(config.messages.savedSnapshotError);
|
|||
|
s.appendChild(document.createTextNode("savetest"));
|
|||
|
}
|
|||
|
|
|||
|
function loadShadowTiddlers()
|
|||
|
{
|
|||
|
var shadows = new TiddlyWiki();
|
|||
|
shadows.loadFromDiv("shadowArea","shadows",true);
|
|||
|
shadows.forEachTiddler(function(title,tiddler){config.shadowTiddlers[title] = tiddler.text;});
|
|||
|
}
|
|||
|
|
|||
|
function loadPlugins(tag)
|
|||
|
{
|
|||
|
if(safeMode)
|
|||
|
return false;
|
|||
|
var tiddlers = store.getTaggedTiddlers(tag);
|
|||
|
tiddlers.sort(function(a,b) {return a.title < b.title ? -1 : (a.title == b.title ? 0 : 1);});
|
|||
|
var toLoad = [];
|
|||
|
var nLoaded = 0;
|
|||
|
var map = {};
|
|||
|
var nPlugins = tiddlers.length;
|
|||
|
installedPlugins = [];
|
|||
|
var i;
|
|||
|
for(i=0; i<nPlugins; i++) {
|
|||
|
var p = getPluginInfo(tiddlers[i]);
|
|||
|
installedPlugins[i] = p;
|
|||
|
var n = p.Name || p.title;
|
|||
|
if(n)
|
|||
|
map[n] = p;
|
|||
|
n = p.Source;
|
|||
|
if(n)
|
|||
|
map[n] = p;
|
|||
|
}
|
|||
|
var visit = function(p) {
|
|||
|
if(!p || p.done)
|
|||
|
return;
|
|||
|
p.done = 1;
|
|||
|
var reqs = p.Requires;
|
|||
|
if(reqs) {
|
|||
|
reqs = reqs.readBracketedList();
|
|||
|
var i;
|
|||
|
for(i=0; i<reqs.length; i++)
|
|||
|
visit(map[reqs[i]]);
|
|||
|
}
|
|||
|
toLoad.push(p);
|
|||
|
};
|
|||
|
for(i=0; i<nPlugins; i++)
|
|||
|
visit(installedPlugins[i]);
|
|||
|
for(i=0; i<toLoad.length; i++) {
|
|||
|
p = toLoad[i];
|
|||
|
pluginInfo = p;
|
|||
|
tiddler = p.tiddler;
|
|||
|
if(isPluginExecutable(p)) {
|
|||
|
if(isPluginEnabled(p)) {
|
|||
|
p.executed = true;
|
|||
|
var startTime = new Date();
|
|||
|
try {
|
|||
|
if(tiddler.text)
|
|||
|
window.eval(tiddler.text);
|
|||
|
nLoaded++;
|
|||
|
} catch(ex) {
|
|||
|
p.log.push(config.messages.pluginError.format([exceptionText(ex)]));
|
|||
|
p.error = true;
|
|||
|
if(!console.tiddlywiki) {
|
|||
|
console.log("error evaluating " + tiddler.title, ex);
|
|||
|
}
|
|||
|
}
|
|||
|
pluginInfo.startupTime = String((new Date()) - startTime) + "ms";
|
|||
|
} else {
|
|||
|
nPlugins--;
|
|||
|
}
|
|||
|
} else {
|
|||
|
p.warning = true;
|
|||
|
}
|
|||
|
}
|
|||
|
return nLoaded != nPlugins;
|
|||
|
}
|
|||
|
|
|||
|
function getPluginInfo(tiddler)
|
|||
|
{
|
|||
|
var p = store.getTiddlerSlices(tiddler.title,["Name","Description","Version","Requires","CoreVersion","Date","Source","Author","License","Browsers"]);
|
|||
|
p.tiddler = tiddler;
|
|||
|
p.title = tiddler.title;
|
|||
|
p.log = [];
|
|||
|
return p;
|
|||
|
}
|
|||
|
|
|||
|
// Check that a particular plugin is valid for execution
|
|||
|
function isPluginExecutable(plugin)
|
|||
|
{
|
|||
|
if(plugin.tiddler.isTagged("systemConfigForce")) {
|
|||
|
plugin.log.push(config.messages.pluginForced);
|
|||
|
return true;
|
|||
|
}
|
|||
|
if(plugin["CoreVersion"]) {
|
|||
|
var coreVersion = plugin["CoreVersion"].split(".");
|
|||
|
var w = parseInt(coreVersion[0],10) - version.major;
|
|||
|
if(w == 0 && coreVersion[1])
|
|||
|
w = parseInt(coreVersion[1],10) - version.minor;
|
|||
|
if(w == 0 && coreVersion[2])
|
|||
|
w = parseInt(coreVersion[2],10) - version.revision;
|
|||
|
if(w > 0) {
|
|||
|
plugin.log.push(config.messages.pluginVersionError);
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
function isPluginEnabled(plugin)
|
|||
|
{
|
|||
|
if(plugin.tiddler.isTagged("systemConfigDisable")) {
|
|||
|
plugin.log.push(config.messages.pluginDisabled);
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Paramifiers
|
|||
|
//--
|
|||
|
|
|||
|
function getParameters()
|
|||
|
{
|
|||
|
var p = null;
|
|||
|
if(window.location.hash) {
|
|||
|
p = decodeURIComponent(window.location.hash.substr(1));
|
|||
|
if(config.browser.firefoxDate != null && config.browser.firefoxDate[1] < "20051111")
|
|||
|
p = convertUTF8ToUnicode(p);
|
|||
|
}
|
|||
|
return p;
|
|||
|
}
|
|||
|
|
|||
|
function invokeParamifier(params,handler)
|
|||
|
{
|
|||
|
if(!params || params.length == undefined || params.length <= 1)
|
|||
|
return;
|
|||
|
var i;
|
|||
|
for(i=1; i<params.length; i++) {
|
|||
|
var p = config.paramifiers[params[i].name];
|
|||
|
if(p && p[handler] instanceof Function)
|
|||
|
p[handler](params[i].value);
|
|||
|
else {
|
|||
|
var h = config.optionHandlers[params[i].name.substr(0,3)];
|
|||
|
if(h && h.set instanceof Function)
|
|||
|
h.set(params[i].name,params[i].value);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
config.paramifiers = {};
|
|||
|
|
|||
|
config.paramifiers.start = {
|
|||
|
oninit: function(v) {
|
|||
|
safeMode = v.toLowerCase() == "safe";
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.open = {
|
|||
|
onstart: function(v) {
|
|||
|
if(!readOnly || store.tiddlerExists(v) || store.isShadowTiddler(v))
|
|||
|
story.displayTiddler("bottom",v,null,false,null);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.story = {
|
|||
|
onstart: function(v) {
|
|||
|
var list = store.getTiddlerText(v,"").parseParams("open",null,false);
|
|||
|
invokeParamifier(list,"onstart");
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.search = {
|
|||
|
onstart: function(v) {
|
|||
|
story.search(v,false,false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.searchRegExp = {
|
|||
|
onstart: function(v) {
|
|||
|
story.prototype.search(v,false,true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.tag = {
|
|||
|
onstart: function(v) {
|
|||
|
story.displayTiddlers(null,store.filterTiddlers("[tag["+v+"]]"),null,false,null);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.newTiddler = {
|
|||
|
onstart: function(v) {
|
|||
|
var args = v.parseParams("anon", null, null)[0];
|
|||
|
var title = args.title ? args.title[0] : v;
|
|||
|
var customFields = args.fields ? args.fields[0] : null;
|
|||
|
if(!readOnly) {
|
|||
|
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,customFields);
|
|||
|
story.focusTiddler(title,"text");
|
|||
|
var i,tags = args.tag || [];
|
|||
|
for(i=0;i<tags.length;i++) {
|
|||
|
story.setTiddlerTag(title,tags[i],+1);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.newJournal = {
|
|||
|
onstart: function(v) {
|
|||
|
if(!readOnly) {
|
|||
|
var now = new Date();
|
|||
|
var title = now.formatString(v.trim());
|
|||
|
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE);
|
|||
|
story.focusTiddler(title,"text");
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.readOnly = {
|
|||
|
onconfig: function(v) {
|
|||
|
var p = v.toLowerCase();
|
|||
|
readOnly = p == "yes" ? true : (p == "no" ? false : readOnly);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.theme = {
|
|||
|
onconfig: function(v) {
|
|||
|
story.switchTheme(v);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.upgrade = {
|
|||
|
onstart: function(v) {
|
|||
|
upgradeFrom(v);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.recent= {
|
|||
|
onstart: function(v) {
|
|||
|
var titles=[];
|
|||
|
var i,tiddlers=store.getTiddlers("modified","excludeLists").reverse();
|
|||
|
for(i=0; i<v && i<tiddlers.length; i++)
|
|||
|
titles.push(tiddlers[i].title);
|
|||
|
story.displayTiddlers(null,titles);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.paramifiers.filter = {
|
|||
|
onstart: function(v) {
|
|||
|
story.displayTiddlers(null,store.filterTiddlers(v),null,false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Formatter helpers
|
|||
|
//--
|
|||
|
|
|||
|
function Formatter(formatters)
|
|||
|
{
|
|||
|
var n;
|
|||
|
this.formatters = [];
|
|||
|
var pattern = [];
|
|||
|
for(n=0; n<formatters.length; n++) {
|
|||
|
pattern.push("(" + formatters[n].match + ")");
|
|||
|
this.formatters.push(formatters[n]);
|
|||
|
}
|
|||
|
this.formatterRegExp = new RegExp(pattern.join("|"),"mg");
|
|||
|
}
|
|||
|
|
|||
|
config.formatterHelpers = {
|
|||
|
|
|||
|
createElementAndWikify: function(w)
|
|||
|
{
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,this.element),this.termRegExp);
|
|||
|
},
|
|||
|
|
|||
|
inlineCssHelper: function(w)
|
|||
|
{
|
|||
|
var styles = [];
|
|||
|
config.textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
var lookaheadMatch = config.textPrimitives.cssLookaheadRegExp.exec(w.source);
|
|||
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|||
|
var s,v;
|
|||
|
if(lookaheadMatch[1]) {
|
|||
|
s = lookaheadMatch[1].unDash();
|
|||
|
v = lookaheadMatch[2];
|
|||
|
} else {
|
|||
|
s = lookaheadMatch[3].unDash();
|
|||
|
v = lookaheadMatch[4];
|
|||
|
}
|
|||
|
if(s=="bgcolor")
|
|||
|
s = "backgroundColor";
|
|||
|
if(s=="float")
|
|||
|
s = "cssFloat";
|
|||
|
styles.push({style: s, value: v});
|
|||
|
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
|
|||
|
config.textPrimitives.cssLookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
lookaheadMatch = config.textPrimitives.cssLookaheadRegExp.exec(w.source);
|
|||
|
}
|
|||
|
return styles;
|
|||
|
},
|
|||
|
|
|||
|
applyCssHelper: function(e,styles)
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=0; t< styles.length; t++) {
|
|||
|
try {
|
|||
|
e.style[styles[t].style] = styles[t].value;
|
|||
|
} catch (ex) {
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
enclosedTextHelper: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
var text = lookaheadMatch[1];
|
|||
|
if(config.browser.isIE)
|
|||
|
text = text.replace(/\n/g,"\r");
|
|||
|
createTiddlyElement(w.output,this.element,null,null,text);
|
|||
|
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
isExternalLink: function(link)
|
|||
|
{
|
|||
|
if(store.tiddlerExists(link) || store.isShadowTiddler(link)) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
var urlRegExp = new RegExp(config.textPrimitives.urlPattern,"mg");
|
|||
|
if(urlRegExp.exec(link)) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
if(link.indexOf(".")!=-1 || link.indexOf("\\")!=-1 || link.indexOf("/")!=-1 || link.indexOf("#")!=-1) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Standard formatters
|
|||
|
//--
|
|||
|
|
|||
|
config.formatters = [
|
|||
|
{
|
|||
|
name: "table",
|
|||
|
match: "^\\|(?:[^\\n]*)\\|(?:[fhck]?)$",
|
|||
|
lookaheadRegExp: /^\|([^\n]*)\|([fhck]?)$/mg,
|
|||
|
rowTermRegExp: /(\|(?:[fhck]?)$\n?)/mg,
|
|||
|
cellRegExp: /(?:\|([^\n\|]*)\|)|(\|[fhck]?$\n?)/mg,
|
|||
|
cellTermRegExp: /((?:\x20*)\|)/mg,
|
|||
|
rowTypes: {"c":"caption", "h":"thead", "":"tbody", "f":"tfoot"},
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
var table = createTiddlyElement(w.output,"table",null,"twtable");
|
|||
|
var prevColumns = [];
|
|||
|
var currRowType = null;
|
|||
|
var rowContainer;
|
|||
|
var rowCount = 0;
|
|||
|
var onmouseover = function() {jQuery(this).addClass("hoverRow");};
|
|||
|
var onmouseout = function() {jQuery(this).removeClass("hoverRow");};
|
|||
|
w.nextMatch = w.matchStart;
|
|||
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|||
|
var nextRowType = lookaheadMatch[2];
|
|||
|
if(nextRowType == "k") {
|
|||
|
table.className = lookaheadMatch[1];
|
|||
|
w.nextMatch += lookaheadMatch[0].length+1;
|
|||
|
} else {
|
|||
|
if(nextRowType != currRowType) {
|
|||
|
rowContainer = createTiddlyElement(table,this.rowTypes[nextRowType]);
|
|||
|
currRowType = nextRowType;
|
|||
|
}
|
|||
|
if(currRowType == "c") {
|
|||
|
// Caption
|
|||
|
w.nextMatch++;
|
|||
|
if(rowContainer != table.firstChild)
|
|||
|
table.insertBefore(rowContainer,table.firstChild);
|
|||
|
rowContainer.setAttribute("align",rowCount == 0?"top":"bottom");
|
|||
|
w.subWikifyTerm(rowContainer,this.rowTermRegExp);
|
|||
|
} else {
|
|||
|
var theRow = createTiddlyElement(rowContainer,"tr",null,rowCount%2?"oddRow":"evenRow");
|
|||
|
theRow.onmouseover = onmouseover;
|
|||
|
theRow.onmouseout = onmouseout;
|
|||
|
this.rowHandler(w,theRow,prevColumns);
|
|||
|
rowCount++;
|
|||
|
}
|
|||
|
}
|
|||
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
}
|
|||
|
},
|
|||
|
rowHandler: function(w,e,prevColumns)
|
|||
|
{
|
|||
|
var col = 0;
|
|||
|
var colSpanCount = 1;
|
|||
|
var prevCell = null;
|
|||
|
this.cellRegExp.lastIndex = w.nextMatch;
|
|||
|
var cellMatch = this.cellRegExp.exec(w.source);
|
|||
|
while(cellMatch && cellMatch.index == w.nextMatch) {
|
|||
|
if(cellMatch[1] == "~") {
|
|||
|
// Rowspan
|
|||
|
var last = prevColumns[col];
|
|||
|
if(last) {
|
|||
|
last.rowSpanCount++;
|
|||
|
last.element.setAttribute("rowspan",last.rowSpanCount);
|
|||
|
last.element.setAttribute("rowSpan",last.rowSpanCount); // Needed for IE
|
|||
|
last.element.valign = "center";
|
|||
|
if(colSpanCount > 1) {
|
|||
|
last.element.setAttribute("colspan",colSpanCount);
|
|||
|
last.element.setAttribute("colSpan",colSpanCount); // Needed for IE
|
|||
|
colSpanCount = 1;
|
|||
|
}
|
|||
|
}
|
|||
|
w.nextMatch = this.cellRegExp.lastIndex-1;
|
|||
|
} else if(cellMatch[1] == ">") {
|
|||
|
// Colspan
|
|||
|
colSpanCount++;
|
|||
|
w.nextMatch = this.cellRegExp.lastIndex-1;
|
|||
|
} else if(cellMatch[2]) {
|
|||
|
// End of row
|
|||
|
if(prevCell && colSpanCount > 1) {
|
|||
|
prevCell.setAttribute("colspan",colSpanCount);
|
|||
|
prevCell.setAttribute("colSpan",colSpanCount); // Needed for IE
|
|||
|
}
|
|||
|
w.nextMatch = this.cellRegExp.lastIndex;
|
|||
|
break;
|
|||
|
} else {
|
|||
|
// Cell
|
|||
|
w.nextMatch++;
|
|||
|
var styles = config.formatterHelpers.inlineCssHelper(w);
|
|||
|
var spaceLeft = false;
|
|||
|
var chr = w.source.substr(w.nextMatch,1);
|
|||
|
while(chr == " ") {
|
|||
|
spaceLeft = true;
|
|||
|
w.nextMatch++;
|
|||
|
chr = w.source.substr(w.nextMatch,1);
|
|||
|
}
|
|||
|
var cell;
|
|||
|
if(chr == "!") {
|
|||
|
cell = createTiddlyElement(e,"th");
|
|||
|
w.nextMatch++;
|
|||
|
} else {
|
|||
|
cell = createTiddlyElement(e,"td");
|
|||
|
}
|
|||
|
prevCell = cell;
|
|||
|
prevColumns[col] = {rowSpanCount:1,element:cell};
|
|||
|
if(colSpanCount > 1) {
|
|||
|
cell.setAttribute("colspan",colSpanCount);
|
|||
|
cell.setAttribute("colSpan",colSpanCount); // Needed for IE
|
|||
|
colSpanCount = 1;
|
|||
|
}
|
|||
|
config.formatterHelpers.applyCssHelper(cell,styles);
|
|||
|
w.subWikifyTerm(cell,this.cellTermRegExp);
|
|||
|
if(w.matchText.substr(w.matchText.length-2,1) == " ") // spaceRight
|
|||
|
cell.align = spaceLeft ? "center" : "left";
|
|||
|
else if(spaceLeft)
|
|||
|
cell.align = "right";
|
|||
|
w.nextMatch--;
|
|||
|
}
|
|||
|
col++;
|
|||
|
this.cellRegExp.lastIndex = w.nextMatch;
|
|||
|
cellMatch = this.cellRegExp.exec(w.source);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "heading",
|
|||
|
match: "^!{1,6}",
|
|||
|
termRegExp: /(\n)/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"h" + w.matchLength),this.termRegExp);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "list",
|
|||
|
match: "^(?:[\\*#;:]+)",
|
|||
|
lookaheadRegExp: /^(?:(?:(\*)|(#)|(;)|(:))+)/mg,
|
|||
|
termRegExp: /(\n)/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
var stack = [w.output];
|
|||
|
var currLevel = 0, currType = null;
|
|||
|
var listLevel, listType, itemType, baseType;
|
|||
|
w.nextMatch = w.matchStart;
|
|||
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
while(lookaheadMatch && lookaheadMatch.index == w.nextMatch) {
|
|||
|
if(lookaheadMatch[1]) {
|
|||
|
listType = "ul";
|
|||
|
itemType = "li";
|
|||
|
} else if(lookaheadMatch[2]) {
|
|||
|
listType = "ol";
|
|||
|
itemType = "li";
|
|||
|
} else if(lookaheadMatch[3]) {
|
|||
|
listType = "dl";
|
|||
|
itemType = "dt";
|
|||
|
} else if(lookaheadMatch[4]) {
|
|||
|
listType = "dl";
|
|||
|
itemType = "dd";
|
|||
|
}
|
|||
|
if(!baseType)
|
|||
|
baseType = listType;
|
|||
|
listLevel = lookaheadMatch[0].length;
|
|||
|
w.nextMatch += lookaheadMatch[0].length;
|
|||
|
var t;
|
|||
|
if(listLevel > currLevel) {
|
|||
|
for(t=currLevel; t<listLevel; t++) {
|
|||
|
var target = (currLevel == 0) ? stack[stack.length-1] : stack[stack.length-1].lastChild;
|
|||
|
stack.push(createTiddlyElement(target,listType));
|
|||
|
}
|
|||
|
} else if(listType!=baseType && listLevel==1) {
|
|||
|
w.nextMatch -= lookaheadMatch[0].length;
|
|||
|
return;
|
|||
|
} else if(listLevel < currLevel) {
|
|||
|
for(t=currLevel; t>listLevel; t--)
|
|||
|
stack.pop();
|
|||
|
} else if(listLevel == currLevel && listType != currType) {
|
|||
|
stack.pop();
|
|||
|
stack.push(createTiddlyElement(stack[stack.length-1].lastChild,listType));
|
|||
|
}
|
|||
|
currLevel = listLevel;
|
|||
|
currType = listType;
|
|||
|
var e = createTiddlyElement(stack[stack.length-1],itemType);
|
|||
|
w.subWikifyTerm(e,this.termRegExp);
|
|||
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "quoteByBlock",
|
|||
|
match: "^<<<\\n",
|
|||
|
termRegExp: /(^<<<(\n|$))/mg,
|
|||
|
element: "blockquote",
|
|||
|
handler: config.formatterHelpers.createElementAndWikify
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "quoteByLine",
|
|||
|
match: "^>+",
|
|||
|
lookaheadRegExp: /^>+/mg,
|
|||
|
termRegExp: /(\n)/mg,
|
|||
|
element: "blockquote",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
var stack = [w.output];
|
|||
|
var currLevel = 0;
|
|||
|
var newLevel = w.matchLength;
|
|||
|
var t,matched;
|
|||
|
do {
|
|||
|
if(newLevel > currLevel) {
|
|||
|
for(t=currLevel; t<newLevel; t++)
|
|||
|
stack.push(createTiddlyElement(stack[stack.length-1],this.element));
|
|||
|
} else if(newLevel < currLevel) {
|
|||
|
for(t=currLevel; t>newLevel; t--)
|
|||
|
stack.pop();
|
|||
|
}
|
|||
|
currLevel = newLevel;
|
|||
|
w.subWikifyTerm(stack[stack.length-1],this.termRegExp);
|
|||
|
createTiddlyElement(stack[stack.length-1],"br");
|
|||
|
this.lookaheadRegExp.lastIndex = w.nextMatch;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
|
|||
|
if(matched) {
|
|||
|
newLevel = lookaheadMatch[0].length;
|
|||
|
w.nextMatch += lookaheadMatch[0].length;
|
|||
|
}
|
|||
|
} while(matched);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "rule",
|
|||
|
match: "^----+$\\n?|<hr ?/?>\\n?",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
createTiddlyElement(w.output,"hr");
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "monospacedByLine",
|
|||
|
match: "^(?:/\\*\\{\\{\\{\\*/|\\{\\{\\{|//\\{\\{\\{|<!--\\{\\{\\{-->)\\n",
|
|||
|
element: "pre",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
switch(w.matchText) {
|
|||
|
case "/*{{{*/\n": // CSS
|
|||
|
this.lookaheadRegExp = /\/\*\{\{\{\*\/\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\*\}\}\}\*\/$\n?)/mg;
|
|||
|
break;
|
|||
|
case "{{{\n": // monospaced block
|
|||
|
this.lookaheadRegExp = /^\{\{\{\n((?:^[^\n]*\n)+?)(^\f*\}\}\}$\n?)/mg;
|
|||
|
break;
|
|||
|
case "//{{{\n": // plugin
|
|||
|
this.lookaheadRegExp = /^\/\/\{\{\{\n\n*((?:^[^\n]*\n)+?)(\n*^\f*\/\/\}\}\}$\n?)/mg;
|
|||
|
break;
|
|||
|
case "<!--{{{-->\n": //template
|
|||
|
this.lookaheadRegExp = /<!--\{\{\{-->\n*((?:^[^\n]*\n)+?)(\n*^\f*<!--\}\}\}-->$\n?)/mg;
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
config.formatterHelpers.enclosedTextHelper.call(this,w);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "wikifyComment",
|
|||
|
match: "^(?:/\\*\\*\\*|<!---)\\n",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
var termRegExp = (w.matchText == "/***\n") ? (/(^\*\*\*\/\n)/mg) : (/(^--->\n)/mg);
|
|||
|
w.subWikifyTerm(w.output,termRegExp);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "macro",
|
|||
|
match: "<<",
|
|||
|
lookaheadRegExp: /<<([^>\s]+)(?:\s*)((?:[^>]|(?:>(?!>)))*)>>/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1]) {
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
invokeMacro(w.output,lookaheadMatch[1],lookaheadMatch[2],w,w.tiddler);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "prettyLink",
|
|||
|
match: "\\[\\[",
|
|||
|
lookaheadRegExp: /\[\[(.*?)(?:\|(~)?(.*?))?\]\]/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
var e;
|
|||
|
var text = lookaheadMatch[1];
|
|||
|
if(lookaheadMatch[3]) {
|
|||
|
// Pretty bracketted link
|
|||
|
var link = lookaheadMatch[3];
|
|||
|
e = (!lookaheadMatch[2] && config.formatterHelpers.isExternalLink(link)) ?
|
|||
|
createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
|
|||
|
} else {
|
|||
|
// Simple bracketted link
|
|||
|
e = createTiddlyLink(w.output,text,false,null,w.isStatic,w.tiddler);
|
|||
|
}
|
|||
|
createTiddlyText(e,text);
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "wikiLink",
|
|||
|
match: config.textPrimitives.unWikiLink+"?"+config.textPrimitives.wikiLink,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink) {
|
|||
|
w.outputText(w.output,w.matchStart+1,w.nextMatch);
|
|||
|
return;
|
|||
|
}
|
|||
|
if(w.matchStart > 0) {
|
|||
|
var preRegExp = new RegExp(config.textPrimitives.anyLetterStrict,"mg");
|
|||
|
preRegExp.lastIndex = w.matchStart-1;
|
|||
|
var preMatch = preRegExp.exec(w.source);
|
|||
|
if(preMatch.index == w.matchStart-1) {
|
|||
|
w.outputText(w.output,w.matchStart,w.nextMatch);
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
if(w.autoLinkWikiWords || store.isShadowTiddler(w.matchText)) {
|
|||
|
var link = createTiddlyLink(w.output,w.matchText,false,null,w.isStatic,w.tiddler);
|
|||
|
w.outputText(link,w.matchStart,w.nextMatch);
|
|||
|
} else {
|
|||
|
w.outputText(w.output,w.matchStart,w.nextMatch);
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "urlLink",
|
|||
|
match: config.textPrimitives.urlPattern,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
w.outputText(createExternalLink(w.output,w.matchText),w.matchStart,w.nextMatch);
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "image",
|
|||
|
match: "\\[[<>]?[Ii][Mm][Gg]\\[",
|
|||
|
lookaheadRegExp: /\[([<]?)(>?)[Ii][Mm][Gg]\[(?:([^\|\]]+)\|)?([^\[\]\|]+)\](?:\[([^\]]*)\])?\]/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
var e = w.output;
|
|||
|
if(lookaheadMatch[5]) {
|
|||
|
var link = lookaheadMatch[5];
|
|||
|
e = config.formatterHelpers.isExternalLink(link) ? createExternalLink(w.output,link) : createTiddlyLink(w.output,link,false,null,w.isStatic,w.tiddler);
|
|||
|
jQuery(e).addClass("imageLink");
|
|||
|
}
|
|||
|
var img = createTiddlyElement(e,"img");
|
|||
|
if(lookaheadMatch[1])
|
|||
|
img.align = "left";
|
|||
|
else if(lookaheadMatch[2])
|
|||
|
img.align = "right";
|
|||
|
if(lookaheadMatch[3]) {
|
|||
|
img.title = lookaheadMatch[3];
|
|||
|
img.setAttribute("alt",lookaheadMatch[3]);
|
|||
|
}
|
|||
|
img.src = lookaheadMatch[4];
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "html",
|
|||
|
match: "<[Hh][Tt][Mm][Ll]>",
|
|||
|
lookaheadRegExp: /<[Hh][Tt][Mm][Ll]>((?:.|\n)*?)<\/[Hh][Tt][Mm][Ll]>/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
createTiddlyElement(w.output,"span").innerHTML = lookaheadMatch[1];
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "commentByBlock",
|
|||
|
match: "/%",
|
|||
|
lookaheadRegExp: /\/%((?:.|\n)*?)%\//mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "characterFormat",
|
|||
|
match: "''|//|__|\\^\\^|~~|--(?!\\s|$)|\\{\\{\\{",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
switch(w.matchText) {
|
|||
|
case "''":
|
|||
|
w.subWikifyTerm(w.output.appendChild(document.createElement("strong")),/('')/mg);
|
|||
|
break;
|
|||
|
case "//":
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"em"),/(\/\/)/mg);
|
|||
|
break;
|
|||
|
case "__":
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"u"),/(__)/mg);
|
|||
|
break;
|
|||
|
case "^^":
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"sup"),/(\^\^)/mg);
|
|||
|
break;
|
|||
|
case "~~":
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"sub"),/(~~)/mg);
|
|||
|
break;
|
|||
|
case "--":
|
|||
|
w.subWikifyTerm(createTiddlyElement(w.output,"strike"),/(--)/mg);
|
|||
|
break;
|
|||
|
case "{{{":
|
|||
|
var lookaheadRegExp = /\{\{\{((?:.|\n)*?)\}\}\}/mg;
|
|||
|
lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]);
|
|||
|
w.nextMatch = lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "customFormat",
|
|||
|
match: "@@|\\{\\{",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
switch(w.matchText) {
|
|||
|
case "@@":
|
|||
|
var e = createTiddlyElement(w.output,"span");
|
|||
|
var styles = config.formatterHelpers.inlineCssHelper(w);
|
|||
|
if(styles.length == 0)
|
|||
|
e.className = "marked";
|
|||
|
else
|
|||
|
config.formatterHelpers.applyCssHelper(e,styles);
|
|||
|
w.subWikifyTerm(e,/(@@)/mg);
|
|||
|
break;
|
|||
|
case "{{":
|
|||
|
var lookaheadRegExp = /\{\{[\s]*([\w]+[\s\w]*)[\s]*\{(\n?)/mg;
|
|||
|
lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch) {
|
|||
|
w.nextMatch = lookaheadRegExp.lastIndex;
|
|||
|
e = createTiddlyElement(w.output,lookaheadMatch[2] == "\n" ? "div" : "span",null,lookaheadMatch[1]);
|
|||
|
w.subWikifyTerm(e,/(\}\}\})/mg);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "mdash",
|
|||
|
match: "--",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
createTiddlyElement(w.output,"span").innerHTML = "—";
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "lineBreak",
|
|||
|
match: "\\n|<br ?/?>",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
createTiddlyElement(w.output,"br");
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "rawText",
|
|||
|
match: "\"{3}|<nowiki>",
|
|||
|
lookaheadRegExp: /(?:\"{3}|<nowiki>)((?:.|\n)*?)(?:\"{3}|<\/nowiki>)/mg,
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
this.lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = this.lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
createTiddlyElement(w.output,"span",null,null,lookaheadMatch[1]);
|
|||
|
w.nextMatch = this.lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
{
|
|||
|
name: "htmlEntitiesEncoding",
|
|||
|
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};)",
|
|||
|
handler: function(w)
|
|||
|
{
|
|||
|
createTiddlyElement(w.output,"span").innerHTML = w.matchText;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
];
|
|||
|
|
|||
|
//--
|
|||
|
//-- Wikifier
|
|||
|
//--
|
|||
|
|
|||
|
function getParser(tiddler,format)
|
|||
|
{
|
|||
|
if(tiddler) {
|
|||
|
if(!format)
|
|||
|
format = tiddler.fields["wikiformat"];
|
|||
|
var i;
|
|||
|
if(format) {
|
|||
|
for(i in config.parsers) {
|
|||
|
if(format == config.parsers[i].format)
|
|||
|
return config.parsers[i];
|
|||
|
}
|
|||
|
} else {
|
|||
|
for(i in config.parsers) {
|
|||
|
if(tiddler.isTagged(config.parsers[i].formatTag))
|
|||
|
return config.parsers[i];
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return formatter;
|
|||
|
}
|
|||
|
|
|||
|
function Wikifier(source,formatter,highlightRegExp,tiddler)
|
|||
|
{
|
|||
|
this.source = source;
|
|||
|
this.output = null;
|
|||
|
this.formatter = formatter;
|
|||
|
this.nextMatch = 0;
|
|||
|
this.autoLinkWikiWords = tiddler && tiddler.autoLinkWikiWords() == false ? false : true;
|
|||
|
this.highlightRegExp = highlightRegExp;
|
|||
|
this.highlightMatch = null;
|
|||
|
this.isStatic = false;
|
|||
|
if(highlightRegExp) {
|
|||
|
highlightRegExp.lastIndex = 0;
|
|||
|
this.highlightMatch = highlightRegExp.exec(source);
|
|||
|
}
|
|||
|
this.tiddler = tiddler;
|
|||
|
}
|
|||
|
|
|||
|
Wikifier.prototype.wikifyPlain = function()
|
|||
|
{
|
|||
|
var e = createTiddlyElement(document.body,"div");
|
|||
|
e.style.display = "none";
|
|||
|
this.subWikify(e);
|
|||
|
var text = jQuery(e).text();
|
|||
|
jQuery(e).remove();
|
|||
|
return text;
|
|||
|
};
|
|||
|
|
|||
|
Wikifier.prototype.subWikify = function(output,terminator)
|
|||
|
{
|
|||
|
try {
|
|||
|
if(terminator)
|
|||
|
this.subWikifyTerm(output,new RegExp("(" + terminator + ")","mg"));
|
|||
|
else
|
|||
|
this.subWikifyUnterm(output);
|
|||
|
} catch(ex) {
|
|||
|
showException(ex);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Wikifier.prototype.subWikifyUnterm = function(output)
|
|||
|
{
|
|||
|
var oldOutput = this.output;
|
|||
|
this.output = output;
|
|||
|
this.formatter.formatterRegExp.lastIndex = this.nextMatch;
|
|||
|
var formatterMatch = this.formatter.formatterRegExp.exec(this.source);
|
|||
|
while(formatterMatch) {
|
|||
|
// Output any text before the match
|
|||
|
if(formatterMatch.index > this.nextMatch)
|
|||
|
this.outputText(this.output,this.nextMatch,formatterMatch.index);
|
|||
|
// Set the match parameters for the handler
|
|||
|
this.matchStart = formatterMatch.index;
|
|||
|
this.matchLength = formatterMatch[0].length;
|
|||
|
this.matchText = formatterMatch[0];
|
|||
|
this.nextMatch = this.formatter.formatterRegExp.lastIndex;
|
|||
|
var t;
|
|||
|
for(t=1; t<formatterMatch.length; t++) {
|
|||
|
if(formatterMatch[t]) {
|
|||
|
this.formatter.formatters[t-1].handler(this);
|
|||
|
this.formatter.formatterRegExp.lastIndex = this.nextMatch;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
formatterMatch = this.formatter.formatterRegExp.exec(this.source);
|
|||
|
}
|
|||
|
if(this.nextMatch < this.source.length) {
|
|||
|
this.outputText(this.output,this.nextMatch,this.source.length);
|
|||
|
this.nextMatch = this.source.length;
|
|||
|
}
|
|||
|
this.output = oldOutput;
|
|||
|
};
|
|||
|
|
|||
|
Wikifier.prototype.subWikifyTerm = function(output,terminatorRegExp)
|
|||
|
{
|
|||
|
var oldOutput = this.output;
|
|||
|
this.output = output;
|
|||
|
terminatorRegExp.lastIndex = this.nextMatch;
|
|||
|
var terminatorMatch = terminatorRegExp.exec(this.source);
|
|||
|
this.formatter.formatterRegExp.lastIndex = this.nextMatch;
|
|||
|
var formatterMatch = this.formatter.formatterRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);
|
|||
|
while(terminatorMatch || formatterMatch) {
|
|||
|
if(terminatorMatch && (!formatterMatch || terminatorMatch.index <= formatterMatch.index)) {
|
|||
|
if(terminatorMatch.index > this.nextMatch)
|
|||
|
this.outputText(this.output,this.nextMatch,terminatorMatch.index);
|
|||
|
this.matchText = terminatorMatch[1];
|
|||
|
this.matchLength = terminatorMatch[1].length;
|
|||
|
this.matchStart = terminatorMatch.index;
|
|||
|
this.nextMatch = this.matchStart + this.matchLength;
|
|||
|
this.output = oldOutput;
|
|||
|
return;
|
|||
|
}
|
|||
|
if(formatterMatch.index > this.nextMatch)
|
|||
|
this.outputText(this.output,this.nextMatch,formatterMatch.index);
|
|||
|
this.matchStart = formatterMatch.index;
|
|||
|
this.matchLength = formatterMatch[0].length;
|
|||
|
this.matchText = formatterMatch[0];
|
|||
|
this.nextMatch = this.formatter.formatterRegExp.lastIndex;
|
|||
|
var t;
|
|||
|
for(t=1; t<formatterMatch.length; t++) {
|
|||
|
if(formatterMatch[t]) {
|
|||
|
this.formatter.formatters[t-1].handler(this);
|
|||
|
this.formatter.formatterRegExp.lastIndex = this.nextMatch;
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
terminatorRegExp.lastIndex = this.nextMatch;
|
|||
|
terminatorMatch = terminatorRegExp.exec(this.source);
|
|||
|
formatterMatch = this.formatter.formatterRegExp.exec(terminatorMatch ? this.source.substr(0,terminatorMatch.index) : this.source);
|
|||
|
}
|
|||
|
if(this.nextMatch < this.source.length) {
|
|||
|
this.outputText(this.output,this.nextMatch,this.source.length);
|
|||
|
this.nextMatch = this.source.length;
|
|||
|
}
|
|||
|
this.output = oldOutput;
|
|||
|
};
|
|||
|
|
|||
|
Wikifier.prototype.outputText = function(place,startPos,endPos)
|
|||
|
{
|
|||
|
while(this.highlightMatch && (this.highlightRegExp.lastIndex > startPos) && (this.highlightMatch.index < endPos) && (startPos < endPos)) {
|
|||
|
if(this.highlightMatch.index > startPos) {
|
|||
|
createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index));
|
|||
|
startPos = this.highlightMatch.index;
|
|||
|
}
|
|||
|
var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos);
|
|||
|
createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd));
|
|||
|
startPos = highlightEnd;
|
|||
|
if(startPos >= this.highlightRegExp.lastIndex)
|
|||
|
this.highlightMatch = this.highlightRegExp.exec(this.source);
|
|||
|
}
|
|||
|
if(startPos < endPos) {
|
|||
|
createTiddlyText(place,this.source.substring(startPos,endPos));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
function wikify(source,output,highlightRegExp,tiddler)
|
|||
|
{
|
|||
|
if(source) {
|
|||
|
var wikifier = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
|
|||
|
var t0 = new Date();
|
|||
|
wikifier.subWikify(output);
|
|||
|
if(tiddler && config.options.chkDisplayInstrumentation)
|
|||
|
displayMessage("wikify:" +tiddler.title+ " in " + (new Date()-t0) + " ms");
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function wikifyStatic(source,highlightRegExp,tiddler,format)
|
|||
|
{
|
|||
|
var e = createTiddlyElement(document.body,"pre");
|
|||
|
e.style.display = "none";
|
|||
|
var html = "";
|
|||
|
if(source && source != "") {
|
|||
|
if(!tiddler)
|
|||
|
tiddler = new Tiddler("temp");
|
|||
|
var wikifier = new Wikifier(source,getParser(tiddler,format),highlightRegExp,tiddler);
|
|||
|
wikifier.isStatic = true;
|
|||
|
wikifier.subWikify(e);
|
|||
|
html = e.innerHTML;
|
|||
|
jQuery(e).remove();
|
|||
|
}
|
|||
|
return html;
|
|||
|
}
|
|||
|
|
|||
|
function wikifyPlainText(text,limit,tiddler)
|
|||
|
{
|
|||
|
if(limit > 0)
|
|||
|
text = text.substr(0,limit);
|
|||
|
var wikifier = new Wikifier(text,formatter,null,tiddler);
|
|||
|
return wikifier.wikifyPlain();
|
|||
|
}
|
|||
|
|
|||
|
function highlightify(source,output,highlightRegExp,tiddler)
|
|||
|
{
|
|||
|
if(source) {
|
|||
|
var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler);
|
|||
|
wikifier.outputText(output,0,source.length);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Macro definitions
|
|||
|
//--
|
|||
|
|
|||
|
function invokeMacro(place,macro,params,wikifier,tiddler)
|
|||
|
{
|
|||
|
try {
|
|||
|
var m = config.macros[macro];
|
|||
|
if(m && m.handler) {
|
|||
|
var tiddlerElem = story.findContainingTiddler(place);
|
|||
|
window.tiddler = tiddlerElem ? store.getTiddler(tiddlerElem.getAttribute("tiddler")) : null;
|
|||
|
window.place = place;
|
|||
|
var allowEval = true;
|
|||
|
if(config.evaluateMacroParameters=="system") {
|
|||
|
if(!tiddler || tiddler.tags.indexOf("systemAllowEval") == -1) {
|
|||
|
allowEval = false;
|
|||
|
}
|
|||
|
}
|
|||
|
m.handler(place,macro,m.noPreParse?null:params.readMacroParams(!allowEval),wikifier,params,tiddler);
|
|||
|
} else {
|
|||
|
createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,config.messages.missingMacro]));
|
|||
|
}
|
|||
|
} catch(ex) {
|
|||
|
createTiddlyError(place,config.messages.macroError.format([macro]),config.messages.macroErrorDetails.format([macro,ex.toString()]));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
config.macros.version.handler = function(place)
|
|||
|
{
|
|||
|
jQuery("<span/>").text(formatVersion()).appendTo(place);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.today.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var now = new Date();
|
|||
|
var text = params[0] ? now.formatString(params[0].trim()) : now.toLocaleString();
|
|||
|
jQuery("<span/>").text(text).appendTo(place);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.template = "<<view title link>>";
|
|||
|
config.macros.list.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
var list = document.createElement("ul");
|
|||
|
jQuery(list).attr({ refresh: "macro", macroName: macroName }).data("params", paramString);
|
|||
|
place.appendChild(list);
|
|||
|
this.refresh(list);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.refresh = function(list) {
|
|||
|
var paramString = jQuery(list).data("params");
|
|||
|
var params = paramString.readMacroParams();
|
|||
|
var args = paramString.parseParams("anon", null, null)[0];
|
|||
|
var type = args.anon ? args.anon[0] : "all";
|
|||
|
jQuery(list).empty().addClass("list list-" + type);
|
|||
|
var template = args.template ? store.getTiddlerText(args.template[0]) : false;
|
|||
|
if(!template) {
|
|||
|
template = config.macros.list.template;
|
|||
|
}
|
|||
|
if(this[type].prompt)
|
|||
|
createTiddlyElement(list,"li",null,"listTitle",this[type].prompt);
|
|||
|
var results;
|
|||
|
if(this[type].handler)
|
|||
|
results = this[type].handler(params);
|
|||
|
var t;
|
|||
|
for(t = 0; t < results.length; t++) {
|
|||
|
var li = document.createElement("li");
|
|||
|
list.appendChild(li);
|
|||
|
var tiddler = results[t];
|
|||
|
if(typeof(tiddler) == 'string') { // deal with missing etc..
|
|||
|
tiddler = store.getTiddler(tiddler) || new Tiddler(tiddler);
|
|||
|
}
|
|||
|
wikify(template, li, null, tiddler);
|
|||
|
}
|
|||
|
if(results.length === 0 && args.emptyMessage) {
|
|||
|
jQuery(list).addClass("emptyList");
|
|||
|
jQuery("<li />").text(args.emptyMessage[0]).appendTo(list);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.all.handler = function(params)
|
|||
|
{
|
|||
|
return store.reverseLookup("tags","excludeLists",false,"title");
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.missing.handler = function(params)
|
|||
|
{
|
|||
|
return store.getMissingLinks();
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.orphans.handler = function(params)
|
|||
|
{
|
|||
|
return store.getOrphans();
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.shadowed.handler = function(params)
|
|||
|
{
|
|||
|
return store.getShadowed();
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.touched.handler = function(params)
|
|||
|
{
|
|||
|
return store.getTouched();
|
|||
|
};
|
|||
|
|
|||
|
config.macros.list.filter.handler = function(params)
|
|||
|
{
|
|||
|
var filter = params[1];
|
|||
|
var results = [];
|
|||
|
if(filter) {
|
|||
|
var tiddlers = store.filterTiddlers(filter);
|
|||
|
var t;
|
|||
|
for(t=0; t<tiddlers.length; t++)
|
|||
|
results.push(tiddlers[t].title);
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.allTags.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var tags = store.getTags(params[0]);
|
|||
|
var ul = createTiddlyElement(place,"ul");
|
|||
|
if(tags.length == 0)
|
|||
|
createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
|
|||
|
var t;
|
|||
|
for(t=0; t<tags.length; t++) {
|
|||
|
var title = tags[t][0];
|
|||
|
var info = getTiddlyLinkInfo(title);
|
|||
|
var li = createTiddlyElement(ul,"li");
|
|||
|
var btn = createTiddlyButton(li,title + " (" + tags[t][1] + ")",this.tooltip.format([title]),onClickTag,info.classes);
|
|||
|
btn.setAttribute("tag",title);
|
|||
|
btn.setAttribute("refresh","link");
|
|||
|
btn.setAttribute("tiddlyLink",title);
|
|||
|
if(params[1]) {
|
|||
|
btn.setAttribute("sortby",params[1]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
var macro = config.macros.timeline;
|
|||
|
merge(macro, {
|
|||
|
handler: function(place,macroName,params, wikifier, paramString, tiddler) {
|
|||
|
var container = jQuery("<div />").attr("params", paramString).
|
|||
|
attr("macroName", macroName).appendTo(place)[0];
|
|||
|
macro.refresh(container);
|
|||
|
},
|
|||
|
refresh: function(container) {
|
|||
|
jQuery(container).attr("refresh", "macro").empty();
|
|||
|
var paramString = jQuery(container).attr("params");
|
|||
|
var args = paramString.parseParams("anon", null, null)[0];
|
|||
|
var params = args.anon || [];
|
|||
|
|
|||
|
var field = params[0] || "modified";
|
|||
|
var dateFormat = params[2] || this.dateFormat;
|
|||
|
var groupTemplate = macro.groupTemplate.format(field, dateFormat);
|
|||
|
groupTemplate = args.groupTemplate ? store.getTiddlerText(args.groupTemplate[0]) || groupTemplate :
|
|||
|
groupTemplate;
|
|||
|
|
|||
|
var itemTemplate = macro.itemTemplate;
|
|||
|
itemTemplate = args.template ? store.getTiddlerText(args.template[0]) || itemTemplate :
|
|||
|
itemTemplate;
|
|||
|
|
|||
|
var tiddlers = args.filter ? store.sortTiddlers(store.filterTiddlers(args.filter[0]), field) :
|
|||
|
store.reverseLookup("tags", "excludeLists", false, field);
|
|||
|
var lastGroup = "", ul;
|
|||
|
var last = params[1] ? tiddlers.length-Math.min(tiddlers.length,parseInt(params[1],10)) : 0;
|
|||
|
var t;
|
|||
|
for(t=tiddlers.length-1; t>=last; t--) {
|
|||
|
var tiddler = tiddlers[t];
|
|||
|
var theGroup = wikifyPlainText(groupTemplate,0,tiddler);
|
|||
|
if(typeof(ul) == "undefined" || theGroup != lastGroup) {
|
|||
|
ul = document.createElement("ul");
|
|||
|
jQuery(ul).addClass("timeline");
|
|||
|
container.appendChild(ul);
|
|||
|
createTiddlyElement(ul,"li",null,"listTitle",theGroup);
|
|||
|
lastGroup = theGroup;
|
|||
|
}
|
|||
|
var item = createTiddlyElement(ul,"li",null,"listLink");
|
|||
|
wikify(itemTemplate,item,null,tiddler);
|
|||
|
}
|
|||
|
},
|
|||
|
groupTemplate: "<<view %0 date '%1'>>",
|
|||
|
itemTemplate: "<<view title link>>"
|
|||
|
});
|
|||
|
|
|||
|
config.macros.tiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var allowEval = true;
|
|||
|
var stack = config.macros.tiddler.tiddlerStack;
|
|||
|
if(stack.length > 0 && config.evaluateMacroParameters == "system") {
|
|||
|
// included tiddler and "system" evaluation required, so check tiddler tagged appropriately
|
|||
|
var title = stack[stack.length-1];
|
|||
|
var pos = title.indexOf(config.textPrimitives.sectionSeparator);
|
|||
|
if(pos != -1) {
|
|||
|
title = title.substr(0,pos); // get the base tiddler title
|
|||
|
}
|
|||
|
var t = store.getTiddler(title);
|
|||
|
if(!t || t.tags.indexOf("systemAllowEval") == -1) {
|
|||
|
allowEval = false;
|
|||
|
}
|
|||
|
}
|
|||
|
params = paramString.parseParams("name",null,allowEval,false,true);
|
|||
|
var names = params[0]["name"];
|
|||
|
var tiddlerName = names[0];
|
|||
|
var className = names[1] || null;
|
|||
|
var args = params[0]["with"];
|
|||
|
var wrapper = createTiddlyElement(place,"span",null,className,null,{
|
|||
|
refresh: "content", tiddler: tiddlerName
|
|||
|
});
|
|||
|
if(args!==undefined)
|
|||
|
wrapper.setAttribute("args","[["+args.join("]] [[")+"]]");
|
|||
|
this.transclude(wrapper,tiddlerName,args);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tiddler.transclude = function(wrapper,tiddlerName,args)
|
|||
|
{
|
|||
|
var text = store.getTiddlerText(tiddlerName);
|
|||
|
if(!text)
|
|||
|
return;
|
|||
|
var stack = config.macros.tiddler.tiddlerStack;
|
|||
|
if(stack.indexOf(tiddlerName) !== -1)
|
|||
|
return;
|
|||
|
stack.push(tiddlerName);
|
|||
|
try {
|
|||
|
if(typeof args == "string")
|
|||
|
args = args.readBracketedList();
|
|||
|
var n = args ? Math.min(args.length,9) : 0;
|
|||
|
var i;
|
|||
|
for(i=0; i<n; i++) {
|
|||
|
var placeholderRE = new RegExp("\\$" + (i + 1),"mg");
|
|||
|
text = text.replace(placeholderRE,args[i]);
|
|||
|
}
|
|||
|
config.macros.tiddler.renderText(wrapper,text,tiddlerName);
|
|||
|
} finally {
|
|||
|
stack.pop();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tiddler.renderText = function(place,text,tiddlerName)
|
|||
|
{
|
|||
|
wikify(text,place,null,store.getTiddler(tiddlerName));
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tiddler.tiddlerStack = [];
|
|||
|
|
|||
|
config.macros.tag.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var btn = createTagButton(place,params[0],null,params[1],params[2]);
|
|||
|
if(params[3]) {
|
|||
|
btn.setAttribute('sortby',params[3]);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tags.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
params = paramString.parseParams("anon",null,true,false,false);
|
|||
|
var ul = createTiddlyElement(place,"ul");
|
|||
|
var title = getParam(params,"anon","");
|
|||
|
if(title && store.tiddlerExists(title))
|
|||
|
tiddler = store.getTiddler(title);
|
|||
|
var sep = getParam(params,"sep"," ");
|
|||
|
var lingo = config.views.wikified.tag;
|
|||
|
var label = null;
|
|||
|
var t;
|
|||
|
for(t=0; t<tiddler.tags.length; t++) {
|
|||
|
var tag = store.getTiddler(tiddler.tags[t]);
|
|||
|
if(!tag || !tag.tags.contains("excludeLists")) {
|
|||
|
if(!label)
|
|||
|
label = createTiddlyElement(ul,"li",null,"listTitle",lingo.labelTags.format([tiddler.title]));
|
|||
|
createTagButton(createTiddlyElement(ul,"li"),tiddler.tags[t],tiddler.title);
|
|||
|
if(t<tiddler.tags.length-1)
|
|||
|
createTiddlyText(ul,sep);
|
|||
|
}
|
|||
|
}
|
|||
|
if(!label)
|
|||
|
createTiddlyElement(ul,"li",null,"listTitle",lingo.labelNoTags.format([tiddler.title]));
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tagging.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
params = paramString.parseParams("anon",null,true,false,false);
|
|||
|
var ul = createTiddlyElement(place,"ul");
|
|||
|
var title = getParam(params,"anon","");
|
|||
|
if(title == "" && tiddler instanceof Tiddler)
|
|||
|
title = tiddler.title;
|
|||
|
var sep = getParam(params,"sep"," ");
|
|||
|
ul.setAttribute("title",this.tooltip.format([title]));
|
|||
|
var sortby = getParam(params,"sortBy",false);
|
|||
|
var tagged = store.getTaggedTiddlers(title,sortby);
|
|||
|
var prompt = tagged.length == 0 ? this.labelNotTag : this.label;
|
|||
|
createTiddlyElement(ul,"li",null,"listTitle",prompt.format([title,tagged.length]));
|
|||
|
var t;
|
|||
|
for(t=0; t<tagged.length; t++) {
|
|||
|
createTiddlyLink(createTiddlyElement(ul,"li"),tagged[t].title,true);
|
|||
|
if(t<tagged.length-1)
|
|||
|
createTiddlyText(ul,sep);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.closeAll.handler = function(place)
|
|||
|
{
|
|||
|
createTiddlyButton(place,this.label,this.prompt,this.onClick);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.closeAll.onClick = function(e)
|
|||
|
{
|
|||
|
story.closeAllTiddlers();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.permaview.handler = function(place)
|
|||
|
{
|
|||
|
createTiddlyButton(place,this.label,this.prompt,this.onClick);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.permaview.onClick = function(e)
|
|||
|
{
|
|||
|
story.permaView();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.saveChanges.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
if(!readOnly)
|
|||
|
createTiddlyButton(place,params[0] || this.label,params[1] || this.prompt,this.onClick,null,null,this.accessKey);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.saveChanges.onClick = function(e)
|
|||
|
{
|
|||
|
saveChanges();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.slider.onClickSlider = function(ev)
|
|||
|
{
|
|||
|
var n = this.nextSibling;
|
|||
|
var cookie = n.getAttribute("cookie");
|
|||
|
var isOpen = n.style.display != "none";
|
|||
|
if(config.options.chkAnimate && anim && typeof Slider == "function")
|
|||
|
anim.startAnimating(new Slider(n,!isOpen,null,"none"));
|
|||
|
else
|
|||
|
n.style.display = isOpen ? "none" : "block";
|
|||
|
config.options[cookie] = !isOpen;
|
|||
|
saveOption(cookie);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.slider.createSlider = function(place,cookie,title,tooltip)
|
|||
|
{
|
|||
|
var c = cookie || "";
|
|||
|
createTiddlyButton(place,title,tooltip,this.onClickSlider);
|
|||
|
var panel = createTiddlyElement(null,"div",null,"sliderPanel");
|
|||
|
panel.setAttribute("cookie",c);
|
|||
|
panel.style.display = config.options[c] ? "block" : "none";
|
|||
|
place.appendChild(panel);
|
|||
|
return panel;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.slider.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var panel = this.createSlider(place,params[0],params[2],params[3]);
|
|||
|
var text = store.getTiddlerText(params[1]);
|
|||
|
panel.setAttribute("refresh","content");
|
|||
|
panel.setAttribute("tiddler",params[1]);
|
|||
|
if(text)
|
|||
|
wikify(text,panel,null,store.getTiddler(params[1]));
|
|||
|
};
|
|||
|
|
|||
|
// <<gradient [[tiddler name]] vert|horiz rgb rgb rgb rgb... >>
|
|||
|
config.macros.gradient.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var panel = wikifier ? createTiddlyElement(place,"div",null,"gradient") : place;
|
|||
|
panel.style.position = "relative";
|
|||
|
panel.style.overflow = "hidden";
|
|||
|
panel.style.zIndex = "0";
|
|||
|
if(wikifier) {
|
|||
|
var styles = config.formatterHelpers.inlineCssHelper(wikifier);
|
|||
|
config.formatterHelpers.applyCssHelper(panel,styles);
|
|||
|
}
|
|||
|
params = paramString.parseParams("color");
|
|||
|
var locolors = [], hicolors = [];
|
|||
|
var t;
|
|||
|
for(t=2; t<params.length; t++) {
|
|||
|
var c = params[t].value;
|
|||
|
if(params[t].name == "snap") {
|
|||
|
hicolors[hicolors.length-1] = c;
|
|||
|
} else {
|
|||
|
locolors.push(c);
|
|||
|
hicolors.push(c);
|
|||
|
}
|
|||
|
}
|
|||
|
drawGradient(panel,params[1].value != "vert",locolors,hicolors);
|
|||
|
if(wikifier)
|
|||
|
wikifier.subWikify(panel,">>");
|
|||
|
if(document.all) {
|
|||
|
panel.style.height = "100%";
|
|||
|
panel.style.width = "100%";
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.message.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
if(params[0]) {
|
|||
|
var names = params[0].split(".");
|
|||
|
var lookupMessage = function(root,nameIndex) {
|
|||
|
if(root[names[nameIndex]]) {
|
|||
|
if(nameIndex < names.length-1)
|
|||
|
return (lookupMessage(root[names[nameIndex]],nameIndex+1));
|
|||
|
else
|
|||
|
return root[names[nameIndex]];
|
|||
|
} else
|
|||
|
return null;
|
|||
|
};
|
|||
|
var m = lookupMessage(config,0);
|
|||
|
if(m == null)
|
|||
|
m = lookupMessage(window,0);
|
|||
|
createTiddlyText(place,m.toString().format(params.splice(1)));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
config.macros.view.depth = 0;
|
|||
|
config.macros.view.values = [];
|
|||
|
config.macros.view.views = {
|
|||
|
text: function(value,place,params,wikifier,paramString,tiddler) {
|
|||
|
highlightify(value,place,highlightHack,tiddler);
|
|||
|
},
|
|||
|
link: function(value,place,params,wikifier,paramString,tiddler) {
|
|||
|
createTiddlyLink(place,value,true);
|
|||
|
},
|
|||
|
wikified: function(value,place,params,wikifier,paramString,tiddler) {
|
|||
|
if(config.macros.view.depth>50)
|
|||
|
return;
|
|||
|
if(config.macros.view.depth>0) {
|
|||
|
if (value==config.macros.view.values[config.macros.view.depth-1]) {
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
config.macros.view.values[config.macros.view.depth] = value;
|
|||
|
config.macros.view.depth++;
|
|||
|
if(params[2])
|
|||
|
value=params[2].unescapeLineBreaks().format([value]);
|
|||
|
wikify(value,place,highlightHack,tiddler);
|
|||
|
config.macros.view.depth--;
|
|||
|
config.macros.view.values[config.macros.view.depth] = null;
|
|||
|
},
|
|||
|
date: function(value,place,params,wikifier,paramString,tiddler) {
|
|||
|
value = Date.convertFromYYYYMMDDHHMM(value);
|
|||
|
createTiddlyText(place,value.formatString(params[2] || config.views.wikified.dateFormat));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.view.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
if((tiddler instanceof Tiddler) && params[0]) {
|
|||
|
var value = store.getValue(tiddler,params[0]);
|
|||
|
if(value) {
|
|||
|
var type = params[1] || config.macros.view.defaultView;
|
|||
|
var handler = config.macros.view.views[type];
|
|||
|
if(handler)
|
|||
|
handler(value,place,params,wikifier,paramString,tiddler);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.edit.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var field = params[0];
|
|||
|
var rows = params[1] || 0;
|
|||
|
var defVal = params[2] || '';
|
|||
|
if((tiddler instanceof Tiddler) && field) {
|
|||
|
story.setDirty(tiddler.title,true);
|
|||
|
var e,v;
|
|||
|
if(field != "text" && !rows) {
|
|||
|
e = createTiddlyElement(null,"input",null,null,null,{
|
|||
|
type: "text", edit: field, size: "40", autocomplete: "off"
|
|||
|
});
|
|||
|
e.value = store.getValue(tiddler,field) || defVal;
|
|||
|
place.appendChild(e);
|
|||
|
} else {
|
|||
|
var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
|
|||
|
var wrapper2 = createTiddlyElement(wrapper1,"div");
|
|||
|
e = createTiddlyElement(wrapper2,"textarea");
|
|||
|
e.value = v = store.getValue(tiddler,field) || defVal;
|
|||
|
rows = rows || 10;
|
|||
|
var lines = v.match(/\n/mg);
|
|||
|
var maxLines = Math.max(parseInt(config.options.txtMaxEditRows,10),5);
|
|||
|
if(lines != null && lines.length > rows)
|
|||
|
rows = lines.length + 5;
|
|||
|
rows = Math.min(rows,maxLines);
|
|||
|
e.setAttribute("rows",rows);
|
|||
|
e.setAttribute("edit",field);
|
|||
|
place.appendChild(wrapper1);
|
|||
|
}
|
|||
|
if(tiddler.isReadOnly()) {
|
|||
|
e.setAttribute("readOnly","readOnly");
|
|||
|
jQuery(e).addClass("readOnly");
|
|||
|
}
|
|||
|
return e;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tagChooser.onClick = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var lingo = config.views.editor.tagChooser;
|
|||
|
var popup = Popup.create(this);
|
|||
|
var tags = store.getTags(this.getAttribute("tags"));
|
|||
|
if(tags.length == 0)
|
|||
|
jQuery("<li/>").text(lingo.popupNone).appendTo(popup);
|
|||
|
var t;
|
|||
|
for(t=0; t<tags.length; t++) {
|
|||
|
var tag = createTiddlyButton(createTiddlyElement(popup,"li"),tags[t][0],lingo.tagTooltip.format([tags[t][0]]),config.macros.tagChooser.onTagClick);
|
|||
|
tag.setAttribute("tag",tags[t][0]);
|
|||
|
tag.setAttribute("tiddler",this.getAttribute("tiddler"));
|
|||
|
}
|
|||
|
Popup.show();
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tagChooser.onTagClick = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
if(e.metaKey || e.ctrlKey) stopEvent(e); //# keep popup open on CTRL-click
|
|||
|
var tag = this.getAttribute("tag");
|
|||
|
var title = this.getAttribute("tiddler");
|
|||
|
if(!readOnly)
|
|||
|
story.setTiddlerTag(title,tag,0);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tagChooser.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
if(tiddler instanceof Tiddler) {
|
|||
|
var lingo = config.views.editor.tagChooser;
|
|||
|
var btn = createTiddlyButton(place,lingo.text,lingo.tooltip,this.onClick);
|
|||
|
btn.setAttribute("tiddler",tiddler.title);
|
|||
|
btn.setAttribute("tags",params[0]);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.refreshDisplay.handler = function(place)
|
|||
|
{
|
|||
|
createTiddlyButton(place,this.label,this.prompt,this.onClick);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.refreshDisplay.onClick = function(e)
|
|||
|
{
|
|||
|
refreshAll();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.annotations.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var title = tiddler ? tiddler.title : null;
|
|||
|
var a = title ? config.annotations[title] : null;
|
|||
|
if(!tiddler || !title || !a)
|
|||
|
return;
|
|||
|
var text = a.format([title]);
|
|||
|
wikify(text,createTiddlyElement(place,"div",null,"annotation"),null,tiddler);
|
|||
|
};
|
|||
|
//--
|
|||
|
//-- NewTiddler and NewJournal macros
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.newTiddler.createNewTiddlerButton = function(place,title,params,label,prompt,accessKey,newFocus,isJournal)
|
|||
|
{
|
|||
|
var tags = [];
|
|||
|
var t;
|
|||
|
for(t=1; t<params.length; t++) {
|
|||
|
if((params[t].name == "anon" && t != 1) || (params[t].name == "tag"))
|
|||
|
tags.push(params[t].value);
|
|||
|
}
|
|||
|
label = getParam(params,"label",label);
|
|||
|
prompt = getParam(params,"prompt",prompt);
|
|||
|
accessKey = getParam(params,"accessKey",accessKey);
|
|||
|
newFocus = getParam(params,"focus",newFocus);
|
|||
|
var customFields = getParam(params,"fields","");
|
|||
|
if(!customFields && !store.isShadowTiddler(title))
|
|||
|
customFields = String.encodeHashMap(config.defaultCustomFields);
|
|||
|
var btn = createTiddlyButton(place,label,prompt,this.onClickNewTiddler,null,null,accessKey);
|
|||
|
btn.setAttribute("newTitle",title);
|
|||
|
btn.setAttribute("isJournal",isJournal ? "true" : "false");
|
|||
|
if(tags.length > 0)
|
|||
|
btn.setAttribute("params",tags.join("|"));
|
|||
|
btn.setAttribute("newFocus",newFocus);
|
|||
|
btn.setAttribute("newTemplate",getParam(params,"template",DEFAULT_EDIT_TEMPLATE));
|
|||
|
if(customFields !== "")
|
|||
|
btn.setAttribute("customFields",customFields);
|
|||
|
var text = getParam(params,"text");
|
|||
|
if(text !== undefined)
|
|||
|
btn.setAttribute("newText",text);
|
|||
|
return btn;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.newTiddler.onClickNewTiddler = function()
|
|||
|
{
|
|||
|
var title = this.getAttribute("newTitle");
|
|||
|
if(this.getAttribute("isJournal") == "true") {
|
|||
|
title = new Date().formatString(title.trim());
|
|||
|
}
|
|||
|
var params = this.getAttribute("params");
|
|||
|
var tags = params ? params.split("|") : [];
|
|||
|
var focus = this.getAttribute("newFocus");
|
|||
|
var template = this.getAttribute("newTemplate");
|
|||
|
var customFields = this.getAttribute("customFields");
|
|||
|
if(!customFields && !store.isShadowTiddler(title))
|
|||
|
customFields = String.encodeHashMap(config.defaultCustomFields);
|
|||
|
story.displayTiddler(null,title,template,false,null,null);
|
|||
|
var tiddlerElem = story.getTiddler(title);
|
|||
|
if(customFields)
|
|||
|
story.addCustomFields(tiddlerElem,customFields);
|
|||
|
var text = this.getAttribute("newText");
|
|||
|
if(typeof text == "string" && story.getTiddlerField(title,"text"))
|
|||
|
story.getTiddlerField(title,"text").value = text.format([title]);
|
|||
|
var t;
|
|||
|
for(t=0;t<tags.length;t++)
|
|||
|
story.setTiddlerTag(title,tags[t],+1);
|
|||
|
story.focusTiddler(title,focus);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.newTiddler.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
if(!readOnly) {
|
|||
|
params = paramString.parseParams("anon",null,true,false,false);
|
|||
|
var title = params[1] && params[1].name == "anon" ? params[1].value : this.title;
|
|||
|
title = getParam(params,"title",title);
|
|||
|
this.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"title",false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.newJournal.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
if(!readOnly) {
|
|||
|
params = paramString.parseParams("anon",null,true,false,false);
|
|||
|
var title = params[1] && params[1].name == "anon" ? params[1].value : config.macros.timeline.dateFormat;
|
|||
|
title = getParam(params,"title",title);
|
|||
|
config.macros.newTiddler.createNewTiddlerButton(place,title,params,this.label,this.prompt,this.accessKey,"text",true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Search macro
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.search.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
params = paramString.parseParams("anon",null,false,false,false);
|
|||
|
createTiddlyButton(place,this.label,this.prompt,this.onClick,"searchButton");
|
|||
|
var txt = createTiddlyElement(null,"input",null,"txtOptionInput searchField");
|
|||
|
txt.value = getParam(params,"anon","");
|
|||
|
if(config.browser.isSafari) {
|
|||
|
txt.setAttribute("type","search");
|
|||
|
txt.setAttribute("results","5");
|
|||
|
} else {
|
|||
|
txt.setAttribute("type","text");
|
|||
|
}
|
|||
|
place.appendChild(txt);
|
|||
|
txt.onkeyup = this.onKeyPress;
|
|||
|
txt.onfocus = this.onFocus;
|
|||
|
txt.setAttribute("size",this.sizeTextbox);
|
|||
|
txt.setAttribute("accessKey",getParam(params,"accesskey",this.accessKey));
|
|||
|
txt.setAttribute("autocomplete","off");
|
|||
|
txt.setAttribute("lastSearchText","");
|
|||
|
txt.setAttribute("placeholder",getParam(params,"placeholder",this.placeholder));
|
|||
|
};
|
|||
|
|
|||
|
// Global because there's only ever one outstanding incremental search timer
|
|||
|
config.macros.search.timeout = null;
|
|||
|
|
|||
|
config.macros.search.doSearch = function(txt)
|
|||
|
{
|
|||
|
if(txt.value.length > 0) {
|
|||
|
story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
|
|||
|
txt.setAttribute("lastSearchText",txt.value);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.search.onClick = function(e)
|
|||
|
{
|
|||
|
config.macros.search.doSearch(this.nextSibling);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.search.onKeyPress = function(ev)
|
|||
|
{
|
|||
|
var me = config.macros.search;
|
|||
|
var e = ev || window.event;
|
|||
|
switch(e.keyCode) {
|
|||
|
case 9: // Tab
|
|||
|
return;
|
|||
|
case 13: // Ctrl-Enter
|
|||
|
case 10: // Ctrl-Enter on IE PC
|
|||
|
me.doSearch(this);
|
|||
|
break;
|
|||
|
case 27: // Escape
|
|||
|
this.value = "";
|
|||
|
clearMessage();
|
|||
|
break;
|
|||
|
}
|
|||
|
if(config.options.chkIncrementalSearch) {
|
|||
|
if(this.value.length > 2) {
|
|||
|
if(this.value != this.getAttribute("lastSearchText")) {
|
|||
|
if(me.timeout) {
|
|||
|
clearTimeout(me.timeout);
|
|||
|
}
|
|||
|
var txt = this;
|
|||
|
me.timeout = setTimeout(function() {me.doSearch(txt);},500);
|
|||
|
}
|
|||
|
} else {
|
|||
|
if(me.timeout) {
|
|||
|
clearTimeout(me.timeout);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.search.onFocus = function(e)
|
|||
|
{
|
|||
|
this.select();
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Tabs macro
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.tabs.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var cookie = params[0];
|
|||
|
var numTabs = (params.length-1)/3;
|
|||
|
var wrapper = createTiddlyElement(null,"div",null,"tabsetWrapper " + cookie);
|
|||
|
var tabset = createTiddlyElement(wrapper,"div",null,"tabset");
|
|||
|
tabset.setAttribute("cookie",cookie);
|
|||
|
var validTab = false;
|
|||
|
var t;
|
|||
|
for(t=0; t<numTabs; t++) {
|
|||
|
var label = params[t*3+1];
|
|||
|
var prompt = params[t*3+2];
|
|||
|
var content = params[t*3+3];
|
|||
|
var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,"tab tabUnselected");
|
|||
|
createTiddlyElement(tab,"span",null,null," ",{style:"font-size:0pt;line-height:0px"});
|
|||
|
tab.setAttribute("tab",label);
|
|||
|
tab.setAttribute("content",content);
|
|||
|
tab.title = prompt;
|
|||
|
if(config.options[cookie] == label)
|
|||
|
validTab = true;
|
|||
|
}
|
|||
|
if(!validTab)
|
|||
|
config.options[cookie] = params[1];
|
|||
|
place.appendChild(wrapper);
|
|||
|
this.switchTab(tabset,config.options[cookie]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tabs.onClickTab = function(e)
|
|||
|
{
|
|||
|
config.macros.tabs.switchTab(this.parentNode,this.getAttribute("tab"));
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.tabs.switchTab = function(tabset,tab)
|
|||
|
{
|
|||
|
var cookie = tabset.getAttribute("cookie");
|
|||
|
var theTab = null;
|
|||
|
var nodes = tabset.childNodes;
|
|||
|
var t;
|
|||
|
for(t=0; t<nodes.length; t++) {
|
|||
|
if(nodes[t].getAttribute && nodes[t].getAttribute("tab") == tab) {
|
|||
|
theTab = nodes[t];
|
|||
|
theTab.className = "tab tabSelected";
|
|||
|
} else {
|
|||
|
nodes[t].className = "tab tabUnselected";
|
|||
|
}
|
|||
|
}
|
|||
|
if(theTab) {
|
|||
|
if(tabset.nextSibling && tabset.nextSibling.className == "tabContents")
|
|||
|
jQuery(tabset.nextSibling).remove();
|
|||
|
var tabContent = createTiddlyElement(null,"div",null,"tabContents");
|
|||
|
tabset.parentNode.insertBefore(tabContent,tabset.nextSibling);
|
|||
|
var contentTitle = theTab.getAttribute("content");
|
|||
|
wikify(store.getTiddlerText(contentTitle),tabContent,null,store.getTiddler(contentTitle));
|
|||
|
if(cookie) {
|
|||
|
config.options[cookie] = tab;
|
|||
|
saveOption(cookie);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Tiddler toolbar
|
|||
|
//--
|
|||
|
|
|||
|
// Create a toolbar command button
|
|||
|
config.macros.toolbar.createCommand = function(place,commandName,tiddler,className)
|
|||
|
{
|
|||
|
if(typeof commandName != "string") {
|
|||
|
var c = null;
|
|||
|
var t;
|
|||
|
for(t in config.commands) {
|
|||
|
if(config.commands[t] == commandName)
|
|||
|
c = t;
|
|||
|
}
|
|||
|
commandName = c;
|
|||
|
}
|
|||
|
if((tiddler instanceof Tiddler) && (typeof commandName == "string")) {
|
|||
|
var command = config.commands[commandName];
|
|||
|
if(command.isEnabled ? command.isEnabled(tiddler) : this.isCommandEnabled(command,tiddler)) {
|
|||
|
var text = command.getText ? command.getText(tiddler) : this.getCommandText(command,tiddler);
|
|||
|
var tooltip = command.getTooltip ? command.getTooltip(tiddler) : this.getCommandTooltip(command,tiddler);
|
|||
|
var cmd = command.type == "popup" ? this.onClickPopup : this.onClickCommand;
|
|||
|
var btn = createTiddlyButton(null,text,tooltip,cmd);
|
|||
|
btn.setAttribute("commandName",commandName);
|
|||
|
btn.setAttribute("tiddler",tiddler.title);
|
|||
|
jQuery(btn).addClass("command_" + commandName);
|
|||
|
if(className)
|
|||
|
jQuery(btn).addClass(className);
|
|||
|
place.appendChild(btn);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.isCommandEnabled = function(command,tiddler)
|
|||
|
{
|
|||
|
var title = tiddler.title;
|
|||
|
var ro = tiddler.isReadOnly();
|
|||
|
var shadow = store.isShadowTiddler(title) && !store.tiddlerExists(title);
|
|||
|
return (!ro || (ro && !command.hideReadOnly)) && !(shadow && command.hideShadow);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.getCommandText = function(command,tiddler)
|
|||
|
{
|
|||
|
return (tiddler.isReadOnly() && command.readOnlyText) || command.text;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.getCommandTooltip = function(command,tiddler)
|
|||
|
{
|
|||
|
return (tiddler.isReadOnly() && command.readOnlyTooltip) || command.tooltip;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.onClickCommand = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
var command = config.commands[this.getAttribute("commandName")];
|
|||
|
return command.handler(e,this,this.getAttribute("tiddler"));
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.onClickPopup = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
var popup = Popup.create(this);
|
|||
|
var command = config.commands[this.getAttribute("commandName")];
|
|||
|
var title = this.getAttribute("tiddler");
|
|||
|
popup.setAttribute("tiddler",title);
|
|||
|
command.handlePopup(popup,title);
|
|||
|
Popup.show();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
// Invoke the first command encountered from a given place that is tagged with a specified class
|
|||
|
config.macros.toolbar.invokeCommand = function(place,className,event)
|
|||
|
{
|
|||
|
var children = place.getElementsByTagName("a");
|
|||
|
var t;
|
|||
|
for(t=0; t<children.length; t++) {
|
|||
|
var c = children[t];
|
|||
|
if(jQuery(c).hasClass(className) && c.getAttribute && c.getAttribute("commandName")) {
|
|||
|
if(c.onclick instanceof Function)
|
|||
|
c.onclick.call(c,event);
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.onClickMore = function(ev)
|
|||
|
{
|
|||
|
var e = this.nextSibling;
|
|||
|
e.style.display = "inline";
|
|||
|
this.style.display = "none";
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.onClickLess = function(ev)
|
|||
|
{
|
|||
|
var e = this.parentNode;
|
|||
|
var m = e.previousSibling;
|
|||
|
e.style.display = "none";
|
|||
|
m.style.display = "inline";
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.toolbar.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=0; t<params.length; t++) {
|
|||
|
var btn;
|
|||
|
var c = params[t];
|
|||
|
switch(c) {
|
|||
|
case "!":
|
|||
|
createTiddlyText(place,this.separator);
|
|||
|
break;
|
|||
|
case "*":
|
|||
|
createTiddlyElement(place,"br");
|
|||
|
break;
|
|||
|
case "<":
|
|||
|
btn = createTiddlyButton(place,this.lessLabel,this.lessPrompt,config.macros.toolbar.onClickLess);
|
|||
|
jQuery(btn).addClass("lessCommand");
|
|||
|
break;
|
|||
|
case ">":
|
|||
|
btn = createTiddlyButton(place,this.moreLabel,this.morePrompt,config.macros.toolbar.onClickMore);
|
|||
|
jQuery(btn).addClass("moreCommand");
|
|||
|
var e = createTiddlyElement(place,"span",null,"moreCommand");
|
|||
|
e.style.display = "none";
|
|||
|
place = e;
|
|||
|
break;
|
|||
|
default:
|
|||
|
var className = "";
|
|||
|
switch(c.substr(0,1)) {
|
|||
|
case "+":
|
|||
|
className = "defaultCommand";
|
|||
|
c = c.substr(1);
|
|||
|
break;
|
|||
|
case "-":
|
|||
|
className = "cancelCommand";
|
|||
|
c = c.substr(1);
|
|||
|
break;
|
|||
|
}
|
|||
|
if(config.commands[c]) {
|
|||
|
this.createCommand(place,c,tiddler,className);
|
|||
|
} else {
|
|||
|
this.customCommand(place,c,wikifier,tiddler);
|
|||
|
}
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Overrideable function to extend toolbar handler
|
|||
|
config.macros.toolbar.customCommand = function(place,command,wikifier,tiddler)
|
|||
|
{
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Menu and toolbar commands
|
|||
|
//--
|
|||
|
|
|||
|
config.commands.closeTiddler.handler = function(event,src,title)
|
|||
|
{
|
|||
|
if(story.isDirty(title) && !readOnly) {
|
|||
|
if(!confirm(config.commands.cancelTiddler.warning.format([title])))
|
|||
|
return false;
|
|||
|
}
|
|||
|
story.setDirty(title,false);
|
|||
|
story.closeTiddler(title,true);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.closeOthers.handler = function(event,src,title)
|
|||
|
{
|
|||
|
story.closeAllTiddlers(title);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.editTiddler.handler = function(event,src,title)
|
|||
|
{
|
|||
|
clearMessage();
|
|||
|
var tiddlerElem = story.getTiddler(title);
|
|||
|
var fields = tiddlerElem.getAttribute("tiddlyFields");
|
|||
|
story.displayTiddler(null,title,DEFAULT_EDIT_TEMPLATE,false,null,fields);
|
|||
|
var e = story.getTiddlerField(title,config.options.txtEditorFocus||"text");
|
|||
|
if(e) {
|
|||
|
setCaretPosition(e,0);
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.saveTiddler.handler = function(event,src,title)
|
|||
|
{
|
|||
|
var newTitle = story.saveTiddler(title,event.shiftKey);
|
|||
|
if(newTitle)
|
|||
|
story.displayTiddler(null,newTitle);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.cancelTiddler.handler = function(event,src,title)
|
|||
|
{
|
|||
|
if(story.hasChanges(title) && !readOnly) {
|
|||
|
if(!confirm(this.warning.format([title])))
|
|||
|
return false;
|
|||
|
}
|
|||
|
story.setDirty(title,false);
|
|||
|
story.displayTiddler(null,title);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.deleteTiddler.handler = function(event,src,title)
|
|||
|
{
|
|||
|
var deleteIt = true;
|
|||
|
if(config.options.chkConfirmDelete)
|
|||
|
deleteIt = confirm(this.warning.format([title]));
|
|||
|
if(deleteIt) {
|
|||
|
store.removeTiddler(title);
|
|||
|
story.closeTiddler(title,true);
|
|||
|
autoSaveChanges();
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.permalink.handler = function(event,src,title)
|
|||
|
{
|
|||
|
var t = encodeURIComponent(String.encodeTiddlyLink(title));
|
|||
|
if(window.location.hash != t)
|
|||
|
window.location.hash = t;
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.references.handlePopup = function(popup,title)
|
|||
|
{
|
|||
|
var references = store.getReferringTiddlers(title);
|
|||
|
var c = false;
|
|||
|
var r;
|
|||
|
for(r=0; r<references.length; r++) {
|
|||
|
if(references[r].title != title && !references[r].isTagged("excludeLists")) {
|
|||
|
createTiddlyLink(createTiddlyElement(popup,"li"),references[r].title,true);
|
|||
|
c = true;
|
|||
|
}
|
|||
|
}
|
|||
|
if(!c)
|
|||
|
createTiddlyElement(popup,"li",null,"disabled",this.popupNone);
|
|||
|
};
|
|||
|
|
|||
|
config.commands.jump.handlePopup = function(popup,title)
|
|||
|
{
|
|||
|
story.forEachTiddler(function(title,element) {
|
|||
|
createTiddlyLink(createTiddlyElement(popup,"li"),title,true,null,false,null,true);
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
config.commands.syncing.handlePopup = function(popup,title)
|
|||
|
{
|
|||
|
var me = config.commands.syncing;
|
|||
|
var tiddler = store.fetchTiddler(title);
|
|||
|
if(!tiddler)
|
|||
|
return;
|
|||
|
var serverType = tiddler.getServerType();
|
|||
|
var serverHost = tiddler.fields["server.host"];
|
|||
|
var serverWorkspace = tiddler.fields["server.workspace"];
|
|||
|
if(!serverWorkspace)
|
|||
|
serverWorkspace = "";
|
|||
|
if(serverType) {
|
|||
|
var e = createTiddlyElement(popup,"li",null,"popupMessage");
|
|||
|
e.innerHTML = me.currentlySyncing.format([serverType,serverHost,serverWorkspace]);
|
|||
|
} else {
|
|||
|
createTiddlyElement(popup,"li",null,"popupMessage",me.notCurrentlySyncing);
|
|||
|
}
|
|||
|
if(serverType) {
|
|||
|
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
|||
|
var btn = createTiddlyButton(createTiddlyElement(popup,"li"),this.captionUnSync,null,me.onChooseServer);
|
|||
|
btn.setAttribute("tiddler",title);
|
|||
|
btn.setAttribute("server.type","");
|
|||
|
}
|
|||
|
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
|||
|
createTiddlyElement(popup,"li",null,"popupMessage",me.chooseServer);
|
|||
|
var feeds = store.getTaggedTiddlers("systemServer","title");
|
|||
|
var t;
|
|||
|
for(t=0; t<feeds.length; t++) {
|
|||
|
var f = feeds[t];
|
|||
|
var feedServerType = store.getTiddlerSlice(f.title,"Type");
|
|||
|
if(!feedServerType)
|
|||
|
feedServerType = "file";
|
|||
|
var feedServerHost = store.getTiddlerSlice(f.title,"URL");
|
|||
|
if(!feedServerHost)
|
|||
|
feedServerHost = "";
|
|||
|
var feedServerWorkspace = store.getTiddlerSlice(f.title,"Workspace");
|
|||
|
if(!feedServerWorkspace)
|
|||
|
feedServerWorkspace = "";
|
|||
|
var caption = f.title;
|
|||
|
if(serverType == feedServerType && serverHost == feedServerHost && serverWorkspace == feedServerWorkspace) {
|
|||
|
caption = me.currServerMarker + caption;
|
|||
|
} else {
|
|||
|
caption = me.notCurrServerMarker + caption;
|
|||
|
}
|
|||
|
btn = createTiddlyButton(createTiddlyElement(popup,"li"),caption,null,me.onChooseServer);
|
|||
|
btn.setAttribute("tiddler",title);
|
|||
|
btn.setAttribute("server.type",feedServerType);
|
|||
|
btn.setAttribute("server.host",feedServerHost);
|
|||
|
btn.setAttribute("server.workspace",feedServerWorkspace);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.commands.syncing.onChooseServer = function(e)
|
|||
|
{
|
|||
|
var tiddler = this.getAttribute("tiddler");
|
|||
|
var serverType = this.getAttribute("server.type");
|
|||
|
if(serverType) {
|
|||
|
store.addTiddlerFields(tiddler,{
|
|||
|
"server.type": serverType,
|
|||
|
"server.host": this.getAttribute("server.host"),
|
|||
|
"server.workspace": this.getAttribute("server.workspace")
|
|||
|
});
|
|||
|
} else {
|
|||
|
store.setValue(tiddler,"server",null);
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.commands.fields.handlePopup = function(popup,title)
|
|||
|
{
|
|||
|
var tiddler = store.fetchTiddler(title);
|
|||
|
if(!tiddler)
|
|||
|
return;
|
|||
|
var items = [];
|
|||
|
store.forEachField(tiddler,function(tiddler,fieldName,value){items.push({field:fieldName,value:value});},true);
|
|||
|
items.sort(function(a,b) {return a.field < b.field ? -1 : (a.field == b.field ? 0 : +1);});
|
|||
|
if(items.length > 0)
|
|||
|
ListView.create(popup,items,this.listViewTemplate);
|
|||
|
else
|
|||
|
createTiddlyElement(popup,"div",null,null,this.emptyText);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Tiddler() object
|
|||
|
//--
|
|||
|
|
|||
|
function Tiddler(title)
|
|||
|
{
|
|||
|
this.title = title;
|
|||
|
this.text = "";
|
|||
|
this.creator = null;
|
|||
|
this.modifier = null;
|
|||
|
this.created = new Date();
|
|||
|
this.modified = this.created;
|
|||
|
this.links = [];
|
|||
|
this.linksUpdated = false;
|
|||
|
this.tags = [];
|
|||
|
this.fields = {};
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
Tiddler.prototype.getLinks = function()
|
|||
|
{
|
|||
|
if(this.linksUpdated==false)
|
|||
|
this.changed();
|
|||
|
return this.links;
|
|||
|
};
|
|||
|
|
|||
|
// Returns the fields that are inherited in string field:"value" field2:"value2" format
|
|||
|
Tiddler.prototype.getInheritedFields = function()
|
|||
|
{
|
|||
|
var f = {};
|
|||
|
var i;
|
|||
|
for(i in this.fields) {
|
|||
|
if(i=="server.host" || i=="server.workspace" || i=="wikiformat"|| i=="server.type") {
|
|||
|
f[i] = this.fields[i];
|
|||
|
}
|
|||
|
}
|
|||
|
return String.encodeHashMap(f);
|
|||
|
};
|
|||
|
|
|||
|
// Increment the changeCount of a tiddler
|
|||
|
Tiddler.prototype.incChangeCount = function()
|
|||
|
{
|
|||
|
var c = this.fields['changecount'];
|
|||
|
c = c ? parseInt(c,10) : 0;
|
|||
|
this.fields['changecount'] = String(c+1);
|
|||
|
};
|
|||
|
|
|||
|
// Clear the changeCount of a tiddler
|
|||
|
Tiddler.prototype.clearChangeCount = function()
|
|||
|
{
|
|||
|
if(this.fields['changecount']) {
|
|||
|
delete this.fields['changecount'];
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.doNotSave = function()
|
|||
|
{
|
|||
|
return this.fields['doNotSave'];
|
|||
|
};
|
|||
|
|
|||
|
// Returns true if the tiddler has been updated since the tiddler was created or downloaded
|
|||
|
Tiddler.prototype.isTouched = function()
|
|||
|
{
|
|||
|
var changecount = this.fields.changecount || 0;
|
|||
|
return changecount > 0;
|
|||
|
};
|
|||
|
|
|||
|
// Change the text and other attributes of a tiddler
|
|||
|
Tiddler.prototype.set = function(title,text,modifier,modified,tags,created,fields,creator)
|
|||
|
{
|
|||
|
this.assign(title,text,modifier,modified,tags,created,fields,creator);
|
|||
|
this.changed();
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
// Change the text and other attributes of a tiddler without triggered a tiddler.changed() call
|
|||
|
Tiddler.prototype.assign = function(title,text,modifier,modified,tags,created,fields,creator)
|
|||
|
{
|
|||
|
if(title != undefined)
|
|||
|
this.title = title;
|
|||
|
if(text != undefined)
|
|||
|
this.text = text;
|
|||
|
if(modifier != undefined)
|
|||
|
this.modifier = modifier;
|
|||
|
if(modified != undefined)
|
|||
|
this.modified = modified;
|
|||
|
if(creator != undefined)
|
|||
|
this.creator = creator;
|
|||
|
if(created != undefined)
|
|||
|
this.created = created;
|
|||
|
if(fields != undefined)
|
|||
|
this.fields = fields;
|
|||
|
if(tags != undefined)
|
|||
|
this.tags = (typeof tags == "string") ? tags.readBracketedList() : tags;
|
|||
|
else if(this.tags == undefined)
|
|||
|
this.tags = [];
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
// Get the tags for a tiddler as a string (space delimited, using [[brackets]] for tags containing spaces)
|
|||
|
Tiddler.prototype.getTags = function()
|
|||
|
{
|
|||
|
return String.encodeTiddlyLinkList(this.tags);
|
|||
|
};
|
|||
|
|
|||
|
// Test if a tiddler carries a tag
|
|||
|
Tiddler.prototype.isTagged = function(tag)
|
|||
|
{
|
|||
|
return this.tags.indexOf(tag) != -1;
|
|||
|
};
|
|||
|
|
|||
|
// Static method to convert "\n" to newlines, "\s" to "\"
|
|||
|
Tiddler.unescapeLineBreaks = function(text)
|
|||
|
{
|
|||
|
return text ? text.unescapeLineBreaks() : "";
|
|||
|
};
|
|||
|
|
|||
|
// Convert newlines to "\n", "\" to "\s"
|
|||
|
Tiddler.prototype.escapeLineBreaks = function()
|
|||
|
{
|
|||
|
return this.text.escapeLineBreaks();
|
|||
|
};
|
|||
|
|
|||
|
// Updates the secondary information (like links[] array) after a change to a tiddler
|
|||
|
Tiddler.prototype.changed = function()
|
|||
|
{
|
|||
|
this.links = [];
|
|||
|
var text = this.text;
|
|||
|
// remove 'quoted' text before scanning tiddler source
|
|||
|
text = text.replace(/\/%((?:.|\n)*?)%\//g,"").
|
|||
|
replace(/\{{3}((?:.|\n)*?)\}{3}/g,"").
|
|||
|
replace(/"""((?:.|\n)*?)"""/g,"").
|
|||
|
replace(/<nowiki\>((?:.|\n)*?)<\/nowiki\>/g,"").
|
|||
|
replace(/<html\>((?:.|\n)*?)<\/html\>/g,"").
|
|||
|
replace(/<script((?:.|\n)*?)<\/script\>/g,"");
|
|||
|
var t = this.autoLinkWikiWords() ? 0 : 1;
|
|||
|
var tiddlerLinkRegExp = t==0 ? config.textPrimitives.tiddlerAnyLinkRegExp : config.textPrimitives.tiddlerForcedLinkRegExp;
|
|||
|
tiddlerLinkRegExp.lastIndex = 0;
|
|||
|
var formatMatch = tiddlerLinkRegExp.exec(text);
|
|||
|
while(formatMatch) {
|
|||
|
var lastIndex = tiddlerLinkRegExp.lastIndex;
|
|||
|
if(t==0 && formatMatch[1] && formatMatch[1] != this.title) {
|
|||
|
// wikiWordLink
|
|||
|
if(formatMatch.index > 0) {
|
|||
|
var preRegExp = new RegExp(config.textPrimitives.unWikiLink+"|"+config.textPrimitives.anyLetter,"mg");
|
|||
|
preRegExp.lastIndex = formatMatch.index-1;
|
|||
|
var preMatch = preRegExp.exec(text);
|
|||
|
if(preMatch.index != formatMatch.index-1)
|
|||
|
this.links.pushUnique(formatMatch[1]);
|
|||
|
} else {
|
|||
|
this.links.pushUnique(formatMatch[1]);
|
|||
|
}
|
|||
|
}
|
|||
|
else if(formatMatch[2-t] && !config.formatterHelpers.isExternalLink(formatMatch[3-t])) // titledBrackettedLink
|
|||
|
this.links.pushUnique(formatMatch[3-t]);
|
|||
|
else if(formatMatch[4-t] && formatMatch[4-t] != this.title) // brackettedLink
|
|||
|
this.links.pushUnique(formatMatch[4-t]);
|
|||
|
tiddlerLinkRegExp.lastIndex = lastIndex;
|
|||
|
formatMatch = tiddlerLinkRegExp.exec(text);
|
|||
|
}
|
|||
|
this.linksUpdated = true;
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.getSubtitle = function()
|
|||
|
{
|
|||
|
var modifier = this.modifier;
|
|||
|
if(!modifier)
|
|||
|
modifier = config.messages.subtitleUnknown || "";
|
|||
|
var modified = this.modified;
|
|||
|
if(modified)
|
|||
|
modified = modified.toLocaleString();
|
|||
|
else
|
|||
|
modified = config.messages.subtitleUnknown || "";
|
|||
|
var f = config.messages.tiddlerLinkTooltip || "%0 - %1, %2";
|
|||
|
return f.format([this.title,modifier,modified]);
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.isReadOnly = function()
|
|||
|
{
|
|||
|
return readOnly;
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.autoLinkWikiWords = function()
|
|||
|
{
|
|||
|
return !(this.isTagged("systemConfig") || this.isTagged("excludeMissing"));
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.getServerType = function()
|
|||
|
{
|
|||
|
var serverType = null;
|
|||
|
if(this.fields['server.type'])
|
|||
|
serverType = this.fields['server.type'];
|
|||
|
if(!serverType)
|
|||
|
serverType = this.fields['wikiformat'];
|
|||
|
if(serverType && !config.adaptors[serverType])
|
|||
|
serverType = null;
|
|||
|
return serverType;
|
|||
|
};
|
|||
|
|
|||
|
Tiddler.prototype.getAdaptor = function()
|
|||
|
{
|
|||
|
var serverType = this.getServerType();
|
|||
|
return serverType ? new config.adaptors[serverType]() : null;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- TiddlyWiki instance contains TiddlerS
|
|||
|
//--
|
|||
|
|
|||
|
function TiddlyWiki(params)
|
|||
|
{
|
|||
|
var tiddlers = {}; // Hashmap by name of tiddlers
|
|||
|
if(params && params.config) {
|
|||
|
this.config = config;
|
|||
|
}
|
|||
|
this.tiddlersUpdated = false;
|
|||
|
this.namedNotifications = []; // Array of {name:,notify:} of notification functions
|
|||
|
this.notificationLevel = 0;
|
|||
|
this.slices = {}; // map tiddlerName->(map sliceName->sliceValue). Lazy.
|
|||
|
this.clear = function() {
|
|||
|
tiddlers = {};
|
|||
|
this.setDirty(false);
|
|||
|
};
|
|||
|
this.fetchTiddler = function(title) {
|
|||
|
var t = tiddlers[title];
|
|||
|
return t instanceof Tiddler ? t : null;
|
|||
|
};
|
|||
|
this.deleteTiddler = function(title) {
|
|||
|
delete this.slices[title];
|
|||
|
delete tiddlers[title];
|
|||
|
};
|
|||
|
this.addTiddler = function(tiddler) {
|
|||
|
delete this.slices[tiddler.title];
|
|||
|
tiddlers[tiddler.title] = tiddler;
|
|||
|
};
|
|||
|
this.forEachTiddler = function(callback) {
|
|||
|
var t;
|
|||
|
for(t in tiddlers) {
|
|||
|
var tiddler = tiddlers[t];
|
|||
|
if(tiddler instanceof Tiddler)
|
|||
|
callback.call(this,t,tiddler);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
TiddlyWiki.prototype.setDirty = function(dirty)
|
|||
|
{
|
|||
|
this.dirty = dirty;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.isDirty = function()
|
|||
|
{
|
|||
|
return this.dirty;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.tiddlerExists = function(title)
|
|||
|
{
|
|||
|
var t = this.fetchTiddler(title);
|
|||
|
return t != undefined;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.isShadowTiddler = function(title)
|
|||
|
{
|
|||
|
return config.shadowTiddlers[title] === undefined ? false : true;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.createTiddler = function(title)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(!tiddler) {
|
|||
|
tiddler = new Tiddler(title);
|
|||
|
this.addTiddler(tiddler);
|
|||
|
this.setDirty(true);
|
|||
|
}
|
|||
|
return tiddler;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getTiddler = function(title)
|
|||
|
{
|
|||
|
var t = this.fetchTiddler(title);
|
|||
|
if(t != undefined)
|
|||
|
return t;
|
|||
|
else
|
|||
|
return null;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getShadowTiddlerText = function(title)
|
|||
|
{
|
|||
|
if(typeof config.shadowTiddlers[title] == "string")
|
|||
|
return config.shadowTiddlers[title];
|
|||
|
else
|
|||
|
return "";
|
|||
|
};
|
|||
|
|
|||
|
// Retrieve tiddler contents
|
|||
|
TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
|
|||
|
{
|
|||
|
if(!title)
|
|||
|
return defaultText;
|
|||
|
var pos = title.indexOf(config.textPrimitives.sectionSeparator);
|
|||
|
var section = null;
|
|||
|
if(pos != -1) {
|
|||
|
section = title.substr(pos + config.textPrimitives.sectionSeparator.length);
|
|||
|
title = title.substr(0,pos);
|
|||
|
}
|
|||
|
pos = title.indexOf(config.textPrimitives.sliceSeparator);
|
|||
|
if(pos != -1) {
|
|||
|
var slice = this.getTiddlerSlice(title.substr(0,pos),title.substr(pos + config.textPrimitives.sliceSeparator.length));
|
|||
|
if(slice)
|
|||
|
return slice;
|
|||
|
}
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
var text = tiddler ? tiddler.text : null;
|
|||
|
if(!tiddler && this.isShadowTiddler(title)) {
|
|||
|
text = this.getShadowTiddlerText(title);
|
|||
|
}
|
|||
|
if(text) {
|
|||
|
if(!section)
|
|||
|
return text;
|
|||
|
var re = new RegExp("(^!{1,6}[ \t]*" + section.escapeRegExp() + "[ \t]*\n)","mg");
|
|||
|
re.lastIndex = 0;
|
|||
|
var match = re.exec(text);
|
|||
|
if(match) {
|
|||
|
var t = text.substr(match.index+match[1].length);
|
|||
|
var re2 = /^!/mg;
|
|||
|
re2.lastIndex = 0;
|
|||
|
match = re2.exec(t); //# search for the next heading
|
|||
|
if(match)
|
|||
|
t = t.substr(0,match.index-1);//# don't include final \n
|
|||
|
return t;
|
|||
|
}
|
|||
|
return defaultText;
|
|||
|
}
|
|||
|
if(defaultText != undefined)
|
|||
|
return defaultText;
|
|||
|
return null;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth)
|
|||
|
{
|
|||
|
var bracketRegExp = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])","mg");
|
|||
|
var text = this.getTiddlerText(title,null);
|
|||
|
if(text == null)
|
|||
|
return defaultText;
|
|||
|
var textOut = [];
|
|||
|
var match,lastPos = 0;
|
|||
|
do {
|
|||
|
match = bracketRegExp.exec(text);
|
|||
|
if(match) {
|
|||
|
textOut.push(text.substr(lastPos,match.index-lastPos));
|
|||
|
if(match[1]) {
|
|||
|
if(depth <= 0)
|
|||
|
textOut.push(match[1]);
|
|||
|
else
|
|||
|
textOut.push(this.getRecursiveTiddlerText(match[1],"",depth-1));
|
|||
|
}
|
|||
|
lastPos = match.index + match[0].length;
|
|||
|
} else {
|
|||
|
textOut.push(text.substr(lastPos));
|
|||
|
}
|
|||
|
} while(match);
|
|||
|
return textOut.join("");
|
|||
|
};
|
|||
|
|
|||
|
//TiddlyWiki.prototype.slicesRE = /(?:^([\'\/]{0,2})~?([\.\w]+)\:\1[\t\x20]*([^\n]+)[\t\x20]*$)|(?:^\|([\'\/]{0,2})~?([\.\w]+)\:?\4\|[\t\x20]*([^\n]+)[\t\x20]*\|$)/gm;
|
|||
|
TiddlyWiki.prototype.slicesRE = /(?:^([\'\/]{0,2})~?([\.\w]+)\:\1[\t\x20]*([^\n]*)[\t\x20]*$)|(?:^\|([\'\/]{0,2})~?([\.\w]+)\:?\4\|[\t\x20]*([^\|\n]*)[\t\x20]*\|$)/gm;
|
|||
|
// @internal
|
|||
|
TiddlyWiki.prototype.calcAllSlices = function(title)
|
|||
|
{
|
|||
|
var slices = {};
|
|||
|
var text = this.getTiddlerText(title,"");
|
|||
|
this.slicesRE.lastIndex = 0;
|
|||
|
var m = this.slicesRE.exec(text);
|
|||
|
while(m) {
|
|||
|
if(m[2])
|
|||
|
slices[m[2]] = m[3];
|
|||
|
else
|
|||
|
slices[m[5]] = m[6];
|
|||
|
m = this.slicesRE.exec(text);
|
|||
|
}
|
|||
|
return slices;
|
|||
|
};
|
|||
|
|
|||
|
// Returns the slice of text of the given name
|
|||
|
TiddlyWiki.prototype.getTiddlerSlice = function(title,sliceName)
|
|||
|
{
|
|||
|
var slices = this.slices[title];
|
|||
|
if(!slices) {
|
|||
|
slices = this.calcAllSlices(title);
|
|||
|
this.slices[title] = slices;
|
|||
|
}
|
|||
|
return slices[sliceName];
|
|||
|
};
|
|||
|
|
|||
|
// Build an hashmap of the specified named slices of a tiddler
|
|||
|
TiddlyWiki.prototype.getTiddlerSlices = function(title,sliceNames)
|
|||
|
{
|
|||
|
var t,r = {};
|
|||
|
for(t=0; t<sliceNames.length; t++) {
|
|||
|
var slice = this.getTiddlerSlice(title,sliceNames[t]);
|
|||
|
if(slice)
|
|||
|
r[sliceNames[t]] = slice;
|
|||
|
}
|
|||
|
return r;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.suspendNotifications = function()
|
|||
|
{
|
|||
|
this.notificationLevel--;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.resumeNotifications = function()
|
|||
|
{
|
|||
|
this.notificationLevel++;
|
|||
|
};
|
|||
|
|
|||
|
// Invoke the notification handlers for a particular tiddler
|
|||
|
TiddlyWiki.prototype.notify = function(title,doBlanket)
|
|||
|
{
|
|||
|
if(!this.notificationLevel) {
|
|||
|
var t;
|
|||
|
for(t=0; t<this.namedNotifications.length; t++) {
|
|||
|
var n = this.namedNotifications[t];
|
|||
|
if((n.name == null && doBlanket) || (n.name == title))
|
|||
|
n.notify(title);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Invoke the notification handlers for all tiddlers
|
|||
|
TiddlyWiki.prototype.notifyAll = function()
|
|||
|
{
|
|||
|
if(!this.notificationLevel) {
|
|||
|
var t;
|
|||
|
for(t=0; t<this.namedNotifications.length; t++) {
|
|||
|
var n = this.namedNotifications[t];
|
|||
|
if(n.name)
|
|||
|
n.notify(n.name);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Add a notification handler to a tiddler
|
|||
|
TiddlyWiki.prototype.addNotification = function(title,fn)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i=0; i<this.namedNotifications.length; i++) {
|
|||
|
if((this.namedNotifications[i].name == title) && (this.namedNotifications[i].notify == fn))
|
|||
|
return this;
|
|||
|
}
|
|||
|
this.namedNotifications.push({name: title, notify: fn});
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.removeTiddler = function(title)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
this.deleteTiddler(title);
|
|||
|
this.notify(title,true);
|
|||
|
this.setDirty(true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Reset the sync status of a freshly synced tiddler
|
|||
|
TiddlyWiki.prototype.resetTiddler = function(title)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
tiddler.clearChangeCount();
|
|||
|
this.notify(title,true);
|
|||
|
this.setDirty(true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.setTiddlerTag = function(title,status,tag)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
var t = tiddler.tags.indexOf(tag);
|
|||
|
if(t != -1)
|
|||
|
tiddler.tags.splice(t,1);
|
|||
|
if(status)
|
|||
|
tiddler.tags.push(tag);
|
|||
|
tiddler.changed();
|
|||
|
tiddler.incChangeCount();
|
|||
|
this.notify(title,true);
|
|||
|
this.setDirty(true);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.addTiddlerFields = function(title,fields)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(!tiddler)
|
|||
|
return;
|
|||
|
merge(tiddler.fields,fields);
|
|||
|
tiddler.changed();
|
|||
|
tiddler.incChangeCount();
|
|||
|
this.notify(title,true);
|
|||
|
this.setDirty(true);
|
|||
|
};
|
|||
|
|
|||
|
// Store tiddler in TiddlyWiki instance
|
|||
|
TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created,creator)
|
|||
|
{
|
|||
|
var tiddler;
|
|||
|
if(title instanceof Tiddler) {
|
|||
|
tiddler = title;
|
|||
|
title = tiddler.title;
|
|||
|
newTitle = title;
|
|||
|
} else {
|
|||
|
tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
created = created || tiddler.created; // Preserve created date
|
|||
|
creator = creator || tiddler.creator;
|
|||
|
this.deleteTiddler(title);
|
|||
|
} else {
|
|||
|
created = created || modified;
|
|||
|
tiddler = new Tiddler();
|
|||
|
}
|
|||
|
fields = merge(merge({},fields),config.defaultCustomFields,true);
|
|||
|
tiddler.set(newTitle,newBody,modifier,modified,tags,created,fields,creator);
|
|||
|
}
|
|||
|
this.addTiddler(tiddler);
|
|||
|
if(clearChangeCount)
|
|||
|
tiddler.clearChangeCount();
|
|||
|
else
|
|||
|
tiddler.incChangeCount();
|
|||
|
if(title != newTitle)
|
|||
|
this.notify(title,true);
|
|||
|
this.notify(newTitle,true);
|
|||
|
if(window.location.protocol == "file:")
|
|||
|
this.setDirty(true);
|
|||
|
return tiddler;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.incChangeCount = function(title)
|
|||
|
{
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler)
|
|||
|
tiddler.incChangeCount();
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getLoader = function()
|
|||
|
{
|
|||
|
if(!this.loader)
|
|||
|
this.loader = new TW21Loader();
|
|||
|
return this.loader;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getSaver = function()
|
|||
|
{
|
|||
|
if(!this.saver)
|
|||
|
this.saver = new TW21Saver();
|
|||
|
return this.saver;
|
|||
|
};
|
|||
|
|
|||
|
// Return all tiddlers formatted as an HTML string
|
|||
|
TiddlyWiki.prototype.allTiddlersAsHtml = function()
|
|||
|
{
|
|||
|
return this.getSaver().externalize(store);
|
|||
|
};
|
|||
|
|
|||
|
// Load contents of a TiddlyWiki from an HTML DIV
|
|||
|
TiddlyWiki.prototype.loadFromDiv = function(src,idPrefix,noUpdate)
|
|||
|
{
|
|||
|
this.idPrefix = idPrefix;
|
|||
|
var storeElem = (typeof src == "string") ? document.getElementById(src) : src;
|
|||
|
if(!storeElem)
|
|||
|
return;
|
|||
|
var tiddlers = this.getLoader().loadTiddlers(this,storeElem.childNodes);
|
|||
|
this.setDirty(false);
|
|||
|
if(!noUpdate) {
|
|||
|
var i;
|
|||
|
for(i = 0;i<tiddlers.length; i++)
|
|||
|
tiddlers[i].changed();
|
|||
|
}
|
|||
|
jQuery(document).trigger("loadTiddlers");
|
|||
|
};
|
|||
|
|
|||
|
// Load contents of a TiddlyWiki from a string
|
|||
|
// Returns null if there's an error
|
|||
|
TiddlyWiki.prototype.importTiddlyWiki = function(text)
|
|||
|
{
|
|||
|
var posDiv = locateStoreArea(text);
|
|||
|
if(!posDiv)
|
|||
|
return null;
|
|||
|
var content = "<" + "html><" + "body>" + text.substring(posDiv[0],posDiv[1] + endSaveArea.length) + "<" + "/body><" + "/html>";
|
|||
|
// Create the iframe
|
|||
|
var iframe = document.createElement("iframe");
|
|||
|
iframe.style.display = "none";
|
|||
|
document.body.appendChild(iframe);
|
|||
|
var doc = iframe.document;
|
|||
|
if(iframe.contentDocument)
|
|||
|
doc = iframe.contentDocument; // For NS6
|
|||
|
else if(iframe.contentWindow)
|
|||
|
doc = iframe.contentWindow.document; // For IE5.5 and IE6
|
|||
|
// Put the content in the iframe
|
|||
|
doc.open();
|
|||
|
doc.writeln(content);
|
|||
|
doc.close();
|
|||
|
// Load the content into a TiddlyWiki() object
|
|||
|
var storeArea = doc.getElementById("storeArea");
|
|||
|
this.loadFromDiv(storeArea,"store");
|
|||
|
// Get rid of the iframe
|
|||
|
iframe.parentNode.removeChild(iframe);
|
|||
|
return this;
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.updateTiddlers = function()
|
|||
|
{
|
|||
|
this.tiddlersUpdated = true;
|
|||
|
this.forEachTiddler(function(title,tiddler) {
|
|||
|
tiddler.changed();
|
|||
|
});
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of tiddlers matching a search regular expression
|
|||
|
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag,match)
|
|||
|
{
|
|||
|
var candidates = this.reverseLookup("tags",excludeTag,!!match);
|
|||
|
var t,results = [];
|
|||
|
for(t=0; t<candidates.length; t++) {
|
|||
|
if((candidates[t].title.search(searchRegExp) != -1) || (candidates[t].text.search(searchRegExp) != -1))
|
|||
|
results.push(candidates[t]);
|
|||
|
}
|
|||
|
if(!sortField)
|
|||
|
sortField = "title";
|
|||
|
results.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Returns a list of all tags in use
|
|||
|
// excludeTag - if present, excludes tags that are themselves tagged with excludeTag
|
|||
|
// Returns an array of arrays where [tag][0] is the name of the tag and [tag][1] is the number of occurances
|
|||
|
TiddlyWiki.prototype.getTags = function(excludeTag)
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function(title,tiddler) {
|
|||
|
var g,c;
|
|||
|
for(g=0; g<tiddler.tags.length; g++) {
|
|||
|
var tag = tiddler.tags[g];
|
|||
|
var n = true;
|
|||
|
for(c=0; c<results.length; c++) {
|
|||
|
if(results[c][0] == tag) {
|
|||
|
n = false;
|
|||
|
results[c][1]++;
|
|||
|
}
|
|||
|
}
|
|||
|
if(n && excludeTag) {
|
|||
|
var t = this.fetchTiddler(tag);
|
|||
|
if(t && t.isTagged(excludeTag))
|
|||
|
n = false;
|
|||
|
}
|
|||
|
if(n)
|
|||
|
results.push([tag,1]);
|
|||
|
}
|
|||
|
});
|
|||
|
results.sort(function(a,b) {return a[0].toLowerCase() < b[0].toLowerCase() ? -1 : (a[0].toLowerCase() == b[0].toLowerCase() ? 0 : +1);});
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of the tiddlers that are tagged with a given tag
|
|||
|
TiddlyWiki.prototype.getTaggedTiddlers = function(tag,sortField)
|
|||
|
{
|
|||
|
return this.reverseLookup("tags",tag,true,sortField);
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.prototype.getValueTiddlers = function(field,value,sortField)
|
|||
|
{
|
|||
|
return this.reverseLookup(field,value,true,sortField);
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of the tiddlers that link to a given tiddler
|
|||
|
TiddlyWiki.prototype.getReferringTiddlers = function(title,unusedParameter,sortField)
|
|||
|
{
|
|||
|
if(!this.tiddlersUpdated)
|
|||
|
this.updateTiddlers();
|
|||
|
return this.reverseLookup("links",title,true,sortField);
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of the tiddlers that do or do not have a specified entry in the specified storage array (ie, "links" or "tags")
|
|||
|
// lookupMatch == true to match tiddlers, false to exclude tiddlers
|
|||
|
TiddlyWiki.prototype.reverseLookup = function(lookupField,lookupValue,lookupMatch,sortField)
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function(title,tiddler) {
|
|||
|
var f = !lookupMatch;
|
|||
|
var values;
|
|||
|
if(["links", "tags"].contains(lookupField)) {
|
|||
|
values = tiddler[lookupField];
|
|||
|
} else {
|
|||
|
var accessor = TiddlyWiki.standardFieldAccess[lookupField];
|
|||
|
if(accessor) {
|
|||
|
values = [ accessor.get(tiddler) ];
|
|||
|
} else {
|
|||
|
values = tiddler.fields[lookupField] ? [tiddler.fields[lookupField]] : [];
|
|||
|
}
|
|||
|
}
|
|||
|
var lookup;
|
|||
|
for(lookup=0; lookup<values.length; lookup++) {
|
|||
|
if(values[lookup] == lookupValue)
|
|||
|
f = lookupMatch;
|
|||
|
}
|
|||
|
if(f)
|
|||
|
results.push(tiddler);
|
|||
|
});
|
|||
|
if(!sortField)
|
|||
|
sortField = "title";
|
|||
|
return this.sortTiddlers(results,sortField);
|
|||
|
};
|
|||
|
|
|||
|
// Return the tiddlers as a sorted array
|
|||
|
TiddlyWiki.prototype.getTiddlers = function(field,excludeTag)
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function(title,tiddler) {
|
|||
|
if(excludeTag == undefined || !tiddler.isTagged(excludeTag))
|
|||
|
results.push(tiddler);
|
|||
|
});
|
|||
|
if(field)
|
|||
|
results.sort(function(a,b) {return a[field] < b[field] ? -1 : (a[field] == b[field] ? 0 : +1);});
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return array of names of tiddlers that are referred to but not defined
|
|||
|
TiddlyWiki.prototype.getMissingLinks = function()
|
|||
|
{
|
|||
|
if(!this.tiddlersUpdated)
|
|||
|
this.updateTiddlers();
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function (title,tiddler) {
|
|||
|
if(tiddler.isTagged("excludeMissing") || tiddler.isTagged("systemConfig"))
|
|||
|
return;
|
|||
|
var n;
|
|||
|
for(n=0; n<tiddler.links.length;n++) {
|
|||
|
var link = tiddler.links[n];
|
|||
|
if(this.getTiddlerText(link,null) == null && !this.isShadowTiddler(link) && !config.macros[link])
|
|||
|
results.pushUnique(link);
|
|||
|
}
|
|||
|
});
|
|||
|
results.sort();
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of names of tiddlers that are defined but not referred to
|
|||
|
TiddlyWiki.prototype.getOrphans = function()
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function (title,tiddler) {
|
|||
|
if(this.getReferringTiddlers(title).length == 0 && !tiddler.isTagged("excludeLists"))
|
|||
|
results.push(title);
|
|||
|
});
|
|||
|
results.sort();
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of names of all the shadow tiddlers
|
|||
|
TiddlyWiki.prototype.getShadowed = function()
|
|||
|
{
|
|||
|
var t,results = [];
|
|||
|
for(t in config.shadowTiddlers) {
|
|||
|
if(this.isShadowTiddler(t))
|
|||
|
results.push(t);
|
|||
|
}
|
|||
|
results.sort();
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Return an array of tiddlers that have been touched since they were downloaded or created
|
|||
|
TiddlyWiki.prototype.getTouched = function()
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
this.forEachTiddler(function(title,tiddler) {
|
|||
|
if(tiddler.isTouched())
|
|||
|
results.push(tiddler);
|
|||
|
});
|
|||
|
results.sort();
|
|||
|
return results;
|
|||
|
};
|
|||
|
|
|||
|
// Resolves a Tiddler reference or tiddler title into a Tiddler object, or null if it doesn't exist
|
|||
|
TiddlyWiki.prototype.resolveTiddler = function(tiddler)
|
|||
|
{
|
|||
|
var t = (typeof tiddler == "string") ? this.getTiddler(tiddler) : tiddler;
|
|||
|
return t instanceof Tiddler ? t : null;
|
|||
|
};
|
|||
|
|
|||
|
// Sort a list of tiddlers
|
|||
|
TiddlyWiki.prototype.sortTiddlers = function(tiddlers,field)
|
|||
|
{
|
|||
|
var asc = +1;
|
|||
|
switch(field.substr(0,1)) {
|
|||
|
case "-":
|
|||
|
asc = -1;
|
|||
|
field = field.substr(1);
|
|||
|
break;
|
|||
|
case "+":
|
|||
|
field = field.substr(1);
|
|||
|
break;
|
|||
|
}
|
|||
|
if(TiddlyWiki.standardFieldAccess[field]) {
|
|||
|
if(field=="title") {
|
|||
|
tiddlers.sort(function(a,b) {return a[field].toLowerCase() < b[field].toLowerCase() ? -asc : (a[field].toLowerCase() == b[field].toLowerCase() ? 0 : asc);});
|
|||
|
} else {
|
|||
|
tiddlers.sort(function(a,b) {return a[field] < b[field] ? -asc : (a[field] == b[field] ? 0 : asc);});
|
|||
|
}
|
|||
|
} else {
|
|||
|
tiddlers.sort(function(a,b) {return a.fields[field] < b.fields[field] ? -asc : (a.fields[field] == b.fields[field] ? 0 : +asc);});
|
|||
|
}
|
|||
|
return tiddlers;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Filter a list of tiddlers
|
|||
|
//--
|
|||
|
|
|||
|
config.filters = {
|
|||
|
tiddler: function(results,match) {
|
|||
|
var title = match[1]||match[4];
|
|||
|
var tiddler = this.fetchTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
results.pushUnique(tiddler);
|
|||
|
} else if(this.isShadowTiddler(title)) {
|
|||
|
tiddler = new Tiddler();
|
|||
|
tiddler.set(title,this.getTiddlerText(title));
|
|||
|
results.pushUnique(tiddler);
|
|||
|
} else {
|
|||
|
results.pushUnique(new Tiddler(title));
|
|||
|
}
|
|||
|
return results;
|
|||
|
},
|
|||
|
tag: function(results,match) {
|
|||
|
var m,matched = this.getTaggedTiddlers(match[3]);
|
|||
|
for(m=0; m<matched.length; m++) {
|
|||
|
results.pushUnique(matched[m]);
|
|||
|
}
|
|||
|
return results;
|
|||
|
},
|
|||
|
sort: function(results,match) {
|
|||
|
return this.sortTiddlers(results,match[3]);
|
|||
|
},
|
|||
|
limit: function(results,match) {
|
|||
|
return results.slice(0,parseInt(match[3],10));
|
|||
|
},
|
|||
|
field: function(results,match) {
|
|||
|
var m,matched = this.getValueTiddlers(match[2],match[3]);
|
|||
|
for (m = 0; m < matched.length; m++) {
|
|||
|
results.pushUnique(matched[m]);
|
|||
|
}
|
|||
|
return results;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Filter a list of tiddlers
|
|||
|
TiddlyWiki.prototype.filterTiddlers = function(filter)
|
|||
|
{
|
|||
|
var re = /([^\s\[\]]+)|(?:\[([ \w\.\-]+)\[([^\]]+)\]\])|(?:\[\[([^\]]+)\]\])/mg;
|
|||
|
|
|||
|
var results = [];
|
|||
|
if(filter) {
|
|||
|
var match = re.exec(filter);
|
|||
|
while(match) {
|
|||
|
var handler = (match[1]||match[4])?'tiddler':config.filters[match[2]]?match[2]:'field';
|
|||
|
results = config.filters[handler].call(this,results,match);
|
|||
|
match = re.exec(filter);
|
|||
|
}
|
|||
|
}
|
|||
|
return results;
|
|||
|
};
|
|||
|
// Returns true if path is a valid field name (path),
|
|||
|
// i.e. a sequence of identifiers, separated by "."
|
|||
|
TiddlyWiki.isValidFieldName = function(name)
|
|||
|
{
|
|||
|
var match = /[a-zA-Z_]\w*(\.[a-zA-Z_]\w*)*/.exec(name);
|
|||
|
return match && (match[0] == name);
|
|||
|
};
|
|||
|
|
|||
|
// Throws an exception when name is not a valid field name.
|
|||
|
TiddlyWiki.checkFieldName = function(name)
|
|||
|
{
|
|||
|
if(!TiddlyWiki.isValidFieldName(name))
|
|||
|
throw config.messages.invalidFieldName.format([name]);
|
|||
|
};
|
|||
|
|
|||
|
function StringFieldAccess(n,readOnly)
|
|||
|
{
|
|||
|
this.set = readOnly ?
|
|||
|
function(t,v) {if(v != t[n]) throw config.messages.fieldCannotBeChanged.format([n]);} :
|
|||
|
function(t,v) {if(v != t[n]) {t[n] = v; return true;}};
|
|||
|
this.get = function(t) {return t[n];};
|
|||
|
}
|
|||
|
|
|||
|
function DateFieldAccess(n)
|
|||
|
{
|
|||
|
this.set = function(t,v) {
|
|||
|
var d = v instanceof Date ? v : Date.convertFromYYYYMMDDHHMM(v);
|
|||
|
if(d != t[n]) {
|
|||
|
t[n] = d; return true;
|
|||
|
}
|
|||
|
};
|
|||
|
this.get = function(t) {return t[n].convertToYYYYMMDDHHMM();};
|
|||
|
}
|
|||
|
|
|||
|
function LinksFieldAccess(n)
|
|||
|
{
|
|||
|
this.set = function(t,v) {
|
|||
|
var s = (typeof v == "string") ? v.readBracketedList() : v;
|
|||
|
if(s.toString() != t[n].toString()) {
|
|||
|
t[n] = s; return true;
|
|||
|
}
|
|||
|
};
|
|||
|
this.get = function(t) {return String.encodeTiddlyLinkList(t[n]);};
|
|||
|
}
|
|||
|
|
|||
|
TiddlyWiki.standardFieldAccess = {
|
|||
|
// The set functions return true when setting the data has changed the value.
|
|||
|
"title": new StringFieldAccess("title",true),
|
|||
|
// Handle the "tiddler" field name as the title
|
|||
|
"tiddler": new StringFieldAccess("title",true),
|
|||
|
"text": new StringFieldAccess("text"),
|
|||
|
"modifier": new StringFieldAccess("modifier"),
|
|||
|
"modified": new DateFieldAccess("modified"),
|
|||
|
"creator": new StringFieldAccess("creator"),
|
|||
|
"created": new DateFieldAccess("created"),
|
|||
|
"tags": new LinksFieldAccess("tags")
|
|||
|
};
|
|||
|
|
|||
|
TiddlyWiki.isStandardField = function(name)
|
|||
|
{
|
|||
|
return TiddlyWiki.standardFieldAccess[name] != undefined;
|
|||
|
};
|
|||
|
|
|||
|
// Sets the value of the given field of the tiddler to the value.
|
|||
|
// Setting an ExtendedField's value to null or undefined removes the field.
|
|||
|
// Setting a namespace to undefined removes all fields of that namespace.
|
|||
|
// The fieldName is case-insensitive.
|
|||
|
// All values will be converted to a string value.
|
|||
|
TiddlyWiki.prototype.setValue = function(tiddler,fieldName,value)
|
|||
|
{
|
|||
|
TiddlyWiki.checkFieldName(fieldName);
|
|||
|
var t = this.resolveTiddler(tiddler);
|
|||
|
if(!t)
|
|||
|
return;
|
|||
|
fieldName = fieldName.toLowerCase();
|
|||
|
var isRemove = (value === undefined) || (value === null);
|
|||
|
var accessor = TiddlyWiki.standardFieldAccess[fieldName];
|
|||
|
if(accessor) {
|
|||
|
if(isRemove)
|
|||
|
// don't remove StandardFields
|
|||
|
return;
|
|||
|
var h = TiddlyWiki.standardFieldAccess[fieldName];
|
|||
|
if(!h.set(t,value))
|
|||
|
return;
|
|||
|
} else {
|
|||
|
var oldValue = t.fields[fieldName];
|
|||
|
if(isRemove) {
|
|||
|
if(oldValue !== undefined) {
|
|||
|
// deletes a single field
|
|||
|
delete t.fields[fieldName];
|
|||
|
} else {
|
|||
|
// no concrete value is defined for the fieldName
|
|||
|
// so we guess this is a namespace path.
|
|||
|
// delete all fields in a namespace
|
|||
|
var re = new RegExp("^"+fieldName+"\\.");
|
|||
|
var dirty = false;
|
|||
|
var n;
|
|||
|
for(n in t.fields) {
|
|||
|
if(n.match(re)) {
|
|||
|
delete t.fields[n];
|
|||
|
dirty = true;
|
|||
|
}
|
|||
|
}
|
|||
|
if(!dirty)
|
|||
|
return;
|
|||
|
}
|
|||
|
} else {
|
|||
|
// the "normal" set case. value is defined (not null/undefined)
|
|||
|
// For convenience provide a nicer conversion Date->String
|
|||
|
value = value instanceof Date ? value.convertToYYYYMMDDHHMMSSMMM() : String(value);
|
|||
|
if(oldValue == value)
|
|||
|
return;
|
|||
|
t.fields[fieldName] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
// When we are here the tiddler/store really was changed.
|
|||
|
this.notify(t.title,true);
|
|||
|
if(!fieldName.match(/^temp\./))
|
|||
|
this.setDirty(true);
|
|||
|
};
|
|||
|
|
|||
|
// Returns the value of the given field of the tiddler.
|
|||
|
// The fieldName is case-insensitive.
|
|||
|
// Will only return String values (or undefined).
|
|||
|
TiddlyWiki.prototype.getValue = function(tiddler,fieldName)
|
|||
|
{
|
|||
|
var t = this.resolveTiddler(tiddler);
|
|||
|
if(!t)
|
|||
|
return undefined;
|
|||
|
if(fieldName.indexOf(config.textPrimitives.sectionSeparator) === 0 || fieldName.indexOf(config.textPrimitives.sliceSeparator) === 0) {
|
|||
|
var sliceType = fieldName.substr(0, 2);
|
|||
|
var sliceName = fieldName.substring(2);
|
|||
|
return store.getTiddlerText("%0%1%2".format(t.title,sliceType,sliceName));
|
|||
|
} else {
|
|||
|
fieldName = fieldName.toLowerCase();
|
|||
|
var accessor = TiddlyWiki.standardFieldAccess[fieldName];
|
|||
|
if(accessor) {
|
|||
|
return accessor.get(t);
|
|||
|
}
|
|||
|
}
|
|||
|
return t.fields[fieldName];
|
|||
|
};
|
|||
|
|
|||
|
// Calls the callback function for every field in the tiddler.
|
|||
|
// When callback function returns a non-false value the iteration stops
|
|||
|
// and that value is returned.
|
|||
|
// The order of the fields is not defined.
|
|||
|
// @param callback a function(tiddler,fieldName,value).
|
|||
|
TiddlyWiki.prototype.forEachField = function(tiddler,callback,onlyExtendedFields)
|
|||
|
{
|
|||
|
var t = this.resolveTiddler(tiddler);
|
|||
|
if(!t)
|
|||
|
return undefined;
|
|||
|
var n,result;
|
|||
|
for(n in t.fields) {
|
|||
|
result = callback(t,n,t.fields[n]);
|
|||
|
if(result)
|
|||
|
return result;
|
|||
|
}
|
|||
|
if(onlyExtendedFields)
|
|||
|
return undefined;
|
|||
|
for(n in TiddlyWiki.standardFieldAccess) {
|
|||
|
if(n != "tiddler") {
|
|||
|
// even though the "title" field can also be referenced through the name "tiddler"
|
|||
|
// we only visit this field once.
|
|||
|
result = callback(t,n,TiddlyWiki.standardFieldAccess[n].get(t));
|
|||
|
if(result)
|
|||
|
return result;
|
|||
|
}
|
|||
|
}
|
|||
|
return undefined;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Story functions
|
|||
|
//--
|
|||
|
|
|||
|
function Story(containerId,idPrefix)
|
|||
|
{
|
|||
|
this.container = containerId;
|
|||
|
this.idPrefix = idPrefix;
|
|||
|
this.highlightRegExp = null;
|
|||
|
this.tiddlerId = function(title) {
|
|||
|
title = title.replace(/_/g, "__").replace(/ /g, "_");
|
|||
|
var id = this.idPrefix + title;
|
|||
|
return id==this.container ? this.idPrefix + "_" + title : id;
|
|||
|
};
|
|||
|
this.containerId = function() {
|
|||
|
return this.container;
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
Story.prototype.getTiddler = function(title)
|
|||
|
{
|
|||
|
return document.getElementById(this.tiddlerId(title));
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.getContainer = function()
|
|||
|
{
|
|||
|
return document.getElementById(this.containerId());
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.forEachTiddler = function(fn)
|
|||
|
{
|
|||
|
var place = this.getContainer();
|
|||
|
if(!place)
|
|||
|
return;
|
|||
|
var e = place.firstChild;
|
|||
|
while(e) {
|
|||
|
var n = e.nextSibling;
|
|||
|
var title = e.getAttribute("tiddler");
|
|||
|
fn.call(this,title,e);
|
|||
|
e = n;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.displayDefaultTiddlers = function()
|
|||
|
{
|
|||
|
this.displayTiddlers(null,store.filterTiddlers(store.getTiddlerText("DefaultTiddlers")));
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.displayTiddlers = function(srcElement,titles,template,animate,unused,customFields,toggle)
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t = titles.length-1;t>=0;t--)
|
|||
|
this.displayTiddler(srcElement,titles[t],template,animate,unused,customFields);
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,unused,customFields,toggle,animationSrc)
|
|||
|
{
|
|||
|
var title = (tiddler instanceof Tiddler) ? tiddler.title : tiddler;
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem) {
|
|||
|
if(toggle) {
|
|||
|
if(tiddlerElem.getAttribute("dirty") != "true")
|
|||
|
this.closeTiddler(title,true);
|
|||
|
} else {
|
|||
|
this.refreshTiddler(title,template,false,customFields);
|
|||
|
}
|
|||
|
} else {
|
|||
|
var place = this.getContainer();
|
|||
|
var before = this.positionTiddler(srcElement);
|
|||
|
tiddlerElem = this.createTiddler(place,before,title,template,customFields);
|
|||
|
}
|
|||
|
if(animationSrc && typeof animationSrc !== "string") {
|
|||
|
srcElement = animationSrc;
|
|||
|
}
|
|||
|
if(srcElement && typeof srcElement !== "string") {
|
|||
|
if(config.options.chkAnimate && (animate == undefined || animate == true) && anim && typeof Zoomer == "function" && typeof Scroller == "function")
|
|||
|
anim.startAnimating(new Zoomer(title,srcElement,tiddlerElem),new Scroller(tiddlerElem));
|
|||
|
else
|
|||
|
window.scrollTo(0,ensureVisible(tiddlerElem));
|
|||
|
}
|
|||
|
return tiddlerElem;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.positionTiddler = function(srcElement)
|
|||
|
{
|
|||
|
var place = this.getContainer();
|
|||
|
var before = null;
|
|||
|
if(typeof srcElement == "string") {
|
|||
|
switch(srcElement) {
|
|||
|
case "top":
|
|||
|
before = place.firstChild;
|
|||
|
break;
|
|||
|
case "bottom":
|
|||
|
before = null;
|
|||
|
break;
|
|||
|
}
|
|||
|
} else {
|
|||
|
var after = this.findContainingTiddler(srcElement);
|
|||
|
if(after == null) {
|
|||
|
before = place.firstChild;
|
|||
|
} else if(after.nextSibling) {
|
|||
|
before = after.nextSibling;
|
|||
|
if(before.nodeType != 1)
|
|||
|
before = null;
|
|||
|
}
|
|||
|
}
|
|||
|
return before;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.createTiddler = function(place,before,title,template,customFields)
|
|||
|
{
|
|||
|
var tiddlerElem = createTiddlyElement(null,"div",this.tiddlerId(title),"tiddler");
|
|||
|
tiddlerElem.setAttribute("refresh","tiddler");
|
|||
|
if(customFields)
|
|||
|
tiddlerElem.setAttribute("tiddlyFields",customFields);
|
|||
|
place.insertBefore(tiddlerElem,before);
|
|||
|
var defaultText = null;
|
|||
|
if(!store.tiddlerExists(title) && !store.isShadowTiddler(title))
|
|||
|
defaultText = this.loadMissingTiddler(title,customFields);
|
|||
|
this.refreshTiddler(title,template,false,customFields,defaultText);
|
|||
|
return tiddlerElem;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.loadMissingTiddler = function(title,fields,callback)
|
|||
|
{
|
|||
|
var getTiddlerCallback = function(context)
|
|||
|
{
|
|||
|
if(context.status) {
|
|||
|
var t = context.tiddler;
|
|||
|
if(!t.created)
|
|||
|
t.created = new Date();
|
|||
|
if(!t.modified)
|
|||
|
t.modified = t.created;
|
|||
|
context.tiddler = store.saveTiddler(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields,true,t.created,t.creator);
|
|||
|
autoSaveChanges();
|
|||
|
} else {
|
|||
|
story.refreshTiddler(context.title,null,true);
|
|||
|
}
|
|||
|
context.adaptor.close();
|
|||
|
if(callback) {
|
|||
|
callback(context);
|
|||
|
}
|
|||
|
};
|
|||
|
var tiddler = new Tiddler(title);
|
|||
|
tiddler.fields = typeof fields == "string" ? fields.decodeHashMap() : fields||{};
|
|||
|
var context = {serverType:tiddler.getServerType()};
|
|||
|
if(!context.serverType)
|
|||
|
return "";
|
|||
|
context.host = tiddler.fields['server.host'];
|
|||
|
context.workspace = tiddler.fields['server.workspace'];
|
|||
|
var adaptor = new config.adaptors[context.serverType]();
|
|||
|
adaptor.getTiddler(title,context,null,getTiddlerCallback);
|
|||
|
return config.messages.loadingMissingTiddler.format([title,context.serverType,context.host,context.workspace]);
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.chooseTemplateForTiddler = function(title,template)
|
|||
|
{
|
|||
|
if(!template)
|
|||
|
template = DEFAULT_VIEW_TEMPLATE;
|
|||
|
if(template == DEFAULT_VIEW_TEMPLATE || template == DEFAULT_EDIT_TEMPLATE)
|
|||
|
template = config.tiddlerTemplates[template];
|
|||
|
return template;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.getTemplateForTiddler = function(title,template,tiddler)
|
|||
|
{
|
|||
|
return store.getRecursiveTiddlerText(template,null,10);
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.refreshTiddler = function(title,template,force,customFields,defaultText)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem) {
|
|||
|
if(tiddlerElem.getAttribute("dirty") == "true" && !force)
|
|||
|
return tiddlerElem;
|
|||
|
template = this.chooseTemplateForTiddler(title,template);
|
|||
|
var currTemplate = tiddlerElem.getAttribute("template");
|
|||
|
if((template != currTemplate) || force) {
|
|||
|
var tiddler = store.getTiddler(title);
|
|||
|
if(!tiddler) {
|
|||
|
tiddler = new Tiddler();
|
|||
|
if(store.isShadowTiddler(title)) {
|
|||
|
var tags = [];
|
|||
|
tiddler.set(title,store.getTiddlerText(title),config.views.wikified.shadowModifier,version.date,tags,version.date);
|
|||
|
} else {
|
|||
|
var text = template=="EditTemplate" ?
|
|||
|
config.views.editor.defaultText.format([title]) :
|
|||
|
config.views.wikified.defaultText.format([title]);
|
|||
|
text = defaultText || text;
|
|||
|
var fields = customFields ? customFields.decodeHashMap() : null;
|
|||
|
tiddler.set(title,text,config.views.wikified.defaultModifier,version.date,[],version.date,fields);
|
|||
|
}
|
|||
|
}
|
|||
|
tiddlerElem.setAttribute("tags",tiddler.tags.join(" "));
|
|||
|
tiddlerElem.setAttribute("tiddler",title);
|
|||
|
tiddlerElem.setAttribute("template",template);
|
|||
|
tiddlerElem.onmouseover = this.onTiddlerMouseOver;
|
|||
|
tiddlerElem.onmouseout = this.onTiddlerMouseOut;
|
|||
|
tiddlerElem.ondblclick = this.onTiddlerDblClick;
|
|||
|
tiddlerElem[window.event?"onkeydown":"onkeypress"] = this.onTiddlerKeyPress;
|
|||
|
tiddlerElem.innerHTML = this.getTemplateForTiddler(title,template,tiddler);
|
|||
|
applyHtmlMacros(tiddlerElem,tiddler);
|
|||
|
if(store.getTaggedTiddlers(title).length > 0)
|
|||
|
jQuery(tiddlerElem).addClass("isTag");
|
|||
|
else
|
|||
|
jQuery(tiddlerElem).removeClass("isTag");
|
|||
|
if(store.tiddlerExists(title)) {
|
|||
|
jQuery(tiddlerElem).removeClass("shadow");
|
|||
|
jQuery(tiddlerElem).removeClass("missing");
|
|||
|
} else {
|
|||
|
jQuery(tiddlerElem).addClass(store.isShadowTiddler(title) ? "shadow" : "missing");
|
|||
|
}
|
|||
|
if(customFields)
|
|||
|
this.addCustomFields(tiddlerElem,customFields);
|
|||
|
}
|
|||
|
}
|
|||
|
return tiddlerElem;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.addCustomFields = function(place,customFields)
|
|||
|
{
|
|||
|
var fields = customFields.decodeHashMap();
|
|||
|
var w = createTiddlyElement(place,"div",null,"customFields");
|
|||
|
w.style.display = "none";
|
|||
|
var t;
|
|||
|
for(t in fields) {
|
|||
|
var e = document.createElement("input");
|
|||
|
e.setAttribute("type","text");
|
|||
|
e.setAttribute("value",fields[t]);
|
|||
|
w.appendChild(e);
|
|||
|
e.setAttribute("edit",t);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.refreshAllTiddlers = function(force)
|
|||
|
{
|
|||
|
var e = this.getContainer().firstChild;
|
|||
|
while(e) {
|
|||
|
var template = e.getAttribute("template");
|
|||
|
if(template && e.getAttribute("dirty") != "true") {
|
|||
|
this.refreshTiddler(e.getAttribute("tiddler"),force ? null : template,true);
|
|||
|
}
|
|||
|
e = e.nextSibling;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.onTiddlerMouseOver = function(e)
|
|||
|
{
|
|||
|
jQuery(this).addClass("selected");
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.onTiddlerMouseOut = function(e)
|
|||
|
{
|
|||
|
jQuery(this).removeClass("selected");
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.onTiddlerDblClick = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var target = resolveTarget(e);
|
|||
|
if(target && target.nodeName.toLowerCase() != "input" && target.nodeName.toLowerCase() != "textarea") {
|
|||
|
if(document.selection && document.selection.empty)
|
|||
|
document.selection.empty();
|
|||
|
config.macros.toolbar.invokeCommand(this,"defaultCommand",e);
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.onTiddlerKeyPress = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
clearMessage();
|
|||
|
var consume = false;
|
|||
|
var title = this.getAttribute("tiddler");
|
|||
|
var target = resolveTarget(e);
|
|||
|
switch(e.keyCode) {
|
|||
|
case 9: // Tab
|
|||
|
var ed = story.getTiddlerField(title,"text");
|
|||
|
if(target.tagName.toLowerCase() == "input" && ed.value==config.views.editor.defaultText.format([title])) {
|
|||
|
// moving from input field and editor still contains default text, so select it
|
|||
|
ed.focus();
|
|||
|
ed.select();
|
|||
|
consume = true;
|
|||
|
}
|
|||
|
if(config.options.chkInsertTabs && target.tagName.toLowerCase() == "textarea") {
|
|||
|
replaceSelection(target,String.fromCharCode(9));
|
|||
|
consume = true;
|
|||
|
}
|
|||
|
if(config.isOpera) {
|
|||
|
target.onblur = function() {
|
|||
|
this.focus();
|
|||
|
this.onblur = null;
|
|||
|
};
|
|||
|
}
|
|||
|
break;
|
|||
|
case 13: // Ctrl-Enter
|
|||
|
case 10: // Ctrl-Enter on IE PC
|
|||
|
case 77: // Ctrl-Enter is "M" on some platforms
|
|||
|
if(e.ctrlKey) {
|
|||
|
blurElement(this);
|
|||
|
config.macros.toolbar.invokeCommand(this,"defaultCommand",e);
|
|||
|
consume = true;
|
|||
|
}
|
|||
|
break;
|
|||
|
case 27: // Escape
|
|||
|
blurElement(this);
|
|||
|
config.macros.toolbar.invokeCommand(this,"cancelCommand",e);
|
|||
|
consume = true;
|
|||
|
break;
|
|||
|
}
|
|||
|
e.cancelBubble = consume;
|
|||
|
if(consume) {
|
|||
|
if(e.stopPropagation) e.stopPropagation(); // Stop Propagation
|
|||
|
e.returnValue = true; // Cancel The Event in IE
|
|||
|
if(e.preventDefault ) e.preventDefault(); // Cancel The Event in Moz
|
|||
|
}
|
|||
|
return !consume;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.getTiddlerField = function(title,field)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
var e = null;
|
|||
|
if(tiddlerElem) {
|
|||
|
var t,children = tiddlerElem.getElementsByTagName("*");
|
|||
|
for(t=0; t<children.length; t++) {
|
|||
|
var c = children[t];
|
|||
|
if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea") {
|
|||
|
if(!e)
|
|||
|
e = c;
|
|||
|
if(c.getAttribute("edit") == field)
|
|||
|
e = c;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return e;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.focusTiddler = function(title,field)
|
|||
|
{
|
|||
|
var e = this.getTiddlerField(title,field);
|
|||
|
if(e) {
|
|||
|
e.focus();
|
|||
|
e.select();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.blurTiddler = function(title)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem && tiddlerElem.focus && tiddlerElem.blur) {
|
|||
|
tiddlerElem.focus();
|
|||
|
tiddlerElem.blur();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.setTiddlerField = function(title,tag,mode,field)
|
|||
|
{
|
|||
|
var c = this.getTiddlerField(title,field);
|
|||
|
var tags = c.value.readBracketedList();
|
|||
|
tags.setItem(tag,mode);
|
|||
|
c.value = String.encodeTiddlyLinkList(tags);
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.setTiddlerTag = function(title,tag,mode)
|
|||
|
{
|
|||
|
this.setTiddlerField(title,tag,mode,"tags");
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.closeTiddler = function(title,animate,unused)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem) {
|
|||
|
clearMessage();
|
|||
|
this.scrubTiddler(tiddlerElem);
|
|||
|
if(config.options.chkAnimate && animate && anim && typeof Slider == "function")
|
|||
|
anim.startAnimating(new Slider(tiddlerElem,false,null,"all"));
|
|||
|
else {
|
|||
|
jQuery(tiddlerElem).remove();
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.scrubTiddler = function(tiddlerElem)
|
|||
|
{
|
|||
|
tiddlerElem.id = null;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.setDirty = function(title,dirty)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem)
|
|||
|
tiddlerElem.setAttribute("dirty",dirty ? "true" : "false");
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.isDirty = function(title)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem)
|
|||
|
return tiddlerElem.getAttribute("dirty") == "true";
|
|||
|
return null;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.areAnyDirty = function()
|
|||
|
{
|
|||
|
var r = false;
|
|||
|
this.forEachTiddler(function(title,element) {
|
|||
|
if(this.isDirty(title))
|
|||
|
r = true;
|
|||
|
});
|
|||
|
return r;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.closeAllTiddlers = function(exclude)
|
|||
|
{
|
|||
|
clearMessage();
|
|||
|
this.forEachTiddler(function(title,element) {
|
|||
|
if((title != exclude) && element.getAttribute("dirty") != "true")
|
|||
|
this.closeTiddler(title);
|
|||
|
});
|
|||
|
window.scrollTo(0,ensureVisible(this.container));
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.isEmpty = function()
|
|||
|
{
|
|||
|
var place = this.getContainer();
|
|||
|
return place && place.firstChild == null;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
|
|||
|
{
|
|||
|
this.closeAllTiddlers();
|
|||
|
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
|
|||
|
var matches = store.search(highlightHack,"title","excludeSearch");
|
|||
|
this.displayTiddlers(null,matches);
|
|||
|
highlightHack = null;
|
|||
|
var q = useRegExp ? "/" : "'";
|
|||
|
if(matches.length > 0)
|
|||
|
displayMessage(config.macros.search.successMsg.format([matches.length.toString(),q + text + q]));
|
|||
|
else
|
|||
|
displayMessage(config.macros.search.failureMsg.format([q + text + q]));
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.findContainingTiddler = function(e)
|
|||
|
{
|
|||
|
while(e && !jQuery(e).hasClass("tiddler")) {
|
|||
|
e = jQuery(e).hasClass("popup") && Popup.stack[0] ? Popup.stack[0].root : e.parentNode;
|
|||
|
}
|
|||
|
return e;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.gatherSaveFields = function(e,fields)
|
|||
|
{
|
|||
|
if(e && e.getAttribute) {
|
|||
|
var f = e.getAttribute("edit");
|
|||
|
if(f)
|
|||
|
fields[f] = e.value.replace(/\r/mg,"");
|
|||
|
if(e.hasChildNodes()) {
|
|||
|
var t,c = e.childNodes;
|
|||
|
for(t=0; t<c.length; t++)
|
|||
|
this.gatherSaveFields(c[t],fields);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.hasChanges = function(title)
|
|||
|
{
|
|||
|
var e = this.getTiddler(title);
|
|||
|
if(e) {
|
|||
|
var fields = {};
|
|||
|
this.gatherSaveFields(e,fields);
|
|||
|
if(store.fetchTiddler(title)) {
|
|||
|
var n;
|
|||
|
for(n in fields) {
|
|||
|
if(store.getValue(title,n) != fields[n]) //# tiddler changed
|
|||
|
return true;
|
|||
|
}
|
|||
|
} else {
|
|||
|
if(store.isShadowTiddler(title) && store.getShadowTiddlerText(title) == fields.text) { //# not checking for title or tags
|
|||
|
return false;
|
|||
|
} else { //# changed shadow or new tiddler
|
|||
|
return true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.saveTiddler = function(title,minorUpdate)
|
|||
|
{
|
|||
|
var tiddlerElem = this.getTiddler(title);
|
|||
|
if(tiddlerElem) {
|
|||
|
var fields = {};
|
|||
|
this.gatherSaveFields(tiddlerElem,fields);
|
|||
|
var newTitle = fields.title || title;
|
|||
|
if(!store.tiddlerExists(newTitle)) {
|
|||
|
newTitle = newTitle.trim();
|
|||
|
var creator = config.options.txtUserName;
|
|||
|
}
|
|||
|
if(store.tiddlerExists(newTitle) && newTitle != title) {
|
|||
|
if(!confirm(config.messages.overwriteWarning.format([newTitle.toString()])))
|
|||
|
return null;
|
|||
|
title = newTitle;
|
|||
|
}
|
|||
|
if(newTitle != title)
|
|||
|
this.closeTiddler(newTitle,false);
|
|||
|
tiddlerElem.id = this.tiddlerId(newTitle);
|
|||
|
tiddlerElem.setAttribute("tiddler",newTitle);
|
|||
|
tiddlerElem.setAttribute("template",DEFAULT_VIEW_TEMPLATE);
|
|||
|
tiddlerElem.setAttribute("dirty","false");
|
|||
|
if(config.options.chkForceMinorUpdate)
|
|||
|
minorUpdate = !minorUpdate;
|
|||
|
if(!store.tiddlerExists(newTitle))
|
|||
|
minorUpdate = false;
|
|||
|
var newDate = new Date();
|
|||
|
if(store.tiddlerExists(title)) {
|
|||
|
var t = store.fetchTiddler(title);
|
|||
|
var extendedFields = t.fields;
|
|||
|
creator = t.creator;
|
|||
|
} else {
|
|||
|
extendedFields = merge({},config.defaultCustomFields);
|
|||
|
}
|
|||
|
var n;
|
|||
|
for(n in fields) {
|
|||
|
if(!TiddlyWiki.isStandardField(n))
|
|||
|
extendedFields[n] = fields[n];
|
|||
|
}
|
|||
|
var tiddler = store.saveTiddler(title,newTitle,fields.text,minorUpdate ? undefined : config.options.txtUserName,minorUpdate ? undefined : newDate,fields.tags,extendedFields,null,null,creator);
|
|||
|
autoSaveChanges(null,[tiddler]);
|
|||
|
return newTitle;
|
|||
|
}
|
|||
|
return null;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.permaView = function()
|
|||
|
{
|
|||
|
var links = [];
|
|||
|
this.forEachTiddler(function(title,element) {
|
|||
|
links.push(String.encodeTiddlyLink(title));
|
|||
|
});
|
|||
|
var t = encodeURIComponent(links.join(" "));
|
|||
|
if(t == "")
|
|||
|
t = "#";
|
|||
|
if(window.location.hash != t)
|
|||
|
window.location.hash = t;
|
|||
|
};
|
|||
|
|
|||
|
Story.prototype.switchTheme = function(theme)
|
|||
|
{
|
|||
|
if(safeMode)
|
|||
|
return;
|
|||
|
|
|||
|
var isAvailable = function(title) {
|
|||
|
var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
|
|||
|
if(s!=-1)
|
|||
|
title = title.substr(0,s);
|
|||
|
return store.tiddlerExists(title) || store.isShadowTiddler(title);
|
|||
|
};
|
|||
|
|
|||
|
var getSlice = function(theme,slice) {
|
|||
|
var r;
|
|||
|
if(readOnly)
|
|||
|
r = store.getTiddlerSlice(theme,slice+"ReadOnly") || store.getTiddlerSlice(theme,"Web"+slice);
|
|||
|
r = r || store.getTiddlerSlice(theme,slice);
|
|||
|
if(r && r.indexOf(config.textPrimitives.sectionSeparator)==0)
|
|||
|
r = theme + r;
|
|||
|
return isAvailable(r) ? r : slice;
|
|||
|
};
|
|||
|
|
|||
|
var replaceNotification = function(i,name,theme,slice) {
|
|||
|
var newName = getSlice(theme,slice);
|
|||
|
if(name!=newName && store.namedNotifications[i].name==name) {
|
|||
|
store.namedNotifications[i].name = newName;
|
|||
|
return newName;
|
|||
|
}
|
|||
|
return name;
|
|||
|
};
|
|||
|
|
|||
|
var pt = config.refresherData.pageTemplate;
|
|||
|
var vi = DEFAULT_VIEW_TEMPLATE;
|
|||
|
var vt = config.tiddlerTemplates[vi];
|
|||
|
var ei = DEFAULT_EDIT_TEMPLATE;
|
|||
|
var et = config.tiddlerTemplates[ei];
|
|||
|
|
|||
|
var i;
|
|||
|
for(i=0; i<config.notifyTiddlers.length; i++) {
|
|||
|
var name = config.notifyTiddlers[i].name;
|
|||
|
switch(name) {
|
|||
|
case "PageTemplate":
|
|||
|
config.refresherData.pageTemplate = replaceNotification(i,config.refresherData.pageTemplate,theme,name);
|
|||
|
break;
|
|||
|
case "StyleSheet":
|
|||
|
removeStyleSheet(config.refresherData.styleSheet);
|
|||
|
config.refresherData.styleSheet = replaceNotification(i,config.refresherData.styleSheet,theme,name);
|
|||
|
break;
|
|||
|
case "ColorPalette":
|
|||
|
config.refresherData.colorPalette = replaceNotification(i,config.refresherData.colorPalette,theme,name);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
config.tiddlerTemplates[vi] = getSlice(theme,"ViewTemplate");
|
|||
|
config.tiddlerTemplates[ei] = getSlice(theme,"EditTemplate");
|
|||
|
if(!startingUp) {
|
|||
|
if(config.refresherData.pageTemplate!=pt || config.tiddlerTemplates[vi]!=vt || config.tiddlerTemplates[ei]!=et) {
|
|||
|
refreshAll();
|
|||
|
this.refreshAllTiddlers(true);
|
|||
|
} else {
|
|||
|
setStylesheet(store.getRecursiveTiddlerText(config.refresherData.styleSheet,"",10),config.refreshers.styleSheet);
|
|||
|
}
|
|||
|
config.options.txtTheme = theme;
|
|||
|
saveOption("txtTheme");
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Backstage
|
|||
|
//--
|
|||
|
// Backstage tasks
|
|||
|
config.tasks.save.action = saveChanges;
|
|||
|
|
|||
|
var backstage = {
|
|||
|
area: null,
|
|||
|
toolbar: null,
|
|||
|
button: null,
|
|||
|
showButton: null,
|
|||
|
hideButton: null,
|
|||
|
cloak: null,
|
|||
|
panel: null,
|
|||
|
panelBody: null,
|
|||
|
panelFooter: null,
|
|||
|
currTabName: null,
|
|||
|
currTabElem: null,
|
|||
|
content: null,
|
|||
|
|
|||
|
init: function() {
|
|||
|
var cmb = config.messages.backstage;
|
|||
|
this.area = document.getElementById("backstageArea");
|
|||
|
this.toolbar = jQuery("#backstageToolbar").empty()[0];
|
|||
|
this.button = jQuery("#backstageButton").empty()[0];
|
|||
|
this.button.style.display = "block";
|
|||
|
var t = cmb.open.text + " " + glyph("bentArrowLeft");
|
|||
|
this.showButton = createTiddlyButton(this.button,t,cmb.open.tooltip,
|
|||
|
function(e) {backstage.show(); return false;},null,"backstageShow");
|
|||
|
t = glyph("bentArrowRight") + " " + cmb.close.text;
|
|||
|
this.hideButton = createTiddlyButton(this.button,t,cmb.close.tooltip,
|
|||
|
function(e) {backstage.hide(); return false;},null,"backstageHide");
|
|||
|
this.cloak = document.getElementById("backstageCloak");
|
|||
|
this.panel = document.getElementById("backstagePanel");
|
|||
|
this.panelFooter = createTiddlyElement(this.panel,"div",null,"backstagePanelFooter");
|
|||
|
this.panelBody = createTiddlyElement(this.panel,"div",null,"backstagePanelBody");
|
|||
|
this.cloak.onmousedown = function(e) {backstage.switchTab(null);};
|
|||
|
createTiddlyText(this.toolbar,cmb.prompt);
|
|||
|
for(t=0; t<config.backstageTasks.length; t++) {
|
|||
|
var taskName = config.backstageTasks[t];
|
|||
|
var task = config.tasks[taskName];
|
|||
|
var handler = task.action ? this.onClickCommand : this.onClickTab;
|
|||
|
var text = task.text + (task.action ? "" : glyph("downTriangle"));
|
|||
|
var btn = createTiddlyButton(this.toolbar,text,task.tooltip,handler,"backstageTab");
|
|||
|
jQuery(btn).addClass(task.action ? "backstageAction" : "backstageTask");
|
|||
|
btn.setAttribute("task", taskName);
|
|||
|
}
|
|||
|
this.content = document.getElementById("contentWrapper");
|
|||
|
if(config.options.chkBackstage)
|
|||
|
this.show();
|
|||
|
else
|
|||
|
this.hide();
|
|||
|
},
|
|||
|
|
|||
|
isVisible: function() {
|
|||
|
return this.area ? this.area.style.display == "block" : false;
|
|||
|
},
|
|||
|
|
|||
|
show: function() {
|
|||
|
this.area.style.display = "block";
|
|||
|
if(anim && config.options.chkAnimate) {
|
|||
|
backstage.toolbar.style.left = findWindowWidth() + "px";
|
|||
|
var p = [{style: "left", start: findWindowWidth(), end: 0, template: "%0px"}];
|
|||
|
anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p));
|
|||
|
} else {
|
|||
|
backstage.area.style.left = "0px";
|
|||
|
}
|
|||
|
jQuery(this.showButton).hide();
|
|||
|
jQuery(this.hideButton).show();
|
|||
|
config.options.chkBackstage = true;
|
|||
|
saveOption("chkBackstage");
|
|||
|
jQuery(this.content).addClass("backstageVisible");
|
|||
|
},
|
|||
|
|
|||
|
hide: function() {
|
|||
|
if(this.currTabElem) {
|
|||
|
this.switchTab(null);
|
|||
|
} else {
|
|||
|
backstage.toolbar.style.left = "0px";
|
|||
|
if(anim && config.options.chkAnimate) {
|
|||
|
var p = [{style: "left", start: 0, end: findWindowWidth(), template: "%0px"}];
|
|||
|
var c = function(element,properties) {backstage.area.style.display = "none";};
|
|||
|
anim.startAnimating(new Morpher(backstage.toolbar,config.animDuration,p,c));
|
|||
|
} else {
|
|||
|
this.area.style.display = "none";
|
|||
|
}
|
|||
|
this.showButton.style.display = "block";
|
|||
|
this.hideButton.style.display = "none";
|
|||
|
config.options.chkBackstage = false;
|
|||
|
saveOption("chkBackstage");
|
|||
|
jQuery(this.content).removeClass("backstageVisible");
|
|||
|
}
|
|||
|
},
|
|||
|
|
|||
|
onClickCommand: function(e) {
|
|||
|
var task = config.tasks[this.getAttribute("task")];
|
|||
|
if(task.action) {
|
|||
|
backstage.switchTab(null);
|
|||
|
task.action();
|
|||
|
}
|
|||
|
return false;
|
|||
|
},
|
|||
|
|
|||
|
onClickTab: function(e) {
|
|||
|
backstage.switchTab(this.getAttribute("task"));
|
|||
|
return false;
|
|||
|
},
|
|||
|
|
|||
|
// Switch to a given tab, or none if null is passed
|
|||
|
switchTab: function(tabName) {
|
|||
|
var tabElem = null;
|
|||
|
var e = this.toolbar.firstChild;
|
|||
|
while(e) {
|
|||
|
if(e.getAttribute && e.getAttribute("task") == tabName)
|
|||
|
tabElem = e;
|
|||
|
e = e.nextSibling;
|
|||
|
}
|
|||
|
if(tabName == backstage.currTabName) {
|
|||
|
backstage.hidePanel();
|
|||
|
return;
|
|||
|
}
|
|||
|
if(backstage.currTabElem) {
|
|||
|
jQuery(this.currTabElem).removeClass("backstageSelTab");
|
|||
|
}
|
|||
|
if(tabElem && tabName) {
|
|||
|
backstage.preparePanel();
|
|||
|
jQuery(tabElem).addClass("backstageSelTab");
|
|||
|
var task = config.tasks[tabName];
|
|||
|
wikify(task.content,backstage.panelBody,null,null);
|
|||
|
backstage.showPanel();
|
|||
|
} else if(backstage.currTabElem) {
|
|||
|
backstage.hidePanel();
|
|||
|
}
|
|||
|
backstage.currTabName = tabName;
|
|||
|
backstage.currTabElem = tabElem;
|
|||
|
},
|
|||
|
|
|||
|
isPanelVisible: function() {
|
|||
|
return backstage.panel ? backstage.panel.style.display == "block" : false;
|
|||
|
},
|
|||
|
|
|||
|
preparePanel: function() {
|
|||
|
backstage.cloak.style.height = findWindowHeight() + "px";
|
|||
|
backstage.cloak.style.display = "block";
|
|||
|
jQuery(backstage.panelBody).empty();
|
|||
|
return backstage.panelBody;
|
|||
|
},
|
|||
|
|
|||
|
showPanel: function() {
|
|||
|
backstage.panel.style.display = "block";
|
|||
|
if(anim && config.options.chkAnimate) {
|
|||
|
backstage.panel.style.top = (-backstage.panel.offsetHeight) + "px";
|
|||
|
var p = [{style: "top", start: -backstage.panel.offsetHeight, end: 0, template: "%0px"}];
|
|||
|
anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p),new Scroller(backstage.panel,false));
|
|||
|
} else {
|
|||
|
backstage.panel.style.top = "0px";
|
|||
|
}
|
|||
|
return backstage.panelBody;
|
|||
|
},
|
|||
|
|
|||
|
hidePanel: function() {
|
|||
|
if(backstage.currTabElem)
|
|||
|
jQuery(backstage.currTabElem).removeClass("backstageSelTab");
|
|||
|
backstage.currTabElem = null;
|
|||
|
backstage.currTabName = null;
|
|||
|
if(anim && config.options.chkAnimate) {
|
|||
|
var p = [
|
|||
|
{style: "top", start: 0, end: -(backstage.panel.offsetHeight), template: "%0px"},
|
|||
|
{style: "display", atEnd: "none"}
|
|||
|
];
|
|||
|
var c = function(element,properties) {backstage.cloak.style.display = "none";};
|
|||
|
anim.startAnimating(new Morpher(backstage.panel,config.animDuration,p,c));
|
|||
|
} else {
|
|||
|
jQuery([backstage.panel,backstage.cloak]).hide();
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.backstage = {};
|
|||
|
|
|||
|
config.macros.backstage.handler = function(place,macroName,params)
|
|||
|
{
|
|||
|
var backstageTask = config.tasks[params[0]];
|
|||
|
if(backstageTask)
|
|||
|
createTiddlyButton(place,backstageTask.text,backstageTask.tooltip,function(e) {backstage.switchTab(params[0]); return false;});
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- ImportTiddlers macro
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
if(readOnly) {
|
|||
|
createTiddlyElement(place,"div",null,"marked",this.readOnlyWarning);
|
|||
|
return;
|
|||
|
}
|
|||
|
var w = new Wizard();
|
|||
|
w.createWizard(place,this.wizardTitle);
|
|||
|
this.restart(w);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onCancel = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
wizard.clear();
|
|||
|
config.macros.importTiddlers.restart(wizard);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onClose = function(e)
|
|||
|
{
|
|||
|
backstage.hidePanel();
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.restart = function(wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
wizard.addStep(this.step1Title,this.step1Html);
|
|||
|
var t,s = wizard.getElement("selTypes");
|
|||
|
for(t in config.adaptors) {
|
|||
|
var e = createTiddlyElement(s,"option",null,null,config.adaptors[t].serverLabel || t);
|
|||
|
e.value = t;
|
|||
|
}
|
|||
|
if(config.defaultAdaptor)
|
|||
|
s.value = config.defaultAdaptor;
|
|||
|
s = wizard.getElement("selFeeds");
|
|||
|
var feeds = this.getFeeds();
|
|||
|
for(t in feeds) {
|
|||
|
e = createTiddlyElement(s,"option",null,null,t);
|
|||
|
e.value = t;
|
|||
|
}
|
|||
|
wizard.setValue("feeds",feeds);
|
|||
|
s.onchange = me.onFeedChange;
|
|||
|
var fileInput = wizard.getElement("txtBrowse");
|
|||
|
fileInput.onchange = me.onBrowseChange;
|
|||
|
fileInput.onkeyup = me.onBrowseChange;
|
|||
|
wizard.setButtons([{caption: this.openLabel, tooltip: this.openPrompt, onClick: me.onOpen}]);
|
|||
|
wizard.formElem.action = "javascript:;";
|
|||
|
wizard.formElem.onsubmit = function() {
|
|||
|
if(!this.txtPath || this.txtPath.value.length) //# check for manually entered path in first step
|
|||
|
this.lastChild.firstChild.onclick();
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.getFeeds = function()
|
|||
|
{
|
|||
|
var feeds = {};
|
|||
|
var t,tagged = store.getTaggedTiddlers("systemServer","title");
|
|||
|
for(t=0; t<tagged.length; t++) {
|
|||
|
var title = tagged[t].title;
|
|||
|
var serverType = store.getTiddlerSlice(title,"Type");
|
|||
|
if(!serverType)
|
|||
|
serverType = "file";
|
|||
|
feeds[title] = {title: title,
|
|||
|
url: store.getTiddlerSlice(title,"URL"),
|
|||
|
workspace: store.getTiddlerSlice(title,"Workspace"),
|
|||
|
workspaceList: store.getTiddlerSlice(title,"WorkspaceList"),
|
|||
|
tiddlerFilter: store.getTiddlerSlice(title,"TiddlerFilter"),
|
|||
|
serverType: serverType,
|
|||
|
description: store.getTiddlerSlice(title,"Description")};
|
|||
|
}
|
|||
|
return feeds;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onFeedChange = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var selTypes = wizard.getElement("selTypes");
|
|||
|
var fileInput = wizard.getElement("txtPath");
|
|||
|
var feeds = wizard.getValue("feeds");
|
|||
|
var f = feeds[this.value];
|
|||
|
if(f) {
|
|||
|
selTypes.value = f.serverType;
|
|||
|
fileInput.value = f.url;
|
|||
|
wizard.setValue("feedName",f.serverType);
|
|||
|
wizard.setValue("feedHost",f.url);
|
|||
|
wizard.setValue("feedWorkspace",f.workspace);
|
|||
|
wizard.setValue("feedWorkspaceList",f.workspaceList);
|
|||
|
wizard.setValue("feedTiddlerFilter",f.tiddlerFilter);
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onBrowseChange = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var file = this.value;
|
|||
|
if(this.files && this.files[0]) {
|
|||
|
file = this.files[0].fileName;
|
|||
|
try {
|
|||
|
if(typeof(netscape) !== "undefined") {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalFileRead");
|
|||
|
}
|
|||
|
} catch (ex) {
|
|||
|
showException(ex);
|
|||
|
}
|
|||
|
}
|
|||
|
var fileInput = wizard.getElement("txtPath");
|
|||
|
fileInput.value = config.macros.importTiddlers.getURLFromLocalPath(file);
|
|||
|
var serverType = wizard.getElement("selTypes");
|
|||
|
serverType.value = "file";
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.getURLFromLocalPath = function(v)
|
|||
|
{
|
|||
|
if(!v || !v.length)
|
|||
|
return v;
|
|||
|
v = v.replace(/\\/g,"/"); // use "/" for cross-platform consistency
|
|||
|
var u;
|
|||
|
var t = v.split(":");
|
|||
|
var p = t[1] || t[0]; // remove drive letter (if any)
|
|||
|
if(t[1] && (t[0] == "http" || t[0] == "https" || t[0] == "file")) {
|
|||
|
u = v;
|
|||
|
} else if(p.substr(0,1)=="/") {
|
|||
|
u = document.location.protocol + "//" + document.location.hostname + (t[1] ? "/" : "") + v;
|
|||
|
} else {
|
|||
|
var c = document.location.href.replace(/\\/g,"/");
|
|||
|
var pos = c.lastIndexOf("/");
|
|||
|
if(pos!=-1)
|
|||
|
c = c.substr(0,pos); // remove filename
|
|||
|
u = c + "/" + p;
|
|||
|
}
|
|||
|
return u;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onOpen = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var fileInput = wizard.getElement("txtPath");
|
|||
|
var url = fileInput.value;
|
|||
|
var serverType = wizard.getElement("selTypes").value || config.defaultAdaptor;
|
|||
|
var adaptor = new config.adaptors[serverType]();
|
|||
|
wizard.setValue("adaptor",adaptor);
|
|||
|
wizard.setValue("serverType",serverType);
|
|||
|
wizard.setValue("host",url);
|
|||
|
adaptor.openHost(url,null,wizard,me.onOpenHost);
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],me.statusOpenHost);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onOpenHost = function(context,wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
var adaptor = wizard.getValue("adaptor");
|
|||
|
if(context.status !== true)
|
|||
|
displayMessage("Error in importTiddlers.onOpenHost: " + context.statusText);
|
|||
|
adaptor.getWorkspaceList(context,wizard,me.onGetWorkspaceList);
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],me.statusGetWorkspaceList);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onGetWorkspaceList = function(context,wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
if(context.status !== true)
|
|||
|
displayMessage("Error in importTiddlers.onGetWorkspaceList: " + context.statusText);
|
|||
|
wizard.setValue("context",context);
|
|||
|
var workspace = wizard.getValue("feedWorkspace");
|
|||
|
if(!workspace && context.workspaces.length==1)
|
|||
|
workspace = context.workspaces[0].title;
|
|||
|
if(workspace) {
|
|||
|
context.adaptor.openWorkspace(workspace,context,wizard,me.onOpenWorkspace);
|
|||
|
wizard.setValue("workspace",workspace);
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],me.statusOpenWorkspace);
|
|||
|
return;
|
|||
|
}
|
|||
|
wizard.addStep(me.step2Title,me.step2Html);
|
|||
|
var t,s = wizard.getElement("selWorkspace");
|
|||
|
s.onchange = me.onWorkspaceChange;
|
|||
|
for(t=0; t<context.workspaces.length; t++) {
|
|||
|
var e = createTiddlyElement(s,"option",null,null,context.workspaces[t].title);
|
|||
|
e.value = context.workspaces[t].title;
|
|||
|
}
|
|||
|
var workspaceList = wizard.getValue("feedWorkspaceList");
|
|||
|
if(workspaceList) {
|
|||
|
var n,list = workspaceList.parseParams("workspace",null,false,true);
|
|||
|
for(n=1; n<list.length; n++) {
|
|||
|
if(context.workspaces.findByField("title",list[n].value) == null) {
|
|||
|
e = createTiddlyElement(s,"option",null,null,list[n].value);
|
|||
|
e.value = list[n].value;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if(workspace) {
|
|||
|
t = wizard.getElement("txtWorkspace");
|
|||
|
t.value = workspace;
|
|||
|
}
|
|||
|
wizard.setButtons([{caption: me.openLabel, tooltip: me.openPrompt, onClick: me.onChooseWorkspace}]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onWorkspaceChange = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var t = wizard.getElement("txtWorkspace");
|
|||
|
t.value = this.value;
|
|||
|
this.selectedIndex = 0;
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onChooseWorkspace = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var adaptor = wizard.getValue("adaptor");
|
|||
|
var workspace = wizard.getElement("txtWorkspace").value;
|
|||
|
wizard.setValue("workspace",workspace);
|
|||
|
var context = wizard.getValue("context");
|
|||
|
adaptor.openWorkspace(workspace,context,wizard,me.onOpenWorkspace);
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],me.statusOpenWorkspace);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onOpenWorkspace = function(context,wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
if(context.status !== true)
|
|||
|
displayMessage("Error in importTiddlers.onOpenWorkspace: " + context.statusText);
|
|||
|
var adaptor = wizard.getValue("adaptor");
|
|||
|
adaptor.getTiddlerList(context,wizard,me.onGetTiddlerList,wizard.getValue("feedTiddlerFilter"));
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],me.statusGetTiddlerList);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onGetTiddlerList = function(context,wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
if(context.status !== true) {
|
|||
|
var error = context.statusText||me.errorGettingTiddlerList;
|
|||
|
if(context.host.indexOf("file://") === 0) {
|
|||
|
error = me.errorGettingTiddlerListFile;
|
|||
|
} else {
|
|||
|
error = context.xhr && context.xhr.status == 404 ? me.errorGettingTiddlerListHttp404 :
|
|||
|
me.errorGettingTiddlerListHttp;
|
|||
|
}
|
|||
|
wizard.setButtons([{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}],"");
|
|||
|
jQuery("span.status", wizard.footerEl).html(error); // so error message can be html
|
|||
|
return;
|
|||
|
}
|
|||
|
// Extract data for the listview
|
|||
|
var listedTiddlers = [];
|
|||
|
if(context.tiddlers) {
|
|||
|
var n;
|
|||
|
for(n=0; n<context.tiddlers.length; n++) {
|
|||
|
var tiddler = context.tiddlers[n];
|
|||
|
listedTiddlers.push({
|
|||
|
title: tiddler.title,
|
|||
|
modified: tiddler.modified,
|
|||
|
modifier: tiddler.modifier,
|
|||
|
text: tiddler.text ? wikifyPlainText(tiddler.text,100) : "",
|
|||
|
tags: tiddler.tags,
|
|||
|
size: tiddler.text ? tiddler.text.length : 0,
|
|||
|
tiddler: tiddler
|
|||
|
});
|
|||
|
}
|
|||
|
}
|
|||
|
listedTiddlers.sort(function(a,b) {return a.title < b.title ? -1 : (a.title == b.title ? 0 : +1);});
|
|||
|
// Display the listview
|
|||
|
wizard.addStep(me.step3Title,me.step3Html);
|
|||
|
var markList = wizard.getElement("markList");
|
|||
|
var listWrapper = document.createElement("div");
|
|||
|
markList.parentNode.insertBefore(listWrapper,markList);
|
|||
|
var listView = ListView.create(listWrapper,listedTiddlers,me.listViewTemplate);
|
|||
|
wizard.setValue("listView",listView);
|
|||
|
wizard.setValue("context",context);
|
|||
|
var txtSaveTiddler = wizard.getElement("txtSaveTiddler");
|
|||
|
txtSaveTiddler.value = me.generateSystemServerName(wizard);
|
|||
|
wizard.setButtons([
|
|||
|
{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel},
|
|||
|
{caption: me.importLabel, tooltip: me.importPrompt, onClick: me.doImport}
|
|||
|
]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.generateSystemServerName = function(wizard)
|
|||
|
{
|
|||
|
var serverType = wizard.getValue("serverType");
|
|||
|
var host = wizard.getValue("host");
|
|||
|
var workspace = wizard.getValue("workspace");
|
|||
|
var pattern = config.macros.importTiddlers[workspace ? "systemServerNamePattern" : "systemServerNamePatternNoWorkspace"];
|
|||
|
return pattern.format([serverType,host,workspace]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.saveServerTiddler = function(wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
var txtSaveTiddler = wizard.getElement("txtSaveTiddler").value;
|
|||
|
if(store.tiddlerExists(txtSaveTiddler)) {
|
|||
|
if(!confirm(me.confirmOverwriteSaveTiddler.format([txtSaveTiddler])))
|
|||
|
return;
|
|||
|
store.suspendNotifications();
|
|||
|
store.removeTiddler(txtSaveTiddler);
|
|||
|
store.resumeNotifications();
|
|||
|
}
|
|||
|
var serverType = wizard.getValue("serverType");
|
|||
|
var host = wizard.getValue("host");
|
|||
|
var workspace = wizard.getValue("workspace");
|
|||
|
var text = me.serverSaveTemplate.format([serverType,host,workspace]);
|
|||
|
store.saveTiddler(txtSaveTiddler,txtSaveTiddler,text,me.serverSaveModifier,new Date(),["systemServer"]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.doImport = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
var wizard = new Wizard(this);
|
|||
|
if(wizard.getElement("chkSave").checked)
|
|||
|
me.saveServerTiddler(wizard);
|
|||
|
var chkSync = wizard.getElement("chkSync").checked;
|
|||
|
wizard.setValue("sync",chkSync);
|
|||
|
var listView = wizard.getValue("listView");
|
|||
|
var rowNames = ListView.getSelectedRows(listView);
|
|||
|
var adaptor = wizard.getValue("adaptor");
|
|||
|
var overwrite = [];
|
|||
|
var t;
|
|||
|
for(t=0; t<rowNames.length; t++) {
|
|||
|
if(store.tiddlerExists(rowNames[t]))
|
|||
|
overwrite.push(rowNames[t]);
|
|||
|
}
|
|||
|
if(overwrite.length > 0) {
|
|||
|
if(!confirm(me.confirmOverwriteText.format([overwrite.join(", ")])))
|
|||
|
return false;
|
|||
|
}
|
|||
|
wizard.addStep(me.step4Title.format([rowNames.length]),me.step4Html);
|
|||
|
for(t=0; t<rowNames.length; t++) {
|
|||
|
var link = document.createElement("div");
|
|||
|
createTiddlyLink(link,rowNames[t],true);
|
|||
|
var place = wizard.getElement("markReport");
|
|||
|
place.parentNode.insertBefore(link,place);
|
|||
|
}
|
|||
|
wizard.setValue("remainingImports",rowNames.length);
|
|||
|
wizard.setButtons([
|
|||
|
{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}
|
|||
|
],me.statusDoingImport);
|
|||
|
var wizardContext = wizard.getValue("context");
|
|||
|
var tiddlers = wizardContext ? wizardContext.tiddlers : [];
|
|||
|
for(t=0; t<rowNames.length; t++) {
|
|||
|
var context = {
|
|||
|
allowSynchronous:true,
|
|||
|
tiddler:tiddlers[tiddlers.findByField("title",rowNames[t])]
|
|||
|
};
|
|||
|
adaptor.getTiddler(rowNames[t],context,wizard,me.onGetTiddler);
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.importTiddlers.onGetTiddler = function(context,wizard)
|
|||
|
{
|
|||
|
var me = config.macros.importTiddlers;
|
|||
|
if(!context.status)
|
|||
|
displayMessage("Error in importTiddlers.onGetTiddler: " + context.statusText);
|
|||
|
var tiddler = context.tiddler;
|
|||
|
store.suspendNotifications();
|
|||
|
store.saveTiddler(tiddler.title, tiddler.title, tiddler.text, tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields, true, tiddler.created);
|
|||
|
if(!wizard.getValue("sync")) {
|
|||
|
store.setValue(tiddler.title,'server',null);
|
|||
|
}
|
|||
|
store.resumeNotifications();
|
|||
|
if(!context.isSynchronous)
|
|||
|
store.notify(tiddler.title,true);
|
|||
|
var remainingImports = wizard.getValue("remainingImports")-1;
|
|||
|
wizard.setValue("remainingImports",remainingImports);
|
|||
|
if(remainingImports == 0) {
|
|||
|
if(context.isSynchronous) {
|
|||
|
store.notifyAll();
|
|||
|
refreshDisplay();
|
|||
|
}
|
|||
|
wizard.setButtons([
|
|||
|
{caption: me.doneLabel, tooltip: me.donePrompt, onClick: me.onClose}
|
|||
|
],me.statusDoneImport);
|
|||
|
autoSaveChanges();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Upgrade macro
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.upgrade.handler = function(place)
|
|||
|
{
|
|||
|
var w = new Wizard();
|
|||
|
w.createWizard(place,this.wizardTitle);
|
|||
|
w.addStep(this.step1Title,this.step1Html.format([this.source,this.source]));
|
|||
|
w.setButtons([{caption: this.upgradeLabel, tooltip: this.upgradePrompt, onClick: this.onClickUpgrade}]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.upgrade.onClickUpgrade = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.upgrade;
|
|||
|
var w = new Wizard(this);
|
|||
|
if(window.location.protocol != "file:") {
|
|||
|
alert(me.errorCantUpgrade);
|
|||
|
return false;
|
|||
|
}
|
|||
|
if(story.areAnyDirty() || store.isDirty()) {
|
|||
|
alert(me.errorNotSaved);
|
|||
|
return false;
|
|||
|
}
|
|||
|
var localPath = getLocalPath(document.location.toString());
|
|||
|
var backupPath = getBackupPath(localPath,me.backupExtension);
|
|||
|
w.setValue("backupPath",backupPath);
|
|||
|
w.setButtons([],me.statusPreparingBackup);
|
|||
|
var original = loadOriginal(localPath);
|
|||
|
w.setButtons([],me.statusSavingBackup);
|
|||
|
var backup = copyFile(backupPath,localPath);
|
|||
|
if(!backup)
|
|||
|
backup = saveFile(backupPath,original);
|
|||
|
if(!backup) {
|
|||
|
w.setButtons([],me.errorSavingBackup);
|
|||
|
alert(me.errorSavingBackup);
|
|||
|
return false;
|
|||
|
}
|
|||
|
w.setButtons([],me.statusLoadingCore);
|
|||
|
var options = {
|
|||
|
type:"GET",
|
|||
|
url:me.source,
|
|||
|
processData:false,
|
|||
|
success:function(data,textStatus,jqXHR) {
|
|||
|
me.onLoadCore(true,w,jqXHR.responseText,me.source,jqXHR);
|
|||
|
},
|
|||
|
error:function(jqXHR,textStatus,errorThrown) {
|
|||
|
me.onLoadCore(false,w,null,me.source,jqXHR);
|
|||
|
}
|
|||
|
};
|
|||
|
ajaxReq(options);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.upgrade.onLoadCore = function(status,params,responseText,url,xhr)
|
|||
|
{
|
|||
|
var me = config.macros.upgrade;
|
|||
|
var w = params;
|
|||
|
var errMsg;
|
|||
|
if(!status)
|
|||
|
errMsg = me.errorLoadingCore;
|
|||
|
var newVer = me.extractVersion(responseText);
|
|||
|
if(!newVer)
|
|||
|
errMsg = me.errorCoreFormat;
|
|||
|
if(errMsg) {
|
|||
|
w.setButtons([],errMsg);
|
|||
|
alert(errMsg);
|
|||
|
return;
|
|||
|
}
|
|||
|
var onStartUpgrade = function(e) {
|
|||
|
w.setButtons([],me.statusSavingCore);
|
|||
|
var localPath = getLocalPath(document.location.toString());
|
|||
|
saveFile(localPath,responseText);
|
|||
|
w.setButtons([],me.statusReloadingCore);
|
|||
|
var backupPath = w.getValue("backupPath");
|
|||
|
var newLoc = document.location.toString() + "?time=" + new Date().convertToYYYYMMDDHHMM() + "#upgrade:[[" + encodeURI(backupPath) + "]]";
|
|||
|
window.setTimeout(function () {window.location = newLoc;},10);
|
|||
|
};
|
|||
|
var step2 = [me.step2Html_downgrade,me.step2Html_restore,me.step2Html_upgrade][compareVersions(version,newVer) + 1];
|
|||
|
w.addStep(me.step2Title,step2.format([formatVersion(newVer),formatVersion(version)]));
|
|||
|
w.setButtons([{caption: me.startLabel, tooltip: me.startPrompt, onClick: onStartUpgrade},{caption: me.cancelLabel, tooltip: me.cancelPrompt, onClick: me.onCancel}]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.upgrade.onCancel = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.upgrade;
|
|||
|
var w = new Wizard(this);
|
|||
|
w.addStep(me.step3Title,me.step3Html);
|
|||
|
w.setButtons([]);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.upgrade.extractVersion = function(upgradeFile)
|
|||
|
{
|
|||
|
var re = /^var version = \{title: "([^"]+)", major: (\d+), minor: (\d+), revision: (\d+)(, beta: (\d+)){0,1}, date: new Date\("([^"]+)"\)/mg;
|
|||
|
var m = re.exec(upgradeFile);
|
|||
|
return m ? {title: m[1], major: m[2], minor: m[3], revision: m[4], beta: m[6], date: new Date(m[7])} : null;
|
|||
|
};
|
|||
|
|
|||
|
function upgradeFrom(path)
|
|||
|
{
|
|||
|
var importStore = new TiddlyWiki();
|
|||
|
var tw = loadFile(path);
|
|||
|
if(window.netscape !== undefined)
|
|||
|
tw = convertUTF8ToUnicode(tw);
|
|||
|
importStore.importTiddlyWiki(tw);
|
|||
|
importStore.forEachTiddler(function(title,tiddler) {
|
|||
|
if(!store.getTiddler(title)) {
|
|||
|
store.addTiddler(tiddler);
|
|||
|
}
|
|||
|
});
|
|||
|
refreshDisplay();
|
|||
|
saveChanges(); //# To create appropriate Markup* sections
|
|||
|
alert(config.messages.upgradeDone.format([formatVersion()]));
|
|||
|
window.location = window.location.toString().substr(0,window.location.toString().lastIndexOf("?"));
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Sync macro
|
|||
|
//--
|
|||
|
|
|||
|
// Synchronisation handlers
|
|||
|
config.syncers = {};
|
|||
|
|
|||
|
// Sync state.
|
|||
|
var currSync = null;
|
|||
|
|
|||
|
// sync macro
|
|||
|
config.macros.sync.handler = function(place,macroName,params,wikifier,paramString,tiddler)
|
|||
|
{
|
|||
|
if(!wikifier.isStatic)
|
|||
|
this.startSync(place);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.cancelSync = function()
|
|||
|
{
|
|||
|
currSync = null;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.startSync = function(place)
|
|||
|
{
|
|||
|
if(currSync)
|
|||
|
config.macros.sync.cancelSync();
|
|||
|
currSync = {};
|
|||
|
currSync.syncList = this.getSyncableTiddlers();
|
|||
|
currSync.syncTasks = this.createSyncTasks(currSync.syncList);
|
|||
|
this.preProcessSyncableTiddlers(currSync.syncList);
|
|||
|
var wizard = new Wizard();
|
|||
|
currSync.wizard = wizard;
|
|||
|
wizard.createWizard(place,this.wizardTitle);
|
|||
|
wizard.addStep(this.step1Title,this.step1Html);
|
|||
|
var markList = wizard.getElement("markList");
|
|||
|
var listWrapper = document.createElement("div");
|
|||
|
markList.parentNode.insertBefore(listWrapper,markList);
|
|||
|
currSync.listView = ListView.create(listWrapper,currSync.syncList,this.listViewTemplate);
|
|||
|
this.processSyncableTiddlers(currSync.syncList);
|
|||
|
wizard.setButtons([{caption: this.syncLabel, tooltip: this.syncPrompt, onClick: this.doSync}]);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.getSyncableTiddlers = function()
|
|||
|
{
|
|||
|
var list = [];
|
|||
|
store.forEachTiddler(function(title,tiddler) {
|
|||
|
var syncItem = {};
|
|||
|
syncItem.serverType = tiddler.getServerType();
|
|||
|
syncItem.serverHost = tiddler.fields['server.host'];
|
|||
|
if(syncItem.serverType && syncItem.serverHost) {
|
|||
|
syncItem.adaptor = new config.adaptors[syncItem.serverType]();
|
|||
|
syncItem.serverHost = syncItem.adaptor.fullHostName(syncItem.serverHost);
|
|||
|
syncItem.serverWorkspace = tiddler.fields['server.workspace'];
|
|||
|
syncItem.tiddler = tiddler;
|
|||
|
syncItem.title = tiddler.title;
|
|||
|
syncItem.isTouched = tiddler.isTouched();
|
|||
|
syncItem.selected = syncItem.isTouched;
|
|||
|
syncItem.syncStatus = config.macros.sync.syncStatusList[syncItem.isTouched ? "changedLocally" : "none"];
|
|||
|
syncItem.status = syncItem.syncStatus.text;
|
|||
|
list.push(syncItem);
|
|||
|
}
|
|||
|
});
|
|||
|
list.sort(function(a,b) {return a.title < b.title ? -1 : (a.title == b.title ? 0 : +1);});
|
|||
|
return list;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.preProcessSyncableTiddlers = function(syncList)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i=0; i<syncList.length; i++) {
|
|||
|
var si = syncList[i];
|
|||
|
si.serverUrl = si.adaptor.generateTiddlerInfo(si.tiddler).uri;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.processSyncableTiddlers = function(syncList)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i=0; i<syncList.length; i++) {
|
|||
|
var si = syncList[i];
|
|||
|
if(si.syncStatus.display)
|
|||
|
si.rowElement.style.display = si.syncStatus.display;
|
|||
|
if(si.syncStatus.className)
|
|||
|
si.rowElement.className = si.syncStatus.className;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.createSyncTasks = function(syncList)
|
|||
|
{
|
|||
|
var i,syncTasks = [];
|
|||
|
for(i=0; i<syncList.length; i++) {
|
|||
|
var si = syncList[i];
|
|||
|
var j,r = null;
|
|||
|
for(j=0; j<syncTasks.length; j++) {
|
|||
|
var cst = syncTasks[j];
|
|||
|
if(si.serverType == cst.serverType && si.serverHost == cst.serverHost && si.serverWorkspace == cst.serverWorkspace)
|
|||
|
r = cst;
|
|||
|
}
|
|||
|
if(r) {
|
|||
|
si.syncTask = r;
|
|||
|
r.syncItems.push(si);
|
|||
|
} else {
|
|||
|
si.syncTask = this.createSyncTask(si);
|
|||
|
syncTasks.push(si.syncTask);
|
|||
|
}
|
|||
|
}
|
|||
|
return syncTasks;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.createSyncTask = function(syncItem)
|
|||
|
{
|
|||
|
var st = {};
|
|||
|
st.serverType = syncItem.serverType;
|
|||
|
st.serverHost = syncItem.serverHost;
|
|||
|
st.serverWorkspace = syncItem.serverWorkspace;
|
|||
|
st.syncItems = [syncItem];
|
|||
|
|
|||
|
var getTiddlerListCallback = function(context,sycnItems) {
|
|||
|
var me = config.macros.sync;
|
|||
|
if(!context.status) {
|
|||
|
displayMessage(context.statusText);
|
|||
|
return false;
|
|||
|
}
|
|||
|
syncItems = context.userParams;
|
|||
|
var i,tiddlers = context.tiddlers;
|
|||
|
for(i=0; i<syncItems.length; i++) {
|
|||
|
var si = syncItems[i];
|
|||
|
var f = tiddlers.findByField("title",si.title);
|
|||
|
if(f !== null) {
|
|||
|
if(tiddlers[f].fields['server.page.revision'] > si.tiddler.fields['server.page.revision']) {
|
|||
|
si.syncStatus = me.syncStatusList[si.isTouched ? 'changedBoth' : 'changedServer'];
|
|||
|
}
|
|||
|
} else {
|
|||
|
si.syncStatus = me.syncStatusList.notFound;
|
|||
|
}
|
|||
|
me.updateSyncStatus(si);
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
var openWorkspaceCallback = function(context,syncItems) {
|
|||
|
if(context.status) {
|
|||
|
context.adaptor.getTiddlerList(context,syncItems,getTiddlerListCallback);
|
|||
|
return true;
|
|||
|
}
|
|||
|
displayMessage(context.statusText);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
var context = {host:st.serverHost,workspace:st.serverWorkspace};
|
|||
|
syncItem.adaptor.openHost(st.serverHost);
|
|||
|
syncItem.adaptor.openWorkspace(st.serverWorkspace,context,st.syncItems,openWorkspaceCallback);
|
|||
|
return st;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.updateSyncStatus = function(syncItem)
|
|||
|
{
|
|||
|
var e = syncItem.colElements["status"];
|
|||
|
jQuery(e).empty();
|
|||
|
createTiddlyText(e,syncItem.syncStatus.text);
|
|||
|
syncItem.rowElement.style.display = syncItem.syncStatus.display;
|
|||
|
if(syncItem.syncStatus.className)
|
|||
|
syncItem.rowElement.className = syncItem.syncStatus.className;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.sync.doSync = function(e)
|
|||
|
{
|
|||
|
var me = config.macros.sync;
|
|||
|
var getTiddlerCallback = function(context,syncItem) {
|
|||
|
if(syncItem) {
|
|||
|
var tiddler = context.tiddler;
|
|||
|
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields,true,tiddler.created);
|
|||
|
syncItem.syncStatus = me.syncStatusList.gotFromServer;
|
|||
|
me.updateSyncStatus(syncItem);
|
|||
|
}
|
|||
|
};
|
|||
|
var putTiddlerCallback = function(context,syncItem) {
|
|||
|
if(syncItem) {
|
|||
|
store.resetTiddler(context.title);
|
|||
|
syncItem.syncStatus = me.syncStatusList.putToServer;
|
|||
|
me.updateSyncStatus(syncItem);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
var rowNames = ListView.getSelectedRows(currSync.listView);
|
|||
|
var i,sl = me.syncStatusList;
|
|||
|
for(i=0; i<currSync.syncList.length; i++) {
|
|||
|
var si = currSync.syncList[i];
|
|||
|
if(rowNames.indexOf(si.title) != -1) {
|
|||
|
var errorMsg = "Error in doSync: ";
|
|||
|
try {
|
|||
|
var r = true;
|
|||
|
switch(si.syncStatus) {
|
|||
|
case sl.changedServer:
|
|||
|
var context = {"workspace": si.serverWorkspace};
|
|||
|
r = si.adaptor.getTiddler(si.title,context,si,getTiddlerCallback);
|
|||
|
break;
|
|||
|
case sl.notFound:
|
|||
|
case sl.changedLocally:
|
|||
|
case sl.changedBoth:
|
|||
|
r = si.adaptor.putTiddler(si.tiddler,null,si,putTiddlerCallback);
|
|||
|
break;
|
|||
|
default:
|
|||
|
break;
|
|||
|
}
|
|||
|
if(!r)
|
|||
|
displayMessage(errorMsg + r);
|
|||
|
} catch(ex) {
|
|||
|
if(ex.name == "TypeError")
|
|||
|
displayMessage("sync operation unsupported: " + ex.message);
|
|||
|
else
|
|||
|
displayMessage(errorMsg + ex.message);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Manager UI for groups of tiddlers
|
|||
|
//--
|
|||
|
|
|||
|
config.macros.plugins.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
var wizard = new Wizard();
|
|||
|
wizard.createWizard(place,this.wizardTitle);
|
|||
|
wizard.addStep(this.step1Title,this.step1Html);
|
|||
|
var markList = wizard.getElement("markList");
|
|||
|
var listWrapper = document.createElement("div");
|
|||
|
markList.parentNode.insertBefore(listWrapper,markList);
|
|||
|
listWrapper.setAttribute("refresh","macro");
|
|||
|
listWrapper.setAttribute("macroName","plugins");
|
|||
|
listWrapper.setAttribute("params",paramString);
|
|||
|
this.refresh(listWrapper,paramString);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.plugins.refresh = function(listWrapper,params)
|
|||
|
{
|
|||
|
var me = config.macros.plugins;
|
|||
|
var wizard = new Wizard(listWrapper);
|
|||
|
var selectedRows = [];
|
|||
|
ListView.forEachSelector(listWrapper,function(e,rowName) {
|
|||
|
if(e.checked)
|
|||
|
selectedRows.push(e.getAttribute("rowName"));
|
|||
|
});
|
|||
|
jQuery(listWrapper).empty();
|
|||
|
params = params.parseParams("anon");
|
|||
|
var plugins = installedPlugins.slice(0);
|
|||
|
var t,tiddler,p;
|
|||
|
var configTiddlers = store.getTaggedTiddlers("systemConfig");
|
|||
|
for(t=0; t<configTiddlers.length; t++) {
|
|||
|
tiddler = configTiddlers[t];
|
|||
|
if(plugins.findByField("title",tiddler.title) == null) {
|
|||
|
p = getPluginInfo(tiddler);
|
|||
|
p.executed = false;
|
|||
|
p.log.splice(0,0,this.skippedText);
|
|||
|
plugins.push(p);
|
|||
|
}
|
|||
|
}
|
|||
|
for(t=0; t<plugins.length; t++) {
|
|||
|
p = plugins[t];
|
|||
|
p.size = p.tiddler.text ? p.tiddler.text.length : 0;
|
|||
|
p.forced = p.tiddler.isTagged("systemConfigForce");
|
|||
|
p.disabled = p.tiddler.isTagged("systemConfigDisable");
|
|||
|
p.Selected = selectedRows.indexOf(plugins[t].title) != -1;
|
|||
|
}
|
|||
|
if(plugins.length == 0) {
|
|||
|
createTiddlyElement(listWrapper,"em",null,null,this.noPluginText);
|
|||
|
wizard.setButtons([]);
|
|||
|
} else {
|
|||
|
var template = readOnly ? this.listViewTemplateReadOnly : this.listViewTemplate;
|
|||
|
var listView = ListView.create(listWrapper,plugins,template,this.onSelectCommand);
|
|||
|
wizard.setValue("listView",listView);
|
|||
|
if(!readOnly) {
|
|||
|
wizard.setButtons([
|
|||
|
{caption: me.removeLabel, tooltip: me.removePrompt, onClick: me.doRemoveTag},
|
|||
|
{caption: me.deleteLabel, tooltip: me.deletePrompt, onClick: me.doDelete}
|
|||
|
]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.plugins.doRemoveTag = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var listView = wizard.getValue("listView");
|
|||
|
var rowNames = ListView.getSelectedRows(listView);
|
|||
|
if(rowNames.length == 0) {
|
|||
|
alert(config.messages.nothingSelected);
|
|||
|
} else {
|
|||
|
var t;
|
|||
|
for(t=0; t<rowNames.length; t++) {
|
|||
|
store.setTiddlerTag(rowNames[t],false,"systemConfig");
|
|||
|
}
|
|||
|
autoSaveChanges();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.plugins.doDelete = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var listView = wizard.getValue("listView");
|
|||
|
var rowNames = ListView.getSelectedRows(listView);
|
|||
|
if(rowNames.length == 0) {
|
|||
|
alert(config.messages.nothingSelected);
|
|||
|
} else {
|
|||
|
if(confirm(config.macros.plugins.confirmDeleteText.format([rowNames.join(", ")]))) {
|
|||
|
var t;
|
|||
|
for(t=0; t<rowNames.length; t++) {
|
|||
|
store.removeTiddler(rowNames[t]);
|
|||
|
story.closeTiddler(rowNames[t],true);
|
|||
|
}
|
|||
|
}
|
|||
|
autoSaveChanges();
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Message area
|
|||
|
//--
|
|||
|
|
|||
|
function getMessageDiv()
|
|||
|
{
|
|||
|
var msgArea = document.getElementById("messageArea");
|
|||
|
if(!msgArea)
|
|||
|
return null;
|
|||
|
if(!msgArea.hasChildNodes())
|
|||
|
createTiddlyButton(createTiddlyElement(msgArea,"div",null,"messageToolbar"),
|
|||
|
config.messages.messageClose.text,
|
|||
|
config.messages.messageClose.tooltip,
|
|||
|
clearMessage);
|
|||
|
msgArea.style.display = "block";
|
|||
|
return createTiddlyElement(msgArea,"div");
|
|||
|
}
|
|||
|
|
|||
|
function displayMessage(text,linkText)
|
|||
|
{
|
|||
|
var e = getMessageDiv();
|
|||
|
if(!e) {
|
|||
|
alert(text);
|
|||
|
return;
|
|||
|
}
|
|||
|
if(linkText) {
|
|||
|
var link = createTiddlyElement(e,"a",null,null,text);
|
|||
|
link.href = linkText;
|
|||
|
link.target = "_blank";
|
|||
|
} else {
|
|||
|
e.appendChild(document.createTextNode(text));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function clearMessage()
|
|||
|
{
|
|||
|
var msgArea = document.getElementById("messageArea");
|
|||
|
if(msgArea) {
|
|||
|
jQuery(msgArea).empty();
|
|||
|
msgArea.style.display = "none";
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Refresh mechanism
|
|||
|
//--
|
|||
|
|
|||
|
config.notifyTiddlers = [
|
|||
|
{name: "SystemSettings", notify: onSystemSettingsChange},
|
|||
|
{name: "StyleSheetLayout", notify: refreshStyles},
|
|||
|
{name: "StyleSheetColors", notify: refreshStyles},
|
|||
|
{name: "StyleSheet", notify: refreshStyles},
|
|||
|
{name: "StyleSheetPrint", notify: refreshStyles},
|
|||
|
{name: "PageTemplate", notify: refreshPageTemplate},
|
|||
|
{name: "SiteTitle", notify: refreshPageTitle},
|
|||
|
{name: "SiteSubtitle", notify: refreshPageTitle},
|
|||
|
{name: "WindowTitle", notify: refreshPageTitle},
|
|||
|
{name: "ColorPalette", notify: refreshColorPalette},
|
|||
|
{name: null, notify: refreshDisplay}
|
|||
|
];
|
|||
|
|
|||
|
config.refreshers = {
|
|||
|
link: function(e,changeList)
|
|||
|
{
|
|||
|
var title = e.getAttribute("tiddlyLink");
|
|||
|
refreshTiddlyLink(e,title);
|
|||
|
return true;
|
|||
|
},
|
|||
|
|
|||
|
tiddler: function(e,changeList)
|
|||
|
{
|
|||
|
var title = e.getAttribute("tiddler");
|
|||
|
var template = e.getAttribute("template");
|
|||
|
if(changeList && (changeList.indexOf && changeList.indexOf(title) != -1) && !story.isDirty(title))
|
|||
|
story.refreshTiddler(title,template,true);
|
|||
|
else
|
|||
|
refreshElements(e,changeList);
|
|||
|
return true;
|
|||
|
},
|
|||
|
|
|||
|
content: function(e,changeList)
|
|||
|
{
|
|||
|
var title = e.getAttribute("tiddler");
|
|||
|
var force = e.getAttribute("force");
|
|||
|
var args = e.getAttribute("args");
|
|||
|
if(force != null || changeList == null || (changeList.indexOf && changeList.indexOf(title) != -1)) {
|
|||
|
jQuery(e).empty();
|
|||
|
config.macros.tiddler.transclude(e,title,args);
|
|||
|
return true;
|
|||
|
} else
|
|||
|
return false;
|
|||
|
},
|
|||
|
|
|||
|
macro: function(e,changeList)
|
|||
|
{
|
|||
|
var macro = e.getAttribute("macroName");
|
|||
|
var params = e.getAttribute("params");
|
|||
|
if(macro)
|
|||
|
macro = config.macros[macro];
|
|||
|
if(macro && macro.refresh)
|
|||
|
macro.refresh(e,params);
|
|||
|
return true;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.refresherData = {
|
|||
|
styleSheet: "StyleSheet",
|
|||
|
defaultStyleSheet: "StyleSheet",
|
|||
|
pageTemplate: "PageTemplate",
|
|||
|
defaultPageTemplate: "PageTemplate",
|
|||
|
colorPalette: "ColorPalette",
|
|||
|
defaultColorPalette: "ColorPalette"
|
|||
|
};
|
|||
|
|
|||
|
function refreshElements(root,changeList)
|
|||
|
{
|
|||
|
var c,nodes = root.childNodes;
|
|||
|
for(c=0; c<nodes.length; c++) {
|
|||
|
var e = nodes[c], type = null;
|
|||
|
if(e.getAttribute && (e.tagName ? e.tagName != "IFRAME" : true))
|
|||
|
type = e.getAttribute("refresh");
|
|||
|
var refresher = config.refreshers[type];
|
|||
|
var refreshed = false;
|
|||
|
if(refresher != undefined)
|
|||
|
refreshed = refresher(e,changeList);
|
|||
|
if(e.hasChildNodes() && !refreshed)
|
|||
|
refreshElements(e,changeList);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function applyHtmlMacros(root,tiddler)
|
|||
|
{
|
|||
|
var e = root.firstChild;
|
|||
|
while(e) {
|
|||
|
var nextChild = e.nextSibling;
|
|||
|
if(e.getAttribute) {
|
|||
|
var macro = e.getAttribute("macro");
|
|||
|
if(macro) {
|
|||
|
e.removeAttribute("macro");
|
|||
|
var params = "";
|
|||
|
var p = macro.indexOf(" ");
|
|||
|
if(p != -1) {
|
|||
|
params = macro.substr(p+1);
|
|||
|
macro = macro.substr(0,p);
|
|||
|
}
|
|||
|
invokeMacro(e,macro,params,null,tiddler);
|
|||
|
}
|
|||
|
}
|
|||
|
if(e.hasChildNodes())
|
|||
|
applyHtmlMacros(e,tiddler);
|
|||
|
e = nextChild;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function refreshPageTemplate(title)
|
|||
|
{
|
|||
|
var stash = jQuery("<div/>").appendTo("body").hide()[0];
|
|||
|
var display = story.getContainer();
|
|||
|
var nodes,t;
|
|||
|
if(display) {
|
|||
|
nodes = display.childNodes;
|
|||
|
for(t=nodes.length-1; t>=0; t--)
|
|||
|
stash.appendChild(nodes[t]);
|
|||
|
}
|
|||
|
var wrapper = document.getElementById("contentWrapper");
|
|||
|
|
|||
|
var isAvailable = function(title) {
|
|||
|
var s = title ? title.indexOf(config.textPrimitives.sectionSeparator) : -1;
|
|||
|
if(s!=-1)
|
|||
|
title = title.substr(0,s);
|
|||
|
return store.tiddlerExists(title) || store.isShadowTiddler(title);
|
|||
|
};
|
|||
|
if(!title || !isAvailable(title))
|
|||
|
title = config.refresherData.pageTemplate;
|
|||
|
if(!isAvailable(title))
|
|||
|
title = config.refresherData.defaultPageTemplate; //# this one is always avaialable
|
|||
|
wrapper.innerHTML = store.getRecursiveTiddlerText(title,null,10);
|
|||
|
applyHtmlMacros(wrapper);
|
|||
|
refreshElements(wrapper);
|
|||
|
display = story.getContainer();
|
|||
|
jQuery(display).empty();
|
|||
|
if(!display)
|
|||
|
display = createTiddlyElement(wrapper,"div",story.containerId());
|
|||
|
nodes = stash.childNodes;
|
|||
|
for(t=nodes.length-1; t>=0; t--)
|
|||
|
display.appendChild(nodes[t]);
|
|||
|
jQuery(stash).remove();
|
|||
|
}
|
|||
|
|
|||
|
function refreshDisplay(hint)
|
|||
|
{
|
|||
|
if(typeof hint == "string")
|
|||
|
hint = [hint];
|
|||
|
var e = document.getElementById("contentWrapper");
|
|||
|
refreshElements(e,hint);
|
|||
|
if(backstage.isPanelVisible()) {
|
|||
|
e = document.getElementById("backstage");
|
|||
|
refreshElements(e,hint);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function refreshPageTitle()
|
|||
|
{
|
|||
|
document.title = getPageTitle();
|
|||
|
}
|
|||
|
|
|||
|
function getPageTitle()
|
|||
|
{
|
|||
|
return wikifyPlainText(store.getTiddlerText("WindowTitle",""),null,tiddler);
|
|||
|
}
|
|||
|
|
|||
|
function refreshStyles(title,doc)
|
|||
|
{
|
|||
|
setStylesheet(title == null ? "" : store.getRecursiveTiddlerText(title,"",10),title,doc || document);
|
|||
|
}
|
|||
|
|
|||
|
function refreshColorPalette(title)
|
|||
|
{
|
|||
|
if(!startingUp)
|
|||
|
refreshAll();
|
|||
|
}
|
|||
|
|
|||
|
function refreshAll()
|
|||
|
{
|
|||
|
refreshPageTemplate();
|
|||
|
refreshDisplay();
|
|||
|
refreshStyles("StyleSheetLayout");
|
|||
|
refreshStyles("StyleSheetColors");
|
|||
|
refreshStyles(config.refresherData.styleSheet);
|
|||
|
refreshStyles("StyleSheetPrint");
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Option handling
|
|||
|
//--
|
|||
|
|
|||
|
config.optionHandlers = {
|
|||
|
'txt': {
|
|||
|
get: function(name) {return encodeCookie(config.options[name].toString());},
|
|||
|
set: function(name,value) {config.options[name] = decodeCookie(value);}
|
|||
|
},
|
|||
|
'chk': {
|
|||
|
get: function(name) {return config.options[name] ? 'true' : 'false';},
|
|||
|
set: function(name,value) {config.options[name] = value == 'true';}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
function setOption(name,value)
|
|||
|
{
|
|||
|
var optType = name.substr(0,3);
|
|||
|
if(config.optionHandlers[optType] && config.optionHandlers[optType].set)
|
|||
|
config.optionHandlers[optType].set(name,value);
|
|||
|
}
|
|||
|
|
|||
|
// Gets the value of an option as a string. Most code should just read from config.options.* directly
|
|||
|
function getOption(name)
|
|||
|
{
|
|||
|
var optType = name.substr(0,3);
|
|||
|
return config.optionHandlers[optType] && config.optionHandlers[optType].get ? config.optionHandlers[optType].get(name) : null;
|
|||
|
}
|
|||
|
|
|||
|
function loadOptions()
|
|||
|
{
|
|||
|
if(safeMode)
|
|||
|
return;
|
|||
|
loadCookies();
|
|||
|
loadSystemSettings();
|
|||
|
}
|
|||
|
// @Deprecated; retained for backwards compatibility
|
|||
|
var loadOptionsCookie = loadOptions;
|
|||
|
|
|||
|
function getCookies()
|
|||
|
{
|
|||
|
var cookieList = document.cookie.split(';');
|
|||
|
var i,cookies = {};
|
|||
|
for(i=0; i<cookieList.length; i++) {
|
|||
|
var p = cookieList[i].indexOf('=');
|
|||
|
if(p != -1) {
|
|||
|
var name = cookieList[i].substr(0,p).trim();
|
|||
|
var value = cookieList[i].substr(p+1).trim();
|
|||
|
cookies[name] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
return cookies;
|
|||
|
}
|
|||
|
|
|||
|
function loadCookies()
|
|||
|
{
|
|||
|
var i,cookies = getCookies();
|
|||
|
if(cookies['TiddlyWiki']) {
|
|||
|
cookies = cookies['TiddlyWiki'].decodeHashMap();
|
|||
|
}
|
|||
|
for(i in cookies) {
|
|||
|
if(config.optionsSource[i] != 'setting') {
|
|||
|
setOption(i,cookies[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function loadSystemSettings()
|
|||
|
{
|
|||
|
var key,settings = store.calcAllSlices('SystemSettings');
|
|||
|
config.optionsSource = {};
|
|||
|
for(key in settings) {
|
|||
|
setOption(key,settings[key]);
|
|||
|
config.optionsSource[key] = 'setting';
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function onSystemSettingsChange()
|
|||
|
{
|
|||
|
if(!startingUp) {
|
|||
|
loadSystemSettings();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function saveOption(name)
|
|||
|
{
|
|||
|
if(safeMode)
|
|||
|
return;
|
|||
|
if(name.match(/[()\s]/g, '_')) {
|
|||
|
alert(config.messages.invalidCookie.format([name]));
|
|||
|
return;
|
|||
|
}
|
|||
|
saveCookie(name);
|
|||
|
if(config.optionsSource[name] == 'setting') {
|
|||
|
saveSystemSetting(name,true);
|
|||
|
}
|
|||
|
}
|
|||
|
// @Deprecated; retained for backwards compatibility
|
|||
|
var saveOptionCookie = saveOption;
|
|||
|
|
|||
|
function removeCookie(name)
|
|||
|
{
|
|||
|
document.cookie = name + '=; expires=Thu, 01-Jan-1970 00:00:01 UTC; path=/;';
|
|||
|
}
|
|||
|
|
|||
|
function saveCookie(name)
|
|||
|
{
|
|||
|
var key,cookies = {};
|
|||
|
for(key in config.options) {
|
|||
|
var value = getOption(key);
|
|||
|
value = value == null ? 'false' : value;
|
|||
|
cookies[key] = value;
|
|||
|
}
|
|||
|
document.cookie = 'TiddlyWiki=' + String.encodeHashMap(cookies) + '; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/';
|
|||
|
cookies = getCookies();
|
|||
|
var c;
|
|||
|
for(c in cookies) {
|
|||
|
var optType = c.substr(0,3);
|
|||
|
if(config.optionHandlers[optType])
|
|||
|
removeCookie(c);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
var systemSettingSave;
|
|||
|
function commitSystemSettings(storeWasDirty)
|
|||
|
{
|
|||
|
if(systemSettingSave) {
|
|||
|
window.clearTimeout(systemSettingSave);
|
|||
|
}
|
|||
|
systemSettingSave = window.setTimeout(function() {
|
|||
|
var tiddler = store.getTiddler('SystemSettings');
|
|||
|
if(storeWasDirty == false && story.areAnyDirty() == false) {
|
|||
|
saveChanges(null,[tiddler]);
|
|||
|
} else {
|
|||
|
autoSaveChanges(null,[tiddler]);
|
|||
|
}
|
|||
|
}, 1000);
|
|||
|
}
|
|||
|
|
|||
|
function saveSystemSetting(name,saveFile)
|
|||
|
{
|
|||
|
var title = 'SystemSettings';
|
|||
|
var slice = store.getTiddlerSlice(title,name);
|
|||
|
if(readOnly || slice === getOption(name)) {
|
|||
|
return; //# don't save if read-only or the option hasn't changed
|
|||
|
}
|
|||
|
var slices = store.calcAllSlices(title);
|
|||
|
var key;
|
|||
|
for(key in config.optionsSource) {
|
|||
|
var value = getOption(key) || '';
|
|||
|
if(slices[key] !== value) {
|
|||
|
slices[key] = value;
|
|||
|
}
|
|||
|
}
|
|||
|
var text = [];
|
|||
|
for(key in slices) {
|
|||
|
text.push('%0: %1'.format([key,slices[key]]));
|
|||
|
}
|
|||
|
text = text.sort().join('\n');
|
|||
|
var storeWasDirty = store.isDirty();
|
|||
|
var tiddler = store.getTiddler(title);
|
|||
|
if(tiddler) {
|
|||
|
tiddler.text = text;
|
|||
|
tiddler = store.saveTiddler(tiddler);
|
|||
|
} else {
|
|||
|
tiddler = store.saveTiddler(title,title,text,'System',new Date(),['excludeLists'],config.defaultCustomFields);
|
|||
|
}
|
|||
|
if(saveFile) {
|
|||
|
commitSystemSettings(storeWasDirty);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function encodeCookie(s)
|
|||
|
{
|
|||
|
return escape(convertUnicodeToHtmlEntities(s));
|
|||
|
}
|
|||
|
|
|||
|
function decodeCookie(s)
|
|||
|
{
|
|||
|
s = unescape(s);
|
|||
|
var re = /&#[0-9]{1,5};/g;
|
|||
|
return s.replace(re,function($0) {return String.fromCharCode(eval($0.replace(/[&#;]/g,'')));});
|
|||
|
}
|
|||
|
|
|||
|
config.macros.option.genericCreate = function(place,type,opt,className,desc)
|
|||
|
{
|
|||
|
var typeInfo = config.macros.option.types[type];
|
|||
|
var c = document.createElement(typeInfo.elementType);
|
|||
|
if(typeInfo.typeValue)
|
|||
|
c.setAttribute('type',typeInfo.typeValue);
|
|||
|
c[typeInfo.eventName] = typeInfo.onChange;
|
|||
|
c.setAttribute('option',opt);
|
|||
|
c.className = className || typeInfo.className;
|
|||
|
if(config.optionsDesc[opt])
|
|||
|
c.setAttribute('title',config.optionsDesc[opt]);
|
|||
|
place.appendChild(c);
|
|||
|
if(desc != 'no')
|
|||
|
createTiddlyText(place,config.optionsDesc[opt] || opt);
|
|||
|
c[typeInfo.valueField] = config.options[opt];
|
|||
|
return c;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.option.genericOnChange = function(e)
|
|||
|
{
|
|||
|
var opt = this.getAttribute('option');
|
|||
|
if(opt) {
|
|||
|
var optType = opt.substr(0,3);
|
|||
|
var handler = config.macros.option.types[optType];
|
|||
|
if(handler.elementType && handler.valueField)
|
|||
|
config.macros.option.propagateOption(opt,handler.valueField,this[handler.valueField],handler.elementType,this);
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
config.macros.option.types = {
|
|||
|
'txt': {
|
|||
|
elementType: 'input',
|
|||
|
valueField: 'value',
|
|||
|
eventName: 'onchange',
|
|||
|
className: 'txtOptionInput',
|
|||
|
create: config.macros.option.genericCreate,
|
|||
|
onChange: config.macros.option.genericOnChange
|
|||
|
},
|
|||
|
'chk': {
|
|||
|
elementType: 'input',
|
|||
|
valueField: 'checked',
|
|||
|
eventName: 'onclick',
|
|||
|
className: 'chkOptionInput',
|
|||
|
typeValue: 'checkbox',
|
|||
|
create: config.macros.option.genericCreate,
|
|||
|
onChange: config.macros.option.genericOnChange
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.option.propagateOption = function(opt,valueField,value,elementType,elem)
|
|||
|
{
|
|||
|
config.options[opt] = value;
|
|||
|
saveOption(opt);
|
|||
|
var t,nodes = document.getElementsByTagName(elementType);
|
|||
|
for(t=0; t<nodes.length; t++) {
|
|||
|
var optNode = nodes[t].getAttribute('option');
|
|||
|
if(opt == optNode && nodes[t]!=elem)
|
|||
|
nodes[t][valueField] = value;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.option.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
params = paramString.parseParams('anon',null,true,false,false);
|
|||
|
var opt = (params[1] && params[1].name == 'anon') ? params[1].value : getParam(params,'name',null);
|
|||
|
var className = (params[2] && params[2].name == 'anon') ? params[2].value : getParam(params,'class',null);
|
|||
|
var desc = getParam(params,'desc','no');
|
|||
|
var type = opt.substr(0,3);
|
|||
|
var h = config.macros.option.types[type];
|
|||
|
if(h && h.create)
|
|||
|
h.create(place,type,opt,className,desc);
|
|||
|
};
|
|||
|
|
|||
|
config.macros.options.handler = function(place,macroName,params,wikifier,paramString)
|
|||
|
{
|
|||
|
params = paramString.parseParams('anon',null,true,false,false);
|
|||
|
var showUnknown = getParam(params,'showUnknown','no');
|
|||
|
var wizard = new Wizard();
|
|||
|
wizard.createWizard(place,this.wizardTitle);
|
|||
|
wizard.addStep(this.step1Title,this.step1Html);
|
|||
|
var markList = wizard.getElement('markList');
|
|||
|
var chkUnknown = wizard.getElement('chkUnknown');
|
|||
|
chkUnknown.checked = showUnknown == 'yes';
|
|||
|
chkUnknown.onchange = this.onChangeUnknown;
|
|||
|
var listWrapper = document.createElement('div');
|
|||
|
markList.parentNode.insertBefore(listWrapper,markList);
|
|||
|
wizard.setValue('listWrapper',listWrapper);
|
|||
|
this.refreshOptions(listWrapper,showUnknown == 'yes');
|
|||
|
};
|
|||
|
|
|||
|
config.macros.options.refreshOptions = function(listWrapper,showUnknown)
|
|||
|
{
|
|||
|
var n,opts = [];
|
|||
|
for(n in config.options) {
|
|||
|
var opt = {};
|
|||
|
opt.option = '';
|
|||
|
opt.name = n;
|
|||
|
opt.lowlight = !config.optionsDesc[n];
|
|||
|
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
|
|||
|
if(!opt.lowlight || showUnknown)
|
|||
|
opts.push(opt);
|
|||
|
}
|
|||
|
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);});
|
|||
|
ListView.create(listWrapper,opts,this.listViewTemplate);
|
|||
|
for(n=0; n<opts.length; n++) {
|
|||
|
var type = opts[n].name.substr(0,3);
|
|||
|
var h = config.macros.option.types[type];
|
|||
|
if(h && h.create) {
|
|||
|
h.create(opts[n].colElements['option'],type,opts[n].name,null,'no');
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
config.macros.options.onChangeUnknown = function(e)
|
|||
|
{
|
|||
|
var wizard = new Wizard(this);
|
|||
|
var listWrapper = wizard.getValue('listWrapper');
|
|||
|
jQuery(listWrapper).empty();
|
|||
|
config.macros.options.refreshOptions(listWrapper,this.checked);
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Saving
|
|||
|
//--
|
|||
|
|
|||
|
var saveUsingSafari = false;
|
|||
|
|
|||
|
var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it
|
|||
|
var startSaveAreaRE = /<((div)|(DIV)) ((id)|(ID))=["']?storeArea['"]?>/; // Used for IE6
|
|||
|
var endSaveArea = '</d' + 'iv>';
|
|||
|
var endSaveAreaCaps = '</D' + 'IV>';
|
|||
|
|
|||
|
// If there are unsaved changes, force the user to confirm before exitting
|
|||
|
function confirmExit()
|
|||
|
{
|
|||
|
hadConfirmExit = true;
|
|||
|
if((store && store.isDirty && store.isDirty()) || (story && story.areAnyDirty && story.areAnyDirty()))
|
|||
|
return config.messages.confirmExit;
|
|||
|
}
|
|||
|
|
|||
|
// Give the user a chance to save changes before exitting
|
|||
|
function checkUnsavedChanges()
|
|||
|
{
|
|||
|
if(store && store.isDirty && store.isDirty() && window.hadConfirmExit === false) {
|
|||
|
if(confirm(config.messages.unsavedChangesWarning))
|
|||
|
saveChanges();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function updateLanguageAttribute(s)
|
|||
|
{
|
|||
|
if(config.locale) {
|
|||
|
var mRE = /(<html(?:.*?)?)(?: xml:lang\="([a-z]+)")?(?: lang\="([a-z]+)")?>/;
|
|||
|
var m = mRE.exec(s);
|
|||
|
if(m) {
|
|||
|
var t = m[1];
|
|||
|
if(m[2])
|
|||
|
t += ' xml:lang="' + config.locale + '"';
|
|||
|
if(m[3])
|
|||
|
t += ' lang="' + config.locale + '"';
|
|||
|
t += ">";
|
|||
|
s = s.substr(0,m.index) + t + s.substr(m.index+m[0].length);
|
|||
|
}
|
|||
|
}
|
|||
|
return s;
|
|||
|
}
|
|||
|
|
|||
|
function updateMarkupBlock(s,blockName,tiddlerName)
|
|||
|
{
|
|||
|
return s.replaceChunk(
|
|||
|
"<!--%0-START-->".format([blockName]),
|
|||
|
"<!--%0-END-->".format([blockName]),
|
|||
|
"\n" + convertUnicodeToFileFormat(store.getRecursiveTiddlerText(tiddlerName,"")) + "\n");
|
|||
|
}
|
|||
|
|
|||
|
function updateOriginal(original,posDiv,localPath)
|
|||
|
{
|
|||
|
if(!posDiv)
|
|||
|
posDiv = locateStoreArea(original);
|
|||
|
if(!posDiv) {
|
|||
|
alert(config.messages.invalidFileError.format([localPath]));
|
|||
|
return null;
|
|||
|
}
|
|||
|
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
|
|||
|
convertUnicodeToFileFormat(store.allTiddlersAsHtml()) + "\n" +
|
|||
|
original.substr(posDiv[1]);
|
|||
|
var newSiteTitle = convertUnicodeToFileFormat(getPageTitle()).htmlEncode();
|
|||
|
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
|
|||
|
revised = updateLanguageAttribute(revised);
|
|||
|
revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
|
|||
|
revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
|
|||
|
revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
|
|||
|
revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
|
|||
|
return revised;
|
|||
|
}
|
|||
|
|
|||
|
function locateStoreArea(original)
|
|||
|
{
|
|||
|
// Locate the storeArea divs
|
|||
|
if(!original)
|
|||
|
return null;
|
|||
|
var posOpeningDiv = original.search(startSaveAreaRE);
|
|||
|
var limitClosingDiv = original.indexOf("<"+"!--POST-STOREAREA--"+">");
|
|||
|
if(limitClosingDiv == -1)
|
|||
|
limitClosingDiv = original.indexOf("<"+"!--POST-BODY-START--"+">");
|
|||
|
var start = limitClosingDiv == -1 ? original.length : limitClosingDiv;
|
|||
|
var posClosingDiv = original.lastIndexOf(endSaveArea,start);
|
|||
|
if(posClosingDiv == -1)
|
|||
|
posClosingDiv = original.lastIndexOf(endSaveAreaCaps,start);
|
|||
|
return (posOpeningDiv != -1 && posClosingDiv != -1) ? [posOpeningDiv,posClosingDiv] : null;
|
|||
|
}
|
|||
|
|
|||
|
function autoSaveChanges(onlyIfDirty,tiddlers)
|
|||
|
{
|
|||
|
if(config.options.chkAutoSave)
|
|||
|
saveChanges(onlyIfDirty,tiddlers);
|
|||
|
}
|
|||
|
|
|||
|
function loadOriginal(localPath)
|
|||
|
{
|
|||
|
return loadFile(localPath);
|
|||
|
}
|
|||
|
|
|||
|
// Save this tiddlywiki with the pending changes
|
|||
|
function saveChanges(onlyIfDirty,tiddlers)
|
|||
|
{
|
|||
|
if(onlyIfDirty && !store.isDirty())
|
|||
|
return;
|
|||
|
clearMessage();
|
|||
|
var t0 = new Date();
|
|||
|
var msg = config.messages;
|
|||
|
var originalPath = document.location.toString();
|
|||
|
if(originalPath.substr(0,5) != "file:") {
|
|||
|
alert(msg.notFileUrlError);
|
|||
|
if(store.tiddlerExists(msg.saveInstructions))
|
|||
|
story.displayTiddler(null,msg.saveInstructions);
|
|||
|
return;
|
|||
|
}
|
|||
|
var localPath = getLocalPath(originalPath);
|
|||
|
var original = loadOriginal(localPath);
|
|||
|
if(original == null) {
|
|||
|
alert(msg.cantSaveError);
|
|||
|
if(store.tiddlerExists(msg.saveInstructions))
|
|||
|
story.displayTiddler(null,msg.saveInstructions);
|
|||
|
return;
|
|||
|
}
|
|||
|
var posDiv = locateStoreArea(original);
|
|||
|
if(!posDiv) {
|
|||
|
alert(msg.invalidFileError.format([localPath]));
|
|||
|
return;
|
|||
|
}
|
|||
|
saveMain(localPath,original,posDiv);
|
|||
|
if(config.options.chkSaveBackups)
|
|||
|
saveBackup(localPath,original);
|
|||
|
if(config.options.chkSaveEmptyTemplate)
|
|||
|
saveEmpty(localPath,original,posDiv);
|
|||
|
if(config.options.chkGenerateAnRssFeed && saveRss instanceof Function)
|
|||
|
saveRss(localPath);
|
|||
|
if(config.options.chkDisplayInstrumentation)
|
|||
|
displayMessage("saveChanges " + (new Date()-t0) + " ms");
|
|||
|
}
|
|||
|
|
|||
|
function saveMain(localPath,original,posDiv)
|
|||
|
{
|
|||
|
var save;
|
|||
|
try {
|
|||
|
var revised = updateOriginal(original,posDiv,localPath);
|
|||
|
save = saveFile(localPath,revised);
|
|||
|
} catch (ex) {
|
|||
|
showException(ex);
|
|||
|
}
|
|||
|
if(save) {
|
|||
|
displayMessage(config.messages.mainSaved,"file://" + localPath);
|
|||
|
store.setDirty(false);
|
|||
|
} else {
|
|||
|
alert(config.messages.mainFailed);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function saveBackup(localPath,original)
|
|||
|
{
|
|||
|
var backupPath = getBackupPath(localPath);
|
|||
|
var backup = copyFile(backupPath,localPath);
|
|||
|
if(!backup)
|
|||
|
backup = saveFile(backupPath,original);
|
|||
|
if(backup)
|
|||
|
displayMessage(config.messages.backupSaved,"file://" + backupPath);
|
|||
|
else
|
|||
|
alert(config.messages.backupFailed);
|
|||
|
}
|
|||
|
|
|||
|
function saveEmpty(localPath,original,posDiv)
|
|||
|
{
|
|||
|
var emptyPath,p;
|
|||
|
if((p = localPath.lastIndexOf("/")) != -1)
|
|||
|
emptyPath = localPath.substr(0,p) + "/";
|
|||
|
else if((p = localPath.lastIndexOf("\\")) != -1)
|
|||
|
emptyPath = localPath.substr(0,p) + "\\";
|
|||
|
else
|
|||
|
emptyPath = localPath + ".";
|
|||
|
emptyPath += "empty.html";
|
|||
|
var empty = original.substr(0,posDiv[0] + startSaveArea.length) + original.substr(posDiv[1]);
|
|||
|
var emptySave = saveFile(emptyPath,empty);
|
|||
|
if(emptySave)
|
|||
|
displayMessage(config.messages.emptySaved,"file://" + emptyPath);
|
|||
|
else
|
|||
|
alert(config.messages.emptyFailed);
|
|||
|
}
|
|||
|
|
|||
|
function getLocalPath(origPath)
|
|||
|
{
|
|||
|
var originalPath = convertUriToUTF8(origPath,config.options.txtFileSystemCharSet);
|
|||
|
// Remove any location or query part of the URL
|
|||
|
var argPos = originalPath.indexOf("?");
|
|||
|
if(argPos != -1)
|
|||
|
originalPath = originalPath.substr(0,argPos);
|
|||
|
var hashPos = originalPath.indexOf("#");
|
|||
|
if(hashPos != -1)
|
|||
|
originalPath = originalPath.substr(0,hashPos);
|
|||
|
// Convert file://localhost/ to file:///
|
|||
|
if(originalPath.indexOf("file://localhost/") == 0)
|
|||
|
originalPath = "file://" + originalPath.substr(16);
|
|||
|
// Convert to a native file format
|
|||
|
var localPath;
|
|||
|
if(originalPath.charAt(9) == ":") // pc local file
|
|||
|
localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
|
|||
|
else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file
|
|||
|
localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
|
|||
|
else if(originalPath.indexOf("file:///") == 0) // mac/unix local file
|
|||
|
localPath = unescape(originalPath.substr(7));
|
|||
|
else if(originalPath.indexOf("file:/") == 0) // mac/unix local file
|
|||
|
localPath = unescape(originalPath.substr(5));
|
|||
|
else // pc network file
|
|||
|
localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
|
|||
|
return localPath;
|
|||
|
}
|
|||
|
|
|||
|
function getBackupPath(localPath,title,extension)
|
|||
|
{
|
|||
|
var slash = "\\";
|
|||
|
var dirPathPos = localPath.lastIndexOf("\\");
|
|||
|
if(dirPathPos == -1) {
|
|||
|
dirPathPos = localPath.lastIndexOf("/");
|
|||
|
slash = "/";
|
|||
|
}
|
|||
|
var backupFolder = config.options.txtBackupFolder;
|
|||
|
if(!backupFolder || backupFolder == "")
|
|||
|
backupFolder = ".";
|
|||
|
var backupPath = localPath.substr(0,dirPathPos) + slash + backupFolder + localPath.substr(dirPathPos);
|
|||
|
backupPath = backupPath.substr(0,backupPath.lastIndexOf(".")) + ".";
|
|||
|
if(title)
|
|||
|
backupPath += title.replace(/[\\\/\*\?\":<> ]/g,"_") + ".";
|
|||
|
backupPath += (new Date()).convertToYYYYMMDDHHMMSSMMM() + "." + (extension || "html");
|
|||
|
return backupPath;
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- RSS Saving
|
|||
|
//--
|
|||
|
|
|||
|
function saveRss(localPath)
|
|||
|
{
|
|||
|
var rssPath = localPath.substr(0,localPath.lastIndexOf(".")) + ".xml";
|
|||
|
if(saveFile(rssPath,convertUnicodeToFileFormat(generateRss())))
|
|||
|
displayMessage(config.messages.rssSaved,"file://" + rssPath);
|
|||
|
else
|
|||
|
alert(config.messages.rssFailed);
|
|||
|
}
|
|||
|
|
|||
|
tiddlerToRssItem = function(tiddler,uri)
|
|||
|
{
|
|||
|
var s = "<title" + ">" + tiddler.title.htmlEncode() + "</title" + ">\n";
|
|||
|
s += "<description>" + wikifyStatic(tiddler.text,null,tiddler).htmlEncode() + "</description>\n";
|
|||
|
var i;
|
|||
|
for(i=0; i<tiddler.tags.length; i++)
|
|||
|
s += "<category>" + tiddler.tags[i] + "</category>\n";
|
|||
|
s += "<link>" + uri + "#" + encodeURIComponent(String.encodeTiddlyLink(tiddler.title)) + "</link>\n";
|
|||
|
s +="<pubDate>" + tiddler.modified.toGMTString() + "</pubDate>\n";
|
|||
|
return s;
|
|||
|
};
|
|||
|
|
|||
|
function generateRss()
|
|||
|
{
|
|||
|
var s = [];
|
|||
|
var d = new Date();
|
|||
|
var u = store.getTiddlerText("SiteUrl");
|
|||
|
// Assemble the header
|
|||
|
s.push("<" + "?xml version=\"1.0\"?" + ">");
|
|||
|
s.push("<rss version=\"2.0\">");
|
|||
|
s.push("<channel>");
|
|||
|
s.push("<title" + ">" + wikifyPlainText(store.getTiddlerText("SiteTitle",""),null,tiddler).htmlEncode() + "</title" + ">");
|
|||
|
if(u)
|
|||
|
s.push("<link>" + u.htmlEncode() + "</link>");
|
|||
|
s.push("<description>" + wikifyPlainText(store.getTiddlerText("SiteSubtitle",""),null,tiddler).htmlEncode() + "</description>");
|
|||
|
s.push("<language>" + config.locale + "</language>");
|
|||
|
s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");
|
|||
|
s.push("<pubDate>" + d.toGMTString() + "</pubDate>");
|
|||
|
s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");
|
|||
|
s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
|
|||
|
s.push("<generator>TiddlyWiki " + formatVersion() + "</generator>");
|
|||
|
// The body
|
|||
|
var tiddlers = store.getTiddlers("modified","excludeLists");
|
|||
|
var i,n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
|
|||
|
for(i=tiddlers.length-1; i>=n; i--) {
|
|||
|
s.push("<item>\n" + tiddlerToRssItem(tiddlers[i],u) + "\n</item>");
|
|||
|
}
|
|||
|
// And footer
|
|||
|
s.push("</channel>");
|
|||
|
s.push("</rss>");
|
|||
|
// Save it all
|
|||
|
return s.join("\n");
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Filesystem code
|
|||
|
//--
|
|||
|
|
|||
|
function convertUTF8ToUnicode(u)
|
|||
|
{
|
|||
|
return config.browser.isOpera || !window.netscape ? manualConvertUTF8ToUnicode(u) : mozConvertUTF8ToUnicode(u);
|
|||
|
}
|
|||
|
|
|||
|
function manualConvertUTF8ToUnicode(utf)
|
|||
|
{
|
|||
|
var uni = utf;
|
|||
|
var src = 0;
|
|||
|
var dst = 0;
|
|||
|
var b1, b2, b3;
|
|||
|
var c;
|
|||
|
while(src < utf.length) {
|
|||
|
b1 = utf.charCodeAt(src++);
|
|||
|
if(b1 < 0x80) {
|
|||
|
dst++;
|
|||
|
} else if(b1 < 0xE0) {
|
|||
|
b2 = utf.charCodeAt(src++);
|
|||
|
c = String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
|
|||
|
uni = uni.substring(0,dst++).concat(c,utf.substr(src));
|
|||
|
} else {
|
|||
|
b2 = utf.charCodeAt(src++);
|
|||
|
b3 = utf.charCodeAt(src++);
|
|||
|
c = String.fromCharCode(((b1 & 0xF) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
|
|||
|
uni = uni.substring(0,dst++).concat(c,utf.substr(src));
|
|||
|
}
|
|||
|
}
|
|||
|
return uni;
|
|||
|
}
|
|||
|
|
|||
|
function mozConvertUTF8ToUnicode(u)
|
|||
|
{
|
|||
|
try {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|||
|
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
|||
|
converter.charset = "UTF-8";
|
|||
|
} catch(ex) {
|
|||
|
return manualConvertUTF8ToUnicode(u);
|
|||
|
} // fallback
|
|||
|
var s = converter.ConvertToUnicode(u);
|
|||
|
var fin = converter.Finish();
|
|||
|
return fin.length > 0 ? s+fin : s;
|
|||
|
}
|
|||
|
|
|||
|
function convertUnicodeToFileFormat(s)
|
|||
|
{
|
|||
|
return config.browser.isOpera || !window.netscape ? (config.browser.isIE ? convertUnicodeToHtmlEntities(s) : s) : mozConvertUnicodeToUTF8(s);
|
|||
|
}
|
|||
|
|
|||
|
function convertUnicodeToHtmlEntities(s)
|
|||
|
{
|
|||
|
var re = /[^\u0000-\u007F]/g;
|
|||
|
return s.replace(re,function($0) {return "&#" + $0.charCodeAt(0).toString() + ";";});
|
|||
|
}
|
|||
|
|
|||
|
function convertUnicodeToUTF8(s)
|
|||
|
{
|
|||
|
// return convertUnicodeToFileFormat to allow plugin migration
|
|||
|
return convertUnicodeToFileFormat(s);
|
|||
|
}
|
|||
|
|
|||
|
function manualConvertUnicodeToUTF8(s)
|
|||
|
{
|
|||
|
return unescape(encodeURIComponent(s));
|
|||
|
}
|
|||
|
|
|||
|
function mozConvertUnicodeToUTF8(s)
|
|||
|
{
|
|||
|
try {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|||
|
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
|
|||
|
converter.charset = "UTF-8";
|
|||
|
} catch(ex) {
|
|||
|
return manualConvertUnicodeToUTF8(s);
|
|||
|
} // fallback
|
|||
|
var u = converter.ConvertFromUnicode(s);
|
|||
|
var fin = converter.Finish();
|
|||
|
return fin.length > 0 ? u + fin : u;
|
|||
|
}
|
|||
|
|
|||
|
function convertUriToUTF8(uri,charSet)
|
|||
|
{
|
|||
|
if(window.netscape == undefined || charSet == undefined || charSet == "")
|
|||
|
return uri;
|
|||
|
try {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|||
|
var converter = Components.classes["@mozilla.org/intl/utf8converterservice;1"].getService(Components.interfaces.nsIUTF8ConverterService);
|
|||
|
} catch(ex) {
|
|||
|
return uri;
|
|||
|
}
|
|||
|
return converter.convertURISpecToUTF8(uri,charSet);
|
|||
|
}
|
|||
|
|
|||
|
function copyFile(dest,source)
|
|||
|
{
|
|||
|
return config.browser.isIE ? ieCopyFile(dest,source) : false;
|
|||
|
}
|
|||
|
|
|||
|
function saveFile(fileUrl,content)
|
|||
|
{
|
|||
|
var r = mozillaSaveFile(fileUrl,content);
|
|||
|
if(!r)
|
|||
|
r = ieSaveFile(fileUrl,content);
|
|||
|
if(!r)
|
|||
|
r = javaSaveFile(fileUrl,content);
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
function loadFile(fileUrl)
|
|||
|
{
|
|||
|
var r = mozillaLoadFile(fileUrl);
|
|||
|
if((r == null) || (r == false))
|
|||
|
r = ieLoadFile(fileUrl);
|
|||
|
if((r == null) || (r == false))
|
|||
|
r = javaLoadFile(fileUrl);
|
|||
|
return r;
|
|||
|
}
|
|||
|
|
|||
|
function ieCreatePath(path)
|
|||
|
{
|
|||
|
try {
|
|||
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|||
|
} catch(ex) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
var pos = path.lastIndexOf("\\");
|
|||
|
if(pos==-1)
|
|||
|
pos = path.lastIndexOf("/");
|
|||
|
if(pos!=-1)
|
|||
|
path = path.substring(0,pos+1);
|
|||
|
|
|||
|
var scan = [path];
|
|||
|
var parent = fso.GetParentFolderName(path);
|
|||
|
while(parent && !fso.FolderExists(parent)) {
|
|||
|
scan.push(parent);
|
|||
|
parent = fso.GetParentFolderName(parent);
|
|||
|
}
|
|||
|
|
|||
|
for(i=scan.length-1;i>=0;i--) {
|
|||
|
if(!fso.FolderExists(scan[i])) {
|
|||
|
fso.CreateFolder(scan[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
|||
|
function ieSaveFile(filePath,content)
|
|||
|
{
|
|||
|
ieCreatePath(filePath);
|
|||
|
try {
|
|||
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|||
|
} catch(ex) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
var file = fso.OpenTextFile(filePath,2,-1,0);
|
|||
|
file.Write(content);
|
|||
|
file.Close();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
|||
|
function ieLoadFile(filePath)
|
|||
|
{
|
|||
|
try {
|
|||
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|||
|
var file = fso.OpenTextFile(filePath,1);
|
|||
|
var content = file.ReadAll();
|
|||
|
file.Close();
|
|||
|
} catch(ex) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return content;
|
|||
|
}
|
|||
|
|
|||
|
function ieCopyFile(dest,source)
|
|||
|
{
|
|||
|
ieCreatePath(dest);
|
|||
|
try {
|
|||
|
var fso = new ActiveXObject("Scripting.FileSystemObject");
|
|||
|
fso.GetFile(source).Copy(dest);
|
|||
|
} catch(ex) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
// Returns null if it can't do it, false if there's an error, true if it saved OK
|
|||
|
function mozillaSaveFile(filePath,content)
|
|||
|
{
|
|||
|
if(window.Components) {
|
|||
|
try {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|||
|
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
|||
|
file.initWithPath(filePath);
|
|||
|
if(!file.exists())
|
|||
|
file.create(0,0x01B4);// 0x01B4 = 0664
|
|||
|
var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
|
|||
|
out.init(file,0x22,0x04,null);
|
|||
|
out.write(content,content.length);
|
|||
|
out.flush();
|
|||
|
out.close();
|
|||
|
return true;
|
|||
|
} catch(ex) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
// Returns null if it can't do it, false if there's an error, or a string of the content if successful
|
|||
|
function mozillaLoadFile(filePath)
|
|||
|
{
|
|||
|
if(window.Components) {
|
|||
|
try {
|
|||
|
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
|||
|
var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
|
|||
|
file.initWithPath(filePath);
|
|||
|
if(!file.exists())
|
|||
|
return null;
|
|||
|
var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
|
|||
|
inputStream.init(file,0x01,0x04,null);
|
|||
|
var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
|
|||
|
sInputStream.init(inputStream);
|
|||
|
var contents = sInputStream.read(sInputStream.available());
|
|||
|
sInputStream.close();
|
|||
|
inputStream.close();
|
|||
|
return contents;
|
|||
|
} catch(ex) {
|
|||
|
return false;
|
|||
|
}
|
|||
|
}
|
|||
|
return null;
|
|||
|
}
|
|||
|
|
|||
|
function javaUrlToFilename(url)
|
|||
|
{
|
|||
|
var f = "//localhost";
|
|||
|
if(url.indexOf(f) == 0)
|
|||
|
return url.substring(f.length);
|
|||
|
var i = url.indexOf(":");
|
|||
|
return i > 0 ? url.substring(i-1) : url;
|
|||
|
}
|
|||
|
|
|||
|
function javaSaveFile(filePath,content)
|
|||
|
{
|
|||
|
try {
|
|||
|
if(document.applets["TiddlySaver"])
|
|||
|
return document.applets["TiddlySaver"].saveFile(javaUrlToFilename(filePath),"UTF-8",content);
|
|||
|
} catch(ex) {
|
|||
|
}
|
|||
|
try {
|
|||
|
var s = new java.io.PrintStream(new java.io.FileOutputStream(javaUrlToFilename(filePath)));
|
|||
|
s.print(content);
|
|||
|
s.close();
|
|||
|
} catch(ex2) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
function javaLoadFile(filePath)
|
|||
|
{
|
|||
|
try {
|
|||
|
if(document.applets["TiddlySaver"]) {
|
|||
|
var ret = document.applets["TiddlySaver"].loadFile(javaUrlToFilename(filePath),"UTF-8");
|
|||
|
if(!ret)
|
|||
|
return null;
|
|||
|
return String(ret);
|
|||
|
}
|
|||
|
} catch(ex) {
|
|||
|
}
|
|||
|
var content = [];
|
|||
|
try {
|
|||
|
var r = new java.io.BufferedReader(new java.io.FileReader(javaUrlToFilename(filePath)));
|
|||
|
var line;
|
|||
|
while((line = r.readLine()) != null)
|
|||
|
content.push(String(line));
|
|||
|
r.close();
|
|||
|
} catch(ex2) {
|
|||
|
return null;
|
|||
|
}
|
|||
|
return content.join("\n");
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Server adaptor base class
|
|||
|
//--
|
|||
|
|
|||
|
function AdaptorBase()
|
|||
|
{
|
|||
|
this.host = null;
|
|||
|
this.store = null;
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
AdaptorBase.prototype.close = function()
|
|||
|
{
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
AdaptorBase.prototype.fullHostName = function(host)
|
|||
|
{
|
|||
|
if(!host)
|
|||
|
return '';
|
|||
|
host = host.trim();
|
|||
|
if(!host.match(/:\/\//))
|
|||
|
host = 'http://' + host;
|
|||
|
if(host.substr(host.length-1) == '/')
|
|||
|
host = host.substr(0,host.length-1);
|
|||
|
return host;
|
|||
|
};
|
|||
|
|
|||
|
AdaptorBase.minHostName = function(host)
|
|||
|
{
|
|||
|
return host;
|
|||
|
};
|
|||
|
|
|||
|
AdaptorBase.prototype.setContext = function(context,userParams,callback)
|
|||
|
{
|
|||
|
if(!context) context = {};
|
|||
|
context.userParams = userParams;
|
|||
|
if(callback) context.callback = callback;
|
|||
|
context.adaptor = this;
|
|||
|
if(!context.host)
|
|||
|
context.host = this.host;
|
|||
|
context.host = this.fullHostName(context.host);
|
|||
|
if(!context.workspace)
|
|||
|
context.workspace = this.workspace;
|
|||
|
return context;
|
|||
|
};
|
|||
|
|
|||
|
// Open the specified host
|
|||
|
AdaptorBase.prototype.openHost = function(host,context,userParams,callback)
|
|||
|
{
|
|||
|
this.host = host;
|
|||
|
context = this.setContext(context,userParams,callback);
|
|||
|
context.status = true;
|
|||
|
if(callback)
|
|||
|
window.setTimeout(function() {context.callback(context,userParams);},10);
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Open the specified workspace
|
|||
|
AdaptorBase.prototype.openWorkspace = function(workspace,context,userParams,callback)
|
|||
|
{
|
|||
|
this.workspace = workspace;
|
|||
|
context = this.setContext(context,userParams,callback);
|
|||
|
context.status = true;
|
|||
|
if(callback)
|
|||
|
window.setTimeout(function() {callback(context,userParams);},10);
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Server adaptor for talking to static TiddlyWiki files
|
|||
|
//--
|
|||
|
|
|||
|
function FileAdaptor()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
FileAdaptor.prototype = new AdaptorBase();
|
|||
|
|
|||
|
FileAdaptor.serverType = 'file';
|
|||
|
FileAdaptor.serverLabel = 'TiddlyWiki';
|
|||
|
|
|||
|
FileAdaptor.loadTiddlyWikiSuccess = function(context,jqXHR)
|
|||
|
{
|
|||
|
context.status = true;
|
|||
|
context.adaptor.store = new TiddlyWiki();
|
|||
|
if(!context.adaptor.store.importTiddlyWiki(jqXHR.responseText)) {
|
|||
|
context.statusText = config.messages.invalidFileError.format([context.host]);
|
|||
|
context.status = false;
|
|||
|
}
|
|||
|
context.complete(context,context.userParams);
|
|||
|
};
|
|||
|
|
|||
|
FileAdaptor.loadTiddlyWikiError = function(context,jqXHR)
|
|||
|
{
|
|||
|
context.status = false;
|
|||
|
context.statusText = jqXHR.message;
|
|||
|
context.complete(context,context.userParams);
|
|||
|
};
|
|||
|
|
|||
|
// Get the list of workspaces on a given server
|
|||
|
FileAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
|
|||
|
{
|
|||
|
context = this.setContext(context,userParams,callback);
|
|||
|
context.workspaces = [{title:"(default)"}];
|
|||
|
context.status = true;
|
|||
|
if(callback)
|
|||
|
window.setTimeout(function() {callback(context,userParams);},10);
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Gets the list of tiddlers within a given workspace
|
|||
|
FileAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
|
|||
|
{
|
|||
|
context = this.setContext(context,userParams,callback);
|
|||
|
if(!context.filter)
|
|||
|
context.filter = filter;
|
|||
|
context.complete = FileAdaptor.getTiddlerListComplete;
|
|||
|
if(this.store) {
|
|||
|
return context.complete(context,context.userParams);
|
|||
|
}
|
|||
|
var options = {
|
|||
|
type:"GET",
|
|||
|
url:context.host,
|
|||
|
processData:false,
|
|||
|
success:function(data,textStatus,jqXHR) {
|
|||
|
FileAdaptor.loadTiddlyWikiSuccess(context,jqXHR);
|
|||
|
},
|
|||
|
error:function(jqXHR,textStatus,errorThrown) {
|
|||
|
context.xhr = jqXHR;
|
|||
|
FileAdaptor.loadTiddlyWikiError(context,jqXHR);
|
|||
|
}
|
|||
|
};
|
|||
|
return ajaxReq(options);
|
|||
|
};
|
|||
|
|
|||
|
FileAdaptor.getTiddlerListComplete = function(context,userParams)
|
|||
|
{
|
|||
|
if(context.status) {
|
|||
|
if(context.filter) {
|
|||
|
context.tiddlers = context.adaptor.store.filterTiddlers(context.filter);
|
|||
|
} else {
|
|||
|
context.tiddlers = [];
|
|||
|
context.adaptor.store.forEachTiddler(function(title,tiddler) {context.tiddlers.push(tiddler);});
|
|||
|
}
|
|||
|
var i;
|
|||
|
for(i=0; i<context.tiddlers.length; i++) {
|
|||
|
context.tiddlers[i].fields['server.type'] = FileAdaptor.serverType;
|
|||
|
context.tiddlers[i].fields['server.host'] = AdaptorBase.minHostName(context.host);
|
|||
|
context.tiddlers[i].fields['server.page.revision'] = context.tiddlers[i].modified.convertToYYYYMMDDHHMM();
|
|||
|
}
|
|||
|
context.status = true;
|
|||
|
}
|
|||
|
if(context.callback) {
|
|||
|
window.setTimeout(function() {context.callback(context,userParams);},10);
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
FileAdaptor.prototype.generateTiddlerInfo = function(tiddler)
|
|||
|
{
|
|||
|
var info = {};
|
|||
|
info.uri = tiddler.fields['server.host'] + "#" + tiddler.title;
|
|||
|
return info;
|
|||
|
};
|
|||
|
|
|||
|
// Retrieve a tiddler from a given workspace on a given server
|
|||
|
FileAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
|
|||
|
{
|
|||
|
context = this.setContext(context,userParams,callback);
|
|||
|
context.title = title;
|
|||
|
context.complete = FileAdaptor.getTiddlerComplete;
|
|||
|
if(context.adaptor.store) {
|
|||
|
return context.complete(context,context.userParams);
|
|||
|
}
|
|||
|
var options = {
|
|||
|
type:"GET",
|
|||
|
url:context.host,
|
|||
|
processData:false,
|
|||
|
success:function(data,textStatus,jqXHR) {
|
|||
|
FileAdaptor.loadTiddlyWikiSuccess(context,jqXHR);
|
|||
|
},
|
|||
|
error:function(jqXHR,textStatus,errorThrown) {
|
|||
|
FileAdaptor.loadTiddlyWikiError(context,jqXHR);
|
|||
|
}
|
|||
|
};
|
|||
|
return ajaxReq(options);
|
|||
|
};
|
|||
|
|
|||
|
FileAdaptor.getTiddlerComplete = function(context,userParams)
|
|||
|
{
|
|||
|
var t = context.adaptor.store.fetchTiddler(context.title);
|
|||
|
if(t) {
|
|||
|
t.fields['server.type'] = FileAdaptor.serverType;
|
|||
|
t.fields['server.host'] = AdaptorBase.minHostName(context.host);
|
|||
|
t.fields['server.page.revision'] = t.modified.convertToYYYYMMDDHHMM();
|
|||
|
context.tiddler = t;
|
|||
|
context.status = true;
|
|||
|
} else { //# tiddler does not exist in document
|
|||
|
context.status = false;
|
|||
|
}
|
|||
|
if(context.allowSynchronous) {
|
|||
|
context.isSynchronous = true;
|
|||
|
context.callback(context,userParams);
|
|||
|
} else {
|
|||
|
window.setTimeout(function() {context.callback(context,userParams);},10);
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
FileAdaptor.prototype.close = function()
|
|||
|
{
|
|||
|
this.store = null;
|
|||
|
};
|
|||
|
|
|||
|
config.adaptors[FileAdaptor.serverType] = FileAdaptor;
|
|||
|
|
|||
|
config.defaultAdaptor = FileAdaptor.serverType;
|
|||
|
|
|||
|
//--
|
|||
|
//-- HTTP request code
|
|||
|
//--
|
|||
|
|
|||
|
function ajaxReq(args)
|
|||
|
{
|
|||
|
if(window.Components && window.netscape && window.netscape.security && document.location.protocol.indexOf("http") == -1)
|
|||
|
window.netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
|||
|
return jQuery.ajax(args);
|
|||
|
}
|
|||
|
|
|||
|
function httpReq(type,url,callback,params,headers,data,contentType,username,password,allowCache)
|
|||
|
{
|
|||
|
var httpSuccess = function(xhr) {
|
|||
|
try {
|
|||
|
// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
|
|||
|
return (!xhr.status && location.protocol === "file:") ||
|
|||
|
(xhr.status >= 200 && xhr.status < 300) ||
|
|||
|
xhr.status === 304 || xhr.status === 1223;
|
|||
|
} catch(e) {}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
var options = {
|
|||
|
type:type,
|
|||
|
url:url,
|
|||
|
processData:false,
|
|||
|
data:data,
|
|||
|
cache:!!allowCache,
|
|||
|
beforeSend: function(xhr) {
|
|||
|
var i;
|
|||
|
for(i in headers)
|
|||
|
xhr.setRequestHeader(i,headers[i]);
|
|||
|
xhr.setRequestHeader("X-Requested-With", "TiddlyWiki " + formatVersion());
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
if(callback) {
|
|||
|
options.complete = function(xhr,textStatus) {
|
|||
|
if(httpSuccess(xhr))
|
|||
|
callback(true,params,xhr.responseText,url,xhr);
|
|||
|
else
|
|||
|
callback(false,params,null,url,xhr);
|
|||
|
};
|
|||
|
}
|
|||
|
if(contentType)
|
|||
|
options.contentType = contentType;
|
|||
|
if(username)
|
|||
|
options.username = username;
|
|||
|
if(password)
|
|||
|
options.password = password;
|
|||
|
if(window.Components && window.netscape && window.netscape.security && document.location.protocol.indexOf("http") == -1)
|
|||
|
window.netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
|||
|
return jQuery.ajax(options);
|
|||
|
}
|
|||
|
//--
|
|||
|
//-- TiddlyWiki-specific utility functions
|
|||
|
//--
|
|||
|
|
|||
|
// Returns TiddlyWiki version string
|
|||
|
function formatVersion(v)
|
|||
|
{
|
|||
|
v = v || version;
|
|||
|
return v.major + "." + v.minor + "." + v.revision +
|
|||
|
(v.alpha ? " (alpha " + v.alpha + ")" : "") +
|
|||
|
(v.beta ? " (beta " + v.beta + ")" : "");
|
|||
|
}
|
|||
|
|
|||
|
function compareVersions(v1,v2)
|
|||
|
{
|
|||
|
var x1,x2,i,a = ["major","minor","revision"];
|
|||
|
for(i = 0; i<a.length; i++) {
|
|||
|
x1 = v1[a[i]] || 0;
|
|||
|
x2 = v2[a[i]] || 0;
|
|||
|
if(x1<x2)
|
|||
|
return 1;
|
|||
|
if(x1>x2)
|
|||
|
return -1;
|
|||
|
}
|
|||
|
x1 = v1.beta || 9999;
|
|||
|
x2 = v2.beta || 9999;
|
|||
|
if(x1<x2)
|
|||
|
return 1;
|
|||
|
return x1 > x2 ? -1 : 0;
|
|||
|
}
|
|||
|
|
|||
|
function merge(dst,src,preserveExisting)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i in src) {
|
|||
|
if(!preserveExisting || dst[i] === undefined)
|
|||
|
dst[i] = src[i];
|
|||
|
}
|
|||
|
return dst;
|
|||
|
}
|
|||
|
|
|||
|
// Resolve the target object of an event
|
|||
|
function resolveTarget(e)
|
|||
|
{
|
|||
|
var obj;
|
|||
|
if(e.target)
|
|||
|
obj = e.target;
|
|||
|
else if(e.srcElement)
|
|||
|
obj = e.srcElement;
|
|||
|
if(obj.nodeType == 3) // defeat Safari bug
|
|||
|
obj = obj.parentNode;
|
|||
|
return obj;
|
|||
|
}
|
|||
|
|
|||
|
// Returns a string containing the description of an exception, optionally prepended by a message
|
|||
|
function exceptionText(e,message)
|
|||
|
{
|
|||
|
var s = e.description || e.toString();
|
|||
|
return message ? "%0:\n%1".format([message,s]) : s;
|
|||
|
}
|
|||
|
|
|||
|
// Displays an alert of an exception description with optional message
|
|||
|
function showException(e,message)
|
|||
|
{
|
|||
|
alert(exceptionText(e,message));
|
|||
|
}
|
|||
|
|
|||
|
function alertAndThrow(m)
|
|||
|
{
|
|||
|
alert(m);
|
|||
|
throw(m);
|
|||
|
}
|
|||
|
|
|||
|
function glyph(name)
|
|||
|
{
|
|||
|
var g = config.glyphs;
|
|||
|
var b = g.currBrowser;
|
|||
|
if(b == null) {
|
|||
|
b = 0;
|
|||
|
while(b < g.browsers.length-1 && !g.browsers[b]())
|
|||
|
b++;
|
|||
|
g.currBrowser = b;
|
|||
|
}
|
|||
|
if(!g.codes[name])
|
|||
|
return "";
|
|||
|
return g.codes[name][b];
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyText(parent,text)
|
|||
|
{
|
|||
|
return parent.appendChild(document.createTextNode(text));
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyCheckbox(parent,caption,checked,onChange)
|
|||
|
{
|
|||
|
var cb = document.createElement("input");
|
|||
|
cb.setAttribute("type","checkbox");
|
|||
|
cb.onclick = onChange;
|
|||
|
parent.appendChild(cb);
|
|||
|
cb.checked = checked;
|
|||
|
cb.className = "chkOptionInput";
|
|||
|
if(caption)
|
|||
|
wikify(caption,parent);
|
|||
|
return cb;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyElement(parent,element,id,className,text,attribs)
|
|||
|
{
|
|||
|
var n,e = document.createElement(element);
|
|||
|
if(className != null)
|
|||
|
e.className = className;
|
|||
|
if(id != null)
|
|||
|
e.setAttribute("id",id);
|
|||
|
if(text != null)
|
|||
|
e.appendChild(document.createTextNode(text));
|
|||
|
if(attribs) {
|
|||
|
for(n in attribs) {
|
|||
|
e.setAttribute(n,attribs[n]);
|
|||
|
}
|
|||
|
}
|
|||
|
if(parent != null)
|
|||
|
parent.appendChild(e);
|
|||
|
return e;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyButton(parent,text,tooltip,action,className,id,accessKey,attribs)
|
|||
|
{
|
|||
|
var i,btn = document.createElement("a");
|
|||
|
btn.setAttribute("href","javascript:;");
|
|||
|
if(action) {
|
|||
|
btn.onclick = action;
|
|||
|
}
|
|||
|
if(tooltip)
|
|||
|
btn.setAttribute("title",tooltip);
|
|||
|
if(text)
|
|||
|
btn.appendChild(document.createTextNode(text));
|
|||
|
btn.className = className || "button";
|
|||
|
if(id)
|
|||
|
btn.id = id;
|
|||
|
if(attribs) {
|
|||
|
for(i in attribs) {
|
|||
|
btn.setAttribute(i,attribs[i]);
|
|||
|
}
|
|||
|
}
|
|||
|
if(parent)
|
|||
|
parent.appendChild(btn);
|
|||
|
if(accessKey)
|
|||
|
btn.setAttribute("accessKey",accessKey);
|
|||
|
return btn;
|
|||
|
}
|
|||
|
|
|||
|
function createExternalLink(place,url,label)
|
|||
|
{
|
|||
|
var link = document.createElement("a");
|
|||
|
link.className = "externalLink";
|
|||
|
link.href = url;
|
|||
|
var f = config.messages.externalLinkTooltip;
|
|||
|
link.title = f ? f.format([url]) : url;
|
|||
|
if(config.options.chkOpenInNewWindow)
|
|||
|
link.target = "_blank";
|
|||
|
place.appendChild(link);
|
|||
|
if(label)
|
|||
|
createTiddlyText(link, label);
|
|||
|
return link;
|
|||
|
}
|
|||
|
|
|||
|
function getTiddlyLinkInfo(title,currClasses)
|
|||
|
{
|
|||
|
var classes = currClasses ? currClasses.split(" ") : [];
|
|||
|
classes.pushUnique("tiddlyLink");
|
|||
|
var tiddler = store.fetchTiddler(title);
|
|||
|
var subTitle;
|
|||
|
if(tiddler) {
|
|||
|
subTitle = tiddler.getSubtitle();
|
|||
|
classes.pushUnique("tiddlyLinkExisting");
|
|||
|
classes.remove("tiddlyLinkNonExisting");
|
|||
|
classes.remove("shadow");
|
|||
|
} else {
|
|||
|
var f;
|
|||
|
classes.remove("tiddlyLinkExisting");
|
|||
|
classes.pushUnique("tiddlyLinkNonExisting");
|
|||
|
if(store.isShadowTiddler(title)) {
|
|||
|
f = config.messages.shadowedTiddlerToolTip;
|
|||
|
classes.pushUnique("shadow");
|
|||
|
} else {
|
|||
|
f = config.messages.undefinedTiddlerToolTip;
|
|||
|
classes.remove("shadow");
|
|||
|
}
|
|||
|
subTitle = f ? f.format([title]) : "";
|
|||
|
}
|
|||
|
if(typeof config.annotations[title]=="string")
|
|||
|
subTitle = config.annotations[title];
|
|||
|
return {classes: classes.join(" "),subTitle: subTitle};
|
|||
|
}
|
|||
|
|
|||
|
// Event handler for clicking on a tiddly link
|
|||
|
function onClickTiddlerLink(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var target = resolveTarget(e);
|
|||
|
var link = target;
|
|||
|
var title = null;
|
|||
|
var fields = null;
|
|||
|
var noToggle = null;
|
|||
|
do {
|
|||
|
title = link.getAttribute("tiddlyLink");
|
|||
|
fields = link.getAttribute("tiddlyFields");
|
|||
|
noToggle = link.getAttribute("noToggle");
|
|||
|
link = link.parentNode;
|
|||
|
} while(title == null && link != null);
|
|||
|
if(!store.isShadowTiddler(title)) {
|
|||
|
var f = fields ? fields.decodeHashMap() : {};
|
|||
|
fields = String.encodeHashMap(merge(f,config.defaultCustomFields,true));
|
|||
|
}
|
|||
|
if(title) {
|
|||
|
var toggling = e.metaKey || e.ctrlKey;
|
|||
|
if(config.options.chkToggleLinks)
|
|||
|
toggling = !toggling;
|
|||
|
if(noToggle)
|
|||
|
toggling = false;
|
|||
|
if(store.getTiddler(title))
|
|||
|
fields = null;
|
|||
|
story.displayTiddler(target,title,null,true,null,fields,toggling);
|
|||
|
}
|
|||
|
clearMessage();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyLink(place,title,includeText,className,isStatic,linkedFromTiddler,noToggle)
|
|||
|
{
|
|||
|
var title = jQuery.trim(title);
|
|||
|
var text = includeText ? title : null;
|
|||
|
var i = getTiddlyLinkInfo(title,className);
|
|||
|
var btn = isStatic ? createExternalLink(place,store.getTiddlerText("SiteUrl",null) + "#" + title) : createTiddlyButton(place,text,i.subTitle,onClickTiddlerLink,i.classes);
|
|||
|
if(isStatic)
|
|||
|
btn.className += ' ' + className;
|
|||
|
btn.setAttribute("refresh","link");
|
|||
|
btn.setAttribute("tiddlyLink",title);
|
|||
|
if(noToggle)
|
|||
|
btn.setAttribute("noToggle","true");
|
|||
|
if(linkedFromTiddler) {
|
|||
|
var fields = linkedFromTiddler.getInheritedFields();
|
|||
|
if(fields)
|
|||
|
btn.setAttribute("tiddlyFields",fields);
|
|||
|
}
|
|||
|
return btn;
|
|||
|
}
|
|||
|
|
|||
|
function refreshTiddlyLink(e,title)
|
|||
|
{
|
|||
|
var i = getTiddlyLinkInfo(title,e.className);
|
|||
|
e.className = i.classes;
|
|||
|
e.title = i.subTitle;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyDropDown(place,onchange,options,defaultValue)
|
|||
|
{
|
|||
|
var sel = createTiddlyElement(place,"select");
|
|||
|
sel.onchange = onchange;
|
|||
|
var t;
|
|||
|
for(t=0; t<options.length; t++) {
|
|||
|
var e = createTiddlyElement(sel,"option",null,null,options[t].caption);
|
|||
|
e.value = options[t].name;
|
|||
|
if(options[t].name == defaultValue)
|
|||
|
e.selected = true;
|
|||
|
}
|
|||
|
return sel;
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- TiddlyWiki-specific popup utility functions
|
|||
|
//--
|
|||
|
|
|||
|
// Event handler for 'open all' on a tiddler popup
|
|||
|
function onClickTagOpenAll(ev)
|
|||
|
{
|
|||
|
var tiddlers = store.getTaggedTiddlers(this.getAttribute("tag"));
|
|||
|
var sortby = this.getAttribute("sortby");
|
|||
|
if(sortby&&sortby.length) {
|
|||
|
store.sortTiddlers(tiddlers,sortby);
|
|||
|
}
|
|||
|
story.displayTiddlers(this,tiddlers);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Event handler for clicking on a tiddler tag
|
|||
|
function onClickTag(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var popup = Popup.create(this);
|
|||
|
jQuery(popup).addClass("taggedTiddlerList");
|
|||
|
var tag = this.getAttribute("tag");
|
|||
|
var title = this.getAttribute("tiddler");
|
|||
|
if(popup && tag) {
|
|||
|
var tagged = tag.indexOf("[")==-1 ? store.getTaggedTiddlers(tag) : store.filterTiddlers(tag);
|
|||
|
var sortby = this.getAttribute("sortby");
|
|||
|
if(sortby&&sortby.length) {
|
|||
|
store.sortTiddlers(tagged,sortby);
|
|||
|
}
|
|||
|
var titles = [];
|
|||
|
var r;
|
|||
|
for(r=0;r<tagged.length;r++) {
|
|||
|
if(tagged[r].title != title)
|
|||
|
titles.push(tagged[r].title);
|
|||
|
}
|
|||
|
var lingo = config.views.wikified.tag;
|
|||
|
if(titles.length > 0) {
|
|||
|
var openAll = createTiddlyButton(createTiddlyElement(popup,"li"),lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
|
|||
|
openAll.setAttribute("tag",tag);
|
|||
|
openAll.setAttribute("sortby",sortby);
|
|||
|
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
|||
|
for(r=0; r<titles.length; r++) {
|
|||
|
createTiddlyLink(createTiddlyElement(popup,"li"),titles[r],true);
|
|||
|
}
|
|||
|
} else {
|
|||
|
createTiddlyElement(popup,"li",null,"disabled",lingo.popupNone.format([tag]));
|
|||
|
}
|
|||
|
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
|
|||
|
var h = createTiddlyLink(createTiddlyElement(popup,"li"),tag,false);
|
|||
|
createTiddlyText(h,lingo.openTag.format([tag]));
|
|||
|
}
|
|||
|
Popup.show();
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Create a button for a tag with a popup listing all the tiddlers that it tags
|
|||
|
function createTagButton(place,tag,excludeTiddler,title,tooltip)
|
|||
|
{
|
|||
|
var btn = createTiddlyButton(place,title||tag,(tooltip||config.views.wikified.tag.tooltip).format([tag]),onClickTag);
|
|||
|
btn.setAttribute("tag",tag);
|
|||
|
if(excludeTiddler)
|
|||
|
btn.setAttribute("tiddler",excludeTiddler);
|
|||
|
return btn;
|
|||
|
}
|
|||
|
|
|||
|
function onClickTiddlyPopup(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var tiddler = this.tiddler;
|
|||
|
if(tiddler.text) {
|
|||
|
var popup = Popup.create(this,"div","popupTiddler");
|
|||
|
wikify(tiddler.text,popup,null,tiddler);
|
|||
|
Popup.show();
|
|||
|
}
|
|||
|
if(e) e.cancelBubble = true;
|
|||
|
if(e && e.stopPropagation) e.stopPropagation();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyPopup(place,caption,tooltip,tiddler)
|
|||
|
{
|
|||
|
if(tiddler.text) {
|
|||
|
createTiddlyLink(place,caption,true);
|
|||
|
var btn = createTiddlyButton(place,glyph("downArrow"),tooltip,onClickTiddlyPopup,"tiddlerPopupButton");
|
|||
|
btn.tiddler = tiddler;
|
|||
|
} else {
|
|||
|
createTiddlyText(place,caption);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function onClickError(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
var popup = Popup.create(this);
|
|||
|
var lines = this.getAttribute("errorText").split("\n");
|
|||
|
var t;
|
|||
|
for(t=0; t<lines.length; t++)
|
|||
|
createTiddlyElement(popup,"li",null,null,lines[t]);
|
|||
|
Popup.show();
|
|||
|
e.cancelBubble = true;
|
|||
|
if(e.stopPropagation) e.stopPropagation();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
function createTiddlyError(place,title,text)
|
|||
|
{
|
|||
|
var btn = createTiddlyButton(place,title,null,onClickError,"errorButton");
|
|||
|
if(text) btn.setAttribute("errorText",text);
|
|||
|
}
|
|||
|
//-
|
|||
|
//- Animation engine
|
|||
|
//-
|
|||
|
|
|||
|
function Animator()
|
|||
|
{
|
|||
|
this.running = 0; // Incremented at start of each animation, decremented afterwards. If zero, the interval timer is disabled
|
|||
|
this.timerID = 0; // ID of the timer used for animating
|
|||
|
this.animations = []; // List of animations in progress
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
// Start animation engine
|
|||
|
Animator.prototype.startAnimating = function() //# Variable number of arguments
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=0; t<arguments.length; t++)
|
|||
|
this.animations.push(arguments[t]);
|
|||
|
if(this.running == 0) {
|
|||
|
var me = this;
|
|||
|
this.timerID = window.setInterval(function() {me.doAnimate(me);},10);
|
|||
|
}
|
|||
|
this.running += arguments.length;
|
|||
|
};
|
|||
|
|
|||
|
// Perform an animation engine tick, calling each of the known animation modules
|
|||
|
Animator.prototype.doAnimate = function(me)
|
|||
|
{
|
|||
|
var a = 0;
|
|||
|
while(a < me.animations.length) {
|
|||
|
var animation = me.animations[a];
|
|||
|
if(animation.tick()) {
|
|||
|
a++;
|
|||
|
} else {
|
|||
|
me.animations.splice(a,1);
|
|||
|
if(--me.running == 0)
|
|||
|
window.clearInterval(me.timerID);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Animator.slowInSlowOut = function(progress)
|
|||
|
{
|
|||
|
return(1-((Math.cos(progress * Math.PI)+1)/2));
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Morpher animation
|
|||
|
//--
|
|||
|
|
|||
|
// Animate a set of properties of an element
|
|||
|
function Morpher(element,duration,properties,callback)
|
|||
|
{
|
|||
|
this.element = element;
|
|||
|
this.duration = duration;
|
|||
|
this.properties = properties;
|
|||
|
this.startTime = new Date();
|
|||
|
this.endTime = Number(this.startTime) + duration;
|
|||
|
this.callback = callback;
|
|||
|
this.tick();
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
Morpher.prototype.assignStyle = function(element,style,value)
|
|||
|
{
|
|||
|
switch(style) {
|
|||
|
case "-tw-vertScroll":
|
|||
|
window.scrollTo(findScrollX(),value);
|
|||
|
break;
|
|||
|
case "-tw-horizScroll":
|
|||
|
window.scrollTo(value,findScrollY());
|
|||
|
break;
|
|||
|
default:
|
|||
|
element.style[style] = value;
|
|||
|
break;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Morpher.prototype.stop = function()
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=0; t<this.properties.length; t++) {
|
|||
|
var p = this.properties[t];
|
|||
|
if(p.atEnd !== undefined) {
|
|||
|
this.assignStyle(this.element,p.style,p.atEnd);
|
|||
|
}
|
|||
|
}
|
|||
|
if(this.callback)
|
|||
|
this.callback(this.element,this.properties);
|
|||
|
};
|
|||
|
|
|||
|
Morpher.prototype.tick = function()
|
|||
|
{
|
|||
|
var currTime = Number(new Date());
|
|||
|
var t,progress = Animator.slowInSlowOut(Math.min(1,(currTime-this.startTime)/this.duration));
|
|||
|
for(t=0; t<this.properties.length; t++) {
|
|||
|
var p = this.properties[t];
|
|||
|
if(p.start !== undefined && p.end !== undefined) {
|
|||
|
var template = p.template || "%0";
|
|||
|
switch(p.format) {
|
|||
|
case undefined:
|
|||
|
case "style":
|
|||
|
var v = p.start + (p.end-p.start) * progress;
|
|||
|
this.assignStyle(this.element,p.style,template.format([v]));
|
|||
|
break;
|
|||
|
case "color":
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
if(currTime >= this.endTime) {
|
|||
|
this.stop();
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Zoomer animation
|
|||
|
//--
|
|||
|
|
|||
|
function Zoomer(text,startElement,targetElement,unused)
|
|||
|
{
|
|||
|
var e = createTiddlyElement(document.body,"div",null,"zoomer");
|
|||
|
createTiddlyElement(e,"div",null,null,text);
|
|||
|
var winWidth = findWindowWidth();
|
|||
|
var winHeight = findWindowHeight();
|
|||
|
var p = [
|
|||
|
{style: 'left', start: findPosX(startElement), end: findPosX(targetElement), template: '%0px'},
|
|||
|
{style: 'top', start: findPosY(startElement), end: findPosY(targetElement), template: '%0px'},
|
|||
|
{style: 'width', start: Math.min(startElement.scrollWidth,winWidth), end: Math.min(targetElement.scrollWidth,winWidth), template: '%0px', atEnd: 'auto'},
|
|||
|
{style: 'height', start: Math.min(startElement.scrollHeight,winHeight), end: Math.min(targetElement.scrollHeight,winHeight), template: '%0px', atEnd: 'auto'},
|
|||
|
{style: 'fontSize', start: 8, end: 24, template: '%0pt'}
|
|||
|
];
|
|||
|
var c = function(element,properties) {jQuery(element).remove();};
|
|||
|
return new Morpher(e,config.animDuration,p,c);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Scroller animation
|
|||
|
//--
|
|||
|
|
|||
|
function Scroller(targetElement)
|
|||
|
{
|
|||
|
var p = [{style: '-tw-vertScroll', start: findScrollY(), end: ensureVisible(targetElement)}];
|
|||
|
return new Morpher(targetElement,config.animDuration,p);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Slider animation
|
|||
|
//--
|
|||
|
|
|||
|
// deleteMode - "none", "all" [delete target element and it's children], [only] "children" [but not the target element]
|
|||
|
function Slider(element,opening,unused,deleteMode)
|
|||
|
{
|
|||
|
element.style.overflow = 'hidden';
|
|||
|
if(opening)
|
|||
|
element.style.height = '0px'; // Resolves a Firefox flashing bug
|
|||
|
element.style.display = 'block';
|
|||
|
var height = element.scrollHeight;
|
|||
|
var p = [];
|
|||
|
var c = null;
|
|||
|
if(opening) {
|
|||
|
p.push({style: 'height', start: 0, end: height, template: '%0px', atEnd: 'auto'});
|
|||
|
p.push({style: 'opacity', start: 0, end: 1, template: '%0'});
|
|||
|
p.push({style: 'filter', start: 0, end: 100, template: 'alpha(opacity:%0)'});
|
|||
|
} else {
|
|||
|
p.push({style: 'height', start: height, end: 0, template: '%0px'});
|
|||
|
p.push({style: 'display', atEnd: 'none'});
|
|||
|
p.push({style: 'opacity', start: 1, end: 0, template: '%0'});
|
|||
|
p.push({style: 'filter', start: 100, end: 0, template: 'alpha(opacity:%0)'});
|
|||
|
switch(deleteMode) {
|
|||
|
case "all":
|
|||
|
c = function(element,properties) {jQuery(element).remove();};
|
|||
|
break;
|
|||
|
case "children":
|
|||
|
c = function(element,properties) {jQuery(element).empty();};
|
|||
|
break;
|
|||
|
}
|
|||
|
}
|
|||
|
return new Morpher(element,config.animDuration,p,c);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Popup menu
|
|||
|
//--
|
|||
|
|
|||
|
var Popup = {
|
|||
|
stack: [] // Array of objects with members root: and popup:
|
|||
|
};
|
|||
|
|
|||
|
Popup.create = function(root,elem,className)
|
|||
|
{
|
|||
|
var stackPosition = this.find(root,"popup");
|
|||
|
Popup.remove(stackPosition+1);
|
|||
|
var popup = createTiddlyElement(document.body,elem || "ol","popup",className || "popup");
|
|||
|
popup.stackPosition = stackPosition;
|
|||
|
Popup.stack.push({root: root, popup: popup});
|
|||
|
return popup;
|
|||
|
};
|
|||
|
|
|||
|
Popup.onDocumentClick = function(ev)
|
|||
|
{
|
|||
|
var e = ev || window.event;
|
|||
|
if(e.eventPhase == undefined)
|
|||
|
Popup.remove();
|
|||
|
else if(e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET)
|
|||
|
Popup.remove();
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
Popup.show = function(valign,halign,offset)
|
|||
|
{
|
|||
|
var curr = Popup.stack[Popup.stack.length-1];
|
|||
|
this.place(curr.root,curr.popup,valign,halign,offset);
|
|||
|
jQuery(curr.root).addClass("highlight");
|
|||
|
if(config.options.chkAnimate && anim && typeof Scroller == "function")
|
|||
|
anim.startAnimating(new Scroller(curr.popup));
|
|||
|
else
|
|||
|
window.scrollTo(0,ensureVisible(curr.popup));
|
|||
|
};
|
|||
|
|
|||
|
Popup.place = function(root,popup,valign,halign,offset)
|
|||
|
{
|
|||
|
if(!offset)
|
|||
|
offset = {x:0,y:0};
|
|||
|
if(popup.stackPosition >= 0 && !valign && !halign) {
|
|||
|
offset.x = offset.x + root.offsetWidth;
|
|||
|
} else {
|
|||
|
offset.x = (halign == "right") ? offset.x + root.offsetWidth : offset.x;
|
|||
|
offset.y = (valign == "top") ? offset.y : offset.y + root.offsetHeight;
|
|||
|
}
|
|||
|
var rootLeft = findPosX(root);
|
|||
|
var rootTop = findPosY(root);
|
|||
|
var popupLeft = rootLeft + offset.x;
|
|||
|
var popupTop = rootTop + offset.y;
|
|||
|
var winWidth = findWindowWidth();
|
|||
|
if(popup.offsetWidth > winWidth*0.75)
|
|||
|
popup.style.width = winWidth*0.75 + "px";
|
|||
|
var popupWidth = popup.offsetWidth;
|
|||
|
var scrollWidth = winWidth - document.body.offsetWidth;
|
|||
|
if(popupLeft + popupWidth > winWidth - scrollWidth - 1) {
|
|||
|
if(halign == "right")
|
|||
|
popupLeft = popupLeft - root.offsetWidth - popupWidth;
|
|||
|
else
|
|||
|
popupLeft = winWidth - popupWidth - scrollWidth - 1;
|
|||
|
}
|
|||
|
popup.style.left = popupLeft + "px";
|
|||
|
popup.style.top = popupTop + "px";
|
|||
|
popup.style.display = "block";
|
|||
|
};
|
|||
|
|
|||
|
Popup.find = function(e)
|
|||
|
{
|
|||
|
var t,pos = -1;
|
|||
|
for(t=this.stack.length-1; t>=0; t--) {
|
|||
|
if(isDescendant(e,this.stack[t].popup))
|
|||
|
pos = t;
|
|||
|
}
|
|||
|
return pos;
|
|||
|
};
|
|||
|
|
|||
|
Popup.remove = function(pos)
|
|||
|
{
|
|||
|
if(!pos) pos = 0;
|
|||
|
if(Popup.stack.length > pos) {
|
|||
|
Popup.removeFrom(pos);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Popup.removeFrom = function(from)
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=Popup.stack.length-1; t>=from; t--) {
|
|||
|
var p = Popup.stack[t];
|
|||
|
jQuery(p.root).removeClass("highlight");
|
|||
|
jQuery(p.popup).remove();
|
|||
|
}
|
|||
|
Popup.stack = Popup.stack.slice(0,from);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Wizard support
|
|||
|
//--
|
|||
|
|
|||
|
function Wizard(elem)
|
|||
|
{
|
|||
|
if(elem) {
|
|||
|
this.formElem = findRelated(elem,"wizard","className");
|
|||
|
this.bodyElem = findRelated(this.formElem.firstChild,"wizardBody","className","nextSibling");
|
|||
|
this.footElem = findRelated(this.formElem.firstChild,"wizardFooter","className","nextSibling");
|
|||
|
} else {
|
|||
|
this.formElem = null;
|
|||
|
this.bodyElem = null;
|
|||
|
this.footElem = null;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
Wizard.prototype.setValue = function(name,value)
|
|||
|
{
|
|||
|
jQuery(this.formElem).data(name, value);
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.getValue = function(name)
|
|||
|
{
|
|||
|
return this.formElem ? jQuery(this.formElem).data(name) : null;
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.createWizard = function(place,title)
|
|||
|
{
|
|||
|
this.formElem = createTiddlyElement(place,"form",null,"wizard");
|
|||
|
createTiddlyElement(this.formElem,"h1",null,null,title);
|
|||
|
this.bodyElem = createTiddlyElement(this.formElem,"div",null,"wizardBody");
|
|||
|
this.footElem = createTiddlyElement(this.formElem,"div",null,"wizardFooter");
|
|||
|
return this.formElem;
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.clear = function()
|
|||
|
{
|
|||
|
jQuery(this.bodyElem).empty();
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.setButtons = function(buttonInfo,status)
|
|||
|
{
|
|||
|
jQuery(this.footElem).empty();
|
|||
|
var t;
|
|||
|
for(t=0; t<buttonInfo.length; t++) {
|
|||
|
createTiddlyButton(this.footElem,buttonInfo[t].caption,buttonInfo[t].tooltip,buttonInfo[t].onClick);
|
|||
|
insertSpacer(this.footElem);
|
|||
|
}
|
|||
|
if(typeof status == "string") {
|
|||
|
createTiddlyElement(this.footElem,"span",null,"status",status);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.addStep = function(stepTitle,html)
|
|||
|
{
|
|||
|
jQuery(this.bodyElem).empty();
|
|||
|
var w = createTiddlyElement(this.bodyElem,"div");
|
|||
|
createTiddlyElement(w,"h2",null,null,stepTitle);
|
|||
|
var step = createTiddlyElement(w,"div",null,"wizardStep");
|
|||
|
step.innerHTML = html;
|
|||
|
applyHtmlMacros(step,tiddler);
|
|||
|
};
|
|||
|
|
|||
|
Wizard.prototype.getElement = function(name)
|
|||
|
{
|
|||
|
return this.formElem.elements[name];
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- ListView gadget
|
|||
|
//--
|
|||
|
|
|||
|
var ListView = {};
|
|||
|
|
|||
|
// Create a listview
|
|||
|
ListView.create = function(place,listObject,listTemplate,callback,className)
|
|||
|
{
|
|||
|
var table = createTiddlyElement(place,"table",null,className || "listView twtable");
|
|||
|
var thead = createTiddlyElement(table,"thead");
|
|||
|
var t,r = createTiddlyElement(thead,"tr");
|
|||
|
for(t=0; t<listTemplate.columns.length; t++) {
|
|||
|
var columnTemplate = listTemplate.columns[t];
|
|||
|
var c = createTiddlyElement(r,"th");
|
|||
|
var colType = ListView.columnTypes[columnTemplate.type];
|
|||
|
if(colType && colType.createHeader) {
|
|||
|
colType.createHeader(c,columnTemplate,t);
|
|||
|
if(columnTemplate.className)
|
|||
|
jQuery(c).addClass(columnTemplate.className);
|
|||
|
}
|
|||
|
}
|
|||
|
var rc,tbody = createTiddlyElement(table,"tbody");
|
|||
|
for(rc=0; rc<listObject.length; rc++) {
|
|||
|
var rowObject = listObject[rc];
|
|||
|
r = createTiddlyElement(tbody,"tr");
|
|||
|
for(c=0; c<listTemplate.rowClasses.length; c++) {
|
|||
|
if(rowObject[listTemplate.rowClasses[c].field])
|
|||
|
jQuery(r).addClass(listTemplate.rowClasses[c].className);
|
|||
|
}
|
|||
|
rowObject.rowElement = r;
|
|||
|
rowObject.colElements = {};
|
|||
|
var cc;
|
|||
|
for(cc=0; cc<listTemplate.columns.length; cc++) {
|
|||
|
c = createTiddlyElement(r,"td");
|
|||
|
columnTemplate = listTemplate.columns[cc];
|
|||
|
var field = columnTemplate.field;
|
|||
|
colType = ListView.columnTypes[columnTemplate.type];
|
|||
|
if(colType && colType.createItem) {
|
|||
|
colType.createItem(c,rowObject,field,columnTemplate,cc,rc);
|
|||
|
if(columnTemplate.className)
|
|||
|
jQuery(c).addClass(columnTemplate.className);
|
|||
|
}
|
|||
|
rowObject.colElements[field] = c;
|
|||
|
}
|
|||
|
}
|
|||
|
if(callback && listTemplate.actions)
|
|||
|
createTiddlyDropDown(place,ListView.getCommandHandler(callback),listTemplate.actions);
|
|||
|
if(callback && listTemplate.buttons) {
|
|||
|
for(t=0; t<listTemplate.buttons.length; t++) {
|
|||
|
var a = listTemplate.buttons[t];
|
|||
|
if(a && a.name != "")
|
|||
|
createTiddlyButton(place,a.caption,null,ListView.getCommandHandler(callback,a.name,a.allowEmptySelection));
|
|||
|
}
|
|||
|
}
|
|||
|
return table;
|
|||
|
};
|
|||
|
|
|||
|
ListView.getCommandHandler = function(callback,name,allowEmptySelection)
|
|||
|
{
|
|||
|
return function(e) {
|
|||
|
var view = findRelated(this,"TABLE",null,"previousSibling");
|
|||
|
var tiddlers = [];
|
|||
|
ListView.forEachSelector(view,function(e,rowName) {
|
|||
|
if(e.checked)
|
|||
|
tiddlers.push(rowName);
|
|||
|
});
|
|||
|
if(tiddlers.length == 0 && !allowEmptySelection) {
|
|||
|
alert(config.messages.nothingSelected);
|
|||
|
} else {
|
|||
|
if(this.nodeName.toLowerCase() == "select") {
|
|||
|
callback(view,this.value,tiddlers);
|
|||
|
this.selectedIndex = 0;
|
|||
|
} else {
|
|||
|
callback(view,name,tiddlers);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
};
|
|||
|
|
|||
|
// Invoke a callback for each selector checkbox in the listview
|
|||
|
ListView.forEachSelector = function(view,callback)
|
|||
|
{
|
|||
|
var checkboxes = view.getElementsByTagName("input");
|
|||
|
var t,hadOne = false;
|
|||
|
for(t=0; t<checkboxes.length; t++) {
|
|||
|
var cb = checkboxes[t];
|
|||
|
if(cb.getAttribute("type") == "checkbox") {
|
|||
|
var rn = cb.getAttribute("rowName");
|
|||
|
if(rn) {
|
|||
|
callback(cb,rn);
|
|||
|
hadOne = true;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
return hadOne;
|
|||
|
};
|
|||
|
|
|||
|
ListView.getSelectedRows = function(view)
|
|||
|
{
|
|||
|
var rowNames = [];
|
|||
|
ListView.forEachSelector(view,function(e,rowName) {
|
|||
|
if(e.checked)
|
|||
|
rowNames.push(rowName);
|
|||
|
});
|
|||
|
return rowNames;
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes = {};
|
|||
|
|
|||
|
ListView.columnTypes.String = {
|
|||
|
createHeader: function(place,columnTemplate,col)
|
|||
|
{
|
|||
|
createTiddlyText(place,columnTemplate.title);
|
|||
|
},
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined)
|
|||
|
createTiddlyText(place,v);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.WikiText = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined)
|
|||
|
wikify(v,place,null,null);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Tiddler = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined && v.title)
|
|||
|
createTiddlyPopup(place,v.title,config.messages.listView.tiddlerTooltip,v);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Size = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var msg = config.messages.sizeTemplates;
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined) {
|
|||
|
var t = 0;
|
|||
|
while(t<msg.length-1 && v<msg[t].unit)
|
|||
|
t++;
|
|||
|
createTiddlyText(place,msg[t].template.format([Math.round(v/msg[t].unit)]));
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Link = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
var c = columnTemplate.text;
|
|||
|
if(v != undefined)
|
|||
|
createExternalLink(place,v,c || v);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Date = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined)
|
|||
|
createTiddlyText(place,v.formatString(columnTemplate.dateFormat));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.StringList = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined) {
|
|||
|
var t;
|
|||
|
for(t=0; t<v.length; t++) {
|
|||
|
createTiddlyText(place,v[t]);
|
|||
|
createTiddlyElement(place,"br");
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Selector = {
|
|||
|
createHeader: function(place,columnTemplate,col)
|
|||
|
{
|
|||
|
createTiddlyCheckbox(place,null,false,this.onHeaderChange);
|
|||
|
},
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var e = createTiddlyCheckbox(place,null,listObject[field],null);
|
|||
|
e.setAttribute("rowName",listObject[columnTemplate.rowName]);
|
|||
|
},
|
|||
|
onHeaderChange: function(e)
|
|||
|
{
|
|||
|
var state = this.checked;
|
|||
|
var view = findRelated(this,"TABLE");
|
|||
|
if(!view)
|
|||
|
return;
|
|||
|
ListView.forEachSelector(view,function(e,rowName) {
|
|||
|
e.checked = state;
|
|||
|
});
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Tags = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var tags = listObject[field];
|
|||
|
createTiddlyText(place,String.encodeTiddlyLinkList(tags));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.Boolean = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
if(listObject[field] == true)
|
|||
|
createTiddlyText(place,columnTemplate.trueText);
|
|||
|
if(listObject[field] == false)
|
|||
|
createTiddlyText(place,columnTemplate.falseText);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.TagCheckbox = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var e = createTiddlyCheckbox(place,null,listObject[field],this.onChange);
|
|||
|
e.setAttribute("tiddler",listObject.title);
|
|||
|
e.setAttribute("tag",columnTemplate.tag);
|
|||
|
},
|
|||
|
onChange : function(e)
|
|||
|
{
|
|||
|
var tag = this.getAttribute("tag");
|
|||
|
var tiddler = this.getAttribute("tiddler");
|
|||
|
store.setTiddlerTag(tiddler,this.checked,tag);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
ListView.columnTypes.TiddlerLink = {
|
|||
|
createHeader: ListView.columnTypes.String.createHeader,
|
|||
|
createItem: function(place,listObject,field,columnTemplate,col,row)
|
|||
|
{
|
|||
|
var v = listObject[field];
|
|||
|
if(v != undefined) {
|
|||
|
var link = createTiddlyLink(place,listObject[columnTemplate.tiddlerLink],false,null);
|
|||
|
createTiddlyText(link,listObject[field]);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Augmented methods for the JavaScript Array() object
|
|||
|
//--
|
|||
|
|
|||
|
// Add indexOf function if browser does not support it
|
|||
|
if(!Array.indexOf) {
|
|||
|
Array.prototype.indexOf = function(item,from)
|
|||
|
{
|
|||
|
if(!from)
|
|||
|
from = 0;
|
|||
|
var i;
|
|||
|
for(i=from; i<this.length; i++) {
|
|||
|
if(this[i] === item)
|
|||
|
return i;
|
|||
|
}
|
|||
|
return -1;
|
|||
|
};}
|
|||
|
|
|||
|
// Find an entry in a given field of the members of an array
|
|||
|
Array.prototype.findByField = function(field,value)
|
|||
|
{
|
|||
|
var t;
|
|||
|
for(t=0; t<this.length; t++) {
|
|||
|
if(this[t][field] === value)
|
|||
|
return t;
|
|||
|
}
|
|||
|
return null;
|
|||
|
};
|
|||
|
|
|||
|
// Return whether an entry exists in an array
|
|||
|
Array.prototype.contains = function(item)
|
|||
|
{
|
|||
|
return this.indexOf(item) != -1;
|
|||
|
};
|
|||
|
|
|||
|
// Adds, removes or toggles a particular value within an array
|
|||
|
// value - value to add
|
|||
|
// mode - +1 to add value, -1 to remove value, 0 to toggle it
|
|||
|
Array.prototype.setItem = function(value,mode)
|
|||
|
{
|
|||
|
var p = this.indexOf(value);
|
|||
|
if(mode == 0)
|
|||
|
mode = (p == -1) ? +1 : -1;
|
|||
|
if(mode == +1) {
|
|||
|
if(p == -1)
|
|||
|
this.push(value);
|
|||
|
} else if(mode == -1) {
|
|||
|
if(p != -1)
|
|||
|
this.splice(p,1);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Return whether one of a list of values exists in an array
|
|||
|
Array.prototype.containsAny = function(items)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i=0; i<items.length; i++) {
|
|||
|
if(this.indexOf(items[i]) != -1)
|
|||
|
return true;
|
|||
|
}
|
|||
|
return false;
|
|||
|
};
|
|||
|
|
|||
|
// Return whether all of a list of values exists in an array
|
|||
|
Array.prototype.containsAll = function(items)
|
|||
|
{
|
|||
|
var i;
|
|||
|
for(i = 0; i<items.length; i++) {
|
|||
|
if(this.indexOf(items[i]) == -1)
|
|||
|
return false;
|
|||
|
}
|
|||
|
return true;
|
|||
|
};
|
|||
|
|
|||
|
// Push a new value into an array only if it is not already present in the array. If the optional unique parameter is false, it reverts to a normal push
|
|||
|
Array.prototype.pushUnique = function(item,unique)
|
|||
|
{
|
|||
|
if(unique === false) {
|
|||
|
this.push(item);
|
|||
|
} else {
|
|||
|
if(this.indexOf(item) == -1)
|
|||
|
this.push(item);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
Array.prototype.remove = function(item)
|
|||
|
{
|
|||
|
var p = this.indexOf(item);
|
|||
|
if(p != -1)
|
|||
|
this.splice(p,1);
|
|||
|
};
|
|||
|
|
|||
|
if(!Array.prototype.map) {
|
|||
|
Array.prototype.map = function(fn,thisObj)
|
|||
|
{
|
|||
|
var scope = thisObj || window;
|
|||
|
var i,j,a = [];
|
|||
|
for(i=0, j=this.length; i < j; ++i) {
|
|||
|
a.push(fn.call(scope,this[i],i,this));
|
|||
|
}
|
|||
|
return a;
|
|||
|
};}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Augmented methods for the JavaScript String() object
|
|||
|
//--
|
|||
|
|
|||
|
// Get characters from the right end of a string
|
|||
|
String.prototype.right = function(n)
|
|||
|
{
|
|||
|
return n < this.length ? this.slice(this.length-n) : this;
|
|||
|
};
|
|||
|
|
|||
|
// Trim whitespace from both ends of a string
|
|||
|
String.prototype.trim = function()
|
|||
|
{
|
|||
|
return this.replace(/^\s*|\s*$/g,"");
|
|||
|
};
|
|||
|
|
|||
|
// Convert a string from a CSS style property name to a JavaScript style name ("background-color" -> "backgroundColor")
|
|||
|
String.prototype.unDash = function()
|
|||
|
{
|
|||
|
var t,s = this.split("-");
|
|||
|
if(s.length > 1) {
|
|||
|
for(t=1; t<s.length; t++)
|
|||
|
s[t] = s[t].substr(0,1).toUpperCase() + s[t].substr(1);
|
|||
|
}
|
|||
|
return s.join("");
|
|||
|
};
|
|||
|
|
|||
|
// Substitute substrings from an array into a format string that includes '%1'-type specifiers
|
|||
|
String.prototype.format = function(s)
|
|||
|
{
|
|||
|
var substrings = s && s.constructor == Array ? s : arguments;
|
|||
|
var subRegExp = /(?:%(\d+))/mg;
|
|||
|
var currPos = 0;
|
|||
|
var match,r = [];
|
|||
|
do {
|
|||
|
match = subRegExp.exec(this);
|
|||
|
if(match && match[1]) {
|
|||
|
if(match.index > currPos)
|
|||
|
r.push(this.substring(currPos,match.index));
|
|||
|
r.push(substrings[parseInt(match[1],10)]);
|
|||
|
currPos = subRegExp.lastIndex;
|
|||
|
}
|
|||
|
} while(match);
|
|||
|
if(currPos < this.length)
|
|||
|
r.push(this.substring(currPos,this.length));
|
|||
|
return r.join("");
|
|||
|
};
|
|||
|
|
|||
|
// Escape any special RegExp characters with that character preceded by a backslash
|
|||
|
String.prototype.escapeRegExp = function()
|
|||
|
{
|
|||
|
var s = "\\^$*+?()=!|,{}[].";
|
|||
|
var t,c = this;
|
|||
|
for(t=0; t<s.length; t++)
|
|||
|
c = c.replace(new RegExp("\\" + s.substr(t,1),"g"),"\\" + s.substr(t,1));
|
|||
|
return c;
|
|||
|
};
|
|||
|
|
|||
|
// Convert "\" to "\s", newlines to "\n" (and remove carriage returns)
|
|||
|
String.prototype.escapeLineBreaks = function()
|
|||
|
{
|
|||
|
return this.replace(/\\/mg,"\\s").replace(/\n/mg,"\\n").replace(/\r/mg,"");
|
|||
|
};
|
|||
|
|
|||
|
// Convert "\n" to newlines, "\b" to " ", "\s" to "\" (and remove carriage returns)
|
|||
|
String.prototype.unescapeLineBreaks = function()
|
|||
|
{
|
|||
|
return this.replace(/\\n/mg,"\n").replace(/\\b/mg," ").replace(/\\s/mg,"\\").replace(/\r/mg,"");
|
|||
|
};
|
|||
|
|
|||
|
// Convert & to "&", < to "<", > to ">" and " to """
|
|||
|
String.prototype.htmlEncode = function()
|
|||
|
{
|
|||
|
return this.replace(/&/mg,"&").replace(/</mg,"<").replace(/>/mg,">").replace(/\"/mg,""");
|
|||
|
};
|
|||
|
|
|||
|
// Convert "&" to &, "<" to <, ">" to > and """ to "
|
|||
|
String.prototype.htmlDecode = function()
|
|||
|
{
|
|||
|
return this.replace(/</mg,"<").replace(/>/mg,">").replace(/"/mg,"\"").replace(/&/mg,"&");
|
|||
|
};
|
|||
|
|
|||
|
// Parse a space-separated string of name:value parameters
|
|||
|
// The result is an array of objects:
|
|||
|
// result[0] = object with a member for each parameter name, value of that member being an array of values
|
|||
|
// result[1..n] = one object for each parameter, with 'name' and 'value' members
|
|||
|
String.prototype.parseParams = function(defaultName,defaultValue,allowEval,noNames,cascadeDefaults)
|
|||
|
{
|
|||
|
var parseToken = function(match,p) {
|
|||
|
var n;
|
|||
|
if(match[p]) // Double quoted
|
|||
|
n = match[p];
|
|||
|
else if(match[p+1]) // Single quoted
|
|||
|
n = match[p+1];
|
|||
|
else if(match[p+2]) // Double-square-bracket quoted
|
|||
|
n = match[p+2];
|
|||
|
else if(match[p+3]) // Double-brace quoted
|
|||
|
try {
|
|||
|
n = match[p+3];
|
|||
|
if(allowEval && config.evaluateMacroParameters != "none") {
|
|||
|
if(config.evaluateMacroParameters == "restricted") {
|
|||
|
if(window.restrictedEval) {
|
|||
|
n = window.restrictedEval(n);
|
|||
|
}
|
|||
|
} else {
|
|||
|
n = window.eval(n);
|
|||
|
}
|
|||
|
}
|
|||
|
} catch(ex) {
|
|||
|
throw "Unable to evaluate {{" + match[p+3] + "}}: " + exceptionText(ex);
|
|||
|
}
|
|||
|
else if(match[p+4]) // Unquoted
|
|||
|
n = match[p+4];
|
|||
|
else if(match[p+5]) // empty quote
|
|||
|
n = "";
|
|||
|
return n;
|
|||
|
};
|
|||
|
var r = [{}];
|
|||
|
var dblQuote = "(?:\"((?:(?:\\\\\")|[^\"])+)\")";
|
|||
|
var sngQuote = "(?:'((?:(?:\\\\\')|[^'])+)')";
|
|||
|
var dblSquare = "(?:\\[\\[((?:\\s|\\S)*?)\\]\\])";
|
|||
|
var dblBrace = "(?:\\{\\{((?:\\s|\\S)*?)\\}\\})";
|
|||
|
var unQuoted = noNames ? "([^\"'\\s]\\S*)" : "([^\"':\\s][^\\s:]*)";
|
|||
|
var emptyQuote = "((?:\"\")|(?:''))";
|
|||
|
var skipSpace = "(?:\\s*)";
|
|||
|
var token = "(?:" + dblQuote + "|" + sngQuote + "|" + dblSquare + "|" + dblBrace + "|" + unQuoted + "|" + emptyQuote + ")";
|
|||
|
var re = noNames ? new RegExp(token,"mg") : new RegExp(skipSpace + token + skipSpace + "(?:(\\:)" + skipSpace + token + ")?","mg");
|
|||
|
var match;
|
|||
|
do {
|
|||
|
match = re.exec(this);
|
|||
|
if(match) {
|
|||
|
var n = parseToken(match,1);
|
|||
|
if(noNames) {
|
|||
|
r.push({name:"",value:n});
|
|||
|
} else {
|
|||
|
var v = parseToken(match,8);
|
|||
|
if(v == null && defaultName) {
|
|||
|
v = n;
|
|||
|
n = defaultName;
|
|||
|
} else if(v == null && defaultValue) {
|
|||
|
v = defaultValue;
|
|||
|
}
|
|||
|
r.push({name:n,value:v});
|
|||
|
if(cascadeDefaults) {
|
|||
|
defaultName = n;
|
|||
|
defaultValue = v;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
} while(match);
|
|||
|
// Summarise parameters into first element
|
|||
|
var t;
|
|||
|
for(t=1; t<r.length; t++) {
|
|||
|
if(r[0][r[t].name])
|
|||
|
r[0][r[t].name].push(r[t].value);
|
|||
|
else
|
|||
|
r[0][r[t].name] = [r[t].value];
|
|||
|
}
|
|||
|
return r;
|
|||
|
};
|
|||
|
|
|||
|
// Process a string list of macro parameters into an array. Parameters can be quoted with "", '',
|
|||
|
// [[]], {{ }} or left unquoted (and therefore space-separated). Double-braces {{}} results in
|
|||
|
// an *evaluated* parameter: e.g. {{config.options.txtUserName}} results in the current user's name.
|
|||
|
String.prototype.readMacroParams = function(notAllowEval)
|
|||
|
{
|
|||
|
var p = this.parseParams("list",null,!notAllowEval,true);
|
|||
|
var t,n = [];
|
|||
|
for(t=1; t<p.length; t++)
|
|||
|
n.push(p[t].value);
|
|||
|
return n;
|
|||
|
};
|
|||
|
|
|||
|
// Process a string list of unique tiddler names into an array. Tiddler names that have spaces in them must be [[bracketed]]
|
|||
|
String.prototype.readBracketedList = function(unique)
|
|||
|
{
|
|||
|
var p = this.parseParams("list",null,false,true);
|
|||
|
var t,n = [];
|
|||
|
for(t=1; t<p.length; t++) {
|
|||
|
if(p[t].value)
|
|||
|
n.pushUnique(p[t].value,unique);
|
|||
|
}
|
|||
|
return n;
|
|||
|
};
|
|||
|
|
|||
|
// Returns array with start and end index of chunk between given start and end marker, or undefined.
|
|||
|
String.prototype.getChunkRange = function(start,end)
|
|||
|
{
|
|||
|
var s = this.indexOf(start);
|
|||
|
if(s != -1) {
|
|||
|
s += start.length;
|
|||
|
var e = this.indexOf(end,s);
|
|||
|
if(e != -1)
|
|||
|
return [s,e];
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Replace a chunk of a string given start and end markers
|
|||
|
String.prototype.replaceChunk = function(start,end,sub)
|
|||
|
{
|
|||
|
var r = this.getChunkRange(start,end);
|
|||
|
return r ? this.substring(0,r[0]) + sub + this.substring(r[1]) : this;
|
|||
|
};
|
|||
|
|
|||
|
// Returns a chunk of a string between start and end markers, or undefined
|
|||
|
String.prototype.getChunk = function(start,end)
|
|||
|
{
|
|||
|
var r = this.getChunkRange(start,end);
|
|||
|
if(r)
|
|||
|
return this.substring(r[0],r[1]);
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
// Static method to bracket a string with double square brackets if it contains a space
|
|||
|
String.encodeTiddlyLink = function(title)
|
|||
|
{
|
|||
|
return title.indexOf(" ") == -1 ? title : "[[" + title + "]]";
|
|||
|
};
|
|||
|
|
|||
|
// Static method to encodeTiddlyLink for every item in an array and join them with spaces
|
|||
|
String.encodeTiddlyLinkList = function(list)
|
|||
|
{
|
|||
|
if(list) {
|
|||
|
var t,results = [];
|
|||
|
for(t=0; t<list.length; t++)
|
|||
|
results.push(String.encodeTiddlyLink(list[t]));
|
|||
|
return results.join(" ");
|
|||
|
} else {
|
|||
|
return "";
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Convert a string as a sequence of name:"value" pairs into a hashmap
|
|||
|
String.prototype.decodeHashMap = function()
|
|||
|
{
|
|||
|
var fields = this.parseParams("anon","",false);
|
|||
|
var t,r = {};
|
|||
|
for(t=1; t<fields.length; t++)
|
|||
|
r[fields[t].name] = fields[t].value;
|
|||
|
return r;
|
|||
|
};
|
|||
|
|
|||
|
// Static method to encode a hashmap into a name:"value"... string
|
|||
|
String.encodeHashMap = function(hashmap)
|
|||
|
{
|
|||
|
var t,r = [];
|
|||
|
for(t in hashmap)
|
|||
|
r.push(t + ':"' + hashmap[t] + '"');
|
|||
|
return r.join(" ");
|
|||
|
};
|
|||
|
|
|||
|
// Static method to left-pad a string with 0s to a certain width
|
|||
|
String.zeroPad = function(n,d)
|
|||
|
{
|
|||
|
var s = n.toString();
|
|||
|
if(s.length < d)
|
|||
|
s = "000000000000000000000000000".substr(0,d-s.length) + s;
|
|||
|
return s;
|
|||
|
};
|
|||
|
|
|||
|
String.prototype.startsWith = function(prefix)
|
|||
|
{
|
|||
|
return !prefix || this.substring(0,prefix.length) == prefix;
|
|||
|
};
|
|||
|
|
|||
|
// Returns the first value of the given named parameter.
|
|||
|
function getParam(params,name,defaultValue)
|
|||
|
{
|
|||
|
if(!params)
|
|||
|
return defaultValue;
|
|||
|
var p = params[0][name];
|
|||
|
return p ? p[0] : defaultValue;
|
|||
|
}
|
|||
|
|
|||
|
// Returns the first value of the given boolean named parameter.
|
|||
|
function getFlag(params,name,defaultValue)
|
|||
|
{
|
|||
|
return !!getParam(params,name,defaultValue);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Augmented methods for the JavaScript Date() object
|
|||
|
//--
|
|||
|
|
|||
|
// Substitute date components into a string
|
|||
|
Date.prototype.formatString = function(template)
|
|||
|
{
|
|||
|
var t = template.replace(/0hh12/g,String.zeroPad(this.getHours12(),2));
|
|||
|
t = t.replace(/hh12/g,this.getHours12());
|
|||
|
t = t.replace(/0hh/g,String.zeroPad(this.getHours(),2));
|
|||
|
t = t.replace(/hh/g,this.getHours());
|
|||
|
t = t.replace(/mmm/g,config.messages.dates.shortMonths[this.getMonth()]);
|
|||
|
t = t.replace(/0mm/g,String.zeroPad(this.getMinutes(),2));
|
|||
|
t = t.replace(/mm/g,this.getMinutes());
|
|||
|
t = t.replace(/0ss/g,String.zeroPad(this.getSeconds(),2));
|
|||
|
t = t.replace(/ss/g,this.getSeconds());
|
|||
|
t = t.replace(/[ap]m/g,this.getAmPm().toLowerCase());
|
|||
|
t = t.replace(/[AP]M/g,this.getAmPm().toUpperCase());
|
|||
|
t = t.replace(/wYYYY/g,this.getYearForWeekNo());
|
|||
|
t = t.replace(/wYY/g,String.zeroPad(this.getYearForWeekNo()-2000,2));
|
|||
|
t = t.replace(/YYYY/g,this.getFullYear());
|
|||
|
t = t.replace(/YY/g,String.zeroPad(this.getFullYear()-2000,2));
|
|||
|
t = t.replace(/MMM/g,config.messages.dates.months[this.getMonth()]);
|
|||
|
t = t.replace(/0MM/g,String.zeroPad(this.getMonth()+1,2));
|
|||
|
t = t.replace(/MM/g,this.getMonth()+1);
|
|||
|
t = t.replace(/0WW/g,String.zeroPad(this.getWeek(),2));
|
|||
|
t = t.replace(/WW/g,this.getWeek());
|
|||
|
t = t.replace(/DDD/g,config.messages.dates.days[this.getDay()]);
|
|||
|
t = t.replace(/ddd/g,config.messages.dates.shortDays[this.getDay()]);
|
|||
|
t = t.replace(/0DD/g,String.zeroPad(this.getDate(),2));
|
|||
|
t = t.replace(/DDth/g,this.getDate()+this.daySuffix());
|
|||
|
t = t.replace(/DD/g,this.getDate());
|
|||
|
var tz = this.getTimezoneOffset();
|
|||
|
var atz = Math.abs(tz);
|
|||
|
t = t.replace(/TZD/g,(tz < 0 ? '+' : '-') + String.zeroPad(Math.floor(atz / 60),2) + ':' + String.zeroPad(atz % 60,2));
|
|||
|
t = t.replace(/\\/g,"");
|
|||
|
return t;
|
|||
|
};
|
|||
|
|
|||
|
Date.prototype.getWeek = function()
|
|||
|
{
|
|||
|
var dt = new Date(this.getTime());
|
|||
|
var d = dt.getDay();
|
|||
|
if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
|
|||
|
dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week to calculate weekNo
|
|||
|
var n = Math.floor((dt.getTime()-new Date(dt.getFullYear(),0,1)+3600000)/86400000);
|
|||
|
return Math.floor(n/7)+1;
|
|||
|
};
|
|||
|
|
|||
|
Date.prototype.getYearForWeekNo = function()
|
|||
|
{
|
|||
|
var dt = new Date(this.getTime());
|
|||
|
var d = dt.getDay();
|
|||
|
if(d==0) d=7;// JavaScript Sun=0, ISO Sun=7
|
|||
|
dt.setTime(dt.getTime()+(4-d)*86400000);// shift day to Thurs of same week
|
|||
|
return dt.getFullYear();
|
|||
|
};
|
|||
|
|
|||
|
Date.prototype.getHours12 = function()
|
|||
|
{
|
|||
|
var h = this.getHours();
|
|||
|
return h > 12 ? h-12 : ( h > 0 ? h : 12 );
|
|||
|
};
|
|||
|
|
|||
|
Date.prototype.getAmPm = function()
|
|||
|
{
|
|||
|
return this.getHours() >= 12 ? config.messages.dates.pm : config.messages.dates.am;
|
|||
|
};
|
|||
|
|
|||
|
Date.prototype.daySuffix = function()
|
|||
|
{
|
|||
|
return config.messages.dates.daySuffixes[this.getDate()-1];
|
|||
|
};
|
|||
|
|
|||
|
// Convert a date to local YYYYMMDDHHMM string format
|
|||
|
Date.prototype.convertToLocalYYYYMMDDHHMM = function()
|
|||
|
{
|
|||
|
return this.getFullYear() + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2);
|
|||
|
};
|
|||
|
|
|||
|
// Convert a date to UTC YYYYMMDDHHMM string format
|
|||
|
Date.prototype.convertToYYYYMMDDHHMM = function()
|
|||
|
{
|
|||
|
return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2);
|
|||
|
};
|
|||
|
|
|||
|
// Convert a date to UTC YYYYMMDD.HHMMSSMMM string format
|
|||
|
Date.prototype.convertToYYYYMMDDHHMMSSMMM = function()
|
|||
|
{
|
|||
|
return this.getUTCFullYear() + String.zeroPad(this.getUTCMonth()+1,2) + String.zeroPad(this.getUTCDate(),2) + "." + String.zeroPad(this.getUTCHours(),2) + String.zeroPad(this.getUTCMinutes(),2) + String.zeroPad(this.getUTCSeconds(),2) + String.zeroPad(this.getUTCMilliseconds(),3) +"0";
|
|||
|
};
|
|||
|
|
|||
|
// Static method to create a date from a UTC YYYYMMDDHHMM format string
|
|||
|
Date.convertFromYYYYMMDDHHMM = function(d)
|
|||
|
{
|
|||
|
d = d?d.replace(/[^0-9]/g, ""):"";
|
|||
|
return Date.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,12));
|
|||
|
};
|
|||
|
|
|||
|
// Static method to create a date from a UTC YYYYMMDDHHMMSS format string
|
|||
|
Date.convertFromYYYYMMDDHHMMSS = function(d)
|
|||
|
{
|
|||
|
d = d?d.replace(/[^0-9]/g, ""):"";
|
|||
|
return Date.convertFromYYYYMMDDHHMMSSMMM(d.substr(0,14));
|
|||
|
};
|
|||
|
|
|||
|
// Static method to create a date from a UTC YYYYMMDDHHMMSSMMM format string
|
|||
|
Date.convertFromYYYYMMDDHHMMSSMMM = function(d)
|
|||
|
{
|
|||
|
d = d ? d.replace(/[^0-9]/g, "") : "";
|
|||
|
return new Date(Date.UTC(parseInt(d.substr(0,4),10),
|
|||
|
parseInt(d.substr(4,2),10)-1,
|
|||
|
parseInt(d.substr(6,2),10),
|
|||
|
parseInt(d.substr(8,2)||"00",10),
|
|||
|
parseInt(d.substr(10,2)||"00",10),
|
|||
|
parseInt(d.substr(12,2)||"00",10),
|
|||
|
parseInt(d.substr(14,3)||"000",10)));
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- RGB colour object
|
|||
|
//--
|
|||
|
|
|||
|
// Construct an RGB colour object from a '#rrggbb', '#rgb' or 'rgb(n,n,n)' string or from separate r,g,b values
|
|||
|
function RGB(r,g,b)
|
|||
|
{
|
|||
|
this.r = 0;
|
|||
|
this.g = 0;
|
|||
|
this.b = 0;
|
|||
|
if(typeof r == "string") {
|
|||
|
if(r.substr(0,1) == "#") {
|
|||
|
if(r.length == 7) {
|
|||
|
this.r = parseInt(r.substr(1,2),16)/255;
|
|||
|
this.g = parseInt(r.substr(3,2),16)/255;
|
|||
|
this.b = parseInt(r.substr(5,2),16)/255;
|
|||
|
} else {
|
|||
|
this.r = parseInt(r.substr(1,1),16)/15;
|
|||
|
this.g = parseInt(r.substr(2,1),16)/15;
|
|||
|
this.b = parseInt(r.substr(3,1),16)/15;
|
|||
|
}
|
|||
|
} else {
|
|||
|
var rgbPattern = /rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/;
|
|||
|
var c = r.match(rgbPattern);
|
|||
|
if(c) {
|
|||
|
this.r = parseInt(c[1],10)/255;
|
|||
|
this.g = parseInt(c[2],10)/255;
|
|||
|
this.b = parseInt(c[3],10)/255;
|
|||
|
}
|
|||
|
}
|
|||
|
} else {
|
|||
|
this.r = r;
|
|||
|
this.g = g;
|
|||
|
this.b = b;
|
|||
|
}
|
|||
|
return this;
|
|||
|
}
|
|||
|
|
|||
|
// Mixes this colour with another in a specified proportion
|
|||
|
// c = other colour to mix
|
|||
|
// f = 0..1 where 0 is this colour and 1 is the new colour
|
|||
|
// Returns an RGB object
|
|||
|
RGB.prototype.mix = function(c,f)
|
|||
|
{
|
|||
|
return new RGB(this.r + (c.r-this.r) * f,this.g + (c.g-this.g) * f,this.b + (c.b-this.b) * f);
|
|||
|
};
|
|||
|
|
|||
|
// Return an rgb colour as a #rrggbb format hex string
|
|||
|
RGB.prototype.toString = function()
|
|||
|
{
|
|||
|
var clamp = function(x,min,max) {
|
|||
|
return x < min ? min : (x > max ? max : x);
|
|||
|
};
|
|||
|
return "#" +
|
|||
|
("0" + Math.floor(clamp(this.r,0,1) * 255).toString(16)).right(2) +
|
|||
|
("0" + Math.floor(clamp(this.g,0,1) * 255).toString(16)).right(2) +
|
|||
|
("0" + Math.floor(clamp(this.b,0,1) * 255).toString(16)).right(2);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- DOM utilities - many derived from www.quirksmode.org
|
|||
|
//--
|
|||
|
|
|||
|
function drawGradient(place,horiz,locolors,hicolors)
|
|||
|
{
|
|||
|
if(!hicolors)
|
|||
|
hicolors = locolors;
|
|||
|
var t;
|
|||
|
for(t=0; t<= 100; t+=2) {
|
|||
|
var bar = document.createElement("div");
|
|||
|
place.appendChild(bar);
|
|||
|
bar.style.position = "absolute";
|
|||
|
bar.style.left = horiz ? t + "%" : 0;
|
|||
|
bar.style.top = horiz ? 0 : t + "%";
|
|||
|
bar.style.width = horiz ? (101-t) + "%" : "100%";
|
|||
|
bar.style.height = horiz ? "100%" : (101-t) + "%";
|
|||
|
bar.style.zIndex = -1;
|
|||
|
var p = t/100*(locolors.length-1);
|
|||
|
var hc = hicolors[Math.floor(p)];
|
|||
|
if(typeof hc == "string")
|
|||
|
hc = new RGB(hc);
|
|||
|
var lc = locolors[Math.ceil(p)];
|
|||
|
if(typeof lc == "string")
|
|||
|
lc = new RGB(lc);
|
|||
|
bar.style.backgroundColor = hc.mix(lc,p-Math.floor(p)).toString();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function addEvent(obj,type,fn)
|
|||
|
{
|
|||
|
if(obj.attachEvent) {
|
|||
|
obj["e"+type+fn] = fn;
|
|||
|
obj[type+fn] = function(){obj["e"+type+fn](window.event);};
|
|||
|
obj.attachEvent("on"+type,obj[type+fn]);
|
|||
|
} else {
|
|||
|
obj.addEventListener(type,fn,false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function removeEvent(obj,type,fn)
|
|||
|
{
|
|||
|
if(obj.detachEvent) {
|
|||
|
obj.detachEvent("on"+type,obj[type+fn]);
|
|||
|
obj[type+fn] = null;
|
|||
|
} else {
|
|||
|
obj.removeEventListener(type,fn,false);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Find the closest relative with a given property value (property defaults to tagName, relative defaults to parentNode)
|
|||
|
function findRelated(e,value,name,relative)
|
|||
|
{
|
|||
|
name = name || "tagName";
|
|||
|
relative = relative || "parentNode";
|
|||
|
if(name == "className") {
|
|||
|
while(e && !jQuery(e).hasClass(value)) {
|
|||
|
e = e[relative];
|
|||
|
}
|
|||
|
} else {
|
|||
|
while(e && e[name] != value) {
|
|||
|
e = e[relative];
|
|||
|
}
|
|||
|
}
|
|||
|
return e;
|
|||
|
}
|
|||
|
|
|||
|
// Get the scroll position for window.scrollTo necessary to scroll a given element into view
|
|||
|
function ensureVisible(e)
|
|||
|
{
|
|||
|
var posTop = findPosY(e);
|
|||
|
var posBot = posTop + e.offsetHeight;
|
|||
|
var winTop = findScrollY();
|
|||
|
var winHeight = findWindowHeight();
|
|||
|
var winBot = winTop + winHeight;
|
|||
|
if(posTop < winTop) {
|
|||
|
return posTop;
|
|||
|
} else if(posBot > winBot) {
|
|||
|
if(e.offsetHeight < winHeight)
|
|||
|
return posTop - (winHeight - e.offsetHeight);
|
|||
|
else
|
|||
|
return posTop;
|
|||
|
} else {
|
|||
|
return winTop;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Get the current width of the display window
|
|||
|
function findWindowWidth()
|
|||
|
{
|
|||
|
return window.innerWidth || document.documentElement.clientWidth;
|
|||
|
}
|
|||
|
|
|||
|
// Get the current height of the display window
|
|||
|
function findWindowHeight()
|
|||
|
{
|
|||
|
return window.innerHeight || document.documentElement.clientHeight;
|
|||
|
}
|
|||
|
|
|||
|
// Get the current horizontal page scroll position
|
|||
|
function findScrollX()
|
|||
|
{
|
|||
|
return window.scrollX || document.documentElement.scrollLeft;
|
|||
|
}
|
|||
|
|
|||
|
// Get the current vertical page scroll position
|
|||
|
function findScrollY()
|
|||
|
{
|
|||
|
return window.scrollY || document.documentElement.scrollTop;
|
|||
|
}
|
|||
|
|
|||
|
function findPosX(obj)
|
|||
|
{
|
|||
|
var curleft = 0;
|
|||
|
while(obj.offsetParent) {
|
|||
|
curleft += obj.offsetLeft;
|
|||
|
obj = obj.offsetParent;
|
|||
|
}
|
|||
|
return curleft;
|
|||
|
}
|
|||
|
|
|||
|
function findPosY(obj)
|
|||
|
{
|
|||
|
var curtop = 0;
|
|||
|
while(obj.offsetParent) {
|
|||
|
curtop += obj.offsetTop;
|
|||
|
obj = obj.offsetParent;
|
|||
|
}
|
|||
|
return curtop;
|
|||
|
}
|
|||
|
|
|||
|
// Blur a particular element
|
|||
|
function blurElement(e)
|
|||
|
{
|
|||
|
if(e && e.focus && e.blur) {
|
|||
|
e.focus();
|
|||
|
e.blur();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Create a non-breaking space
|
|||
|
function insertSpacer(place)
|
|||
|
{
|
|||
|
var e = document.createTextNode(String.fromCharCode(160));
|
|||
|
if(place)
|
|||
|
place.appendChild(e);
|
|||
|
return e;
|
|||
|
}
|
|||
|
|
|||
|
// Replace the current selection of a textarea or text input and scroll it into view
|
|||
|
function replaceSelection(e,text)
|
|||
|
{
|
|||
|
if(e.setSelectionRange) {
|
|||
|
var oldpos = e.selectionStart;
|
|||
|
var isRange = e.selectionEnd > e.selectionStart;
|
|||
|
e.value = e.value.substr(0,e.selectionStart) + text + e.value.substr(e.selectionEnd);
|
|||
|
e.setSelectionRange(isRange ? oldpos : oldpos + text.length,oldpos + text.length);
|
|||
|
var linecount = e.value.split("\n").length;
|
|||
|
var thisline = e.value.substr(0,e.selectionStart).split("\n").length-1;
|
|||
|
e.scrollTop = Math.floor((thisline - e.rows / 2) * e.scrollHeight / linecount);
|
|||
|
} else if(document.selection) {
|
|||
|
var range = document.selection.createRange();
|
|||
|
if(range.parentElement() == e) {
|
|||
|
var isCollapsed = range.text == "";
|
|||
|
range.text = text;
|
|||
|
if(!isCollapsed) {
|
|||
|
range.moveStart("character", -text.length);
|
|||
|
range.select();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Set the caret position in a text area
|
|||
|
function setCaretPosition(e,pos)
|
|||
|
{
|
|||
|
if(e.selectionStart || e.selectionStart == '0') {
|
|||
|
e.selectionStart = pos;
|
|||
|
e.selectionEnd = pos;
|
|||
|
e.focus();
|
|||
|
} else if(document.selection) {
|
|||
|
// IE support
|
|||
|
e.focus ();
|
|||
|
var sel = document.selection.createRange();
|
|||
|
sel.moveStart('character', -e.value.length);
|
|||
|
sel.moveStart('character',pos);
|
|||
|
sel.moveEnd('character',0);
|
|||
|
sel.select();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Returns the text of the given (text) node, possibly merging subsequent text nodes
|
|||
|
function getNodeText(e)
|
|||
|
{
|
|||
|
var t = "";
|
|||
|
while(e && e.nodeName == "#text") {
|
|||
|
t += e.nodeValue;
|
|||
|
e = e.nextSibling;
|
|||
|
}
|
|||
|
return t;
|
|||
|
}
|
|||
|
|
|||
|
// Returns true if the element e has a given ancestor element
|
|||
|
function isDescendant(e,ancestor)
|
|||
|
{
|
|||
|
while(e) {
|
|||
|
if(e === ancestor)
|
|||
|
return true;
|
|||
|
e = e.parentNode;
|
|||
|
}
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
// deprecate the following...
|
|||
|
|
|||
|
// Prevent an event from bubbling
|
|||
|
function stopEvent(e)
|
|||
|
{
|
|||
|
var ev = e || window.event;
|
|||
|
ev.cancelBubble = true;
|
|||
|
if(ev.stopPropagation) ev.stopPropagation();
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// Remove any event handlers or non-primitve custom attributes
|
|||
|
function scrubNode(e)
|
|||
|
{
|
|||
|
if(!config.browser.isIE)
|
|||
|
return;
|
|||
|
var att = e.attributes;
|
|||
|
if(att) {
|
|||
|
var t;
|
|||
|
for(t=0; t<att.length; t++) {
|
|||
|
var n = att[t].name;
|
|||
|
if(n !== "style" && (typeof e[n] === "function" || (typeof e[n] === "object" && e[n] != null))) {
|
|||
|
try {
|
|||
|
e[n] = null;
|
|||
|
} catch(ex) {
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
var c = e.firstChild;
|
|||
|
while(c) {
|
|||
|
scrubNode(c);
|
|||
|
c = c.nextSibling;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
function setStylesheet(s,id,doc)
|
|||
|
{
|
|||
|
jQuery.twStylesheet(s,{id:id,doc:doc});
|
|||
|
}
|
|||
|
|
|||
|
function removeStyleSheet(id)
|
|||
|
{
|
|||
|
jQuery.twStylesheet.remove({id:id});
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- LoaderBase and SaverBase
|
|||
|
//--
|
|||
|
|
|||
|
function LoaderBase() {}
|
|||
|
|
|||
|
LoaderBase.prototype.loadTiddler = function(store,node,tiddlers)
|
|||
|
{
|
|||
|
var title = this.getTitle(store,node);
|
|||
|
if(safeMode && store.isShadowTiddler(title))
|
|||
|
return;
|
|||
|
if(title) {
|
|||
|
var tiddler = store.createTiddler(title);
|
|||
|
this.internalizeTiddler(store,tiddler,title,node);
|
|||
|
tiddlers.push(tiddler);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
LoaderBase.prototype.loadTiddlers = function(store,nodes)
|
|||
|
{
|
|||
|
var t,tiddlers = [];
|
|||
|
for(t = 0; t < nodes.length; t++) {
|
|||
|
try {
|
|||
|
this.loadTiddler(store,nodes[t],tiddlers);
|
|||
|
} catch(ex) {
|
|||
|
showException(ex,config.messages.tiddlerLoadError.format([this.getTitle(store,nodes[t])]));
|
|||
|
}
|
|||
|
}
|
|||
|
return tiddlers;
|
|||
|
};
|
|||
|
|
|||
|
function SaverBase() {}
|
|||
|
|
|||
|
SaverBase.prototype.externalize = function(store)
|
|||
|
{
|
|||
|
var results = [];
|
|||
|
var t,tiddlers = store.getTiddlers("title");
|
|||
|
for(t = 0; t < tiddlers.length; t++) {
|
|||
|
if(!tiddlers[t].doNotSave())
|
|||
|
results.push(this.externalizeTiddler(store, tiddlers[t]));
|
|||
|
}
|
|||
|
return results.join("\n");
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- TW21Loader (inherits from LoaderBase)
|
|||
|
//--
|
|||
|
|
|||
|
function TW21Loader() {}
|
|||
|
|
|||
|
TW21Loader.prototype = new LoaderBase();
|
|||
|
|
|||
|
TW21Loader.prototype.getTitle = function(store,node)
|
|||
|
{
|
|||
|
var title = null;
|
|||
|
if(node.getAttribute) {
|
|||
|
title = node.getAttribute("title");
|
|||
|
if(!title)
|
|||
|
title = node.getAttribute("tiddler");
|
|||
|
}
|
|||
|
if(!title && node.id) {
|
|||
|
var lenPrefix = store.idPrefix.length;
|
|||
|
if(node.id.substr(0,lenPrefix) == store.idPrefix)
|
|||
|
title = node.id.substr(lenPrefix);
|
|||
|
}
|
|||
|
return title;
|
|||
|
};
|
|||
|
|
|||
|
TW21Loader.prototype.internalizeTiddler = function(store,tiddler,title,node)
|
|||
|
{
|
|||
|
var e = node.firstChild;
|
|||
|
var text = null;
|
|||
|
if(node.getAttribute("tiddler")) {
|
|||
|
text = getNodeText(e).unescapeLineBreaks();
|
|||
|
} else {
|
|||
|
while(e.nodeName!="PRE" && e.nodeName!="pre") {
|
|||
|
e = e.nextSibling;
|
|||
|
}
|
|||
|
text = e.innerHTML.replace(/\r/mg,"").htmlDecode();
|
|||
|
}
|
|||
|
var creator = node.getAttribute("creator");
|
|||
|
var modifier = node.getAttribute("modifier");
|
|||
|
var c = node.getAttribute("created");
|
|||
|
var m = node.getAttribute("modified");
|
|||
|
var created = c ? Date.convertFromYYYYMMDDHHMMSS(c) : version.date;
|
|||
|
var modified = m ? Date.convertFromYYYYMMDDHHMMSS(m) : created;
|
|||
|
var tags = node.getAttribute("tags");
|
|||
|
var fields = {};
|
|||
|
var i,attrs = node.attributes;
|
|||
|
for(i = attrs.length-1; i >= 0; i--) {
|
|||
|
var name = attrs[i].name;
|
|||
|
if(attrs[i].specified && !TiddlyWiki.isStandardField(name)) {
|
|||
|
fields[name] = attrs[i].value.unescapeLineBreaks();
|
|||
|
}
|
|||
|
}
|
|||
|
tiddler.assign(title,text,modifier,modified,tags,created,fields,creator);
|
|||
|
return tiddler;
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- TW21Saver (inherits from SaverBase)
|
|||
|
//--
|
|||
|
|
|||
|
function TW21Saver() {}
|
|||
|
|
|||
|
TW21Saver.prototype = new SaverBase();
|
|||
|
|
|||
|
TW21Saver.prototype.externalizeTiddler = function(store,tiddler)
|
|||
|
{
|
|||
|
try {
|
|||
|
var extendedAttributes = "";
|
|||
|
var usePre = config.options.chkUsePreForStorage;
|
|||
|
store.forEachField(tiddler,
|
|||
|
function(tiddler,fieldName,value) {
|
|||
|
// don't store stuff from the temp namespace
|
|||
|
if(typeof value != "string")
|
|||
|
value = "";
|
|||
|
if(!fieldName.match(/^temp\./))
|
|||
|
extendedAttributes += ' %0="%1"'.format([fieldName,value.escapeLineBreaks().htmlEncode()]);
|
|||
|
},true);
|
|||
|
var created = tiddler.created;
|
|||
|
var modified = tiddler.modified;
|
|||
|
var attributes = tiddler.creator ? ' creator="' + tiddler.creator.htmlEncode() + '"' : "";
|
|||
|
attributes += tiddler.modifier ? ' modifier="' + tiddler.modifier.htmlEncode() + '"' : "";
|
|||
|
attributes += (usePre && created == version.date) ? "" :' created="' + created.convertToYYYYMMDDHHMM() + '"';
|
|||
|
attributes += (usePre && modified == created) ? "" : ' modified="' + modified.convertToYYYYMMDDHHMM() +'"';
|
|||
|
var tags = tiddler.getTags();
|
|||
|
if(!usePre || tags)
|
|||
|
attributes += ' tags="' + tags.htmlEncode() + '"';
|
|||
|
return ('<div %0="%1"%2%3>%4</'+'div>').format([
|
|||
|
usePre ? "title" : "tiddler",
|
|||
|
tiddler.title.htmlEncode(),
|
|||
|
attributes,
|
|||
|
extendedAttributes,
|
|||
|
usePre ? "\n<pre>" + tiddler.text.htmlEncode() + "</pre>\n" : tiddler.text.escapeLineBreaks().htmlEncode()
|
|||
|
]);
|
|||
|
} catch (ex) {
|
|||
|
throw exceptionText(ex,config.messages.tiddlerSaveError.format([tiddler.title]));
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
|
|||
|
<script id="jsdeprecatedArea" type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
//--
|
|||
|
//-- Deprecated Crypto functions and associated conversion routines.
|
|||
|
//-- Use the jQuery.encoding functions directly instead.
|
|||
|
//--
|
|||
|
|
|||
|
// Crypto 'namespace'
|
|||
|
function Crypto() {}
|
|||
|
|
|||
|
// Convert a string to an array of big-endian 32-bit words
|
|||
|
Crypto.strToBe32s = function(str)
|
|||
|
{
|
|||
|
return jQuery.encoding.strToBe32s(str);
|
|||
|
};
|
|||
|
|
|||
|
// Convert an array of big-endian 32-bit words to a string
|
|||
|
Crypto.be32sToStr = function(be)
|
|||
|
{
|
|||
|
return jQuery.encoding.be32sToStr(be);
|
|||
|
};
|
|||
|
|
|||
|
// Convert an array of big-endian 32-bit words to a hex string
|
|||
|
Crypto.be32sToHex = function(be)
|
|||
|
{
|
|||
|
return jQuery.encoding.be32sToHex(be);
|
|||
|
};
|
|||
|
|
|||
|
// Return, in hex, the SHA-1 hash of a string
|
|||
|
Crypto.hexSha1Str = function(str)
|
|||
|
{
|
|||
|
return jQuery.encoding.digests.hexSha1Str(str);
|
|||
|
};
|
|||
|
|
|||
|
// Return the SHA-1 hash of a string
|
|||
|
Crypto.sha1Str = function(str)
|
|||
|
{
|
|||
|
return jQuery.encoding.digests.sha1Str(str);
|
|||
|
};
|
|||
|
|
|||
|
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
|||
|
Crypto.sha1 = function(x,blen)
|
|||
|
{
|
|||
|
return jQuery.encoding.digests.sha1(x,blen);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated code
|
|||
|
//--
|
|||
|
|
|||
|
// @Deprecated: Use createElementAndWikify and this.termRegExp instead
|
|||
|
config.formatterHelpers.charFormatHelper = function(w)
|
|||
|
{
|
|||
|
w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
|
|||
|
};
|
|||
|
|
|||
|
// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
|
|||
|
config.formatterHelpers.monospacedByLineHelper = function(w)
|
|||
|
{
|
|||
|
var lookaheadRegExp = new RegExp(this.lookahead,"mg");
|
|||
|
lookaheadRegExp.lastIndex = w.matchStart;
|
|||
|
var lookaheadMatch = lookaheadRegExp.exec(w.source);
|
|||
|
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
|
|||
|
var text = lookaheadMatch[1];
|
|||
|
if(config.browser.isIE)
|
|||
|
text = text.replace(/\n/g,"\r");
|
|||
|
createTiddlyElement(w.output,"pre",null,null,text);
|
|||
|
w.nextMatch = lookaheadRegExp.lastIndex;
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// @Deprecated: Use <br> or <br /> instead of <<br>>
|
|||
|
config.macros.br = {};
|
|||
|
config.macros.br.handler = function(place)
|
|||
|
{
|
|||
|
createTiddlyElement(place,"br");
|
|||
|
};
|
|||
|
|
|||
|
// Find an entry in an array. Returns the array index or null
|
|||
|
// @Deprecated: Use indexOf instead
|
|||
|
Array.prototype.find = function(item)
|
|||
|
{
|
|||
|
var i = this.indexOf(item);
|
|||
|
return i == -1 ? null : i;
|
|||
|
};
|
|||
|
|
|||
|
// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
|
|||
|
// @Deprecated: Use store.getLoader().internalizeTiddler instead
|
|||
|
Tiddler.prototype.loadFromDiv = function(divRef,title)
|
|||
|
{
|
|||
|
return store.getLoader().internalizeTiddler(store,this,title,divRef);
|
|||
|
};
|
|||
|
|
|||
|
// Format the text for storage in an HTML DIV
|
|||
|
// @Deprecated Use store.getSaver().externalizeTiddler instead.
|
|||
|
Tiddler.prototype.saveToDiv = function()
|
|||
|
{
|
|||
|
return store.getSaver().externalizeTiddler(store,this);
|
|||
|
};
|
|||
|
|
|||
|
// @Deprecated: Use store.allTiddlersAsHtml() instead
|
|||
|
function allTiddlersAsHtml()
|
|||
|
{
|
|||
|
return store.allTiddlersAsHtml();
|
|||
|
}
|
|||
|
|
|||
|
// @Deprecated: Use refreshPageTemplate instead
|
|||
|
function applyPageTemplate(title)
|
|||
|
{
|
|||
|
refreshPageTemplate(title);
|
|||
|
}
|
|||
|
|
|||
|
// @Deprecated: Use story.displayTiddlers instead
|
|||
|
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
|
|||
|
{
|
|||
|
story.displayTiddlers(srcElement,titles,template,animate);
|
|||
|
}
|
|||
|
|
|||
|
// @Deprecated: Use story.displayTiddler instead
|
|||
|
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
|
|||
|
{
|
|||
|
story.displayTiddler(srcElement,title,template,animate);
|
|||
|
}
|
|||
|
|
|||
|
// @Deprecated: Use functions on right hand side directly instead
|
|||
|
var createTiddlerPopup = Popup.create;
|
|||
|
var scrollToTiddlerPopup = Popup.show;
|
|||
|
var hideTiddlerPopup = Popup.remove;
|
|||
|
|
|||
|
// @Deprecated: Use right hand side directly instead
|
|||
|
var regexpBackSlashEn = new RegExp("\\\\n","mg");
|
|||
|
var regexpBackSlash = new RegExp("\\\\","mg");
|
|||
|
var regexpBackSlashEss = new RegExp("\\\\s","mg");
|
|||
|
var regexpNewLine = new RegExp("\n","mg");
|
|||
|
var regexpCarriageReturn = new RegExp("\r","mg");
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated FileAdaptor functions
|
|||
|
//--
|
|||
|
|
|||
|
FileAdaptor.loadTiddlyWikiCallback = function(status,context,responseText,url,xhr)
|
|||
|
{
|
|||
|
context.status = status;
|
|||
|
if(!status) {
|
|||
|
context.statusText = "Error reading file";
|
|||
|
} else {
|
|||
|
context.adaptor.store = new TiddlyWiki();
|
|||
|
if(!context.adaptor.store.importTiddlyWiki(responseText)) {
|
|||
|
context.statusText = config.messages.invalidFileError.format([url]);
|
|||
|
context.status = false;
|
|||
|
}
|
|||
|
}
|
|||
|
context.complete(context,context.userParams);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated HTTP request code
|
|||
|
//-- Use the jQuery ajax functions directly instead
|
|||
|
//--
|
|||
|
|
|||
|
function loadRemoteFile(url,callback,params)
|
|||
|
{
|
|||
|
return httpReq("GET",url,callback,params);
|
|||
|
}
|
|||
|
|
|||
|
function doHttp(type,url,data,contentType,username,password,callback,params,headers,allowCache)
|
|||
|
{
|
|||
|
return httpReq(type,url,callback,params,headers,data,contentType,username,password,allowCache);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated String functions
|
|||
|
//--
|
|||
|
|
|||
|
// @Deprecated: no direct replacement, since not used in core code
|
|||
|
String.prototype.toJSONString = function()
|
|||
|
{
|
|||
|
// Convert a string to it's JSON representation by encoding control characters, double quotes and backslash. See json.org
|
|||
|
var m = {
|
|||
|
'\b': '\\b',
|
|||
|
'\f': '\\f',
|
|||
|
'\n': '\\n',
|
|||
|
'\r': '\\r',
|
|||
|
'\t': '\\t',
|
|||
|
'"' : '\\"',
|
|||
|
'\\': '\\\\'
|
|||
|
};
|
|||
|
var replaceFn = function(a,b) {
|
|||
|
var c = m[b];
|
|||
|
if(c)
|
|||
|
return c;
|
|||
|
c = b.charCodeAt();
|
|||
|
return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
|
|||
|
};
|
|||
|
if(/["\\\x00-\x1f]/.test(this))
|
|||
|
return '"' + this.replace(/([\x00-\x1f\\"])/g,replaceFn) + '"';
|
|||
|
return '"' + this + '"';
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated Tiddler code
|
|||
|
//--
|
|||
|
|
|||
|
// @Deprecated: Use tiddlerToRssItem(tiddler,uri) instead
|
|||
|
Tiddler.prototype.toRssItem = function(uri)
|
|||
|
{
|
|||
|
return tiddlerToRssItem(this,uri);
|
|||
|
};
|
|||
|
|
|||
|
// @Deprecated: Use "<item>\n" + tiddlerToRssItem(tiddler,uri) + "\n</item>" instead
|
|||
|
Tiddler.prototype.saveToRss = function(uri)
|
|||
|
{
|
|||
|
return "<item>\n" + tiddlerToRssItem(this,uri) + "\n</item>";
|
|||
|
};
|
|||
|
|
|||
|
// @Deprecated: Use jQuery.encoding.digests.hexSha1Str instead
|
|||
|
Tiddler.prototype.generateFingerprint = function()
|
|||
|
{
|
|||
|
return "0x" + Crypto.hexSha1Str(this.text);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated Number functions
|
|||
|
//--
|
|||
|
|
|||
|
// @Deprecated: no direct replacement, since not used in core code
|
|||
|
// Clamp a number to a range
|
|||
|
Number.prototype.clamp = function(min,max)
|
|||
|
{
|
|||
|
var c = this;
|
|||
|
if(c < min)
|
|||
|
c = min;
|
|||
|
if(c > max)
|
|||
|
c = max;
|
|||
|
return Number(c);
|
|||
|
};
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated utility functions
|
|||
|
//-- Use the jQuery functions directly instead
|
|||
|
//--
|
|||
|
|
|||
|
// Remove all children of a node
|
|||
|
function removeChildren(e)
|
|||
|
{
|
|||
|
jQuery(e).empty();
|
|||
|
}
|
|||
|
|
|||
|
// Remove a node and all it's children
|
|||
|
function removeNode(e)
|
|||
|
{
|
|||
|
jQuery(e).remove();
|
|||
|
}
|
|||
|
|
|||
|
// Return the content of an element as plain text with no formatting
|
|||
|
function getPlainText(e)
|
|||
|
{
|
|||
|
return jQuery(e).text();
|
|||
|
}
|
|||
|
|
|||
|
function addClass(e,className)
|
|||
|
{
|
|||
|
jQuery(e).addClass(className);
|
|||
|
}
|
|||
|
|
|||
|
function removeClass(e,className)
|
|||
|
{
|
|||
|
jQuery(e).removeClass(className);
|
|||
|
}
|
|||
|
|
|||
|
function hasClass(e,className)
|
|||
|
{
|
|||
|
return jQuery(e).hasClass(className);
|
|||
|
}
|
|||
|
|
|||
|
//--
|
|||
|
//-- Deprecated Wikifier code
|
|||
|
//--
|
|||
|
|
|||
|
function wikifyPlain(title,theStore,limit)
|
|||
|
{
|
|||
|
if(!theStore)
|
|||
|
theStore = store;
|
|||
|
if(theStore.tiddlerExists(title) || theStore.isShadowTiddler(title)) {
|
|||
|
return wikifyPlainText(theStore.getTiddlerText(title),limit,tiddler);
|
|||
|
} else {
|
|||
|
return "";
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
<script id="jslibArea" type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
/*! jQuery v1.6.4 http://jquery.com/ | http://jquery.org/license */
|
|||
|
(function(a,b){function cu(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cr(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cq(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cp(){cn=b}function co(){setTimeout(cp,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bA.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bW(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bP,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bW(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bW(a,c,d,e,"*",g));return l}function bV(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bL),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function by(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bt:bu;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bv(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bl(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bd,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bk(a){f.nodeName(a,"input")?bj(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bj)}function bj(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bi(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bh(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a
|
|||
|
t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,M(a.origType,a.selector),f.extend({},a,{handler:L,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,M(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?D:C):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=D;var a=this.originalEvent;!a||(a.preventDefault?a.prev
|
|||
|
(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bh(a,d),e=bi(a),g=bi(d);for(h=0;e[h];++h)g[h]&&bh(e[h],g[h])}if(b){bg(a,d);if(c){e=bi(a),g=bi(d);for(h=0;e[h];++h)bg(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1></$2>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=be[l]||be._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bk(k[i]);else bk(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bc.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bm=/alpha\([^)]*\)/i,bn=/opacity=([^)]*)/,bo=/([A-Z]|^ms)/g,bp=/^-?\d+(?:px)?$/i,bq=/^-?\d/,br=/^([\-+])=([\-+.\de]+)/,bs={position:"absolute",visibility:"hidden",display:"block"},bt=["Left","Right"],bu=["Top","Bottom"],bv,bw,bx;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bv(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=br.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bv)return bv(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:fu
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
<script id="jqueryArea" type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
/*
|
|||
|
jQuery.encoding.digests.sha1.js
|
|||
|
|
|||
|
SHA-1 digest and associated utility functions
|
|||
|
|
|||
|
Copyright (c) UnaMesa Association 2009
|
|||
|
|
|||
|
Dual licensed under the MIT and GPL licenses:
|
|||
|
http://www.opensource.org/licenses/mit-license.php
|
|||
|
http://www.gnu.org/licenses/gpl.html
|
|||
|
*/
|
|||
|
|
|||
|
(function($) {
|
|||
|
|
|||
|
if(!$.encoding)
|
|||
|
$.encoding = {};
|
|||
|
$.extend($.encoding,{
|
|||
|
strToBe32s: function(str) {
|
|||
|
// Convert a string to an array of big-endian 32-bit words
|
|||
|
var be=[];
|
|||
|
var len=Math.floor(str.length/4);
|
|||
|
var i, j;
|
|||
|
for(i=0, j=0; i<len; i++, j+=4) {
|
|||
|
be[i]=((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
|
|||
|
}
|
|||
|
while(j<str.length) {
|
|||
|
be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
|
|||
|
j++;
|
|||
|
}
|
|||
|
return be;
|
|||
|
},
|
|||
|
be32sToStr: function(be) {
|
|||
|
// Convert an array of big-endian 32-bit words to a string
|
|||
|
var str='';
|
|||
|
for(var i=0;i<be.length*32;i+=8) {
|
|||
|
str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
|
|||
|
}
|
|||
|
return str;
|
|||
|
},
|
|||
|
be32sToHex: function(be) {
|
|||
|
// Convert an array of big-endian 32-bit words to a hex string
|
|||
|
var hex='0123456789ABCDEF';
|
|||
|
var str='';
|
|||
|
for(var i=0;i<be.length*4;i++) {
|
|||
|
str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
|
|||
|
}
|
|||
|
return str;
|
|||
|
}
|
|||
|
});
|
|||
|
})(jQuery);
|
|||
|
|
|||
|
|
|||
|
(function($) {
|
|||
|
|
|||
|
if(!$.encoding.digests)
|
|||
|
$.encoding.digests = {};
|
|||
|
$.extend($.encoding.digests,{
|
|||
|
hexSha1Str: function(str) {
|
|||
|
// Return, in hex, the SHA-1 hash of a string
|
|||
|
return $.encoding.be32sToHex($.encoding.digests.sha1Str(str));
|
|||
|
},
|
|||
|
sha1Str: function(str) {
|
|||
|
// Return the SHA-1 hash of a string
|
|||
|
return sha1($.encoding.strToBe32s(str),str.length);
|
|||
|
},
|
|||
|
sha1: function(x,blen) {
|
|||
|
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
|||
|
return sha1($.encoding.strToBe32s(str),str.length);
|
|||
|
}
|
|||
|
});
|
|||
|
|
|||
|
// Private functions.
|
|||
|
function sha1(x,blen) {
|
|||
|
// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
|
|||
|
function add32(a,b) {
|
|||
|
// Add 32-bit integers, wrapping at 32 bits
|
|||
|
// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
|||
|
var lsw=(a&0xFFFF)+(b&0xFFFF);
|
|||
|
var msw=(a>>16)+(b>>16)+(lsw>>16);
|
|||
|
return (msw<<16)|(lsw&0xFFFF);
|
|||
|
}
|
|||
|
function AA(a,b,c,d,e) {
|
|||
|
// Cryptographic round helper function. Add five 32-bit integers, wrapping at 32 bits, second parameter is rotated left 5 bits before the addition
|
|||
|
// Uses 16-bit operations internally to work around bugs in some JavaScript interpreters.
|
|||
|
b=(b>>>27)|(b<<5);
|
|||
|
var lsw=(a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
|
|||
|
var msw=(a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
|
|||
|
return (msw<<16)|(lsw&0xFFFF);
|
|||
|
}
|
|||
|
function RR(w,j) {
|
|||
|
// Cryptographic round helper function.
|
|||
|
var n=w[j-3]^w[j-8]^w[j-14]^w[j-16];
|
|||
|
return (n>>>31)|(n<<1);
|
|||
|
}
|
|||
|
|
|||
|
var len=blen*8;
|
|||
|
x[len>>5] |= 0x80 << (24-len%32);
|
|||
|
x[((len+64>>9)<<4)+15]=len;
|
|||
|
var w=new Array(80);
|
|||
|
|
|||
|
var k1=0x5A827999;
|
|||
|
var k2=0x6ED9EBA1;
|
|||
|
var k3=0x8F1BBCDC;
|
|||
|
var k4=0xCA62C1D6;
|
|||
|
|
|||
|
var h0=0x67452301;
|
|||
|
var h1=0xEFCDAB89;
|
|||
|
var h2=0x98BADCFE;
|
|||
|
var h3=0x10325476;
|
|||
|
var h4=0xC3D2E1F0;
|
|||
|
|
|||
|
for(var i=0;i<x.length;i+=16) {
|
|||
|
var j=0;
|
|||
|
var t;
|
|||
|
var a=h0;
|
|||
|
var b=h1;
|
|||
|
var c=h2;
|
|||
|
var d=h3;
|
|||
|
var e=h4;
|
|||
|
while(j<16) {
|
|||
|
w[j]=x[i+j];
|
|||
|
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
|||
|
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
|||
|
}
|
|||
|
while(j<20) {
|
|||
|
w[j]=RR(w,j);
|
|||
|
t=AA(e,a,d^(b&(c^d)),w[j],k1);
|
|||
|
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
|||
|
}
|
|||
|
while(j<40) {
|
|||
|
w[j]=RR(w,j);
|
|||
|
t=AA(e,a,b^c^d,w[j],k2);
|
|||
|
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
|||
|
}
|
|||
|
while(j<60) {
|
|||
|
w[j]=RR(w,j);
|
|||
|
t=AA(e,a,(b&c)|(d&(b|c)),w[j],k3);
|
|||
|
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
|||
|
}
|
|||
|
while(j<80) {
|
|||
|
w[j]=RR(w,j);
|
|||
|
t=AA(e,a,b^c^d,w[j],k4);
|
|||
|
e=d; d=c; c=(b>>>2)|(b<<30); b=a; a=t; j++;
|
|||
|
}
|
|||
|
h0=add32(h0,a);
|
|||
|
h1=add32(h1,b);
|
|||
|
h2=add32(h2,c);
|
|||
|
h3=add32(h3,d);
|
|||
|
h4=add32(h4,e);
|
|||
|
}
|
|||
|
return [h0,h1,h2,h3,h4];
|
|||
|
}
|
|||
|
})(jQuery);
|
|||
|
/*
|
|||
|
jQuery.twStylesheet.js
|
|||
|
|
|||
|
jQuery plugin to dynamically insert CSS rules into a document
|
|||
|
|
|||
|
Usage:
|
|||
|
jQuery.twStylesheet applies style definitions
|
|||
|
jQuery.twStylesheet.remove neutralizes style definitions
|
|||
|
|
|||
|
Copyright (c) UnaMesa Association 2009
|
|||
|
|
|||
|
Triple licensed under the BSD, MIT and GPL licenses:
|
|||
|
http://www.opensource.org/licenses/bsd-license.php
|
|||
|
http://www.opensource.org/licenses/mit-license.php
|
|||
|
http://www.gnu.org/licenses/gpl.html
|
|||
|
*/
|
|||
|
|
|||
|
(function($) {
|
|||
|
|
|||
|
var defaultId = "customStyleSheet"; // XXX: rename to dynamicStyleSheet?
|
|||
|
|
|||
|
// Add or replace a style sheet
|
|||
|
// css argument is a string of CSS rule sets
|
|||
|
// options.id is an optional name identifying the style sheet
|
|||
|
// options.doc is an optional document reference
|
|||
|
// N.B.: Uses DOM methods instead of jQuery to ensure cross-browser comaptibility.
|
|||
|
$.twStylesheet = function(css, options) {
|
|||
|
options = options || {};
|
|||
|
var id = options.id || defaultId;
|
|||
|
var doc = options.doc || document;
|
|||
|
var el = doc.getElementById(id);
|
|||
|
if(doc.createStyleSheet) { // IE-specific handling
|
|||
|
if(el) {
|
|||
|
el.parentNode.removeChild(el);
|
|||
|
}
|
|||
|
doc.getElementsByTagName("head")[0].insertAdjacentHTML("beforeEnd",
|
|||
|
' <style id="' + id + '" type="text/css">' + css + '</style>'); // fails without
|
|||
|
} else { // modern browsers
|
|||
|
if(el) {
|
|||
|
el.replaceChild(doc.createTextNode(css), el.firstChild);
|
|||
|
} else {
|
|||
|
el = doc.createElement("style");
|
|||
|
el.type = "text/css";
|
|||
|
el.id = id;
|
|||
|
el.appendChild(doc.createTextNode(css));
|
|||
|
doc.getElementsByTagName("head")[0].appendChild(el);
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
// Remove existing style sheet
|
|||
|
// options.id is an optional name identifying the style sheet
|
|||
|
// options.doc is an optional document reference
|
|||
|
$.twStylesheet.remove = function(options) {
|
|||
|
options = options || {};
|
|||
|
var id = options.id || defaultId;
|
|||
|
var doc = options.doc || document;
|
|||
|
var el = doc.getElementById(id);
|
|||
|
if(el) {
|
|||
|
el.parentNode.removeChild(el);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
})(jQuery);
|
|||
|
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
<script type="text/javascript">
|
|||
|
//<![CDATA[
|
|||
|
if(useJavaSaver)
|
|||
|
document.write("<applet style='position:absolute;left:-1px' name='TiddlySaver' code='TiddlySaver.class' archive='TiddlySaver.jar' width='1' height='1'></applet>");
|
|||
|
//]]>
|
|||
|
</script>
|
|||
|
<!--POST-SCRIPT-START-->
|
|||
|
|
|||
|
<!--POST-SCRIPT-END-->
|
|||
|
</body>
|
|||
|
</html>
|