A small request: could you make the link to the just-uploaded file more
obvious? The "Uploaded to Shared Records" is obviously a link, but it
isn't clear to what it links.
Saq Imtiaz wrote:
> I've come up with a partial solution for uploading TiddlyWiki files to
> Shared Records.
>
> The limitations of my implementation are:
>
> * The last saved version of the TiddlyWiki file is uploaded. If
> you've been editing the file and have not saved it, those
> changes are not included. (They could be included for files
> being edited locally, but not for remote files. So in the
> interest of keeping the user experience the same, I haven't
> saved the changes in either case)
> * Uploading an online/remote TiddlyWiki file is reliant on a
> simple server-side script. Currently this script is run off one
> of my servers, but could be hosted on Shared Records if desired.
> Note that the same script hosted on my server or Shared Records
> can be used by TiddlyWiki's on any domain.
> * It is not possible to save a 'upload history' tiddler for
> vanilla remote/online TiddlyWiki files since they would need be
> to able to save themselves. The upload log is only
> created/updated if the the file is not readOnly and has the
> ability to save itself (UploadPlugin/WebDavPlugin etc)
>
> Features:
>
> * The user experience is the same whether using an online or local
> TiddlyWiki file, just click a 'upload to SR' button.
> * Is not limited by cross-domain restrictions and end users dont
> need to deploy any server-side scripts
> * An upload log is created if the file is not readOnly
> * There is a bookmarklet version, which can be used to upload any
> local or remote TiddlyWiki file to Shared Records
> * There is a bookmarklet that allows any online html file to be
> saved to Shared Records
>
> Online demo: http://test.tiddlythemes.com/sruploaddemo.html
> Local demo attached.
> Bookmarklets: http://api.lewcid.org/sharedrecords/bookmarklets.html
>
> Code in SVN:
> http://svn.tiddlywiki.org/Trunk/contributors/SaqImtiaz/plugins/SharedRecordsUpload/
> <http://svn.tiddlywiki.org/Trunk/contributors/SaqImtiaz/plugins/SharedRecordsUpload/>
>
> Regards,
>
> Saq Imtiaz
> PS: Using the local version you might get a 'non responsive script'
> message. This is caused by the SHA1 code that TiddlyWiki's Crypto
> library has, which is used to calculate the hash. It might be worth
> exploring if there is a more efficient implementation.
>
> --
> Tiddly Learning ( http://lewcid.org ) : TiddlyWiki news, plugins,
> themes and educational usage
> ------------------------------------------------------------------------
>
> Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007
> UnaMesa Association
> <!--{{{-->
> <link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
> <!--}}}-->
> 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
> /*{{{*/
> 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]];}
>
> #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]];}
>
> .sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
> .sparktick {background:[[ColorPalette::PrimaryDark]];}
>
> .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]];}
>
> #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)';}
> /*}}}*/
> /*{{{*/
> * 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 0em 1em 1em; left:-1px; top:-1px;}
> .headerForeground {position:absolute; padding:4.5em 0em 1em 1em; left:0px; top:0px;}
>
> .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:0em 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 .3em 0;}
> #sidebarTabs .tabContents {width:15em; overflow:hidden;}
>
> .wizard {padding:0.1em 1em 0em 2em;}
> .wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
> .wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0em 0em 0em 0em; margin:0.4em 0em 0.2em 0em;}
> .wizardStep {padding:1em 1em 1em 1em;}
> .wizard .button {margin:0.5em 0em 0em 0em; font-size:1.2em;}
> .wizardFooter {padding:0.8em 0.4em 0.8em 0em;}
> .wizardFooter .status {padding:0em 0.4em 0em 0.4em; margin-left:1em;}
> .wizard .button {padding:0.1em 0.2em 0.1em 0.2em;}
>
> #messageArea {position:fixed; top:2em; right:0em; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
> .messageToolbar {display:block; text-align:right; padding:0.2em 0.2em 0.2em 0.2em;}
> #messageArea a {text-decoration:underline;}
>
> .tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
> .popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
> .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 0em 0em 0.5em;}
> .tab {margin:0em 0em 0em 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 0em 14em;}
>
> .toolbar {text-align:right; font-size:.9em;}
>
> .tiddler {padding:1em 1em 0em 1em;}
>
> .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:0em 0.25em; padding:0em 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:0px 3px 0px 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 0em; font-size:.9em;}
> .editorFooter .button {padding-top:0px; padding-bottom:0px;}
>
> .fieldsetFix {border:0; padding:0; margin:1px 0px 1px 0px;}
>
> .sparkline {line-height:1em;}
> .sparktick {outline:0;}
>
> .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 0.3em 0.5em;}
> #backstageToolbar {position:relative;}
> #backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
> #backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
> #backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
> #backstage {position:relative; width:100%; z-index:50;}
> #backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
> .backstagePanelFooter {padding-top:0.2em; float:right;}
> .backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
> #backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}
>
> .whenBackstage {display:none;}
> .backstageVisible .whenBackstage {display:block;}
> /*}}}*/
> /***
> 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;}
> /*}}}*/
> /*{{{*/
> @media print {
> #mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none ! important;}
> #displayArea {margin: 1em 1em 0em 1em;}
> /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
> noscript {display:none;}
> }
> /*}}}*/
> <!--{{{-->
> <div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
> <div class='headerShadow'>
> <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
> <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
> </div>
> <div class='headerForeground'>
> <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>
> <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>
> <!--}}}-->
> <!--{{{-->
> <div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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>
> <!--}}}-->
> <!--{{{-->
> <div class='toolbar' macro='toolbar +saveTiddler -cancelTiddler deleteTiddler'></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'></span></div>
> <!--}}}-->
> 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>>
> 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
> <<importTiddlers>>
> /***
> |''Name:''|CryptoFunctionsPlugin|
> |''Description:''|Support for cryptographic functions|
> ***/
> //{{{
> if(!version.extensions.CryptoFunctionsPlugin) {
> version.extensions.CryptoFunctionsPlugin = {installed:true};
>
> //--
> //-- Crypto functions and associated conversion routines
> //--
>
> // Crypto "namespace"
> function Crypto() {}
>
> // Convert a string to an array of big-endian 32-bit words
> Crypto.strToBe32s = function(str)
> {
> var be = Array();
> 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;
> };
>
> // Convert an array of big-endian 32-bit words to a string
> Crypto.be32sToStr = function(be)
> {
> var str = "";
> for(var i=0;i<be.length*32;i+=8)
> str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
> return str;
> };
>
> // Convert an array of big-endian 32-bit words to a hex string
> Crypto.be32sToHex = function(be)
> {
> 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;
> };
>
> // Return, in hex, the SHA-1 hash of a string
> Crypto.hexSha1Str = function(str)
> {
> return Crypto.be32sToHex(Crypto.sha1Str(str));
> };
>
> // Return the SHA-1 hash of a string
> Crypto.sha1Str = function(str)
> {
> return Crypto.sha1(Crypto.strToBe32s(str),str.length);
> };
>
> // Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
> Crypto.sha1 = function(x,blen)
> {
> // Add 32-bit integers, wrapping at 32 bits
> add32 = function(a,b)
> {
> var lsw = (a&0xFFFF)+(b&0xFFFF);
> var msw = (a>>16)+(b>>16)+(lsw>>16);
> return (msw<<16)|(lsw&0xFFFF);
> };
> // Add five 32-bit integers, wrapping at 32 bits
> add32x5 = function(a,b,c,d,e)
> {
> 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);
> };
> // Bitwise rotate left a 32-bit integer by 1 bit
> rol32 = function(n)
> {
> return (n>>>31)|(n<<1);
> };
>
> var len = blen*8;
> // Append padding so length in bits is 448 mod 512
> x[len>>5] |= 0x80 << (24-len%32);
> // Append length
> x[((len+64>>9)<<4)+15] = len;
> var w = 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,t;
> var a = h0;
> var b = h1;
> var c = h2;
> var d = h3;
> var e = h4;
> for(j = 0;j<16;j++) {
> w[j] = x[i+j];
> t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
> e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
> }
> for(j=16;j<20;j++) {
> w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
> t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
> e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
> }
> for(j=20;j<40;j++) {
> w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
> t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
> e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
> }
> for(j=40;j<60;j++) {
> w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
> t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
> e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
> }
> for(j=60;j<80;j++) {
> w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
> t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
> e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
> }
>
> h0 = add32(h0,a);
> h1 = add32(h1,b);
> h2 = add32(h2,c);
> h3 = add32(h3,d);
> h4 = add32(h4,e);
> }
> return Array(h0,h1,h2,h3,h4);
> };
>
>
> }
> //}}}
> /***
> |''Name:''|DeprecatedFunctionsPlugin|
> |''Description:''|Support for deprecated functions removed from core|
> ***/
> //{{{
> if(!version.extensions.DeprecatedFunctionsPlugin) {
> version.extensions.DeprecatedFunctionsPlugin = {installed:true};
>
> //--
> //-- 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");
>
> }
> //}}}
> <<sharedRecordsUpload>>
> /***
> |''Name:''|LegacyStrikeThroughPlugin|
> |''Description:''|Support for legacy (pre 2.1) strike through formatting|
> |''Version:''|1.0.2|
> |''Date:''|Jul 21, 2006|
> |''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
> |''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
> |''License:''|[[BSD open source license]]|
> |''CoreVersion:''|2.1.0|
> ***/
>
> //{{{
> // Ensure that the LegacyStrikeThrough Plugin is only installed once.
> if(!version.extensions.LegacyStrikeThroughPlugin) {
> version.extensions.LegacyStrikeThroughPlugin = {installed:true};
>
> config.formatters.push(
> {
> name: "legacyStrikeByChar",
> match: "==",
> termRegExp: /(==)/mg,
> element: "strike",
> handler: config.formatterHelpers.createElementAndWikify
> });
>
> } //# end of "install only once"
> //}}}
> config.macros.sharedRecordsBackup={
> handler : function(place,macroName,params,wikifier,paramString,tiddler){
> createTiddlyButton(place,"backup","backup",this.onclick);
> },
>
> onclick : function(e){
> var callback = function(status,params,responseText,url,xhr){
> if(status){
> displayMessage("backup saved to: "+url,url);
> console.log(xhr)
> }
> else{
> displayMessage("error saving backup: "+xhr.statusText + xhr.responseText+url);
> }
> };
>
> var originalPath = document.location.toString();
> var localPath = getLocalPath(originalPath);
> var original = loadFile(localPath);
> var posDiv = locateStoreArea(original);
> var revised = updateOriginal(original,posDiv);
> var hash = Crypto.hexSha1Str(convertUnicodeToUTF8(revised)).toLowerCase();
> var path = "http://sra.sharedrecords.org:8080/SRCDataStore/RESTServlet/"+hash;
>
> doHttp("PUT",path,revised,"text/html",null,null,callback,null,{'Content-Length':revised.length});
> }
> };
>
> config.macros.sharedRecordsBackupXss={
> handler : function(place,macroName,params,wikifier,paramString,tiddler){
> createTiddlyButton(place,"backup xss","backup",this.onclick);
> },
>
> onclick : function(e){
> var url = "http://tiddlypublisher.lewcid.org/xss.cgi";
> var params= {
> 'url' : document.location.toString(),
> callback : 'config.macros.sharedRecordsBackupXss.callback',
> mode: 'json'
> };
> xssRequest(url,params)
> },
>
> callback : function(status,statusText,code,body,url){
> if(status){
> displayMessage("backup saved to: "+url,url);
> }
> else{
> displayMessage("error saving backup: "+status+responseText+statusText);
> }
> }
>
> };
>
> function xssRequest(url,params){
> url = url + "?";
> for (var n in params){
> url += n+"="+params[n]+"&";
> }
> url+= "nocache=" + new Date().getTime();
> console.log(url);
>
> var script = createTiddlyElement(null,"script",null,null,null,{type:"text/javascript",src:url});
> document.getElementsByTagName("head")[0].appendChild(script);
> document.getElementsByTagName("head")[0].removeChild(script);
> }
>
>
>
> config.macros.sharedRecordsUpload={
> lingo : {
> label: "upload to SR",
> tooltip: "upload this file to Shared Records",
> error: "Error uploading to Shared Records",
> saving: "Uploading to Shared Records...",
> saved: "Uploaded to Shared Records",
> dateFormat: "0DD/0MM/YYYY 0hh:0mm:0ss",
> xssurl: "http://api.lewcid.org/sharedrecords/xss.cgi",
> SRServerPath: "http://sra.sharedrecords.org:8080/SRCDataStore/RESTServlet/"
> },
>
> handler : function(place,macroName,params,wikifier,paramString,tiddler){
> createTiddlyButton(place,this.lingo.label,this.lingo.tooltip,this.onclick);
> },
>
> onclick : function(e){
> clearMessage();
> displayMessage(config.macros.sharedRecordsUpload.lingo.saving);
> var protocol = document.location.protocol;
> if (protocol == 'http:' || protocol == 'https:'){
> var url = config.macros.sharedRecordsUpload.lingo.xssurl;
> var params= {
> 'url' : document.location.toString(),
> callback : 'config.macros.sharedRecordsUpload.callbackXss',
> mode: 'json'
> };
> xssRequest(url,params);
> }
> else{
> var originalPath = document.location.toString();
> var localPath = getLocalPath(originalPath);
> var original = loadFile(localPath);
> var revised = original;
> //var posDiv = locateStoreArea(original);
> //var revised = updateOriginal(original,posDiv);
> var hash = Crypto.hexSha1Str(unescape( encodeURIComponent(revised) ));
> var path = config.macros.sharedRecordsUpload.lingo.SRServerPath + hash;
> doHttp("PUT",path,revised,"text/html",null,null,config.macros.sharedRecordsUpload.callbackLocal,null,{'Content-Length':revised.length});
> }
> return false;
> },
>
> callbackXss : function(status,statusText,code,body,url){
> clearMessage();
> if(status){
> config.macros.sharedRecordsUpload.onUploaded(url);
> }
> else{
> displayMessage(config.macros.sharedRecordsUpload.lingo.error+"\nstatus:"+code+"\nresponseText:"+responseText+"\nstatusText:"+statusText+"\nurl:"+url);
> }
> },
>
> callbackLocal : function(status,params,responseText,url,xhr){
> clearMessage();
> if(status){
> config.macros.sharedRecordsUpload.onUploaded(url);
> }
> else{
> displayMessage(config.macros.sharedRecordsUpload.lingo.error+"\nstatus:"+xhr.status+"\nstatusText:"+xhr.statusText+"\nresponseText:"+responseText+"\nurl:"+url);
> }
> },
>
> onUploaded : function(url){
> url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
> displayMessage (config.macros.sharedRecordsUpload.lingo.saved,url);
> if(! readOnly){
> var tiddler = config.macros.sharedRecordsUpload.getLogTiddler();
> oldText = tiddler.text;
> store.setValue(tiddler,'text',oldText+"\n*[["+(new Date).formatString(config.macros.sharedRecordsUpload.lingo.dateFormat)+"|"+url+"]]");
> autoSaveChanges();
> }
> },
>
> getLogTiddler : function(){
> var tiddler = store.getTiddler("SharedRecordsUploadLog");
> if (!tiddler) {
> tiddler = new Tiddler();
> tiddler.title = "SharedRecordsUploadLog";
> tiddler.text = "!History of uploads to Shared Records\n";
> tiddler.created = new Date();
> tiddler.modifier = config.options.txtUserName;
> tiddler.modified = new Date();
> store.addTiddler(tiddler);
> }
> return tiddler;
> }
>
> };
>
> function xssRequest(url,params){
> url = url + "?";
> for (var n in params){
> url += n+"="+params[n]+"&";
> }
> url+= "nocache=" + new Date().getTime();
> scriptObj = document.createElement("script");
>
> scriptObj.setAttribute("type", "text/javascript");
> scriptObj.setAttribute("src", url);
> document.getElementsByTagName("head")[0].appendChild(scriptObj);
> //document.getElementsByTagName("head")[0].removeChild(scriptObj);
> }
>
>
>
> /***
> |''Name:''|SparklinePlugin|
> |''Description:''|Sparklines macro|
> ***/
> //{{{
> if(!version.extensions.SparklinePlugin) {
> version.extensions.SparklinePlugin = {installed:true};
>
> //--
> //-- Sparklines
> //--
>
> config.macros.sparkline = {};
> config.macros.sparkline.handler = function(place,macroName,params)
> {
> var data = [];
> var min = 0;
> var max = 0;
> var v;
> for(var t=0; t<params.length; t++) {
> v = parseInt(params[t]);
> if(v < min)
> min = v;
> if(v > max)
> max = v;
> data.push(v);
> }
> if(data.length < 1)
> return;
> var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
> box.title = data.join(",");
> var w = box.offsetWidth;
> var h = box.offsetHeight;
> box.style.paddingRight = (data.length * 2 - w) + "px";
> box.style.position = "relative";
> for(var d=0; d<data.length; d++) {
> var tick = document.createElement("img");
> tick.border = 0;
> tick.className = "sparktick";
> tick.style.position = "absolute";
> tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
> tick.style.left = d*2 + "px";
> tick.style.width = "2px";
> v = Math.floor(((data[d] - min)/(max-min)) * h);
> tick.style.top = (h-v) + "px";
> tick.style.height = v + "px";
> box.appendChild(tick);
> }
> };
>
>
> }
> //}}}
-Greg
On 12/12/07, Martin Budden <mjbu...@gmail.com> wrote:
> Saq,
>
> I was considering doing something along these lines now that I've got
> the Shared Records adaptor working, but you've beaten me to it!
>
> WRT the SHA1 code: the unfortunate fact of the matter is that
> calculating an SHA1 hash involves a lot of bit manipulation and
> javascript is not particularly good at bit manipulation. I spent quite
> a bit of time optimizing the SHA1 code. Having said that there is
> another version with unwound loops (it trades code size for speed) at:
>
> http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/SHA-1UnwoundPlugin.js
>
> You may wish to try that. I don't believe you will find a faster
> implementation of SHA1 in javascript anywhere (even if I do say so
> myself!). (Actually I think there is one possible improvement: there
> are 3 local functions which could be made global functions - this
> might make some minor speed improvements (because of the way
> javascript handles closures).)
>
> Martin
--
UnaMesa.org - Learning to Serve
I was considering doing something along these lines now that I've got
the Shared Records adaptor working, but you've beaten me to it!
WRT the SHA1 code: the unfortunate fact of the matter is that
calculating an SHA1 hash involves a lot of bit manipulation and
javascript is not particularly good at bit manipulation. I spent quite
a bit of time optimizing the SHA1 code. Having said that there is
another version with unwound loops (it trades code size for speed) at:
http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/SHA-1UnwoundPlugin.js
You may wish to try that. I don't believe you will find a faster
implementation of SHA1 in javascript anywhere (even if I do say so
myself!). (Actually I think there is one possible improvement: there
are 3 local functions which could be made global functions - this
might make some minor speed improvements (because of the way
javascript handles closures).)
Martin
On Dec 12, 2007 3:04 PM, Saq Imtiaz <lew...@gmail.com> wrote:
Saq Imtiaz wrote:
> Martin,
>
> One of things I would really like to do next week, is go over my two
> educational note-sharing scenarios and see how we can best implement
> those in light of the new API and adaptor. I think those use-cases
> will lead to a wider usage scenario than just the notes sharing, and
> will help us on the route towards using multiple servers and
> workspaces in one TiddlyWiki. Most importantly it will give you
> something concrete to work with while you develop the demo.
>
> Regarding the attached demo, doing a 'saveAndPut' throws the following
> error:
> *
> this.workspace has no properties
> [Break on this error] lookaheadRegExp: /^\|([^\n]*)\|([fhck]?)$/mg,
>
> Lastly, any ideas on how easy it might be to implement a Trac adaptor?
> Is there any API we can use?
>
> Martin, can we go ahead and reserve a conference room at Osmosoft to
> use for next week's call?
>
> Cheers,
> Saq
> *
>
> On Dec 12, 2007 7:29 PM, Greg Wolff <greg...@unamesa.org
> <mailto:greg...@unamesa.org>> wrote:
>
> Here's a screen shot of the errors that I've run into in trying to
> import.
>
> -Greg
>
> On 12/12/07, Martin Budden <mjbu...@gmail.com
> <mailto:mjbu...@gmail.com>> wrote:
> > Saq,
> >
> > I was considering doing something along these lines now that
> I've got
> > the Shared Records adaptor working, but you've beaten me to it!
> >
> > WRT the SHA1 code: the unfortunate fact of the matter is that
> > calculating an SHA1 hash involves a lot of bit manipulation and
> > javascript is not particularly good at bit manipulation. I spent
> quite
> > a bit of time optimizing the SHA1 code. Having said that there is
> > another version with unwound loops (it trades code size for
> speed) at:
> >
> >
> http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/plugins/SHA-1UnwoundPlugin.js
>
> >
> > You may wish to try that. I don't believe you will find a faster
> > implementation of SHA1 in javascript anywhere (even if I do say so
> > myself!). (Actually I think there is one possible improvement:
> there
> > are 3 local functions which could be made global functions - this
> > might make some minor speed improvements (because of the way
> > javascript handles closures).)
> >
> > Martin
> >
> > On Dec 12, 2007 3:04 PM, Saq Imtiaz < lew...@gmail.com
I look forward to discussing the scenarios next week.
Thanks for the bug report - I'll look into it. I'll also see if it's
possible to reserve a conference room at osmosoft for the call next
week.
On the subject of the trac adaptor, the JSPWiki adaptor at:
http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/JSPWikiAdaptorPlugin.js
uses XML-RPC and can be used as a basis for an adaptor using the Trac
XML-RPC API that Andreas linked to.
Martin
On Dec 12, 2007 6:53 PM, Saq Imtiaz <lew...@gmail.com> wrote:
> Martin,
>
> One of things I would really like to do next week, is go over my two
> educational note-sharing scenarios and see how we can best implement those
> in light of the new API and adaptor. I think those use-cases will lead to a
> wider usage scenario than just the notes sharing, and will help us on the
> route towards using multiple servers and workspaces in one TiddlyWiki. Most
> importantly it will give you something concrete to work with while you
> develop the demo.
>
> Regarding the attached demo, doing a 'saveAndPut' throws the following
> error:
> this.workspace has no properties