508a509,994 >
//{{{ > config.options.txtTheme = "WritableTheme"; > //}}}>
/*** > |''Name''|HTTPSavingPlugin| > |''Description''|<...>| > |''Author''|Zooko| > |''Contributors''|FND| > |''Version''|0.2.1| > |''Status''|@@experimental@@| > |''Source''|http://allmydata.org/trac/tiddly_on_tahoe| > |''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/| > |''License''|GPLv2+ or TGPPLv1.0+| > |''Keywords''|<...>| > !Description > <...> > !Notes > This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]]. > ***/ > /* The following comment is to let jslint know which variables are supposed to be global. */ > /*global clearMessage, config, getPath, readOnly, saveChanges, saveTest, showBackstage, store, story, version, convertUriToUTF8, convertUnicodeToFileFormat, getLocalPath, loadRemoteFile, locateStoreArea, saveBackup, saveEmpty, saveFile, saveMain, saveRss, unescape, displayMessage, httpReq */ > //{{{ > if (!version.extensions.HTTPSavingPlugin) { //# ensure that the plugin is only installed once > version.extensions.HTTPSavingPlugin = { installed: true }; > > (function () { //# wrapper > readOnly = false; > config.options.chkHttpReadOnly = false; > showBackstage = true; > > saveTest = function () { > var s = document.getElementById("saveTest"); > /*if (s.hasChildNodes()) { > alert(config.messages.savedSnapshotError); > }*/ > s.appendChild(document.createTextNode("savetest")); > }; > > // Save this TiddlyWiki with the pending changes > saveChanges = function (onlyIfDirty, tiddlers) { > var originalPath, localCallback, result; > if (onlyIfDirty && !store.isDirty()) { > return; > } > clearMessage(); > // Get the URL of the document > originalPath = getPath(document.location.toString()); > // Load the original file > localCallback = function (status, context, original, url, xhr) { > //log("loaded remote file from ", originalPath); > /*log("got callback status ", status, "\n", context: ", context, "\n", > URL: ", url, "\n", XHR: ", xhr);*/ > if (original === null) { > alert(config.messages.cantSaveError); > if (store.tiddlerExists(config.messages.saveInstructions)) { > story.displayTiddler(null, config.messages.saveInstructions); > } > return; > } > // Locate the storeArea div's > var posDiv = locateStoreArea(original); > if (!posDiv) { > alert(config.messages.invalidFileError.format([originalPath])); > return; > } > saveRss(originalPath); > saveEmpty(originalPath, original, posDiv); > saveMain(originalPath, original, posDiv); > }; > result = loadRemoteFile(originalPath, localCallback); > //log("result from loadRemoteFile: ", result); > return true; > }; > > // override and disable saveBackup() > saveBackup = function (localPath, original) {}; > > // override and disable getLocalPath() > getLocalPath = function (origPath) {}; > > // override getPath() > getPath = function (origPath) { > var originalPath, argPos, hashPos, resultPath; > originalPath = convertUriToUTF8(origPath, config.options.txtFileSystemCharSet); > // Remove any location or query part of the URL > argPos = originalPath.indexOf("?"); > if (argPos !== -1) { > originalPath = originalPath.substr(0, argPos); > } > 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 > if (originalPath.indexOf("http://") === 0) { // HTTP file > resultPath = originalPath; > } else if (originalPath.charAt(9) === ":") { // PC local file > resultPath = unescape(originalPath.substr(8)).replace(new RegExp("/", "g"), "\\"); > } else if (originalPath.indexOf("file://///") === 0) { // Firefox PC network file > resultPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/", "g"), "\\"); > } else if (originalPath.indexOf("file:///") === 0) { // *nix local file > resultPath = unescape(originalPath.substr(7)); > } else if (originalPath.indexOf("file:/") === 0) { // *nix local file > resultPath = unescape(originalPath.substr(5)); > } else { // PC local file > resultPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/", "g"), "\\"); > } > return resultPath; > }; > > // override saveFile() > saveFile = function (fileUrl, content, callb) { > displayMessage("saving... please wait"); // XXX: belongs into command handler -- TODO: i18n > //alert("whee! about to save to " + fileUrl); > var localCallback = function (status, params, responseText, url, xhr) { > if (!status) { > displayMessage("saving failed: " + responseText); > } > }; > return httpReq("PUT", fileUrl, localCallback, null, null, content, "text/html;charset=utf-8"); > }; > > // override convertUnicodeToFileFormat() > convertUnicodeToFileFormat = function (s) > { > return s; > }; > > })(); //# end of wrapper > } //# end of "install only once" > //}}} >>
<!--{{{--> > <div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'> > <div class='headerShadow'> > <div id='accessControlExplanationDivId' macro='accessControlExplanation'></div> > <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span> > <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span> > </div> > <div class='headerForeground'> > <div id='accessControlExplanationDivId' macro='accessControlExplanation'></div> > <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> > <!--}}}-->>
/*** > |''Name''|HTTPSavingPlugin| > |''Description''|<...>| > |''Author''|Zooko| > |''Contributors''|FND| > |''Version''|0.2.1| > |''Status''|@@experimental@@| > |''Source''|http://allmydata.org/trac/tiddly_on_tahoe| > |''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/| > |''License''|GPLv2+ or TGPPLv1.0+| > |''Keywords''|<...>| > !Description > <...> > !Notes > This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]]. > ***/ > /* The following comment is to let jslint know which variables are supposed to be global. */ > /*global clearMessage, config, getPath, readOnly, saveChanges, saveTest, showBackstage, store, story, version, convertUriToUTF8, convertUnicodeToFileFormat, getLocalPath, loadRemoteFile, locateStoreArea, saveBackup, saveEmpty, saveFile, saveMain, saveRss, unescape, displayMessage, httpReq */ > //{{{ > if (!version.extensions.HTTPSavingPlugin) { //# ensure that the plugin is only installed once > version.extensions.HTTPSavingPlugin = { installed: true }; > > (function () { //# wrapper > readOnly = false; > config.options.chkHttpReadOnly = false; > showBackstage = true; > > saveTest = function () { > var s = document.getElementById("saveTest"); > /*if (s.hasChildNodes()) { > alert(config.messages.savedSnapshotError); > }*/ > s.appendChild(document.createTextNode("savetest")); > }; > > // Save this TiddlyWiki with the pending changes > saveChanges = function (onlyIfDirty, tiddlers) { > var originalPath, localCallback, result; > if (onlyIfDirty && !store.isDirty()) { > return; > } > clearMessage(); > // Get the URL of the document > originalPath = getPath(document.location.toString()); > // Load the original file > localCallback = function (status, context, original, url, xhr) { > //log("loaded remote file from ", originalPath); > /*log("got callback status ", status, "\n", context: ", context, "\n", > URL: ", url, "\n", XHR: ", xhr);*/ > if (original === null) { > alert(config.messages.cantSaveError); > if (store.tiddlerExists(config.messages.saveInstructions)) { > story.displayTiddler(null, config.messages.saveInstructions); > } > return; > } > // Locate the storeArea div's > var posDiv = locateStoreArea(original); > if (!posDiv) { > alert(config.messages.invalidFileError.format([originalPath])); > return; > } > saveRss(originalPath); > saveEmpty(originalPath, original, posDiv); > saveMain(originalPath, original, posDiv); > }; > result = loadRemoteFile(originalPath, localCallback); > //log("result from loadRemoteFile: ", result); > return true; > }; > > // override and disable saveBackup() > saveBackup = function (localPath, original) {}; > > // override and disable getLocalPath() > getLocalPath = function (origPath) {}; > > // override getPath() > getPath = function (origPath) { > var originalPath, argPos, hashPos, resultPath; > originalPath = convertUriToUTF8(origPath, config.options.txtFileSystemCharSet); > // Remove any location or query part of the URL > argPos = originalPath.indexOf("?"); > if (argPos !== -1) { > originalPath = originalPath.substr(0, argPos); > } > 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 > if (originalPath.indexOf("http://") === 0) { // HTTP file > resultPath = originalPath; > } else if (originalPath.charAt(9) === ":") { // PC local file > resultPath = unescape(originalPath.substr(8)).replace(new RegExp("/", "g"), "\\"); > } else if (originalPath.indexOf("file://///") === 0) { // Firefox PC network file > resultPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/", "g"), "\\"); > } else if (originalPath.indexOf("file:///") === 0) { // *nix local file > resultPath = unescape(originalPath.substr(7)); > } else if (originalPath.indexOf("file:/") === 0) { // *nix local file > resultPath = unescape(originalPath.substr(5)); > } else { // PC local file > resultPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/", "g"), "\\"); > } > return resultPath; > }; > > // override saveFile() > saveFile = function (fileUrl, content, callb) { > displayMessage("saving... please wait"); // XXX: belongs into command handler -- TODO: i18n > //alert("whee! about to save to " + fileUrl); > var localCallback = function (status, params, responseText, url, xhr) { > if (!status) { > displayMessage("saving failed: " + responseText); > } > }; > return httpReq("PUT", fileUrl, localCallback, null, null, content, "text/html;charset=utf-8"); > }; > > // override convertUnicodeToFileFormat() > convertUnicodeToFileFormat = function (s) > { > return s; > }; > > })(); //# end of wrapper > } //# end of "install only once" > //}}} > /*** > |''Name''|TahoePlugin| > |''Description''|<...>| > |''Author''|Zooko| > |''Contributors''|FND, EricShulman| > |''Version''|0.2.0| > |''Requires''|HTTPSavingPlugin| > |''Status''|@@experimental@@| > |''Source''|http://allmydata.org/trac/tiddly_on_tahoe| > |''CodeRepository''|http://allmydata.org/source/tiddly_on_tahoe/trunk/| > |''License''|GPLv2+ or TGPPLv1.0+| > |''Keywords''|<...>| > !Description > <...> > !Notes > This plugin is being developed for [[Tiddly on Tahoe|http://allmydata.org/trac/tiddly_on_tahoe]]. > ***/ > //{{{ > /* The following comment is to let jslint know which variables are supposed to be global. */ > /*global version, readOnly, showBackstage, config, loadRemoteFile, wikify */ > if (!version.extensions.TahoePlugin) { //# ensure that the plugin is only installed once > version.extensions.TahoePlugin = { installed: true }; > > (function () { //# wrapper > var BASE32CHAR, BASE32CHAR_3bits, BASE32CHAR_1bits, SEP, NUMBER, HTTPLEAD, BASE32STR_128bits, BASE32STR_256bits, ALPHANUMERIC_STRING, TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR, TAHOE_FUTURE_READONLY_CAP_RE_STR, TAHOE_FUTURE_WRITABLE_CAP_RE_STR, TAHOE_IMMUTABLE_CAP_RE_STR, TAHOE_READONLY_FILE_CAP_RE_STR, TAHOE_READONLY_DIR_CAP_RE_STR, TAHOE_WRITABLE_FILE_CAP_RE_STR, TAHOE_WRITABLE_DIR_CAP_RE_STR, TAHOE_NONWRITABLE_THING_CAP_RE_STR, TAHOE_WRITABLE_THING_CAP_RE_STR, TAHOE_ANY_CAP_RE_STR, splitTahoeURL, scrapeOutReadonlyCap, diminishToReadonlyCap, getReadonlyURLToThisPage; > > BASE32CHAR = '[abcdefghijklmnopqrstuvwxyz234567]'; > BASE32CHAR_3bits = '[aqiyemu4]'; > BASE32CHAR_1bits = '[aq]'; > SEP = '(?::|%3A)'; > NUMBER = '[0-9]+'; > HTTPLEAD = 'https?://(?:[^:/]+)(?::' + NUMBER + ')?/(uri|file|cap)/?'; > > BASE32STR_128bits = '(' + BASE32CHAR + '{25}' + BASE32CHAR_3bits + ')'; > BASE32STR_256bits = '(' + BASE32CHAR + '{51}' + BASE32CHAR_1bits + ')'; > > ALPHANUMERIC_STRING = '[A-Za-z0-9]+'; > > // This is speculative: maybe in the future there will be a version of Tahoe where caps > // start with these symbols, and if so then this JavaScript code will magically work with > // that version of Tahoe. > TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR = "i_" + ALPHANUMERIC_STRING; > TAHOE_FUTURE_READONLY_CAP_RE_STR = "r_" + ALPHANUMERIC_STRING; > TAHOE_FUTURE_WRITABLE_CAP_RE_STR = "W_" + ALPHANUMERIC_STRING; > > TAHOE_IMMUTABLE_CAP_RE_STR = "(?:URI" + SEP + "CHK" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits + SEP + NUMBER + SEP + NUMBER + SEP + NUMBER + '|' + TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR + ')'; > TAHOE_READONLY_FILE_CAP_RE_STR = "URI" + SEP + "SSK-RO" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits; > TAHOE_READONLY_DIR_CAP_RE_STR = "URI" + SEP + "DIR2-RO" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits; > TAHOE_WRITABLE_FILE_CAP_RE_STR = "URI" + SEP + "SSK" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits; > TAHOE_WRITABLE_DIR_CAP_RE_STR = "URI" + SEP + "DIR2" + SEP + BASE32STR_128bits + SEP + BASE32STR_256bits; > > TAHOE_NONWRITABLE_THING_CAP_RE_STR = '(' + TAHOE_READONLY_FILE_CAP_RE_STR + '|' + TAHOE_READONLY_DIR_CAP_RE_STR + '|' + TAHOE_IMMUTABLE_CAP_RE_STR + '|' + TAHOE_FUTURE_IMMUTABLE_CAP_RE_STR + '|' + TAHOE_FUTURE_READONLY_CAP_RE_STR + ')'; > TAHOE_WRITABLE_THING_CAP_RE_STR = '(' + TAHOE_WRITABLE_DIR_CAP_RE_STR + '|' + TAHOE_WRITABLE_FILE_CAP_RE_STR + '|' + TAHOE_FUTURE_WRITABLE_CAP_RE_STR + ')'; > > TAHOE_ANY_CAP_RE_STR = '(' + TAHOE_NONWRITABLE_THING_CAP_RE_STR + '|' + TAHOE_WRITABLE_THING_CAP_RE_STR + ')'; > > readOnly = document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_NONWRITABLE_THING_CAP_RE_STR)); > showBackstage = !readOnly; > config.options.chkHttpReadOnly = false; > > /* Returns server (which is "http://$HOST:$PORT/uri"), cap, and suffix, which can be a > path from the cap through the tahoe filesystem and/or trailing extra arguments. */ > splitTahoeURL = function (someURL) { > var u, urlSuffix, candidate_cap, urlPrefix; > > u = someURL.split('/'); > urlSuffix = []; > candidate_cap = u.pop(); > urlPrefix = u.join('/'); > while ((u.length > 0) && (!urlPrefix.match(new RegExp("^" + HTTPLEAD + "$")))) { > urlSuffix.unshift(candidate_cap); > candidate_cap = u.pop(); > urlPrefix = u.join('/'); > } > // Okay we've found the HTTPLEAD. Is the following thing shaped like a Tahoe capability? > if (candidate_cap.match(new RegExp(TAHOE_ANY_CAP_RE_STR))) { > // Yes! > return {'urlPrefix': urlPrefix, 'cap': candidate_cap, 'urlSuffix': urlSuffix}; > } else { > // No! > return; > } > }; > > scrapeOutReadonlyCap = function (metadata) { > // example of tahoe-lafs json-encoded metadata: > // [ > // "dirnode", > // { > // "rw_uri": "URI:DIR2:ouojn4oj2fa7fphdf54hz5bfaq:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", > // "ro_uri": "URI:DIR2-RO:sznrgoyz7lbjorhe4ipzcnmluy:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", > // "children": { > // "tw_empty.html": [ > // "filenode", > // { > // "mutable": false, > // "metadata": { > // "ctime": 1229263396.69, > // "mtime": 1229263396.69 > // }, > // "ro_uri": "URI:CHK:cofm2lm3ywu4r4efeqwjzuzyeq:dfw7oi65smf7dhtcx6wvr4ouazswprhwkvc3uopqtmvn3e7cactq:3:10:295520", > // "size": 295520 > // } > // ] > // }, > // "mutable": true > // } > //] > > // another example: > // [ > // "filenode", > // { > // "rw_uri": "URI:SSK:ouojn4oj2fa7fphdf54hz5bfaq:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", > // "mutable": true, > // "ro_uri": "URI:SSK-RO:sznrgoyz7lbjorhe4ipzcnmluy:rf56nzb6klj3ctvssqghy2ugalp6wundystbysxujodttrhxbqwa", > // "size": "?" > // } > // ] > var matchobj = metadata.match(new RegExp("^\\s*\\[[^\\[]*\"ro_uri\"\\s*:\\s*\"([^\"]*)\"")); > if (matchobj) { > return matchobj[1]; > } > }; > > diminishToReadonlyCap = function (urlPrefix, writableCap, callback) { > var queryURL = [urlPrefix, writableCap, "?t=json"].join("/"); > > loadRemoteFile(queryURL, function (success, param, txt, src, xhr) { > if (success) { > callback(scrapeOutReadonlyCap(txt)); > } > }); > }; > > getReadonlyURLToThisPage = function (callback) { > if (document.location.tahoeDiminishedCapabilityURL) { > return callback(document.location.tahoeDiminishedCapabilityURL); > } else { > var pieces = splitTahoeURL(document.location.toString()); > diminishToReadonlyCap(pieces.urlPrefix, pieces.cap, function (diminishedCap) { > var diminishedURL = pieces.urlPrefix + "/" + diminishedCap + "/" + pieces.urlSuffix; > document.location.tahoeDiminishedCapabilityURL = diminishedURL; > callback(diminishedURL); > }); > } > }; > > config.macros.accessControlExplanation = { > > handler: function (place, macroName, params, wikifier, paramString, tiddler) { > if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_IMMUTABLE_CAP_RE_STR))) { > wikify("This is an immutable view of this page. Using this link will always give this exact same page, even if a newer version has been uploaded.", place); > } else if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_NONWRITABLE_THING_CAP_RE_STR))) { > wikify("This is a read-only view of this page. Using this link will give the most recent version of this page, but doesn't allow the user to change the page.", place); > } else if (document.location.toString().match(new RegExp(HTTPLEAD + TAHOE_WRITABLE_THING_CAP_RE_STR))) { > getReadonlyURLToThisPage(function (readonlyCap) { > wikify("You are accessing this page with a writable link. If you share this link with someone else, they will gain the ability to write to this page. Click here for a [[read-only link to this page|" + readonlyCap + "]].", place); > }); > } else { > wikify("You are accessing this page not through the Tahoe-LAFS secure, distributed filesystem.", place); > } > } > }; > })(); //# end of wrapper > } //# end of "install only once" > //}}} >>
|StyleSheet|##AuthorStyles| > |StyleSheetReadOnly|##ReaderStyles| > > !AuthorStyles > /*{{{*/ > [[StyleSheet]] > body { > background: #eee; > } > /*}}}*/ > > !ReaderStyles > /*{{{*/ > [[StyleSheet]] > body { > } > /*}}}*/>