Welcome to TiddlyWiki created by Jeremy Ruston, Copyright © 2007 UnaMesa Association
EDB på HU
Forslag til hvad vi kan gøre for at forbedre edbforholdene på Himmerlands
Ungdomsskole. Så vidt jeg kan se, kan det deles ind i to områder:
1. [[Netværk]]
a)Hvordan og hvornår skal vores adgang til Internettet og skolens lokale
netværk / portal være?
2. [[Portal]]
a)Hvordan kommunikerer vi med hinanden, forældre, elever?
b)Hvordan opbevarer / deler vi filer?
c) Hvordan sikrer vi at alle computere taler samme sprog?
Ud over, hvad vi selv kan gøre, bør vi kontakte andre skoler i forbindelse med
de to emner: Netværk og Portal.
[[Netværk]]
✗ Trådløst netværk på hele skolen?
✗ Trådløst netværk hele døgnet?
✗ Trådløst netværk i en tidsbegrænset periode?
✗ Elevernes adgang til ovenstående?
✗ Hvad gør andre skoler?
[[Portal]]
✗ Claroline – hvad kan det bruges til – hvad kan det ikke bruges til?
✗ Hjemmesiden?
✗ Wiki? - hvad kan det bruges til – hvad kan det ikke bruges til?
✗ Formål / behov?
✗ Hvad gør andre skoler?
[[Konkrete tiltag]]
✗ Forbindelse mellem det nye og mixen ca. 5.000 kr.
➢ Hele den nye fløj kommer på med stik til mange kabler
➢ Timer på trådløse routere ca. 500 kr.
➢ Trådløse routere på hele skolen ca. 6.000 kr.
[[Andet]]
✗ Storskærm til information til elever og lærere på evt. den lange gang?
EDB på HU – Jakob Mols Græsborg – 21. januar 2009
<<comments>>
<html><h2>In Praise of the Hyperlink</h2> <ul> <li>Listen to <a href="http://www.archive.org/download/JeremyKeithInPraiseoftheHyperlink/In_Praise_of_the_Hyperlink.mp3" type="audio/mpeg">an audio recording</a> of this talk.</li> <li>Watch <a href="http://ia311517.us.archive.org/1/items/reboot8_videos/reboot8_jeremy_keith.mp4" type="video/mp4">a video</a> of this talk.</li> </ul> <p>Web 2.0. Love the term or hate it, you’ve certainly heard it. Even if you’re a hardened cynic and you pride yourself on not drinking Tim O’Reilly’s koolaid, it’s hard to deny that <em>something</em> is going on: something new, something that is just the start of a brave new world 2.0.</p> <p class="vevent">The theme of <span title="20060602" class="dtstart">this year’s</span> <span class="summary">Reboot</span> is renaissance. It doesn’t take much of a stretch to compare that term with the ubiquitous “Web 2.0”.</p> <p class="vevent">The common perception of <span title="14000101" class="dtstart">15th century</span> <span class="location">Northern Italy</span> is to view it as the birthplace of a whole new movement in art and culture: a Culture 2.0, if you will. We tend to think of <span class="summary">the Renaissance</span> as an almost revolutionary movement, sweeping aside the old-school 1.0 dark ages.</p> <p>But the Renaissance didn’t come out of nowhere. The word itself means rebirth, not birth. The movers and shakers of the Renaissance — the analogerati of Florence — weren’t trying to make a break with the past. They were trying to get back to their roots. At its heart, the Renaissance was a very conservative movement with an emphasis on reviving and preserving classical ideas. By classical, I mean Greek and Roman. There is a direct line of descent from the Acropolis in Athens to the beautiful buildings built in Copenhagen during the Danish Renaissance. The building blocks of the Renaissance were centuries-old ideas about mathematics, aesthetics, and science.</p> <p>There is a lesson for us there. With all this talk of a Web 2.0, there’s a danger that we as web developers, whilst looking to the future, are forgetting our past. In our haste to forge a new kind of World Wide Web, we run the risk of destroying the fundamental building blocks that helped create the Web that we fell in love with in the first place.</p> <p>I don’t intend to run through all the building blocks that form the foundation of the Web. Each one deserves its own praise. HTTP, for example, the protocol that enables the flow of pages on the Web, is worthy of its own love letter.</p> <p>I’d like to focus on one very small, very simple, very beautiful building block: the hyperlink.</p> <p>The hyperlink is an amazing solution to an old problem. That problem is classification.</p> <h3>The Garden of Forking Paths</h3> <p>Language is the most powerful tool ever used by man. Together with its offspring writing, language enables us to document things, ideas, and experiences. I can translate a physical object into a piece of information that can be later retrieved, not only by myself, but by anyone. But there are economies of scale with this kind of information storage and retrieval. The physical world is a very, very big place filled with a multitude of things bright and beautiful; creatures great and small. If we could use the gift of language to store and retrieve information on everything in the physical world, right down to the microscopic level, the result would be transcendental.</p> <blockquote> <p>To see a world in a grain of sand And heaven in a wild flower</p> </blockquote> <p>The first person to seriously tackle the task of cataloguing the world was born after the Renaissance. Bishop John Wilkins lived in England in the 17th century. He was no stranger to attempting the seemingly impossible. He proposed interplanetary travel three centuries before the invention of powered flight. He is best remembered for his 1668 work, <cite>An Essay towards a Real Character and a Philosophical Language</cite>.</p> <p>The gist of Wilkins’s essay is explained by Jorge Luis Borges in <cite>El idioma analítico de John Wilkins</cite> (<a href="http://www.alamut.com/subj/artiface/language/johnWilkins.html">The Analytic Language of John Wilkins</a>).</p> <blockquote> <p>He divided the universe in forty categories or classes, these being further subdivided into differences, which was then subdivided into species. He assigned to each class a monosyllable of two letters; to each difference, a consonant; to each species, a vowel. For example: <strong>de</strong>, which means an element; <strong>deb</strong>, the first of the elements, fire; <strong>deba</strong>, a part of the element fire, a flame.</p> </blockquote> <p class="vcard">You can find more delvings into Borges’s essay on a weblog by <span class="fn">Matt Webb</span>; the fittingly named <a href="http://interconnected.org/home/" class="url">interconnected.org</a>.</p> <p>The problem with Wilkins’s approach will be obvious to anyone who has ever designed a relational database. Wilkins was attempting to create a one to one relationship between words and things. Apart from the sheer size of the task he was attempting, Wilkins’s rigidity meant that his task was doomed to fail.</p> <p>Still, Wilkins’s endeavour was a noble one at heart. One of his contemporaries recognised the value and scope of what Wilkins was attempting.</p> <p>Gottfried Wilhelm von Leibniz possessed one of the finest minds of his, or any other, generation. It’s a shame that his talent has been overshadowed by the spat between Newton and himself caused by their simultaneous independent invention of calculus.</p> <p>Leibniz wanted to create an encyclopaedia of human knowledge that was free from the restrictions of strict hierarchies or categories. He recognised that concepts and notions could be approached from different viewpoints. His approach was more network-like with its many to many relationships.</p> <p>Where Wilkins associated concepts with sounds, Leibniz attempted to associate concepts with symbols. But he didn’t stop there. Instead of just creating a static catalogue of symbols, Leibniz wanted to perform calculations on these symbols. Because the symbols correlate to real-world concepts, this would make anything calculable. Leibniz believed that through a sort of algebra of logic, a theoretical machine could compute and answer any question. He called this machine the Calculus ratiocinator. The idea is a forerunner of Turing’s universal machine.</p> <blockquote> <p>The general idea of a computing machine is nothing but a mechanisation of Leibniz’s calculus ratiocinator. - Norbert Wiener, Cybernetics, 1948</p> </blockquote> <p>Let me tell you about another theoretical device. It’s called the memex (short for “memory extender”). This device was proposed by Vannevar Bush in 1945 in an article in the The Atlantic Monthly called <cite><a href="http://www.theatlantic.com/doc/194507/bush">As We May Think</a></cite>. Bush described the memex as being electronically linked to a library of microfilm. The device, contained within a desk, would be capable of following cross-references between books and films. This almost sounds like hypertext.</p> <p>But there may be a form of proto-hypertext that precedes the memex.</p> <h3>Shite and onions</h3> <p>In recent years the works of James Joyce have been revisited and re-examined through the prism of hypertext. <cite>Ulysses</cite> and <cite>Finnegan’s Wake</cite> make sense when viewed, not linearly, but as a network of interconnected ideas. Marshall McLuhan was heavily inspired by Joyce’s communication technology. The medium was very much the message.</p> <p>For most of us, <cite>Finnegan’s Wake</cite> remains an impenetrable book, at least in the narrative sense. It might make more sense to us if we suffered from a medical condition called apophenia: the perception of connections and meaningfulness in unrelated things.</p> <p>This isn’t necessarily an affliction. In his book <cite>Pattern Recognition</cite>, William Gibson describes an apopheniac cool-hunter hired by marketers to detect the presence of Gladwellian tipping points in a product’s future.</p> <p>Apophenia is a boon for conspiracy theorists. If you’re fond of a good conspiracy theory, I recommend staying away from the linear and predictable Da Vinci Code. For a real hot-tub of conspiracy theory pleasure, nothing beats <cite>Foucault’s Pendulum</cite> by Umberto Eco.</p> <blockquote> <p>…luck rewarded us, because, wanting connections, we found connections — always, everywhere, and between everything. The world exploded into <strong>a whirling network of kinships, where everything pointed to everything else</strong>, everything explained everything else…</p> </blockquote> <p>For a conspiracy theorist, there can be no better tool than a piece of technology that allows you to arbitrarily connect information. That tool now exists. It’s called the World Wide Web and it was invented by Sir Tim Berners-Lee.</p> <h3>Enquire Within Upon Everything</h3> <p>There was no magical “Eureka!” moment in the invention of the Web. It was practical problem solving, not divine revelation that resulted in the building blocks of Universal Resource Identifiers (URIs), the Hypertext Transfer Protocol (HTTP), and the Hypertext Markup Language (HTML). Berners-Lee’s proposal built on top of the work already done by Ted Nelson and Douglas Engelbart, the inventors of the first true hypertext system in 1965.</p> <h4>US Patent Number 4,873,662</h4> <p>If there was anything revolutionary about the World Wide Web, it was the fact that it was not patented, instead being declared free for all to use. That spirit of scientific sharing clearly didn’t rub off on British Telecom who attempted to enforce a patent which they claimed gave them intellectual property rights over the concept of hyperlinks. The claim was, fortunately, laughed out of court.</p> <h4>Model View Controller</h4> <p>The World Wide Web is the ultimate MVC framework. URIs are the models controlled by HTTP and viewed through HTML. While the view may seem like the least significant component, it is the simplicity of HTML that is responsible for the explosive growth of the Web.</p> <p>There was nothing new about markup languages. Standard Generalised Markup Language had been around for years. Before that, red pens allowed editors to literally mark up text to indicate meaning.</p> <p>Like SGML, HTML used tags — delineated with angle brackets — to nest parts of a document in descriptive containers called elements. The P element can be used to describe a paragraph, the H1 element describes a level one heading, and so on.</p> <h4>Alpha and Omega</h4> <p>The shortest element is the most powerful. A stands for anchor. Nestled within the anchor element is the href attribute. This attribute, short for hypertext reference, is the conduit through which the dreams of Leibniz, Joyce, and a thousand conspiracy theorists can finally be realised.</p> <blockquote> <p>The vision I have for the Web is about anything being potentially connected with anything.</p> </blockquote> <p>Anybody could create anchors containing hypertext references. Just about everybody did. The Web grew exponentially in size and popularity. With every new web page and every hyperlink, the expanding Web became a more valuable and powerful aggregate resource.</p> <h3>Backrub</h3> <p>This power was harnessed by Sergey Brin and Lawrence Page. The concept behind their <a href="http://www-db.stanford.edu/%7Ebackrub/google.html">PageRank</a> algorithm is simple: links are a vote of confidence. If a lot of links point to the same page, that page is highly regarded. By combining this idea with traditional page analysis, they created the best search engine on the Web; Google.</p> <p>In order to measure the PageRank of everything on the Web, the googlebot spider was unleashed. In some ways, the googlebot is like any other user agent: it visits web pages and follows links. It’s also possible to see the googlebot as a kind of quantum device.</p> <h4>Schrödinger’s cat</h4> <p>When you or I visit a web page that has, say, ten links, there are two theories about what happens. According to superposition, the next page we visit exists only as a probability. Not until we make a decision and click on a link does the page resolve into one of the ten possibilities.</p> <h4>The multiverse</h4> <p>The alternative view is the many worlds interpretation. According to this theory, visiting a page with ten links would cause the universe itself to branch into ten different universes. You or I will remain in the universe that matches the link we clicked. But the googlebot is different: it follows all ten links at once, spidering alternate worlds.</p> <h4>September 19th</h4> <p>I have first hand experience of Google’s stockpile of parallel universes. To celebrate Talk Like a Pirate Day, I created <a href="http://adactio.com/extras/talklikeapirate/">a simple server-side script</a>. You can pass in the URL of a web page and the script will display the contents interspersed with choice pirate phrases such as “arr!”, “shiver me timbers!”, and “blow me down!”. The script also rewrites any hrefs in the page so that the pages they point to are also run through the pirate-speak transmogrifier.</p> <p>It was amusing. It even appeared on <a href="http://www.metafilter.com/">Metafilter</a>. The problems started later on. I began to get irate emails, even phone calls, from website owners demanding that I remove their files from my server. I was even threatened with the Digital Millennium Copyright Act. I was fielding angry emails from people all over the world in charge of completely disparate websites.</p> <p>The googlebot had landed on my Talk Like a Pirate page (perhaps it followed a link from Metafilter). Then it began to spider. It never stopped. Somewhere within the Googleplex there is a complete one to one scale model of the World Wide Web that’s written entirely in pirate-speak.</p> <p>Now when site owners do a search for their websites to check their ranking, the pirate facsimile often appears before the original. I can’t help it if my Googlejuice is better than theirs.</p> <p>I began to feel remorse when I heard from the proprietor of a spinal surgery clinic in Florida who told me that potential customers were being scared away by messages detailing “professional treatment, me hearties!”</p> <p>I have since added a robots.txt file but it can be a long time between googledances. Parallel universes don’t just disappear overnight. I guess the googlebot isn’t a quantum device after all because, it seems, it can’t be everywhere at once. That’s where it falls down. How is it supposed to deal with websites that are updated frequently?</p> <h3>Blog, short for weblog…</h3> <p>Trying to define what a blog is can be a slippery task. Most definitions include the words “online journal”. I’ve been told that my online journal isn’t a blog because I don’t have comments enabled. I must have missed the memo.</p> <p>What really makes a blog a blog isn’t the addition of comments or the fact that it’s an online journal. The defining characteristic of a blog is the presence of permalinks. Permalink, a portmanteau word from permanent and link, should be a tautology. All links should be permanent.</p> <p>Permalinks, and by extension, blogs, encourage linking. Instead of simply saying “here’s my opinion”, blogs allow us to say “here’s a permanent linkable address for my opinion.”</p> <p>The earlist blogs were link logs, places you could visit to find links that somebody thinks are worth visiting. Even now, I find that the best blog posts are often ones that point out the connections between seemingly separate links. Bloggers are natural apopheniacs; conspiracy theorists who can back up their claims not just with references to their sources but with <em>hypertext references</em>… hrefs.</p> <p>Even though all blogs have permalinks, there’s something inherently transient in the nature of blogging. It’s a tired cliché but the aggregate web of blogs really is like a conversation. The googlebot can’t hope to follow all the links spawned by all these voices speaking at once. <a href="http://technorati.com/">Technorati</a> does okay though.</p> <h3>Microformats</h3> <p class="vcard">Technorati is also the breeding ground for some infectious little ideas called microformats. These microformats embrace and extend the Hypertext Markup Language. Making use of the little-known rel attribute, the anchor element can be made even more powerful. In <a href="http://gmpg.org/xfn/">XFN</a>, XHTML Friends Network, the addition of rel equals friend, colleague, met, and other descriptors adds extra semantic weight to a link (as yet there is no Enemies Network, but <a href="http://suda.co.uk/" rel="friend met" class="fn url">Brian Suda</a> and I are working on a draft specification).</p> <p>The bonus semantics offered by microformats can be harvested and collated to form a clearer picture of the connections that were previously less defined.</p> <p>Microformats are the nanotechnology for building a semantic web.</p> <p>That’s lowercase semantic web. The uppercase Semantic Web still lies in our future. Another theoretical future technology is XHTML 2, wherein any element whatsoever can have a hypertext reference.</p> <p>Perhaps we aren’t worthy of such a bounty of hrefs. Right now hrefs exist only in the anchor element and yet still we manage to abuse them.</p> <pre><code>a href="javascript:..."<br /></code></pre> <p class="vcard">I like JavaScript. It is, as <a href="http://crockford.com/" rel="met muse" class="fn url">Douglas Crockford</a> put it, the world’s most misunderstood programming language. The problem lies not with the JavaScript language but its integration into hypertext documents.</p> <p>The javascript pseudo-protocol is an abomination. It is not a valid hypertext reference.</p> <pre><code>a href="#" onclick="..."<br /></code></pre> <p>Using a pointless empty internal page reference is almost as bad. If you can’t provide a valid resource for the href value, don’t use the anchor element. Anchors are for links. Don’t treat them as empty husks upon which you hang some cool Ajaxian behaviour. Respect the link.</p> <p>If we value and cherish the links of today, who knows what the future may bring?</p> <h3>Future Shock</h3> <p>Maybe Bruce Sterling is right. Maybe we’ll have an internet of things. Spimes, blogjects, thinglinks… whatever the individual resources are called, they’ll have to be linkable: hyperlinked addressable objects existing in our regular, non hyper-, space.</p> <p>It sounds like an exciting future. We live in an equally exciting present.</p> <h3>Linked</h3> <p>We have all come together here in Copenhagen because of how much we love the World Wide Web. I bet every one of you has a story to tell about the first time you “got” the Web. Remember that thrill? Remember the realisation that you were interacting with something that was potentially neverending; a borderless labyrinth of information, all interconnected through the beautiful simplicity of the hyperlink. We may have grown accustomed to this miracle but that doesn’t make it any less wondrous.</p> <p>We are storytellers, no longer huddled around separate campfires, we now sit around a virtual hearth where we are warmed by the interweaving tales told by our brothers and sisters. Everyone is connected to everyone else by just six degrees of separation. Thanks to the hyperlink, we can find those connections and make them tangible.</p> <p>The dream of hypertext has become a reality.</p> <h2>Further Reading</h2> <p><a href="http://www.amazon.com/exec/obidos/ASIN/0060593083/thesession-20/"><img alt="Quicksilver" src="http://images.amazon.com/images/P/0060593083.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0393322297/thesession-20/"><img alt="Engines of Logic" src="http://ec1.images-amazon.com/images/P/0393322297.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0631174656/thesession-20/"><img alt="The Search for the Perfect Language" src="http://images.amazon.com/images/P/0631174656.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0345368754/thesession-20/"><img alt="Foucault's Pendulum" src="http://images.amazon.com/images/P/0345368754.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0141181265/thesession-20/"><img alt="Finnegan's Wake" src="http://images.amazon.com/images/P/0141181265.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0679722769/thesession-20/"><img alt="Ulysses" src="http://images.amazon.com/images/P/0679722769.01._SCMZZZZZZZ_.gif" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0425192938/thesession-20/"><img alt="Pattern Recognition" src="http://images.amazon.com/images/P/0425192938.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0316346624/thesession-20/"><img alt="The Tipping Point" src="http://images.amazon.com/images/P/0316346624.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/006251587X/thesession-20/"><img alt="Weaving The Web" src="http://images.amazon.com/images/P/006251587X.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0385495323/thesession-20/"><img alt="The Code Book" src="http://images.amazon.com/images/P/0385495323.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0393324427/thesession-20/"><img alt="Nexus" src="http://images.amazon.com/images/P/0393324427.01._SCMZZZZZZZ_.jpg" /></a> <a href="http://www.amazon.com/exec/obidos/ASIN/0393325423/thesession-20/"><img alt="Six Degrees" src="http://images.amazon.com/images/P/0393325423.01._SCMZZZZZZZ_.jpg" /></a></p> <p class="time">June 2nd, 2006</p><p>Source: [[Adactio: Articles—In Praise of the Hyperlink|http://adactio.com/articles/1132/]]</p></html>
# Don't forget to save and reload your ~TiddlyWiki after installing the package...
# You might want to put [[Welcome to TiddlyChatter]] and/or [[TiddlyChatter]] in your MainMenu or DefaultTiddlers.
# The key to ~TiddlyChatter is your subscription to someone else's "~ChatterFeed". You have been set up with one subscription, called ChatterFeed, to some test content on http://tiddlychatter.tiddlyspot.com. You can manage your subscriptions from the main [[TiddlyChatter]] tiddler. Click "manage" and then "new subscription" and put in the URL of a ~TiddlyWiki which is publishing a feed.
<<siteMap [[Allan]] . sliders>>
✗ Storskærm til information til elever og lærere på evt. den lange gang?
<<comments>>
<html><p><span style="font-size: larger;"><span style="font-family: Comic Sans MS;">En selvbiografisk og gribende fortælling om en drengs opdragelse i ondskab, fra faderens mishandlinger til de brutale magtkampe i skolegården. Erik kommer fra en rig familie, han er dygtig i skolen og god til sport. Men hjemme i familien får han tæv af faderenen hver dag. </span></span></p><p><span style="font-size: larger;"><span style="font-family: Comic Sans MS;">Erik lærer at slås og klare mange tæv, men det giver ham problemer i skolen. Han bliver bortvist og sendt til en kostskole, hvor de ældre elevers systematiske undertrykkelse fører til en endeløs cirkel af provokationer og afstraffelser. Det eneste lyspunkt er vennen Pierre og hævnen, som han får til sidst. </span></span></p><p><span style="font-size: larger;"><span style="font-family: Comic Sans MS;"> Easy reader udgave af den oprindelige roman i serien Lette klassikere.</span></span></p></html>
People who have used ~TiddlyWiki before may wish to access TW features that I have hidden or changed:
#Use the StyleSheet to adjust colors, font-sizes, page layout tweaks and other design features.
#Use [[zzConfigOptions]] to change the settings for saving options, animations, toggle options, single page mode options (to view multiple tiddlers) and search options.
#Use ViewTemplate to restore tiddler subtitles and tagging boxes. Warning: you will need to carefully add lines of code from the original ViewTemplate at http://www.tiddlywiki.com.
!Current
* 1/11/07 - generation of ChatterFeed pointing to self fails when viewing root host rather than full URL e.g. http://domain.com rather than http://domain.com/index.html - Update 1/11/07, FND suggested using localPath not window.location
* 24/10/07 - Parent content tiddler's unread status doesn't get updated to unread when a new note is added, which it should - or the displayed status should be unread if at least one of the notes' statuses' is unread
** 23/10/07 - Update: partial fix: problem is that the process is not repeatable, as the match looking for feeds to import from returns an empty array
** 30/10/07 - Update: behaviour arises due to use of Regex.exec, which maintains state; should change to Regex.match
* 23/10/07 - ordering of content in ListView is not right - for content on same day, latest doesn't appear at the top
* 09/10/07 - refresh mechanism implemented in a way I don't fully understand - could be unstable?
** 23/10/07 - adding new content doesn't update the TiddlyChatter content list, although hitting "mark as read" or "mark as unread" does
* 16/10/07 - if we're going to have public and published tags, then we need to: show whether public content is published or not in the list view; not need ChatterFeeds to be tagged public, as we don't want them showing up in the list view - or do we? There needs to be a clear semantic difference between something tagged public and something tagged published; also, Manage subscriptions appears to work with a tag it shouldn't - think it is published (update: actually it is "channel")
! Fixed
* 29/10/07 - File_adaptor_filter_plugin broke with no filter provided - Fixed 30/10/07, removed plugin as core FileAdaptor updated to support filter
* 23/10/07 - Get updates doesn't get all your subscriptions - Fixed 24/10/07
* 16/10/07 - Creating a new tiddler doesn't add the unread field necessary to make the unread macro work properly - Fixed 17/10/07
* 16/10/07 - author name not working for imported content - Fixed 23/10/07
* 16/10/07 - Tiddler says "No notes" if you import other people's notes - Fixed 23/10/07
* 16/10/07 - existing content is overwritten by other people's content; stop this and alert the user; overwrites notes too - maybe we can do something with the number extension? Although that might break the symmetry of content between TiddlyWikis. This becomes a big issue when there are more than two people, as this could happen frequently. Add username to end of title, as in tiddler-NotesJayFresh0 ? - Fixed 23/10/07, design decision: notes are unique by user ID, content not supposed to be updated by people other than the content owner - in future, put in notification if new content updates come and a user has changed their copy
* 16/10/07 - list view looking for unread property on latest note, not on parent tiddler; notes don't even need unread properties (although they will probably keep them for ease) - Fixed 23/10/07, design decision: "mark as read" button now reflects the status of the newest update
* 16/10/07 - Ken Girard - I discovered that the current 'New subscription' button over writes the current ChatterFeed tiddler, so put the following in a tiddler named what ever:
{{{|''Type:''|RSS|
|''URL:''|http://no-sin.com/wiki/tiddlychatter.xml|
|''Workspace:''|No-SinFeed|
|''TiddlerFilter:''|[tag[public]]|}}} - Fixed 23/10/07, design decision: the first time TiddlyChatter runs, it creates a new feed called ChatterFeed with the username appended and points the url at the user's own xml feed; this means that ChatterFeed remains what the user uses as their default subscription
** Tag it: "systemServer TiddlyChatter public channel" and lets see where it goes.
Direkte link: [[Behovsanalyse|http://spreadsheets.google.com/viewform?formkey=cHFkeS0tU2FYcDV6c2dGcmRTZl9IUEE6MA..]]
<<miniBrowser hidecontrols http://spreadsheets.google.com/viewform?formkey=cHFkeS0tU2FYcDV6c2dGcmRTZl9IUEE6MA..>>
[[Efter titel]]
[[Efter forfatter]]
[[Efter tema]]
[[Efter titel|By title]]
[[Efter forfatter|By author]]
[[Efter tema|By topic]]
Our other note-taking ~TiddlyWiki, called BibblyWiki, is better for creating bibliographies. But we include a simple bibliography feature here for those who want it.
#Click on 'new bib entry' in the right sidebar menu.
#Assign the tiddler a title and click 'done.'
#Fill in any form fields you wish, especially the first four fields.
##To remove a particular form field from all notes, open [[NewBibEntryTemplate]] and find and carefully remove the appropriate code.
#Open "Bibliography" in the left menu to see your entry in the three bibliographies.
|''URL:''|http://tiddlywiki.bidix.info/|
|''Description:''|Repository for BidiX's TiddlyWiki Extensions|
|''Author:''|BidiX|
{{tuduSlider{<<slider chkBookSummary Bibliografi 'Bibliografi »'>>}}}<<newTiddler label:"Ny bog/artikel" text:{{"<<formTiddler NewBibEntryTemplate\>\>"}} tag:"authorbook""Bøger">>
|''Type:''|RSS|
|''URL:''|http://phil1.tiddlyspot.com/index.xml|
|''Workspace:''||
|''TiddlerFilter:''|[tag[public]]|
|''Type:''|RSS|
|''URL:''|file:///C:/Documents%20and%20Settings/mama/Skrivebord/edb(2).xml|
|''Workspace:''||
|''TiddlerFilter:''|[tag[public]]|
|''Type:''|RSS|
|''URL:''|http://edb.tiddlyspot.com/|
|''Workspace:''||
|''TiddlerFilter:''|[tag[public]]|
/***
|Name:|CloseOnCancelPlugin|
|Description:|Closes the tiddler if you click new tiddler then cancel. Default behaviour is to leave it open|
|Version:|3.0.1 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#CloseOnCancelPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.commands.cancelTiddler,{
handler_mptw_orig_closeUnsaved: config.commands.cancelTiddler.handler,
handler: function(event,src,title) {
this.handler_mptw_orig_closeUnsaved(event,src,title);
if (!store.tiddlerExists(title) && !store.isShadowTiddler(title))
story.closeTiddler(title,true);
return false;
}
});
//}}}
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #110077
PrimaryMid: #110077
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*
TiddlyWiki Comments Plugin - Online demo at http://tiddlyguv.org/CommentsPlugin.html
TODO:
- Support Cascade comment delete when the top-level tiddler is deleted
- Support more than one <<comments>> per tiddler. This will probably entail creating an invisible root tiddler to
hold all the comments for a macro together. The user will need to provide an ID for this tiddler.
- Don't use global "macro" var (use "macro" param a la jquery)
*/
/***
|Name|CommentsPlugin|
|Description|Macro for nested comments, where each comment is a separate tiddler.|
|Source|http://tiddlyguv.org/CommentsPlugin.html#CommentsPlugin|
|Documentation|http://tiddlyguv.org/CommentsPlugin.html#CommentsPluginInfo|
|Version|0.1|
|Author|Michael Mahemoff, Osmosoft|
|''License:''|[[BSD open source license]]|
|~CoreVersion|2.2|
***/
/*{{{*/
if(!version.extensions.CommentsPlugin) {
version.extensions.CommentsPlugin = {installed:true};
var macro = config.macros.comments = {
init: function() {
var stylesheet = store.getTiddlerText(tiddler.title + "##StyleSheet");
config.shadowTiddlers["StyleSheetCommentsPlugin"] = stylesheet;
store.addNotification("StyleSheetCommentsPlugin", refreshStyles);
},
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
macro.log(paramString);
var macroParams = paramString.parseParams();
macro.buildCommentsArea(tiddler, place, macroParams);
macro.refreshComments(story.getTiddler(tiddler.title).commentsEl, tiddler, macroParams);
// var macroParams = macroParams.parsemacroParams(null, "val", true);
},
buildCommentsArea: function(rootTiddler, place, macroParams) {
var suffix = "_" + rootTiddler.title.trim();
var commentsArea = createTiddlyElement(place, "div", null, "comments");
// var heading = createTiddlyElement(commentsArea, "h2", null, "", "Comments");
var comments = createTiddlyElement(commentsArea, "div", null, "");
story.getTiddler(rootTiddler.title).commentsEl = comments;
createTiddlyElement(commentsArea, "div");
var newCommentArea = createTiddlyElement(commentsArea, "div", null, "newCommentArea", "Ny kommentar:");
var newCommentEl = macro.makeTextArea(newCommentArea, macroParams);
var addComment = createTiddlyElement(newCommentArea, "button", null, "addComment", "Tilføj kommentar");
addComment.onclick = function() {
var comment = macro.createComment(newCommentEl.value, rootTiddler, macroParams);
newCommentEl.value = "";
};
},
makeTextArea: function(container, macroParams) {
var textArea = createTiddlyElement(container, "textarea");
textArea.rows = getParam(macroParams, "textRows") || 4;
textArea.cols = getParam(macroParams, "textCols") || 20;
textArea.value = getParam(macroParams, "text") || "";
return textArea;
},
refreshComments: function(daddyCommentsEl, tiddler, macroParams) {
var refreshedEl;
if (tiddler.fields.daddy) {
var commentEl = macro.buildCommentEl(daddyCommentsEl, tiddler, macroParams);
daddyCommentsEl.appendChild(commentEl);
refreshedEl = commentEl;
} else {
removeChildren(daddyCommentsEl);
refreshedEl = story.getTiddler(tiddler.title);
}
prev=null;
for (var child = store.getTiddler(tiddler.fields.firstchild); child; child = store.getTiddler(child.fields.nextchild)) {
if (prev==child) {
macro.log(prev, child, "breaking");
break;
}
macro.refreshComments(refreshedEl.commentsEl, child, macroParams);
prev = child;
}
},
buildCommentEl: function(daddyCommentsEl, comment, macroParams) {
// COMMENT ELEMENT
var commentEl = document.createElement("div");
commentEl.className = "comment";
// HEADING <- METAINFO AND DELETE
var headingEl = createTiddlyElement(commentEl, "div", null, "heading");
var metaInfoEl = createTiddlyElement(headingEl, "div", null, "commentTitle", comment.modifier + '@' + comment.modified.formatString(getParam(macroParams,"dateFormat") || "DDD, MMM DDth, YYYY hh12:0mm:0ss am"));
metaInfoEl.onclick = function() {
// story.closeAllTiddlers();
story.displayTiddler("top", comment.title, null, true);
// document.location.hash = "#" + comment.title;
};
var deleteEl = createTiddlyElement(headingEl, "div", null, "deleteComment", "X");
deleteEl.onclick = function() {
if (true || confirm("Delete this comment and all of its replies?")) {
macro.deleteTiddlerAndDescendents(comment);
commentEl.parentNode.removeChild(commentEl);
}
};
// TEXT
commentEl.text = createTiddlyElement(commentEl, "div", null, "commentText");
wikify(comment.text, commentEl.text);
// REPLY LINK
var replyLinkZone = createTiddlyElement(commentEl, "div", null, "replyLinkZone");
var replyLink = createTiddlyElement(replyLinkZone, "span", null, "replyLink", "besvar denne kommentar");
replyLink.onclick = function() { macro.openReplyLink(comment, commentEl, replyLink, macroParams); };
// var clearance = createTiddlyElement(commentEl, "clearance", null, "clearance");
// clearance.innerHTML = " ";
// COMMENTS AREA
commentEl.commentsEl = createTiddlyElement(commentEl, "div", null, "comments");
// RETURN
return commentEl;
},
openReplyLink: function(commentTiddler, commentEl, replyLink, macroParams) {
if (commentEl.replyEl) {
commentEl.replyEl.style.display = "block";
return;
}
commentEl.replyEl = document.createElement("div");
commentEl.replyEl.className = "reply";
replyLink.style.display = "none";
var newReplyHeading = createTiddlyElement(commentEl.replyEl, "div", null, "newReply");
createTiddlyElement(newReplyHeading, "div", null, "newReplyLabel", "New Reply:");
var closeNewReply = createTiddlyElement(newReplyHeading, "div", null, "closeNewReply", "close");
closeNewReply.onclick = function() {
commentEl.replyEl.style.display = "none";
replyLink.style.display = "block";
};
var replyText = macro.makeTextArea(commentEl.replyEl, macroParams)
var submitReply = createTiddlyElement(commentEl.replyEl, "button", null, null, "Reply");
submitReply.onclick = function() {
var newComment = macro.createComment(replyText.value, commentTiddler, macroParams);
replyText.value = "";
closeNewReply.onclick();
macro.refreshComments(commentEl.commentsEl, newComment, macroParams);
};
commentEl.insertBefore(commentEl.replyEl, commentEl.commentsEl);
},
createComment: function(text, daddy, macroParams) {
var newComment = macro.createCommentTiddler();// store.createTiddler(macro.generateCommentID());
// macro.copyFields(daddy, newComment,
// "server.bag", "server.host", /* "server.page.revision",*** "server.type", "server.workspace");
var fieldsParam = getParam(macroParams, "fields") || "";
var fields = fieldsParam.decodeHashMap();
macro.log("fields", fields);
macro.log(getParam(macroParams, "inheritedFields"));
var inheritedFields = (getParam(macroParams, "inheritedFields") || "").split(",");
macro.log("inheritedFields", inheritedFields);
macro.forEach(inheritedFields, function(field) {
macro.log("inherited", field);
if (field!="") fields[field] = daddy.fields[field];
});
var tagsParam = getParam(macroParams, "tags") || "comment";
var now = new Date();
newComment.set(null, text, config.options.txtUserName, now, tagsParam.split(","), now, fields);
// macro.copyFields(daddy, newComment, (getParam(macroParams, "inheritedFields") || "").split(","));
newComment.fields.daddy = daddy.title;
// macro.copyFields(daddy, newComment,
// "server.bag", "server.host", /* "server.page.revision", */"server.type", "server.workspace");
if (!daddy.fields.firstchild) {
daddy.fields.firstchild = newComment.title;
} else {
for (last = store.getTiddler(daddy.fields.firstchild); last.fields.nextchild; last = store.getTiddler(last.fields.nextchild))
{}
last.fields.nextchild = newComment.title;
store.saveTiddler(last.title);
}
store.saveTiddler(newComment.title);
store.saveTiddler(daddy.title);
autoSaveChanges(false);
return newComment;
},
deleteTiddlerAndDescendents: function(tiddler, doAutoSave) {
doAutoSave = (arguments.length==1 || doAutoSave);
var daddy = store.getTiddler(tiddler.fields.daddy);
if (daddy.fields.firstchild==tiddler.title) {
tiddler.fields.nextchild ? daddy.fields.firstchild = tiddler.fields.nextchild :
delete daddy.fields.firstchild;
store.saveTiddler(daddy.title);
} else {
for (prev = store.getTiddler(daddy.fields.firstchild); prev.fields.nextchild!=tiddler.title; prev = store.getTiddler(prev.fields.nextchild))
{}
tiddler.fields.nextchild ? prev.fields.nextchild = tiddler.fields.nextchild :
delete prev.fields.nextchild;
store.saveTiddler(prev.title);
}
var child = store.getTiddler(tiddler.fields.firstchild);
while (child) {
var nextchild = store.getTiddler(child.fields.nextchild);
macro.deleteTiddlerAndDescendents(child, false);
child = nextchild;
}
store.deleteTiddler(tiddler.title);
if (doAutoSave) autoSaveChanges(false); // Should only apply to top level
},
forEach: function(list, visitor) { for (var i=0; i<list.length; i++) visitor(list[i]); },
select: function(list, selector) {
var selection = [];
macro.forEach(list, function(currentItem) {
if (selector(currentItem)) { selection.push(currentItem); }
});
return selection;
},
map: function(list, mapper) {
var mapped = [];
macro.forEach(list, function(currentItem) { mapped.push(mapper(currentItem)); });
return mapped;
},
remove: function(list, unwantedItem) {
return macro.select(list,
function(currentItem) { return currentItem!=unwantedItem; });
},
// callers may replace this with their own ID generation algorithm
createCommentTiddler: function() {
if (!store.createGuidTiddler) return store.createTiddler("comment_"+((new Date()).getTime()));
return store.createGuidTiddler("comment_");
},
log: function() { if (console && console.firebug) console.log.apply(console, arguments); },
copyFields: function(fromTiddler, toTiddler, field1, field2, fieldN) {
for (var i=2; i<arguments.length; i++) {
fieldKey = arguments[i];
if (fromTiddler.fields[fieldKey]) toTiddler.fields[fieldKey] = fromTiddler.fields[fieldKey];
}
}
}
/***
!StyleSheet
.comments h1 { margin-bottom: 0; padding-bottom: 0; }
.comments { padding: 0; }
.comment .comments { margin-left: 1em; }
.comment { padding: 0 0 1em 0; margin: 1em 0 0; }
.comment .comment { margin 0; }
.comment .toolbar .button { border: 0; color: #9a4; }
.comment .heading { background: [[ColorPalette::PrimaryPale]]; color: [[ColorPalette::PrimaryDark]]; border-bottom: 1px solid [[ColorPalette::PrimaryLight]]; border-right: 1px solid [[ColorPalette::PrimaryLight]]; padding: 0.15em; height: 1.3em; }
.commentTitle { float: left; }
.commentTitle:hover { text-decoration: underline; cursor: pointer; }
.commentText { clear: both; padding: 1em 0; }
.deleteComment { float: right; cursor: pointer; text-decoration:underline; color:[[ColorPalette::SecondaryDark]]; padding-right: 0.3em; }
.comment .reply { margin-left: 1em; }
.comment .replyLink { color:[[ColorPalette::SecondaryDark]]; font-style: italic;
cursor: pointer; text-decoration: underline; margin: 0 0.0em; }
.comment .created { }
.comment .newReply { color:[[ColorPalette::SecondaryDark]]; margin-top: 1em; }
.newReplyLabel { float: left; }
.closeNewReply { cursor: pointer; float: right; text-decoration: underline; }
.comments textarea { width: 100%; }
.comments button { margin-top: 0.3em; }
.clearance { clear: both; }
!(end of StyleSheet)
***/
macro.init();
} // end of 'install only once'
/*}}}*/
title: CommentsPlugin
modifier: Mahemoff
created: 200601031639
modified: 200809181408
tags: systemConfig
server.host: osmosoft.com
creator: Michael Mahemoff, Osmosoft
server.page.revision: 200809181408
server.type: file
changecount: 3
This is a comments macro. Usage:
<<comments>>
There are various options available as illustrated below. All are optional:
<<comments text:"initial text" textRows:10 textCols:20 tags:specialComment,brilliant,amazing fields:"testField:done foo:bar" inheritedFields:"healthy,food,nonExistent" dateFormat:"MMM DD hh:0mm">>
For use with TiddlyWeb, you want something like:
<<comments fields:"server.bag:comments" inheritedFields:"server.host,server.type,server.workspace">>
You may only include a single <<comments>> macro per tiddler. If you wish to include more than one, you could create new container tiddlers, each with a <<comments>> tag, and then collect them in a single tiddler using <<tiddler>> tags. (Note that this is an intrinsic limitation of the manner in which comments refer to the tiddler in which they are contained, and vice-versa. The only way to get around it would be to require the caller to include a unique ID for each comments block, and this would be virtually the same thing as the workaround mentioned here.)
//{{{
window.alert = function() { return null; }
window.confirm = function() { return null; }
readOnly = config.options.chkHttpReadOnly = false;
config.options.chkAutoSave = true;
config.options.chkSaveBackups = true;
var origRestart = restart;
restart = function() { origRestart(); document.body.onunload = function() {}; }
//}}}
title: ConfigTweaks
modifier: Mahemoff
created: 200601031639
modified: 200809181408
tags: systemConfig
server.host: osmosoft.com
creator: Michael Mahemoff, Osmosoft
server.page.revision: 200809181408
server.type: file
changecount: 3
{{{
/*** 16/10 - Patch not accepted, being revised ***/
ListView.getCommandHandler = function(callback,name,allowEmptySelection)
{
return function(e) {
var that = this;
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.call(that,view,this.value,tiddlers);
this.selectedIndex = 0;
} else {
callback.call(that,view,name,tiddlers);
}
}
return false;
};
};
/*** 16/10 - Patch not submitted yet ***/
// Returns the number of days since the Date
Date.prototype.relativeDays = function() {
var now = new Date();
var interval = now.getTime() - this.getTime();
interval = Math.floor(interval / (1000 * 60 * 60 * 24));
return interval;
};
}}}
/***
|''Name''|CrossIndexingMacro|
|''Version''|0.7|
|''Status''|@@beta@@|
|''Author''|FND|
|''Source''|[[FND's DevPad|http://devpad.tiddlyspot.com/#CrossIndexingMacro]]|
|''License''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion''|2.1|
|''Type''|macro|
|''Requires''|N/A|
|''Overrides''|N/A|
|''Description''|[//TBD//]|
!Notes
Created [[for DaveG|http://groups.google.com/group/TiddlyWiki/browse_thread/thread/afa54bd105e791fa]]'s [[My Notes TiddlyWiki|http://www.giffmex.org/emptynotestw.html]].
!Usage
{{{
<<crossIndex [tag] [scope]>>
}}}
!Revision History
!!v0.5 (2008-02-08)
* initial release
!!v0.6 (2008-02-09)
* renamed to CrossIndexingMacro (from TiddlerHierarchyMacro)
* added listing of uncategorized items
* linkified headings
!!v0.7 (2008-02-10)
* added optional scope parameter
* fixed "uncategorized" listings
* minor code enhancements
!To Do
* rename
* documentation
* code sanitizing
!Code
***/
//{{{
config.macros.crossIndex = {};
config.macros.crossIndex.handler = function(place, macroName, params, wikifier, paramString, tiddler) {
var scope = params[1] || tiddler.title;
var index = this.getIndex(scope, params[0]);
var output = "";
var i;
for(topic in index) {
if(index[topic].length > 0) {
output += "![[" + topic + "]]\n";
for(i = 0; i < index[topic].length; i++) {
output += "* [[" + index[topic][i] + "]]\n";
}
}
}
wikify(output, place);
}
config.macros.crossIndex.getIndex = function(scope, category) {
// retrieve topics
var topics = store.getTaggedTiddlers(category).map(function(t) { return t.title });
// generate index
var index = {
uncategorized: []
};
for(i = 0; i < topics.length; i++) {
index[topics[i]] = [];
store.forEachTiddler(function(title, tiddler) {
if(tiddler.tags.containsAll([scope, topics[i]]))
index[topics[i]].push(title);
else if(tiddler.tags.contains(scope) && !tiddler.tags.containsAny(topics))
index.uncategorized.pushUnique(title);
});
}
return index;
}
//}}}
/***
|''Navn:''|DanishTranslationPlugin|
|''Beskrivelse:''|Translation of TiddlyWiki into Danish|
|''Forfatter:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''Kilde:''|www.example.com |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/association/locales/core/en/locale.en.js |
|''Version:''|0.3.7|
|''Dato:''|Jul 6, 2007|
|''Kommentarer:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''Licens:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]] |
|''~CoreVersion:''|2.4|
***/
//{{{
//--
//-- Translateable strings
//--
// Strings in "double quotes" should be translated; strings in 'single quotes' should be left alone
config.locale = "da"; // W3C language tag
if (config.options.txtUserName == 'YourName') // do not translate this line, but do translate the next line
merge(config.options,{txtUserName: "DitNavn"});
merge(config.tasks,{
save: {text: "gem", tooltip: "Gem dine ændringer til denne TiddlyWiki", action: saveChanges},
sync: {text: "synk", tooltip: "Synkronisér ændringer med andre TiddlyWiki filer og servere", content: '<<sync>>'},
importTask: {text: "importér", tooltip: "Importér tiddlers og plugins fra andre TiddlyWiki filer og servere", content: '<<importTiddlers>>'},
tweak: {text: "Tilpas", tooltip: "Tilpas TiddlyWikis udseende og opførsel", content: '<<options>>'},
upgrade: {text: "upgradér", tooltip: "Upgrader TiddlyWikis kerne kode", content: '<<upgrade>>'},
plugins: {text: "udvidelser", tooltip: "Administrér installerede udvidelser", content: '<<plugins>>'}
});
// Options that can be set in the options panel and/or cookies
merge(config.optionsDesc,{
txtUserName: "Brugernavn til signering af dine ændringer",
chkRegExpSearch: "Avend almindelige udtryk til søgninger",
chkCaseSensitiveSearch: "Forskel på store og små bogstaver",
chkIncrementalSearch: "Bogstav for bogstav-søgning",
chkAnimate: "Anvend animationer",
chkSaveBackups: "Gem en backupfil når der gemmes ændringer",
chkAutoSave: "Gem automatisk ændringer",
chkGenerateAnRssFeed: "Lav et RSS feed når der gemmes ændringer",
chkSaveEmptyTemplate: "Lav en tom skabelon når der gemmes ændringer",
chkOpenInNewWindow: "Åben internet links i et nyt vindue",
chkToggleLinks: "Når man klikker på et link i åbne tiddlers lukkes de",
chkHttpReadOnly: "Skjul redigeringsværktøjer når den vises over HTTP",
chkForceMinorUpdate: "Opdatér ikke brugernavn og dato når tiddlers bliver ændrede",
chkConfirmDelete: "Bed om bekræftelse før tiddlers slettes",
chkInsertTabs: "Brug tab tasten til at indsætte tab tegn istedet for at hoppe imellem felter",
txtBackupFolder: "Navn på mappe til brug for backups",
txtMaxEditRows: "Maximum antal af rækker i edit bokse",
txtFileSystemCharSet: "Default tegnsæt til at gemme ændringer (Kun i Firefox/Mozilla)"});
merge(config.messages,{
customConfigError: "Der opstod problemer ved loading af udvidelser. Se PluginManager for detaljer",
pluginError: "Fejl: %0",
pluginDisabled: "Ikke udført fordi det er slået fra via 'systemConfigDisable' tag",
pluginForced: "Udført fordi det er tvunget via 'systemConfigForce' tag",
pluginVersionError: "Ikke udført fordi denne udvidelse kræver en nyere udgave af TiddlyWiki",
nothingSelected: "Intet er valgt. Du er nødt til at vælge en eller flere ting først",
savedSnapshotError: "Det ser ud som om denne TiddlyWiki er blevet gemt forkert. Se venligst http://www.tiddlywiki.com/#DownloadSoftware for details",
subtitleUnknown: "(ukendt)",
undefinedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu",
shadowedTiddlerToolTip: "Tiddleren '%0' findes ikke endnu, men har en foruddefineret skygge værdi",
tiddlerLinkTooltip: "%0 - %1, %2",
externalLinkTooltip: "Internet link til %0",
noTags: "Der er ingen taggede tiddlere",
notFileUrlError: "Du er nødt til at gemme denne TiddlyWiki til en fil før du kan gemme ændringer",
cantSaveError: "Det er ikke muligt at gemme ændringer. Mulige grunde indbefatter:\n- din browser understøtter det ikke (Firefox, Internet Explorer, Safari og Opera virker alle fint hvis de er konfigurerede korrekt)\n- stien til din TiddlyWiki fil indeholder ulovlige tegn\n- TiddlyWiki HTML filen er blevet flyttet eller omdøbt",
invalidFileError: "Den originale fil '%0' lader ikke til at være en rigtig TiddlyWiki",
backupSaved: "Backup gemt",
backupFailed: "Det lykkedes IKKE at gemme en backup fil",
rssSaved: "RSS feed gemt",
rssFailed: "Det lykkedes IKKE at gemme et RSS feed",
emptySaved: "Tom skabelon gemt",
emptyFailed: "Det lykkedes IKKE at gemme en tom skabelon",
mainSaved: "Hoved TiddlyWiki fil gemt",
mainFailed: "Det lykkedes IKKE at gemme hoved TiddlyWiki filen. Dine ændringer er IKKE blevet gemt",
macroError: "Fejl i makro <<\%0>>",
macroErrorDetails: "Fejl ved udførsel af makro <<\%0>>:\n%1",
missingMacro: "Ingen sådan makro",
overwriteWarning: "En tiddler med navnet '%0' findes allerede. Vælg OK for at overskrive den",
unsavedChangesWarning: "ADVARSEL! Der er ugemte æmdringer i TiddlyWikien\n\nVælg OK for at gemme\nVælg FORTRYD for at afvise",
confirmExit: "--------------------------------\n\nDer er ugemte ændringer i TiddlyWikien. Hvis du fortsætter vil du miste disse ændringer\n\n--------------------------------",
saveInstructions: "GemÆndringer",
unsupportedTWFormat: "Ikke understøttet TiddlyWiki format '%0'",
tiddlerSaveError: "Fejl ved forsøg på at gemme tiddler '%0'",
tiddlerLoadError: "Fejl ved load af tiddler '%0'",
wrongSaveFormat: "Kan ikke gemme med formatet '%0'. Bruger standard format til at gemme.",
invalidFieldName: "Ikke tilladt feltnavn %0",
fieldCannotBeChanged: "Felt '%0' kan ikke ændres",
loadingMissingTiddler: "Forsøger at hente tiddleren '%0' fra '%1' serveren ved:\n\n'%2' i arbejdsområdet '%3'",
upgradeDone: "Opgradering til version %0 er nu fuldført\n\nKlik 'OK' for at genopfriske den nyligt opgraderede TiddlyWiki"});
merge(config.messages.messageClose,{
text: "luk",
tooltip: "luk dette meddelelsesområde"});
config.messages.backstage = {
open: {text: "bagscenen", tooltip: "Åben bagsceneområdet for at ændre på nogle grundlæggende indstillinger"},
close: {text: "luk", tooltip: "Luk bagsceneområdet"},
prompt: "bagscenen: ",
decal: {
edit: {text: "edit", tooltip: "Redigér tiddleren '%0'"}
}
};
config.messages.listView = {
tiddlerTooltip: "Klik for at se hele denne tiddlers tekst",
previewUnavailable: "(forhåndsvisning er ikke tilgængelig)"
};
config.messages.dates.months = ["Januar", "Februar", "Marts", "April", "Maj", "Juni", "Juli", "August", "September", "Oktober", "November","December"];
config.messages.dates.days = ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"];
config.messages.dates.shortMonths = ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"];
config.messages.dates.shortDays = ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"];
// suffixes for dates, eg "1ste","2den","3die"..."30te","31te"
config.messages.dates.daySuffixes = ["ste","den","die","te","te","te","te","te","te","te",
"te","te","te","te","te","te","te","te","te","te",
"ste","den","die","te","te","te","te","te","te","te",
"te"];
config.messages.dates.am = "formiddag";
config.messages.dates.pm = "eftermiddag";
merge(config.messages.tiddlerPopup,{
});
merge(config.views.wikified.tag,{
labelNoTags: "ingen tags",
labelTags: "tags: ",
openTag: "Åben tag '%0'",
tooltip: "Vis tiddlere der er taggede med '%0'",
openAllText: "Åben alle",
openAllTooltip: "Åben alle disse tiddlere",
popupNone: "Ingen andre tiddlere er taggede med '%0'"});
merge(config.views.wikified,{
defaultText: "Tiddleren '%0' findes ikke endnu. Dobbelt-klik for at lave den",
defaultModifier: "(mangler)",
shadowModifier: "(indbygget skygge tiddler)",
dateFormat: "DD MMM YYYY", // use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
createdPrompt: "lavet"});
merge(config.views.editor,{
tagPrompt: "Skriv tags delt med mellemrum, [[brug 2 dobbelte firkantede klammer]] om nødvendigt, eller tilføj allerede eksisterende",
defaultText: "Skriv teksten til '%0'"});
merge(config.views.editor.tagChooser,{
text: "tags",
tooltip: "Vælg eksisterende tags som tilføjelse til denne tiddler",
popupNone: "Der er ikke defineret nogen tags",
tagTooltip: "Tilføj tagget '%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: "søg",
prompt: "Søg i denne TiddlyWiki",
accessKey: "F",
successMsg: "Der er fundet %0 tiddlere som matcher %1",
failureMsg: "Der er ikke fundet nogen tiddlere som matcher %0"});
merge(config.macros.tagging,{
label: "tagger: ",
labelNotTag: "tagger ikke",
tooltip: "Liste over tiddlere der er taggede med '%0'"});
merge(config.macros.timeline,{
dateFormat: "DD MMM YYYY"});// use this to change the date format for your locale, eg "YYYY MMM DD", do not translate the Y, M or D
merge(config.macros.allTags,{
tooltip: "Vis tiddlere der er taggede med '%0'",
noTags: "Der er ingen taggede tiddlere"});
config.macros.list.all.prompt = "Alle tiddlere i alfabetisk orden";
config.macros.list.missing.prompt = "Tiddlere der linkes til men som ikke er definerede";
config.macros.list.orphans.prompt = "Tiddlere som der ikke linkes til fra nogen andre tiddlere";
config.macros.list.shadowed.prompt = "Tiddlere som er skyggede med grundlæggende indhold";
config.macros.list.touched.prompt = "Tiddlere som er blevet ændret lokalt ";
merge(config.macros.closeAll,{
label: "luk alle",
prompt: "Luk alle viste tiddlere (untaget dem som er ved at blive redigerede)"});
merge(config.macros.permaview,{
label: "vis permalink",
prompt: "Lav et link til en URL som henter alle de netop nu synlige tiddlere"});
merge(config.macros.saveChanges,{
label: "gem ændringer",
prompt: "Gem alle tiddlere for at lave en ny TiddlyWiki",
accessKey: "S"});
merge(config.macros.newTiddler,{
label: "ny tiddler",
prompt: "Lav en ny tiddler",
title: "Ny Tiddler",
accessKey: "N"});
merge(config.macros.newJournal,{
label: "ny journal",
prompt: "Lav en ny tiddler ud fra nuværende dato og tid",
accessKey: "J"});
merge(config.macros.options,{
wizardTitle: "Tilpas avancerede muligheder",
step1Title: "Disse muligheder gemmes i cookies i din browser",
step1Html: "<input type='hidden' name='markList'></input><br><input type='checkbox' checked='false' name='chkUnknown'>Show unknown options</input>",
unknownDescription: "//(ukendt)//",
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: "Administrer udvidelser",
step1Title: "Aktive udvidelser",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
skippedText: "(Denne udvidelse er ikke blevet aktiveret fordi den først er blevet tilføjet efter start)",
noPluginText: "Der er ikke installeret nogen udvidelser",
confirmDeleteText: "Er du sikker på at du vil slette disse udvidelser:\n\n%0",
removeLabel: "Fjern systemConfig tag",
removePrompt: "Fjern systemConfig tag",
deleteLabel: "slet",
deletePrompt: "Slet disse tiddlere permanent",
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: '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'}
]}
});
merge(config.macros.toolbar,{
moreLabel: "mere",
morePrompt: "Vis flere muligheder"
});
merge(config.macros.refreshDisplay,{
label: "genopfrisk",
prompt: "Genopfrisk hele TiddlyWikiens udseende"
});
merge(config.macros.importTiddlers,{
readOnlyWarning: "Du kan ikke importere til en låst TiddlyWiki fil. Prøv at åbne den fra en fil:// URL",
wizardTitle: "Importer tiddlere fra en anden fil eller server",
step1Title: "Trin 1: Find serveren eller TiddlyWiki filen",
step1Html: "Vælg servertypen: <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: "Åben forbindelsen til denne fil eller server",
openError: "Der var problemer med at hente tiddlywiki filen",
statusOpenHost: "Forbinder til hosten",
statusGetWorkspaceList: "Henter en liste over tilgængelige arbejdsområder",
step2Title: "Trin 2: Vælg arbejdsområde",
step2Html: "Indskriv et navn på arbejdsområdet: <input type='text' size=50 name='txtWorkspace'><br>...eller vælg et der allerede er der: <select name='selWorkspace'><option value=''>Choose...</option></select>",
cancelLabel: "fortryd",
cancelPrompt: "Fortryd denne import",
statusOpenWorkspace: "Åben arbejdsområdet",
statusGetTiddlerList: "Henter listen over tilgængelige tiddlere",
errorGettingTiddlerList: "Fejl ved hentning af liste over tiddlere, klik Fortryd for at prøve igen",
step3Title: "Trin 3: Vælg hvilke tiddlere der skal importeres",
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: "importer",
importPrompt: "Importer disse tiddlere",
confirmOverwriteText: "Er du sikker på at du vil overskrive disse tiddlere:\n\n%0",
step4Title: "Trin 4: Importerer %0 tiddler(e)",
step4Html: "<input type='hidden' name='markReport'></input>", // DO NOT TRANSLATE
doneLabel: "udført",
donePrompt: "Luk denne wizard",
statusDoingImport: "Importerer tiddlere",
statusDoneImport: "Alle tiddlere er importede",
systemServerNamePattern: "%2 on %1",
systemServerNamePatternNoWorkspace: "%1",
confirmOverwriteSaveTiddler: "Tiddleren '%0' findes allerede. Klik 'OK' for at overskrive den med detaljerne fra denne server, eller 'Fortryd' for at efterlade uændret",
serverSaveTemplate: "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n\nDenne tiddler blev lavet automatisk for at skrive denne servers detaljer",
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: "Opgrader TiddlyWikis kerne kode",
step1Title: "Opdater eller reparer denne TiddlyWiki til sidste nye udgivelse",
step1Html: "Du er ved at opgradere til sidste nye udgave af TiddlyWikis kerne kode (from <a href='%0' class='externalLink' target='_blank'>%1</a>). Dit indhold vil blive bibeholdt under opgraderinen.<br><br>Bemærk at opgraderinger kan konfikte med gamle udvidelser. Hvis du får problemer med den opgraderede fil se her <a href='http://www.tiddlywiki.org/wiki/CoreUpgrades' class='externalLink' target='_blank'>http://www.tiddlywiki.org/wiki/CoreUpgrades</a>",
errorCantUpgrade: "Kan ikke opgradere denne TiddlyWiki. Du kan kun opgradere en TiddlyWiki fil som er gemt lokalt på en pc",
errorNotSaved: "Du skal gemme ændringer før du kan gennemføre en opgradering",
step2Title: "Bekræft opgraderingsdetaljer",
step2Html_downgrade: "Du er ved at nedgradere til TiddlyWiki version %0 fra %1.<br><br>Nedgradering til en ældre udgave af kerne koden er IKKE tilrådeligt",
step2Html_restore: "Denne tiddlyWike bruger allerede den sidste nye kerne kode (%0).<br><br>Du kan fortsætte med opgraderingen for at sikre dig at koden ikke er blevet ødelagt",
step2Html_upgrade: "Du er ved at opgradere til TiddlyWiki version %0 fra %1",
upgradeLabel: "opgrader",
upgradePrompt: "Forbered opgraderingsprocessen",
statusPreparingBackup: "Forbereder backup",
statusSavingBackup: "Gemmer backup fil",
errorSavingBackup: "Der var problemer med at gemme backup filen",
statusLoadingCore: "Loader kernekoden",
errorLoadingCore: "Fejl ved load af kernekoden",
errorCoreFormat: "Fejl ved den nye kernekode",
statusSavingCore: "Gemmer den nye kernekode",
statusReloadingCore: "Genloader den nye kernekode",
startLabel: "start",
startPrompt: "Start opgraderingsprocessen",
cancelLabel: "fortryd",
cancelPrompt: "Fortryd opgraderingsprocessen",
step3Title: "Opgradering afbrudt",
step3Html: "Du har afbrudt opgraderingsprocessen"
});
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: "Synkronisér disse tiddlere", name: 'sync'}
]},
wizardTitle: "Synkroniser med internet servere og filer",
step1Title: "Vælg hvilke tiddlere du vil synkronisere",
step1Html: "<input type='hidden' name='markList'></input>", // DO NOT TRANSLATE
syncLabel: "synk",
syncPrompt: "Synkronisér disse tiddlere",
hasChanged: "Ændret imens den var koblet fra",
hasNotChanged: "Uændret imens den var koblet fra",
syncStatusList: {
none: {text: "...", color: "gennemsigtig", display:null},
changedServer: {text: "Ændret på serveren", color: '#8080ff', display:null},
changedLocally: {text: "Ændret imens den var koblet fra", color: '#80ff80', display:null},
changedBoth: {text: "ændret imens den var koblet fra også på serveren", color: '#ff8080', display:null},
notFound: {text: "Ikke fundet på serveren", color: '#ffff80', display:null},
putToServer: {text: "Gemt update på serveren", color: '#ff80ff', display:null},
gotFromServer: {text: "Hentet update fra serveren", color: '#80ffff', display:null}
}
});
merge(config.commands.closeTiddler,{
text: "luk",
tooltip: "Luk denne tiddler"});
merge(config.commands.closeOthers,{
text: "luk andre",
tooltip: "Luk alle andre tiddlere"});
merge(config.commands.editTiddler,{
text: "redigér",
tooltip: "Redigér denne tiddler",
readOnlyText: "se",
readOnlyTooltip: "Se denne tiddlers kilde"});
merge(config.commands.saveTiddler,{
text: "færdig",
tooltip: "Gem ændringer til denne tiddler"});
merge(config.commands.cancelTiddler,{
text: "fortryd",
tooltip: "Fortryd ændringer til denne tiddler",
warning: "Er du sikker på at du vil fortryde dine ændringer til '%0'?",
readOnlyText: "færdig",
readOnlyTooltip: "Se tiddlere normalt"});
merge(config.commands.deleteTiddler,{
text: "slet",
tooltip: "Slet denne tiddler",
warning: "Er du sikker på at du vil slette '%0'?"});
merge(config.commands.permalink,{
text: "permalink",
tooltip: "Permalink til denne tiddler"});
merge(config.commands.references,{
text: "referencer",
tooltip: "Vis tiddlere som linker til denne tiddler",
popupNone: "Ingen referencer"});
merge(config.commands.jump,{
text: "spring",
tooltip: "Spring til en anden tiddler"});
merge(config.commands.syncing,{
text: "synkroniserer",
tooltip: "Kontroller synkronisering af denne tiddler med en server eller en fil",
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: "Sykroniserer ikke lige nu",
captionUnSync: "Stop synkronisering af denne tiddler",
chooseServer: "Synkronisér denne tiddler med en anden server:",
currServerMarker: "\u25cf ",
notCurrServerMarker: " "});
merge(config.commands.fields,{
text: "felter",
tooltip: "Vis denne tiddlers udvidede felter",
emptyText: "Der er ingen udvidede felter til rådighed for denne 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: "[[TranslatedGettingStarted]]",
MainMenu: "[[TranslatedGettingStarted]]\n\n\n^^~TiddlyWiki version <<version>>\n© 2007 [[UnaMesa|http://www.unamesa.org/]]^^",
TranslatedGettingStarted: "For at komme i gang med denne tomme tiddlywiki, skal du ændre på de følgende tiddlere:\n* SiteTitle & SiteSubtitle: Sidens titel og undertitel, som vist øverst (efter de er gemt, vil de også vise sig i browserens titelmenu)\n* MainMenu: er hovedmenuen (er oftest placeret til venstre)\n* DefaultTiddlers: Indeholder navnene på de tiddlere du vilhave skal starte op når du åbner TiddlyWiki\nDu skal også skrive dit brugernavn for at signere dine redigeringer: <<option txtUserName>>",
SiteTitle: "Min TiddlyWiki",
SiteSubtitle: "en genbrugelig ikke-liniær personlig web notesbog",
SiteUrl: "http://www.tiddlywiki.com/",
OptionsPanel: "Disse muligheder for at ændre på TiddlyWiki bliver gemt i din browser\n\nDit brugernavn til at signere dine ændringer. Skriv det som et WikiOrd (f.eks. PerPoulsen)\n<<option txtUserName>>\n\n<<option chkSaveBackups>> Save backups\n<<option chkAutoSave>> Auto save\n<<option chkRegExpSearch>> Regexp search\n<<option chkCaseSensitiveSearch>> Case sensitive search\n<<option chkAnimate>> Enable animations\n\n----\nAlso see [[TranslatedAdvancedOptions|AdvancedOptions]]",
SideBarOptions: '<<search>><<closeAll>><<permaview>><<newTiddler>><<newJournal "DD MMM YYYY" "journal">><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel "muligheder \u00bb" "Ændre på TiddlyWikis avancerede muligheder">>',
SideBarTabs: '<<tabs txtMainTab "Tidslinie" "Tidslinie" TabTimeline "Alle" "Alle tiddlere" TabAll "Tags" "Alle tags" TabTags "Flere" "Flere lister" TabMore>>',
TabMore: '<<tabs txtMoreTab "Manglende" "Manglende tiddlere" TabMoreMissing "Uden tilknytning" "Tiddlere" TabMoreOrphans "Skyggede" "Skyggede tiddlere" TabMoreShadowed>>'
});
merge(config.annotations,{
AdvancedOptions: "Denne skygge tiddler giver adgang til flere avancerede muligheder",
ColorPalette: "Disse værdier i denne skyggetiddler bestemmer hvilket farveskema, der bliver brugt til ~TiddlyWikis brugerflade",
DefaultTiddlers: "Tiddlere som er listede i denne skyggetiddler vil automatisk blive vist når ~TiddlyWiki starter op",
EditTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud når de bliver redigerede",
GettingStarted: "Denne skyggetiddler giver instruktioner om grundlæggende anvendelse",
ImportTiddlers: "Denne skyggetiddler giver mulighed for at importere tiddlere",
MainMenu: "Denne tiddler bliver brugt til at definere indholdet af hoved menuen i venstre side af skærmen",
MarkupPreHead: "Denne tiddler bliver indsat i toppen af <head> sektionen på TiddlyWiki HTML filen",
MarkupPostHead: "Denne tiddler bliver indsat i bunden af <head> sektionen på TiddlyWiki HTML filen",
MarkupPreBody: "Denne tiddler bliver indsat i toppen af<body> sektionen på TiddlyWiki HTML filen",
MarkupPostBody: "Denne tiddler bliver indsat i slutningen af <body> sektionen på TiddlyWiki HTML filen umiddelbart efter script blokken",
OptionsPanel: "Denne skyggetiddler bliver brugt til indholdet af muligheder skydepanelet i højre side",
PageTemplate: "HTML skabelonen i denne skyggetiddler bestemmer det overordnede ~TiddlyWiki layout",
PluginManager: "Denne skyggetiddler giver adgang til udvidelsesadministrationen",
SideBarOptions: "Denne skyggetiddler bruges til indholdet af muligheder panelet i højre sidemenu",
SideBarTabs: "Denne skyggetiddler bruges til indholdet af fanebladspanelet i højre sidemenu",
SiteSubtitle: "Denne skyggetiddler bruges som anden del af sidens titel",
SiteTitle: "Denne skyggetiddler bruges som første del af sidens titel",
SiteUrl: "Denne skyggetiddler bør sættes til den fulde mål-URL til publikation",
StyleSheetColors: "Denne skyggetiddler indeholder CSS definitionerne der bestemmer farverne på side elementerne. ''REDIGÉR IKKE DENNE TIDDLER'', lav i stedet dine ændringer i StyleSheet skyggetiddleren",
StyleSheet: "Denne tiddler kan indeholde specialle CSS definitioner",
StyleSheetLayout: "Denne skyggetiddler indeholder CSS definitioner der bestemmer layoutet på side elementer. ''REDIGÉR IKKE DENNE TIDDLER'', lav i stedet dine ændringer i StyleSheet skyggetiddleren",
StyleSheetLocale: "Denne skyggetiddler indeholder CSS definitioner relateret til lokale oversættelser",
StyleSheetPrint: "Denne skyggetiddler indeholder CSS definitioner til print",
TabAll: "Denne skyggetiddler indeholder hvad der er i 'Alle' fanen i højre sidemenu",
TabMore: "Denne skyggetiddler indeholder hvad der er i 'Flere' fanen i højre sidemenu",
TabMoreMissing: "Denne skyggetiddler indeholder hvad der er i 'Mangler' fanen i højre sidemenu",
TabMoreOrphans: "Denne skyggetiddler indeholder hvad der er i 'Mangler tilknytning' fanen i højre sidemenu",
TabMoreShadowed: "Denne skyggetiddler indeholder hvad der er i 'Skyggede' fanen i højre sidemenu",
TabTags: "Denne skyggetiddler indeholder hvad der er i 'Tags' fanen i højre sidemenu",
TabTimeline: "Denne skyggetiddler indeholder hvad der er i 'Tidslinie' fanen i højre sidemenu",
ToolbarCommands: "Denne skyggetiddler bestemmer hvilke værktøjer der vises i tiddleres værktøjslinier",
ViewTemplate: "HTML skabelonen i denne skyggetiddler bestemmer hvordan tiddlere ser ud"
});
//}}}
/***
|''Name:''|DataTiddlerPlugin|
|''Version:''|1.0.6 (2006-08-26)|
|''Source:''|http://tiddlywiki.abego-software.de/#DataTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Enhance your tiddlers with structured data (such as strings, booleans, numbers, or even arrays and compound objects) that can be easily accessed and modified through named fields (in JavaScript code).
Such tiddler data can be used in various applications. E.g. you may create tables that collect data from various tiddlers.
''//Example: "Table with all December Expenses"//''
{{{
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
}}}
//(This assumes that expenses are stored in tiddlers tagged with "expense".)//
<<forEachTiddler
where
'tiddler.tags.contains("expense") && tiddler.data("month") == "Dec"'
write
'"|[["+tiddler.title+"]]|"+tiddler.data("descr")+"| "+tiddler.data("amount")+"|\n"'
>>
For other examples see DataTiddlerExamples.
''Access and Modify Tiddler Data''
You can "attach" data to every tiddler by assigning a JavaScript value (such as a string, boolean, number, or even arrays and compound objects) to named fields.
These values can be accessed and modified through the following Tiddler methods:
|!Method|!Example|!Description|
|{{{data(field)}}}|{{{t.data("age")}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{data(field,defaultValue)}}}|{{{t.data("isVIP",false)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{data()}}}|{{{t.data()}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{setData(field,value)}}}|{{{t.setData("age",42)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{setData(field,value,defaultValue)}}}|{{{t.setData("isVIP",flag,false)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
Alternatively you may use the following functions to access and modify the data. In this case the tiddler argument is either a tiddler or the name of a tiddler.
|!Method|!Description|
|{{{DataTiddler.getData(tiddler,field)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined {{{undefined}}} is returned.|
|{{{DataTiddler.getData(tiddler,field,defaultValue)}}}|Returns the value of the given data field of the tiddler. When no such field is defined or its value is undefined the defaultValue is returned.|
|{{{DataTiddler.getDataObject(tiddler)}}}|Returns the data object of the tiddler, with a property for every field. The properties of the returned data object may only be read and not be modified. To modify the data use DataTiddler.setData(...) or the corresponding Tiddler method.|
|{{{DataTiddler.setData(tiddler,field,value)}}}|Sets the value of the given data field of the tiddler to the value. When the value is {{{undefined}}} the field is removed.|
|{{{DataTiddler.setData(tiddler,field,value,defaultValue)}}}|Sets the value of the given data field of the tiddler to the value. When the value is equal to the defaultValue no value is set (and the field is removed).|
//(For details on the various functions see the detailed comments in the source code.)//
''Data Representation in a Tiddler''
The data of a tiddler is stored as plain text in the tiddler's content/text, inside a "data" section that is framed by a {{{<data>...</data>}}} block. Inside the data section the information is stored in the [[JSON format|http://www.crockford.com/JSON/index.html]].
//''Data Section Example:''//
{{{
<data>{"isVIP":true,"user":"John Brown","age":34}</data>
}}}
The data section is not displayed when viewing the tiddler (see also "The showData Macro").
Beside the data section a tiddler may have all kind of other content.
Typically you will not access the data section text directly but use the methods given above. Nevertheless you may retrieve the text of the data section's content through the {{{DataTiddler.getDataText(tiddler)}}} function.
''Saving Changes''
The "setData" methods respect the "ForceMinorUpdate" and "AutoSave" configuration values. I.e. when "ForceMinorUpdate" is true changing a value using setData will not affect the "modifier" and "modified" attributes. With "AutoSave" set to true every setData will directly save the changes after a setData.
''Notifications''
No notifications are sent when a tiddler's data value is changed through the "setData" methods.
''Escape Data Section''
In case that you want to use the text {{{<data>}}} or {{{</data>}}} in a tiddler text you must prefix the text with a tilde ('~'). Otherwise it may be wrongly considered as the data section. The tiddler text {{{~<data>}}} is displayed as {{{<data>}}}.
''The showData Macro''
By default the data of a tiddler (that is stored in the {{{<data>...</data>}}} section of the tiddler) is not displayed. If you want to display this data you may used the {{{<<showData ...>>}}} macro:
''Syntax:''
|>|{{{<<}}}''showData '' [''JSON''] [//tiddlerName//] {{{>>}}}|
|''JSON''|By default the data is rendered as a table with a "Name" and "Value" column. When defining ''JSON'' the data is rendered in JSON format|
|//tiddlerName//|Defines the tiddler holding the data to be displayed. When no tiddler is given the tiddler containing the showData macro is used. When the tiddler name contains spaces you must quote the name (or use the {{{[[...]]}}} syntax.)|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
!Revision history
* v1.0.6 (2006-08-26)
** Removed misleading comment
* v1.0.5 (2006-02-27) (Internal Release Only)
** Internal
*** Make "JSLint" conform
* v1.0.4 (2006-02-05)
** Bugfix: showData fails in TiddlyWiki 2.0
* v1.0.3 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.2 (2005-12-22)
** Enhancements:
*** Handle texts "<data>" or "</data>" more robust when used in a tiddler text or as a field value.
*** Improved (JSON) error messages.
** Bugs fixed:
*** References are not updated when using the DataTiddler.
*** Changes to compound objects are not always saved.
*** "~</data>" is not rendered correctly (expected "</data>")
* v1.0.1 (2005-12-13)
** Features:
*** The showData macro supports an optional "tiddlername" argument to specify the tiddler containing the data to be displayed
** Bugs fixed:
*** A script immediately following a data section is deleted when the data is changed. (Thanks to GeoffS for reporting.)
* v1.0.0 (2005-12-12)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// DataTiddlerPlugin
//============================================================================
//============================================================================
// Ensure that the DataTiddler Plugin is only installed once.
//
if (!version.extensions.DataTiddlerPlugin) {
version.extensions.DataTiddlerPlugin = {
major: 1, minor: 0, revision: 6,
date: new Date(2006, 7, 26),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#DataTiddlerPlugin"
};
// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window;
if (!TiddlyWiki.prototype.getTiddler) {
TiddlyWiki.prototype.getTiddler = function(title) {
var t = this.tiddlers[title];
return (t !== undefined && t instanceof Tiddler) ? t : null;
};
}
//============================================================================
// DataTiddler Class
//============================================================================
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
function DataTiddler() {
}
DataTiddler = {
// Function to stringify a JavaScript value, producing the text for the data section content.
// (Must match the implementation of DataTiddler.parse.)
//
stringify : null,
// Function to parse the text for the data section content, producing a JavaScript value.
// (Must match the implementation of DataTiddler.stringify.)
//
parse : null
};
// Ensure access for IE
window.DataTiddler = DataTiddler;
// ---------------------------------------------------------------------------
// Data Accessor and Mutator
// ---------------------------------------------------------------------------
// Returns the value of the given data field of the tiddler.
// When no such field is defined or its value is undefined
// the defaultValue is returned.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.getData = function(tiddler, field, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataValue(t, field, defaultValue);
};
// Sets the value of the given data field of the tiddler to
// the value. When the value is equal to the defaultValue
// no value is set (and the field is removed)
//
// Changing data of a tiddler will not trigger notifications.
//
// @param tiddler either a tiddler name or a tiddler
//
DataTiddler.setData = function(tiddler, field, value, defaultValue) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler+ "("+t+")";
}
DataTiddler.setTiddlerDataValue(t, field, value, defaultValue);
};
// Returns the data object of the tiddler, with a property for every field.
//
// The properties of the returned data object may only be read and
// not be modified. To modify the data use DataTiddler.setData(...)
// or the corresponding Tiddler method.
//
// If no data section is defined a new (empty) object is returned.
//
// @param tiddler either a tiddler name or a Tiddler
//
DataTiddler.getDataObject = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.getTiddlerDataObject(t);
};
// Returns the text of the content of the data section of the tiddler.
//
// When no data section is defined for the tiddler null is returned
//
// @param tiddler either a tiddler name or a Tiddler
// @return [may be null]
//
DataTiddler.getDataText = function(tiddler) {
var t = (typeof tiddler == "string") ? store.getTiddler(tiddler) : tiddler;
if (!(t instanceof Tiddler)) {
throw "Tiddler expected. Got "+tiddler;
}
return DataTiddler.readDataSectionText(t);
};
// ---------------------------------------------------------------------------
// Internal helper methods (must not be used by code from outside this plugin)
// ---------------------------------------------------------------------------
// Internal.
//
// The original JSONError is not very user friendly,
// especially it does not define a toString() method
// Therefore we extend it here.
//
DataTiddler.extendJSONError = function(ex) {
if (ex.name == 'JSONError') {
ex.toString = function() {
return ex.name + ": "+ex.message+" ("+ex.text+")";
};
}
return ex;
};
// Internal.
//
// @param t a Tiddler
//
DataTiddler.getTiddlerDataObject = function(t) {
if (t.dataObject === undefined) {
var data = DataTiddler.readData(t);
t.dataObject = (data) ? data : {};
}
return t.dataObject;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.getTiddlerDataValue = function(tiddler, field, defaultValue) {
var value = DataTiddler.getTiddlerDataObject(tiddler)[field];
return (value === undefined) ? defaultValue : value;
};
// Internal.
//
// @param tiddler a Tiddler
//
DataTiddler.setTiddlerDataValue = function(tiddler, field, value, defaultValue) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
var oldValue = data[field];
if (value == defaultValue) {
if (oldValue !== undefined) {
delete data[field];
DataTiddler.save(tiddler);
}
return;
}
data[field] = value;
DataTiddler.save(tiddler);
};
// Internal.
//
// Reads the data section from the tiddler's content and returns its text
// (as a String).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readDataSectionText = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
if (matches === null || !matches[2]) {
return null;
}
return matches[2];
};
// Internal.
//
// Reads the data section from the tiddler's content and returns it
// (as an internalized object).
//
// Returns null when no data is defined.
//
// @param tiddler a Tiddler
// @return [may be null]
//
DataTiddler.readData = function(tiddler) {
var text = DataTiddler.readDataSectionText(tiddler);
try {
return text ? DataTiddler.parse(text) : null;
} catch(ex) {
throw DataTiddler.extendJSONError(ex);
}
};
// Internal.
//
// Returns the serialized text of the data of the given tiddler, as it
// should be stored in the data section.
//
// @param tiddler a Tiddler
//
DataTiddler.getDataTextOfTiddler = function(tiddler) {
var data = DataTiddler.getTiddlerDataObject(tiddler);
return DataTiddler.stringify(data);
};
// Internal.
//
DataTiddler.indexOfNonEscapedText = function(s, subString, startIndex) {
var index = s.indexOf(subString, startIndex);
while ((index > 0) && (s[index-1] == '~')) {
index = s.indexOf(subString, index+1);
}
return index;
};
// Internal.
//
DataTiddler.getDataSectionInfo = function(text) {
// Special care must be taken to handle "<data>" and "</data>" texts inside
// a data section.
// Also take care not to use an escaped <data> (i.e. "~<data>") as the start
// of a data section. (Same for </data>)
// NOTE: we are explicitly searching for a data section that contains a JSON
// string, i.e. framed with braces. This way we are little bit more robust in
// case the tiddler contains unescaped texts "<data>" or "</data>". This must
// be changed when using a different stringifier.
var startTagText = "<data>{";
var endTagText = "}</data>";
var startPos = 0;
// Find the first not escaped "<data>".
var startDataTagIndex = DataTiddler.indexOfNonEscapedText(text, startTagText, 0);
if (startDataTagIndex < 0) {
return null;
}
// Find the *last* not escaped "</data>".
var endDataTagIndex = text.indexOf(endTagText, startDataTagIndex);
if (endDataTagIndex < 0) {
return null;
}
var nextEndDataTagIndex;
while ((nextEndDataTagIndex = text.indexOf(endTagText, endDataTagIndex+1)) >= 0) {
endDataTagIndex = nextEndDataTagIndex;
}
return {
prefixEnd: startDataTagIndex,
dataStart: startDataTagIndex+(startTagText.length)-1,
dataEnd: endDataTagIndex,
suffixStart: endDataTagIndex+(endTagText.length)
};
};
// Internal.
//
// Returns the "matches" of a content of a DataTiddler on the
// "data" regular expression. Return null when no data is defined
// in the tiddler content.
//
// Group 1: text before data section (prefix)
// Group 2: content of data section
// Group 3: text behind data section (suffix)
//
// @param tiddler a Tiddler
// @return [may be null] null when the tiddler contains no data section, otherwise see above.
//
DataTiddler.getDataTiddlerMatches = function(tiddler) {
var text = tiddler.text;
var info = DataTiddler.getDataSectionInfo(text);
if (!info) {
return null;
}
var prefix = text.substr(0,info.prefixEnd);
var data = text.substr(info.dataStart, info.dataEnd-info.dataStart+1);
var suffix = text.substr(info.suffixStart);
return [text, prefix, data, suffix];
};
// Internal.
//
// Saves the data in a <data> block of the given tiddler (as a minor change).
//
// The "chkAutoSave" and "chkForceMinorUpdate" options are respected.
// I.e. the TiddlyWiki *file* is only saved when AutoSave is on.
//
// Notifications are not send.
//
// This method should only be called when the data really has changed.
//
// @param tiddler
// the tiddler to be saved.
//
DataTiddler.save = function(tiddler) {
var matches = DataTiddler.getDataTiddlerMatches(tiddler);
var prefix;
var suffix;
if (matches === null) {
prefix = tiddler.text;
suffix = "";
} else {
prefix = matches[1];
suffix = matches[3];
}
var dataText = DataTiddler.getDataTextOfTiddler(tiddler);
var newText =
(dataText !== null)
? prefix + "<data>" + dataText + "</data>" + suffix
: prefix + suffix;
if (newText != tiddler.text) {
// make the change in the tiddlers text
// ... see DataTiddler.MyTiddlerChangedFunction
tiddler.isDataTiddlerChange = true;
// ... do the action change
tiddler.set(
tiddler.title,
newText,
config.options.txtUserName,
config.options.chkForceMinorUpdate? undefined : new Date(),
tiddler.tags);
// ... see DataTiddler.MyTiddlerChangedFunction
delete tiddler.isDataTiddlerChange;
// Mark the store as dirty.
store.dirty = true;
// AutoSave if option is selected
if(config.options.chkAutoSave) {
saveChanges();
}
}
};
// Internal.
//
DataTiddler.MyTiddlerChangedFunction = function() {
// Remove the data object from the tiddler when the tiddler is changed
// by code other than DataTiddler code.
//
// This is necessary since the data object is just a "cached version"
// of the data defined in the data section of the tiddler and the
// "external" change may have changed the content of the data section.
// Thus we are not sure if the data object reflects the data section
// contents.
//
// By deleting the data object we ensure that the data object is
// reconstructed the next time it is needed, with the data defined by
// the data section in the tiddler's text.
// To indicate that a change is a "DataTiddler change" a temporary
// property "isDataTiddlerChange" is added to the tiddler.
if (this.dataObject && !this.isDataTiddlerChange) {
delete this.dataObject;
}
// call the original code.
DataTiddler.originalTiddlerChangedFunction.apply(this, arguments);
};
//============================================================================
// Formatters
//============================================================================
// This formatter ensures that "~<data>" is rendered as "<data>". This is used to
// escape the "<data>" of a data section, just in case someone really wants to use
// "<data>" as a text in a tiddler and not start a data section.
//
// Same for </data>.
//
config.formatters.push( {
name: "data-escape",
match: "~<\\/?data>",
handler: function(w) {
w.outputText(w.output,w.matchStart + 1,w.nextMatch);
}
} );
// This formatter ensures that <data>...</data> sections are not rendered.
//
config.formatters.push( {
name: "data",
match: "<data>",
handler: function(w) {
var info = DataTiddler.getDataSectionInfo(w.source);
if (info && info.prefixEnd == w.matchStart) {
w.nextMatch = info.suffixStart;
} else {
w.outputText(w.output,w.matchStart,w.nextMatch);
}
}
} );
//============================================================================
// Tiddler Class Extension
//============================================================================
// "Hijack" the changed method ---------------------------------------------------
DataTiddler.originalTiddlerChangedFunction = Tiddler.prototype.changed;
Tiddler.prototype.changed = DataTiddler.MyTiddlerChangedFunction;
// Define accessor methods -------------------------------------------------------
// Returns the value of the given data field of the tiddler. When no such field
// is defined or its value is undefined the defaultValue is returned.
//
// When field is undefined (or null) the data object is returned. (See
// DataTiddler.getDataObject.)
//
// @param field [may be null, undefined]
// @param defaultValue [may be null, undefined]
// @return [may be null, undefined]
//
Tiddler.prototype.data = function(field, defaultValue) {
return (field)
? DataTiddler.getTiddlerDataValue(this, field, defaultValue)
: DataTiddler.getTiddlerDataObject(this);
};
// Sets the value of the given data field of the tiddler to the value. When the
// value is equal to the defaultValue no value is set (and the field is removed).
//
// @param value [may be null, undefined]
// @param defaultValue [may be null, undefined]
//
Tiddler.prototype.setData = function(field, value, defaultValue) {
DataTiddler.setTiddlerDataValue(this, field, value, defaultValue);
};
//============================================================================
// showData Macro
//============================================================================
config.macros.showData = {
// Standard Properties
label: "showData",
prompt: "Display the values stored in the data section of the tiddler"
};
config.macros.showData.handler = function(place,macroName,params) {
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the optional "JSON"
var showInJSONFormat = false;
if ((i < params.length) && params[i] == "JSON") {
i++;
showInJSONFormat = true;
}
var tiddlerName = story.findContainingTiddler(place).id.substr(7);
if (i < params.length) {
tiddlerName = params[i];
i++;
}
// --- Processing ------------------------------------------
try {
if (showInJSONFormat) {
this.renderDataInJSONFormat(place, tiddlerName);
} else {
this.renderDataAsTable(place, tiddlerName);
}
} catch (e) {
this.createErrorElement(place, e);
}
};
config.macros.showData.renderDataInJSONFormat = function(place,tiddlerName) {
var text = DataTiddler.getDataText(tiddlerName);
if (text) {
createTiddlyElement(place,"pre",null,null,text);
}
};
config.macros.showData.renderDataAsTable = function(place,tiddlerName) {
var text = "|!Name|!Value|\n";
var data = DataTiddler.getDataObject(tiddlerName);
if (data) {
for (var i in data) {
var value = data[i];
text += "|"+i+"|"+DataTiddler.stringify(value)+"|\n";
}
}
wikify(text, place);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.showData.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"showDataError","<<showData ...>>: "+message);
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".showDataError{color: #ffffff;background-color: #880000;}",
"showData");
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... TiddlyWiki Core
/*global createTiddlyElement, saveChanges, store, story, wikify */
// ... DataTiddler
/*global DataTiddler */
// ... JSON
/*global JSON */
/***
!JSON Code, used to serialize the data
***/
/*
Copyright (c) 2005 JSON.org
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The Software shall be used for Good, not Evil.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
/*
The global object JSON contains two methods.
JSON.stringify(value) takes a JavaScript value and produces a JSON text.
The value must not be cyclical.
JSON.parse(text) takes a JSON text and produces a JavaScript value. It will
throw a 'JSONError' exception if there is an error.
*/
var JSON = {
copyright: '(c)2005 JSON.org',
license: 'http://www.crockford.com/JSON/license.html',
/*
Stringify a JavaScript value, producing a JSON text.
*/
stringify: function (v) {
var a = [];
/*
Emit a string.
*/
function e(s) {
a[a.length] = s;
}
/*
Convert a value.
*/
function g(x) {
var c, i, l, v;
switch (typeof x) {
case 'object':
if (x) {
if (x instanceof Array) {
e('[');
l = a.length;
for (i = 0; i < x.length; i += 1) {
v = x[i];
if (typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(v);
}
}
e(']');
return;
} else if (typeof x.toString != 'undefined') {
e('{');
l = a.length;
for (i in x) {
v = x[i];
if (x.hasOwnProperty(i) &&
typeof v != 'undefined' &&
typeof v != 'function') {
if (l < a.length) {
e(',');
}
g(i);
e(':');
g(v);
}
}
return e('}');
}
}
e('null');
return;
case 'number':
e(isFinite(x) ? +x : 'null');
return;
case 'string':
l = x.length;
e('"');
for (i = 0; i < l; i += 1) {
c = x.charAt(i);
if (c >= ' ') {
if (c == '\\' || c == '"') {
e('\\');
}
e(c);
} else {
switch (c) {
case '\b':
e('\\b');
break;
case '\f':
e('\\f');
break;
case '\n':
e('\\n');
break;
case '\r':
e('\\r');
break;
case '\t':
e('\\t');
break;
default:
c = c.charCodeAt();
e('\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16));
}
}
}
e('"');
return;
case 'boolean':
e(String(x));
return;
default:
e('null');
return;
}
}
g(v);
return a.join('');
},
/*
Parse a JSON text, producing a JavaScript value.
*/
parse: function (text) {
var p = /^\s*(([,:{}\[\]])|"(\\.|[^\x00-\x1f"\\])*"|-?\d+(\.\d*)?([eE][+-]?\d+)?|true|false|null)\s*/,
token,
operator;
function error(m, t) {
throw {
name: 'JSONError',
message: m,
text: t || operator || token
};
}
function next(b) {
if (b && b != operator) {
error("Expected '" + b + "'");
}
if (text) {
var t = p.exec(text);
if (t) {
if (t[2]) {
token = null;
operator = t[2];
} else {
operator = null;
try {
token = eval(t[1]);
} catch (e) {
error("Bad token", t[1]);
}
}
text = text.substring(t[0].length);
} else {
error("Unrecognized token", text);
}
} else {
token = operator = undefined;
}
}
function val() {
var k, o;
switch (operator) {
case '{':
next('{');
o = {};
if (operator != '}') {
for (;;) {
if (operator || typeof token != 'string') {
error("Missing key");
}
k = token;
next();
next(':');
o[k] = val();
if (operator != ',') {
break;
}
next(',');
}
}
next('}');
return o;
case '[':
next('[');
o = [];
if (operator != ']') {
for (;;) {
o.push(val());
if (operator != ',') {
break;
}
next(',');
}
}
next(']');
return o;
default:
if (operator !== null) {
error("Missing value");
}
k = token;
next();
return k;
}
}
next();
return val();
}
};
/***
!Setup the data serialization
***/
DataTiddler.format = "JSON";
DataTiddler.stringify = JSON.stringify;
DataTiddler.parse = JSON.parse;
//}}}
<<miniBrowser hidecontrols http://digitallearning.macfound.org/site/c.enJLKQNlFiG/b.2029199/k.94AC/Latest_News.htm>>
En scrapbog til alle mulige [[IT-ressourcer|IT]] mm..
For at gemme eller downloade skal du åbne Sidepanel (i topmenuen) og Tiddlyspot.
Koden er "alarmkoden"
Hvis du vil signere dine "redigeringer" automatisk, skriver du dit navn i boksen til venstre.
Bemærk at wysiwyg funktionen kun virker online. (- eller hvis du downloader fck-editor og lægger den i samme mappe som edb.html-filen)
Happy Hacking MaMa
Se også [[Kom godt igang]]
|TiddlyChatter|h
|<<tiddler [[Welcome to TiddlyChatter]]>>|
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]] wikibar'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div macro='tiddler QuickEditToolbar'></div>
<div class='editor' macro='edit tags'></div>
<div macro='showWhen tiddler.tags.contains("Emner") || tiddler.title =="Skriv navnet på dit nye hovedemne her"'>[[TopicNote]]</div>
<div macro='showWhen tiddler.tags.contains("Note") || tiddler.title =="Ny Note"'>[[NoteNote]]</div>
<div class='editor' macro='edit text'></div>
<!--}}}-->
<<forEachTiddler
where
'tiddler.tags.contains("authorbook") && tiddler.data("author")'
sortBy 'tiddler.data("author")'
write
'"{{indent{"+tiddler.data("author")+".}}} {{indent{//"+tiddler.data("booktitle")+"//}}} {{indent{[[here|"+tiddler.title+"]]}}}<br>\n"'
>>
<<forEachTiddler
where 'tiddler.tags.contains("authorbook") && tiddler.data("primtopic")'
sortBy 'GroupTitle = tiddler.data("primtopic")+"###"+tiddler.data("booktitle")'
script 'function getGroupTitle(tiddler, context) {
if (!context.lastGroup || context.lastGroup != tiddler.data("primtopic"))
{
context.lastGroup = tiddler.data("primtopic");
return "!! {{{"+(context.lastGroup?context.lastGroup:"no categorizados")+"}}}\n";
} else return "";}'
write
'getGroupTitle(tiddler, context)+"** [["+tiddler.title+"]]\n"'
>>
<<forEachTiddler
where
'tiddler.tags.contains("authorbook") && tiddler.data("booktitle")'
sortBy 'tiddler.data("booktitle")'
write
'"#{{indent{//"+tiddler.data("booktitle")+"//}}} {{indent{"+tiddler.data("author")+".}}} {{indent{[[here|"+tiddler.title+"]]}}}<br>\n"'
>>
<html><div align="center"><iframe src="http://www.c4lpt.net/" frameborder="0" width="100%" height="600"></iframe></div></html>
<html>
<img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyNDIzNDA*MTk*MzcmcHQ9MTI*MjM*MDQyMjgyOCZwPTEwMTkxJmQ9c3NfZW1iZWQmZz*yJnQ9Jm89ZWY*NDI2MmQ3YTFjNDJmMTk4MjkxNmVjZmU1MTk5MTcmb2Y9MA==.gif" /><div style="width:425px;text-align:left" id="__ss_1367508"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" href="http://www.slideshare.net/janehart/using-elgg-as-a-social-learning-platform?type=presentation" title="Using Elgg as a Social Learning platform">Using Elgg as a Social Learning platform</a><object style="margin:0px" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sociallearning2-090430051112-phpapp02&stripped_title=using-elgg-as-a-social-learning-platform" /><param name="allowFullScreen" value="true"/><param name="allowScriptAccess" value="always"/><embed src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=sociallearning2-090430051112-phpapp02&stripped_title=using-elgg-as-a-social-learning-platform" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="355"></embed></object><div style="font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;">View more <a style="text-decoration:underline;" href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration:underline;" href="http://www.slideshare.net/janehart">Jane Hart</a>.</div></div>
</html>
/***
|Name:|ExtentTagButtonPlugin|
|Description:|Adds a New tiddler button in the tag drop down|
|Version:|3.2 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#ExtendTagButtonPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
window.onClickTag_mptw_orig = window.onClickTag;
window.onClickTag = function(e) {
window.onClickTag_mptw_orig.apply(this,arguments);
var tag = this.getAttribute("tag");
var title = this.getAttribute("tiddler");
// Thanks Saq, you're a genius :)
var popup = Popup.stack[Popup.stack.length-1].popup;
createTiddlyElement(createTiddlyElement(popup,"li",null,"listBreak"),"div");
wikify("<<newTiddler label:'New tiddler' tag:'"+tag+"'>>",createTiddlyElement(popup,"li"));
return false;
}
//}}}
/***
|''Name:''|FCKeditorPlugin|
|''Description:''|Wysiwyg editor for TiddlyWiki using FCKeditor.|
|''Version:''|1.1.1|
|''Date:''|Dec 21,2007|
|''Source:''|http://visualtw.ouvaton.org/VisualTW.html|
|''Author:''|Pascal Collin|
|''License:''|[[BSD open source license|License]]|
|''~CoreVersion:''|2.2.0|
|''Browser:''|Firefox 2.0; InternetExplorer 6.0, others|
!Demo:
On the plugin [[homepage|http://visualtw.ouvaton.org/VisualTW.html]], see and edit [[WysiwygDemo]].
!Installation:
#download and unzip [[FCKeditor|http://www.fckeditor.net/download]] (by default, in a wiki subfolder, such that the relative path "fckeditor/fckeditor.js" is right).
#import [[FCKeditorPlugin]] (systemConfig tagged)
#add the following text to MarkupPreHead : {{{<script type="text/javascript" src="fckeditor/fckeditor.js"></script>}}}
#customize FCKeditorPath if needed (in MarkupPreHead and in options below)
#save and reload
#use the <<toolbar editHtml>> button in the tiddler's toolbar (in default ViewTemplate) or add {{{editHtml}}} command in your own toolbar.
! Useful Addons
*[[HTMLFormattingPlugin|http://www.tiddlytools.com/#HTMLFormattingPlugin]] to embed wiki syntax in html tiddlers.<<br>>//__Tips__ : When this plugin is installed, you can use anchor syntax to link tiddlers in wysiwyg mode (example : #example). Anchors are converted back and from wiki syntax when editing.//
*[[TaggedTemplateTweak|http://www.TiddlyTools.com/#TaggedTemplateTweak]] to use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values.
!Configuration options :
|FCKeditor folder (absolute or relative)|<<option txtFCKeditorPath>> |
|FCKeditor custom configuration script path (relative or absolute)<<br>>[[Example|fckeditor/editor/custom_config.js]] : {{{ fckeditor/editor/custom_config.js}}}|<<option txtFCKCustomConfigScript>>|
|Toolbar name ("Default", "Basic" or custom)<<br>>See [[FCKeditor documentation|http://wiki.fckeditor.net/Developer%27s_Guide/Configuration/Toolbar]] for more information on custom toolbars|<<option txtFCKToolbar>>|
|FCKeditor default height (if blank = 500px)|<<option txtFCKheight>>|
|Template called by the {{{wysiwyg}}} button|EditHtmlTemplate|
!Code
***/
//{{{
config.options.txtFCKeditorPath = config.options.txtFCKeditorPath ? config.options.txtFCKeditorPath : "fckeditor/";
config.options.txtFCKCustomConfigScript = config.options.txtFCKCustomConfigScript ? config.options.txtFCKCustomConfigScript : "";
config.options.txtFCKToolbar = config.options.txtFCKToolbar ? config.options.txtFCKToolbar : "";
config.options.txtFCKheight = config.options.txtFCKheight ? config.options.txtFCKheight : "500px";
config.macros.editHtml = {
handler : function(place,macroName,params,wikifier,paramString,tiddler) {
var field = params[0];
var height = params[1] ? params[1] : config.options.txtFCKheight;
if (typeof FCKeditor=="undefined"){
displayMessage(config.macros.editHtml.FCKeditorUnavailable);
config.macros.edit.handler(place,macroName,params,wikifier,paramString,tiddler);
}
else if (field) {
var e = createTiddlyElement(null,"div");
var fckName = "FCKeditor"+ Math.random();
if(tiddler.isReadOnly())
e.setAttribute("readOnly","readOnly");
e.setAttribute("editHtml",field);
if (height) e.setAttribute("height",height);
e.setAttribute("fckName",fckName);
place.appendChild(e);
var fck = new FCKeditor(fckName);
fck.BasePath = config.options.txtFCKeditorPath;
if (config.options.txtFCKCustomConfigScript) fck.Config["CustomConfigurationsPath"] = config.options.txtFCKCustomConfigScript ;
if (config.options.txtFCKToolbar) fck.ToolbarSet = config.options.txtFCKToolbar;
fck.Height=height;
var re = /^<html>(.*)<\/html>$/m;
var fieldValue=store.getValue(tiddler,field);
var htmlValue = re.exec(fieldValue);
var value = (htmlValue && (htmlValue.length>0)) ? htmlValue[1] : fieldValue;
value=value.replace(/\[\[([^|\]]*)\|([^\]]*)]]/g,'<a href="#$2">$1</a>');
config.macros.editHtml.FCKvalues[fckName]=value;
e.innerHTML = fck.CreateHtml();
}
},
gather : function(e) {
var name = e.getAttribute("fckName");
var oEditor = window.FCKeditorAPI ? FCKeditorAPI.GetInstance(name) : null;
if (oEditor) {
var html = oEditor.GetHTML();
if (html!=null)
return "<html>"+html.replace(/<a href="#([^>]*)">([^<]*)<\/a>/gi,"[[$2|$1]]")+"</html>";
}
},
FCKvalues : {},
FCKeditorUnavailable : "FCKeditor kunne ikke hentes. Check om du har internet og evt. også plugin konfigurationen og genopfrisk."
}
window.FCKeditor_OnComplete= function( editorInstance ) {
var name=editorInstance.Name;
var value = config.macros.editHtml.FCKvalues[name];
delete config.macros.editHtml.FCKvalues[name];
oEditor = FCKeditorAPI.GetInstance(name);
if (value) oEditor.SetHTML(value);
}
Story.prototype.previousGatherSaveEditHtml = Story.prototype.previousGatherSaveEditHtml ? Story.prototype.previousGatherSaveEditHtml : Story.prototype.gatherSaveFields; // to avoid looping if this line is called several times
Story.prototype.gatherSaveFields = function(e,fields){
if(e && e.getAttribute) {
var f = e.getAttribute("editHtml");
if(f){
var newVal = config.macros.editHtml.gather(e);
if (newVal) fields[f] = newVal;
}
this.previousGatherSaveEditHtml(e, fields);
}
};
config.shadowTiddlers.EditHtmlTemplate = config.shadowTiddlers.EditTemplate.replace(/macro='edit text'/,"macro='editHtml text'");
config.commands.editHtml={
text: "wysiwyg",
tooltip: "redigér denne tiddler med en RichText editor",
readOnlyText: "",
handler : function(event,src,title) {
clearMessage();
var tiddlerElem = document.getElementById(story.idPrefix + title);
var fields = tiddlerElem.getAttribute("tiddlyFields");
story.displayTiddler(null,title,"EditHtmlTemplate",false,null,fields);
return false;
}
}
config.shadowTiddlers.ViewTemplate = config.shadowTiddlers.ViewTemplate.replace(/\+editTiddler/,"+editTiddler editHtml");
//}}}
<html><p align="center" class="style11" style="text-align: center;"> </p> <center> <embed height="250" align="middle" width="300" src="http://www.satisfaction.com/photo-cube-generator/show.swf?baseURL=http://www.satisfaction.com/photo-cube-generator/&clickURL=http://www.satisfaction.com/photo-cube-generator/&flashLABEL=Satisfaction.com&clickLABEL=Photo%20Cube%20Generator&file=http%3A%2F%2Fwww%2Esatisfaction%2Ecom%2Fphoto%2Dcube%2Dgenerator%2Fuploads%2F04%5F02%5F2009%2F08%2Fpic54386527%2Egif" quality="high" bgcolor="#ffffff" name="show" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed> <br /> <small><a href="http://www.satisfaction.com/photo-cube-generator/">Photo Cube Generator</a></small> </center> <p align="center" class="style11" style="text-align: center;"> </p> <center> <center><center><center><st1:place w:st="on"><span class="style98">"Education is not the filling of a pail, but the lighting of a fire." <br /> </span></st1:place><span class="style98"><st1:place w:st="on">William Butler Yeats </st1:place></span> </center> </center> </center> </center> <div align="right"> </div> <p align="center" class="style98" style="text-align: center;"><st1:place w:st="on"></st1:place><st1:place w:st="on"></st1:place><st1:place w:st="on"><b><span style="font-size: 10.5pt;">Mission</span></b></st1:place><b><span style="font-size: 10.5pt;"> Statement </span><span style="font-size: 9pt; color: black;"><o:p></o:p></span></b></p> <div class="style100"><address class="style8" style="text-align: center;"><span class="style94"><b><span style="font-size: 9pt; color: black;">We at <st1:place w:st="on"><st1:placename w:st="on">Challenger</st1:placename> <st1:placename w:st="on">Middle</st1:placename> <st1:placetype w:st="on">School</st1:placetype></st1:place>, an exemplary learning institution set in a technologically advanced community, ensure our students’ intellectual, emotional, physical and social growth through innovative instructional techniques and active participation in a variety of learning opportunities.<u2:p></u2:p> <o:p></o:p><o:p></o:p><o:p></o:p><o:p></o:p><o:p></o:p></span></b> </span></address></div> <p align="center" style="text-align: center;"><span class="style98"><b><span style="font-size: 9pt; color: black;"> <!-- #BeginDate format:Am1 -->April 28, 2009<!-- #EndDate --> </span></b></span><b> <span style="font-size: 9pt; color: black;"><br /> </span></b></p><p>Kilde: [[MS_Index|http://www.hsv.k12.al.us/schools/middle/chalms/]]</p></html>
<html><p align="center" class="style11" style="text-align: center;"> </p> <center> <embed height="250" align="middle" width="300" src="http://www.satisfaction.com/photo-cube-generator/show.swf?baseURL=http://www.satisfaction.com/photo-cube-generator/&clickURL=http://www.satisfaction.com/photo-cube-generator/&flashLABEL=Satisfaction.com&clickLABEL=Photo%20Cube%20Generator&file=http%3A%2F%2Fwww%2Esatisfaction%2Ecom%2Fphoto%2Dcube%2Dgenerator%2Fuploads%2F04%5F02%5F2009%2F08%2Fpic54386527%2Egif" quality="high" bgcolor="#ffffff" name="show" wmode="transparent" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed> <br /> <small><a href="http://www.satisfaction.com/photo-cube-generator/">Photo Cube Generator</a></small> </center> <p align="center" class="style11" style="text-align: center;"> </p> <center> <center><center><center><st1:place w:st="on"><span class="style98">"Education is not the filling of a pail, but the lighting of a fire." <br /> </span></st1:place><span class="style98"><st1:place w:st="on">William Butler Yeats </st1:place></span> </center> </center> </center> </center> <div align="right"> </div> <p align="center" class="style98" style="text-align: center;"><st1:place w:st="on"></st1:place><st1:place w:st="on"></st1:place><st1:place w:st="on"><b><span style="font-size: 10.5pt;">Mission</span></b></st1:place><b><span style="font-size: 10.5pt;"> Statement </span><span style="font-size: 9pt; color: black;"><o:p></o:p></span></b></p> <div class="style100"><address class="style8" style="text-align: center;"><span class="style94"><b><span style="font-size: 9pt; color: black;">We at <st1:place w:st="on"><st1:placename w:st="on">Challenger</st1:placename> <st1:placename w:st="on">Middle</st1:placename> <st1:placetype w:st="on">School</st1:placetype></st1:place>, an exemplary learning institution set in a technologically advanced community, ensure our students’ intellectual, emotional, physical and social growth through innovative instructional techniques and active participation in a variety of learning opportunities.<u2:p></u2:p> <o:p></o:p><o:p></o:p><o:p></o:p><o:p></o:p><o:p></o:p></span></b> </span></address></div> <p align="center" style="text-align: center;"><span class="style98"><b><span style="font-size: 9pt; color: black;"> <!-- #BeginDate format:Am1 -->April 28, 2009<!-- #EndDate --> </span></b></span><b> <span style="font-size: 9pt; color: black;"><br /> </span></b></p><p>Kilde: [[MS_Index|http://www.hsv.k12.al.us/schools/middle/chalms/]]</p></html>
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|© 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description
Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.
''Syntax:''
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]] is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].
!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features:
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen)
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features:
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs:
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features:
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// ForEachTiddlerPlugin
//============================================================================
//============================================================================
// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {
if (!window.abego) window.abego = {};
version.extensions.ForEachTiddlerPlugin = {
major: 1, minor: 0, revision: 8,
date: new Date(2007,3,12),
source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};
// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
TiddlyWiki.prototype.forEachTiddler = function(callback) {
for(var t in this.tiddlers) {
callback.call(this,t,this.tiddlers[t]);
}
};
}
//============================================================================
// forEachTiddler Macro
//============================================================================
version.extensions.forEachTiddler = {
major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};
// ---------------------------------------------------------------------------
// Configurations and constants
// ---------------------------------------------------------------------------
config.macros.forEachTiddler = {
// Standard Properties
label: "forEachTiddler",
prompt: "Perform actions on a (sorted) selection of tiddlers",
// actions
actions: {
addToList: {},
write: {}
}
};
// ---------------------------------------------------------------------------
// The forEachTiddler Macro Handler
// ---------------------------------------------------------------------------
config.macros.forEachTiddler.getContainingTiddler = function(e) {
while(e && !hasClass(e,"tiddler"))
e = e.parentNode;
var title = e ? e.getAttribute("tiddler") : null;
return title ? store.getTiddler(title) : null;
};
config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);
if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// Parse the "in" clause
var tiddlyWikiPath = undefined;
if ((i < params.length) && params[i] == "in") {
i++;
if (i >= params.length) {
this.handleError(place, "TiddlyWiki path expected behind 'in'.");
return;
}
tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the where clause
var whereClause ="true";
if ((i < params.length) && params[i] == "where") {
i++;
whereClause = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the sort stuff
var sortClause = null;
var sortAscending = true;
if ((i < params.length) && params[i] == "sortBy") {
i++;
if (i >= params.length) {
this.handleError(place, "sortClause missing behind 'sortBy'.");
return;
}
sortClause = this.paramEncode(params[i]);
i++;
if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
sortAscending = params[i] == "ascending";
i++;
}
}
// Parse the script
var scriptText = null;
if ((i < params.length) && params[i] == "script") {
i++;
scriptText = this.paramEncode((i < params.length) ? params[i] : "");
i++;
}
// Parse the action.
// When we are already at the end use the default action
var actionName = "addToList";
if (i < params.length) {
if (!config.macros.forEachTiddler.actions[params[i]]) {
this.handleError(place, "Unknown action '"+params[i]+"'.");
return;
} else {
actionName = params[i];
i++;
}
}
// Get the action parameter
// (the parsing is done inside the individual action implementation.)
var actionParameter = params.slice(i);
// --- Processing ------------------------------------------
try {
this.performMacro({
place: place,
inTiddler: tiddler,
whereClause: whereClause,
sortClause: sortClause,
sortAscending: sortAscending,
actionName: actionName,
actionParameter: actionParameter,
scriptText: scriptText,
tiddlyWikiPath: tiddlyWikiPath});
} catch (e) {
this.handleError(place, e);
}
};
// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {
var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);
var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
context["tiddlyWiki"] = tiddlyWiki;
// Get the tiddlers, as defined by the whereClause
var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
context["tiddlers"] = tiddlers;
// Sort the tiddlers, when sorting is required.
if (parameter.sortClause) {
this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
}
return {tiddlers: tiddlers, context: context};
};
// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
return this.getTiddlersAndContext(parameter).tiddlers;
};
// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
// The following properties are supported:
//
// place
// whereClause
// sortClause
// sortAscending
// actionName
// actionParameter
// scriptText
// tiddlyWikiPath
//
// All properties are optional.
// For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
var tiddlersAndContext = this.getTiddlersAndContext(parameter);
// Perform the action
var actionName = parameter.actionName ? parameter.actionName : "addToList";
var action = config.macros.forEachTiddler.actions[actionName];
if (!action) {
this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
return;
}
var actionHandler = action.handler;
actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};
// ---------------------------------------------------------------------------
// The actions
// ---------------------------------------------------------------------------
// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
return;
}
// Perform the action.
var list = document.createElement("ul");
place.appendChild(list);
for (var i = 0; i < tiddlers.length; i++) {
var tiddler = tiddlers[i];
var listItem = document.createElement("li");
list.appendChild(listItem);
createTiddlyLink(listItem, tiddler.title, true);
}
};
abego.parseNamedParameter = function(name, parameter, i) {
var beginExpression = null;
if ((i < parameter.length) && parameter[i] == name) {
i++;
if (i >= parameter.length) {
throw "Missing text behind '%0'".format([name]);
}
return config.macros.forEachTiddler.paramEncode(parameter[i]);
}
return null;
}
// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
// Parse the parameter
var p = 0;
if (p >= parameter.length) {
this.handleError(place, "Missing expression behind 'write'.");
return;
}
var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
// Parse the "begin" option
var beginExpression = abego.parseNamedParameter("begin", parameter, p);
if (beginExpression !== null)
p += 2;
var endExpression = abego.parseNamedParameter("end", parameter, p);
if (endExpression !== null)
p += 2;
var noneExpression = abego.parseNamedParameter("none", parameter, p);
if (noneExpression !== null)
p += 2;
// Parse the "toFile" option
var filename = null;
var lineSeparator = undefined;
if ((p < parameter.length) && parameter[p] == "toFile") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
return;
}
filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
p++;
if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
p++;
if (p >= parameter.length) {
this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
return;
}
lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
p++;
}
}
// Check for extra parameters
if (parameter.length > p) {
config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
return;
}
// Perform the action.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
var count = tiddlers.length;
var text = "";
if (count > 0 && beginExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
for (var i = 0; i < count; i++) {
var tiddler = tiddlers[i];
text += func(tiddler, context, count, i);
}
if (count > 0 && endExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);
if (count == 0 && noneExpression)
text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
if (filename) {
if (lineSeparator !== undefined) {
lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
text = text.replace(/\n/mg,lineSeparator);
}
saveFile(filename, convertUnicodeToUTF8(text));
} else {
var wrapper = createTiddlyElement(place, "span");
wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
}
};
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
return {
place : placeParam,
whereClause : whereClauseParam,
sortClause : sortClauseParam,
sortAscending : sortAscendingParam,
script : scriptText,
actionName : actionNameParam,
actionParameter : actionParameterParam,
tiddlyWikiPath : tiddlyWikiPathParam,
inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
};
};
// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
if (!idPrefix) {
idPrefix = "store";
}
var lenPrefix = idPrefix.length;
// Read the content of the given file
var content = loadFile(this.getLocalPath(path));
if(content === null) {
throw "TiddlyWiki '"+path+"' not found.";
}
var tiddlyWiki = new TiddlyWiki();
// Starting with TW 2.2 there is a helper function to import the tiddlers
if (tiddlyWiki.importTiddlyWiki) {
if (!tiddlyWiki.importTiddlyWiki(content))
throw "File '"+path+"' is not a TiddlyWiki.";
tiddlyWiki.dirty = false;
return tiddlyWiki;
}
// The legacy code, for TW < 2.2
// Locate the storeArea div's
var posOpeningDiv = content.indexOf(startSaveArea);
var posClosingDiv = content.lastIndexOf(endSaveArea);
if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
throw "File '"+path+"' is not a TiddlyWiki.";
}
var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
// Create a "div" element that contains the storage text
var myStorageDiv = document.createElement("div");
myStorageDiv.innerHTML = storageText;
myStorageDiv.normalize();
// Create all tiddlers in a new TiddlyWiki
// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
var store = myStorageDiv.childNodes;
for(var t = 0; t < store.length; t++) {
var e = store[t];
var title = null;
if(e.getAttribute)
title = e.getAttribute("tiddler");
if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
title = e.id.substr(lenPrefix);
if(title && title !== "") {
var tiddler = tiddlyWiki.createTiddler(title);
tiddler.loadFromDiv(e,title);
}
}
tiddlyWiki.dirty = false;
return tiddlyWiki;
};
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
//
// (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
var script = context["script"];
var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
var fullText = (script ? script+";" : "")+functionText+";theFunction;";
return eval(fullText);
};
// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
var result = [];
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
tiddlyWiki.forEachTiddler(function(title,tiddler) {
if (func(tiddler, context, undefined, undefined)) {
result.push(tiddler);
}
});
return result;
};
// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
var message = "Extra parameter behind '"+actionName+"':";
for (var i = firstUnusedIndex; i < parameter.length; i++) {
message += " "+parameter[i];
}
this.handleError(place, message);
};
// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? -1
: +1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
var result =
(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue)
? 0
: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
? +1
: -1;
return result;
};
// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
// To avoid evaluating the sortClause whenever two items are compared
// we pre-calculate the sortValue for every item in the array and store it in a
// temporary property ("forEachTiddlerSortValue") of the tiddlers.
var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
var count = tiddlers.length;
var i;
for (i = 0; i < count; i++) {
var tiddler = tiddlers[i];
tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
}
// Do the sorting
tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);
// Delete the temporary property that holds the sortValue.
for (i = 0; i < tiddlers.length; i++) {
delete tiddlers[i].forEachTiddlerSortValue;
}
};
// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
displayMessage(message);
};
// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
var message ="<<"+macroName;
for (var i = 0; i < params.length; i++) {
message += " "+params[i];
}
message += ">>";
displayMessage(message);
};
// Internal.
//
// Creates an element that holds an error message
//
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
var message = (exception.description) ? exception.description : exception.toString();
return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};
// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
if (place) {
this.createErrorElement(place, exception);
} else {
throw exception;
}
};
// Internal.
//
// Encodes the given string.
//
// Replaces
// "$))" to ">>"
// "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
var reGTGT = new RegExp("\\$\\)\\)","mg");
var reGT = new RegExp("\\$\\)","mg");
return s.replace(reGTGT, ">>").replace(reGT, ">");
};
// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
//
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
// Remove any location part of the URL
var hashPos = originalPath.indexOf("#");
if(hashPos != -1)
originalPath = originalPath.substr(0,hashPos);
// Convert to a native file format assuming
// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
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;
};
// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
"forEachTiddler");
//============================================================================
// End of forEachTiddler Macro
//============================================================================
//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
var n = prefix.length;
return (this.length >= n) && (this.slice(0, n) == prefix);
};
//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
var n = suffix.length;
return (this.length >= n) && (this.right(n) == suffix);
};
//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
return this.indexOf(substring) >= 0;
};
//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item) {
return i;
}
}
return -1;
};
//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false.
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
return (this.indexOf(item) >= 0);
};
//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
for(var i = 0; i < items.length; i++) {
if (this.contains(items[i])) {
return true;
}
}
return false;
};
//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
//
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null]
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
for(var i = 0; i < items.length; i++) {
if (!this.contains(items[i])) {
return false;
}
}
return true;
};
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... DOM
/*global document */
// ... TiddlyWiki Core
/*global convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink,
displayMessage, endSaveArea, hasClass, loadFile, saveFile,
startSaveArea, store, wikify */
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
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 abego Software 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.
***/
The {{{<<formTiddler ...>>}}} macro defined by the FormTiddlerPlugin.
When a tiddler T1 references the (FormTemplate) tiddler T2 in the FormTiddlerMacro, the data of T1 can be edited through the INPUT elements defined by T2.
/***
<<checkForDataTiddlerPlugin>>
|''Name:''|FormTiddlerPlugin|
|''Version:''|1.0.6 (2007-06-24)|
|''Source:''|http://tiddlywiki.abego-software.de/#FormTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license]]|
|''Macros:''|formTiddler, checkForDataTiddlerPlugin, newTiddlerWithForm|
|''Requires:''|DataTiddlerPlugin|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; InternetExplorer 6.0|
!Description
Use form-based tiddlers to enter your tiddler data using text fields, listboxes, checkboxes etc. (All standard HTML Form input elements supported).
''Syntax:''
|>|{{{<<}}}''formTiddler'' //tiddlerName//{{{>>}}}|
|//tiddlerName//|The name of the FormTemplate tiddler to be used to edit the data of the tiddler containing the macro.|
|>|{{{<<}}}''newTiddlerWithForm'' //formTemplateName// //buttonLabel// [//titleExpression// [''askUser'']] {{{>>}}}|
|//formTemplateName//|The name of the tiddler that defines the form the new tiddler should use.|
|//buttonLabel//|The label of the button|
|//titleExpression//|A (quoted) JavaScript String expression that defines the title (/name) of the new tiddler.|
|''askUser''|Typically the user is not asked for the title when a title is specified (and not yet used). When ''askUser'' is given the user will be asked in any case. This may be used when the calculated title is just a suggestion that must be confirmed by the user|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|
For details and how to use the macros see the [[introduction|FormTiddler Introduction]] and the [[examples|FormTiddler Examples]].
!Revision history
* v1.0.6 (2007-06-24)
** Fixed problem when using SELECT component in Internet Explorer (thanks to MaikBoenig for reporting)
* v1.0.5 (2006-02-24)
** Removed "debugger;" instruction
* v1.0.4 (2006-02-07)
** Bug: On IE no data is written to data section when field values changed (thanks to KenGirard for reporting)
* v1.0.3 (2006-02-05)
** Bug: {{{"No form template specified in <<formTiddler>>"}}} when using formTiddler macro on InternetExplorer (thanks to KenGirard for reporting)
* v1.0.2 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.1 (2005-12-22)
** Features:
*** Support InternetExplorer
*** Added newTiddlerWithForm Macro
* v1.0.0 (2005-12-14)
** initial version
!Code
***/
//{{{
//============================================================================
//============================================================================
// FormTiddlerPlugin
//============================================================================
//============================================================================
if (!window.abego) window.abego = {};
abego.getOptionsValue = function(element,i) {
var v = element.options[i].value;
if (!v && element.options[i].text)
v = element.options[i].text;
return v;
};
version.extensions.FormTiddlerPlugin = {
major: 1, minor: 0, revision: 5,
date: new Date(2006, 2, 24),
type: 'plugin',
source: "http://tiddlywiki.abego-software.de/#FormTiddlerPlugin"
};
// For backward compatibility with v1.2.x
//
if (!window.story) window.story=window;
if (!TiddlyWiki.prototype.getTiddler) TiddlyWiki.prototype.getTiddler = function(title) { return t = this.tiddlers[title]; return (t != undefined && t instanceof Tiddler) ? t : null; }
//============================================================================
// formTiddler Macro
//============================================================================
// -------------------------------------------------------------------------------
// Configurations and constants
// -------------------------------------------------------------------------------
config.macros.formTiddler = {
// Standard Properties
label: "formTiddler",
version: {major: 1, minor: 0, revision: 4, date: new Date(2006, 2, 7)},
prompt: "Edit tiddler data using forms",
// Define the "setters" that set the values of INPUT elements of a given type
// (must match the corresponding "getter")
setter: {
button: function(e, value) {/*contains no data */ },
checkbox: function(e, value) {e.checked = value;},
file: function(e, value) {try {e.value = value;} catch(e) {/* ignore, possibly security error*/}},
hidden: function(e, value) {e.value = value;},
password: function(e, value) {e.value = value;},
radio: function(e, value) {e.checked = (e.value == value);},
reset: function(e, value) {/*contains no data */ },
"select-one": function(e, value) {config.macros.formTiddler.setSelectOneValue(e,value);},
"select-multiple": function(e, value) {config.macros.formTiddler.setSelectMultipleValue(e,value);},
submit: function(e, value) {/*contains no data */},
text: function(e, value) {e.value = value;},
textarea: function(e, value) {e.value = value;}
},
// Define the "getters" that return the value of INPUT elements of a given type
// Return undefined to not store any data.
getter: {
button: function(e, value) {return undefined;},
checkbox: function(e, value) {return e.checked;},
file: function(e, value) {return e.value;},
hidden: function(e, value) {return e.value;},
password: function(e, value) {return e.value;},
radio: function(e, value) {return e.checked ? e.value : undefined;},
reset: function(e, value) {return undefined;},
"select-one": function(e, value) {return config.macros.formTiddler.getSelectOneValue(e);},
"select-multiple": function(e, value) {return config.macros.formTiddler.getSelectMultipleValue(e);},
submit: function(e, value) {return undefined;},
text: function(e, value) {return e.value;},
textarea: function(e, value) {return e.value;}
}
};
// -------------------------------------------------------------------------------
// The formTiddler Macro Handler
// -------------------------------------------------------------------------------
config.macros.formTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
if (!config.macros.formTiddler.checkForExtensions(place, macroName)) {
return;
}
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// get the name of the form template tiddler
var formTemplateName = undefined;
if (i < params.length) {
formTemplateName = params[i];
i++;
}
if (!formTemplateName) {
config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
return;
}
// --- Processing ------------------------------------------
// Get the form template text.
// (This contains the INPUT elements for the form.)
var formTemplateTiddler = store.getTiddler(formTemplateName);
if (!formTemplateTiddler) {
config.macros.formTiddler.createErrorElement(place, "Form template '" + formTemplateName + "' not found.");
return;
}
var templateText = formTemplateTiddler.text;
if(!templateText) {
// Shortcut: when template text is empty we do nothing.
return;
}
// Get the name of the tiddler containing this "formTiddler" macro
// (i.e. the tiddler, that will be edited and that contains the data)
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(place);
// Append a "form" element.
var formName = "form"+formTemplateName+"__"+tiddlerName;
var e = document.createElement("form");
e.setAttribute("name", formName);
place.appendChild(e);
// "Embed" the elements defined by the templateText (i.e. the INPUT elements)
// into the "form" element we just created
wikify(templateText, e);
// Initialize the INPUT elements.
config.macros.formTiddler.initValuesAndHandlersInFormElements(formName, DataTiddler.getDataObject(tiddlerName));
}
// -------------------------------------------------------------------------------
// Form Data Access
// -------------------------------------------------------------------------------
// Internal.
//
// Initialize the INPUT elements of the form with the values of their "matching"
// data fields in the tiddler. Also setup the onChange handler to ensure that
// changes in the INPUT elements are stored in the tiddler's data.
//
config.macros.formTiddler.initValuesAndHandlersInFormElements = function(formName, data) {
// config.macros.formTiddler.trace("initValuesAndHandlersInFormElements(formName="+formName+", data="+data+")");
// find the form
var form = config.macros.formTiddler.findForm(formName);
if (!form) {
return;
}
try {
var elems = form.elements;
for (var i = 0; i < elems.length; i++) {
var c = elems[i];
var setter = config.macros.formTiddler.setter[c.type];
if (setter) {
var value = data[c.name];
if (value != null) {
setter(c, value);
}
c.onchange = onFormTiddlerChange;
} else {
config.macros.formTiddler.displayFormTiddlerError("No setter defined for INPUT element of type '"+c.type+"'. (Element '"+c.name+"' in form '"+formName+"')");
}
}
} catch(e) {
config.macros.formTiddler.displayFormTiddlerError("Error when updating elements with new formData. "+e);
}
}
// Internal.
//
// @return [may be null]
//
config.macros.formTiddler.findForm = function(formName) {
// We must manually iterate through the document's forms, since
// IE does not support the "document[formName]" approach
var forms = window.document.forms;
for (var i = 0; i < forms.length; i++) {
var form = forms[i];
if (form.name == formName) {
return form;
}
}
return null;
}
// Internal.
//
config.macros.formTiddler.setSelectOneValue = function(element,value) {
var n = element.options.length;
for (var i = 0; i < n; i++) {
element.options[i].selected = abego.getOptionsValue(element,i) == value;
}
}
// Internal.
//
config.macros.formTiddler.setSelectMultipleValue = function(element,value) {
var values = {};
for (var i = 0; i < value.length; i++) {
values[value[i]] = true;
}
var n = element.length;
for (var i = 0; i < n; i++) {
element.options[i].selected = !(!values[abego.getOptionsValue(element,i)]);
}
}
// Internal.
//
config.macros.formTiddler.getSelectOneValue = function(element) {
var i = element.selectedIndex;
return (i >= 0) ? abego.getOptionsValue(element,i) : null;
}
// Internal.
//
config.macros.formTiddler.getSelectMultipleValue = function(element) {
var values = [];
var n = element.length;
for (var i = 0; i < n; i++) {
if (element.options[i].selected) {
values.push(abego.getOptionsValue(element,i));
}
}
return values;
}
// -------------------------------------------------------------------------------
// Helpers
// -------------------------------------------------------------------------------
// Internal.
//
config.macros.formTiddler.checkForExtensions = function(place,macroName) {
if (!version.extensions.DataTiddlerPlugin) {
config.macros.formTiddler.createErrorElement(place, "<<" + macroName + ">> requires the DataTiddlerPlugin. (You can get it from http://tiddlywiki.abego-software.de/#DataTiddlerPlugin)");
return false;
}
return true;
}
// Internal.
//
// Displays a trace message in the "TiddlyWiki" message pane.
// (used for debugging)
//
config.macros.formTiddler.trace = function(s) {
displayMessage("Trace: "+s);
}
// Internal.
//
// Display some error message in the "TiddlyWiki" message pane.
//
config.macros.formTiddler.displayFormTiddlerError = function(s) {
alert("FormTiddlerPlugin Error: "+s);
}
// Internal.
//
// Creates an element that holds an error message
//
config.macros.formTiddler.createErrorElement = function(place, message) {
return createTiddlyElement(place,"span",null,"formTiddlerError",message);
}
// Internal.
//
// Returns the name of the tiddler containing the given element.
//
config.macros.formTiddler.getContainingTiddlerName = function(element) {
return story.findContainingTiddler(element).id.substr(7);
}
// -------------------------------------------------------------------------------
// Event Handlers
// -------------------------------------------------------------------------------
// This function must be called by the INPUT elements whenever their
// data changes. Typically this is done through an "onChange" handler.
//
function onFormTiddlerChange (e) {
// config.macros.formTiddler.trace("onFormTiddlerChange "+e);
if (!e) var e = window.event;
var target = resolveTarget(e);
var tiddlerName = config.macros.formTiddler.getContainingTiddlerName(target);
var getter = config.macros.formTiddler.getter[target.type];
if (getter) {
var value = getter(target);
DataTiddler.setData(tiddlerName, target.name, value);
} else {
config.macros.formTiddler.displayFormTiddlerError("No getter defined for INPUT element of type '"+target.type+"'. (Element '"+target.name+"' used in tiddler '"+tiddlerName+"')");
}
}
// ensure that the function can be used in HTML event handler
window.onFormTiddlerChange = onFormTiddlerChange;
// -------------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// -------------------------------------------------------------------------------
setStylesheet(
".formTiddlerError{color: #ffffff;background-color: #880000;}",
"formTiddler");
//============================================================================
// checkForDataTiddlerPlugin Macro
//============================================================================
config.macros.checkForDataTiddlerPlugin = {
// Standard Properties
label: "checkForDataTiddlerPlugin",
version: {major: 1, minor: 0, revision: 0, date: new Date(2005, 12, 14)},
prompt: "Check if the DataTiddlerPlugin exists"
}
config.macros.checkForDataTiddlerPlugin.handler = function(place,macroName,params) {
config.macros.formTiddler.checkForExtensions(place, config.macros.formTiddler.label);
}
//============================================================================
// newTiddlerWithForm Macro
//============================================================================
config.macros.newTiddlerWithForm = {
// Standard Properties
label: "newTiddlerWithForm",
version: {major: 1, minor: 0, revision: 1, date: new Date(2006, 1, 6)},
prompt: "Creates a new Tiddler with a <<formTiddler ...>> macro"
}
config.macros.newTiddlerWithForm.handler = function(place,macroName,params) {
// --- Parsing ------------------------------------------
var i = 0; // index running over the params
// get the name of the form template tiddler
var formTemplateName = undefined;
if (i < params.length) {
formTemplateName = params[i];
i++;
}
if (!formTemplateName) {
config.macros.formTiddler.createErrorElement(place, "No form template specified in <<" + macroName + ">>.");
return;
}
// get the button label
var buttonLabel = undefined;
if (i < params.length) {
buttonLabel = params[i];
i++;
}
if (!buttonLabel) {
config.macros.formTiddler.createErrorElement(place, "No button label specified in <<" + macroName + ">>.");
return;
}
// get the (optional) tiddlerName script and "askUser"
var tiddlerNameScript = undefined;
var askUser = false;
if (i < params.length) {
tiddlerNameScript = params[i];
i++;
if (i < params.length && params[i] == "askUser") {
askUser = true;
i++;
}
}
// --- Processing ------------------------------------------
if(!readOnly) {
var onClick = function() {
var tiddlerName;
if (tiddlerNameScript) {
try {
tiddlerName = eval(tiddlerNameScript);
} catch (ex) {
}
}
if (!tiddlerName || askUser) {
tiddlerName = prompt("Please specify a tiddler name.", askUser ? tiddlerName : "");
}
while (tiddlerName && store.getTiddler(tiddlerName)) {
tiddlerName = prompt("A tiddler named '"+tiddlerName+"' already exists.\n\n"+"Please specify a tiddler name.", tiddlerName);
}
// tiddlerName is either null (user canceled) or a name that is not yet in the store.
if (tiddlerName) {
var body = "<<formTiddler [["+formTemplateName+"]]>>";
var tags = [];
store.saveTiddler(tiddlerName,tiddlerName,body,config.options.txtUserName,new Date(),tags);
story.displayTiddler(null,tiddlerName,1);
}
}
createTiddlyButton(place,buttonLabel,buttonLabel,onClick);
}
}
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])
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 abego Software 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.
***/
/***
|Name|FramedLinksPlugin|
|Source|http://www.TiddlyTools.com/#FramedLinksPlugin|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|createExternalLink|
|Options|##Configuration|
|Description|clicking an external link opens an IFRAME following the link instead of opening a new tab/window|
This plugin causes clicks on external links to be rendered into inline frames (~IFRAMEs) instead of opening them in new browser tabs/windows.
!!!!!Usage
<<<
Just place an external link into your tiddler content using standard TiddlyWiki syntax. When the {{{chkFramedLinks}}} checkbox is enabled or a tiddler is tagged with 'framedLinks' (see Configuration section, below), an IFRAME will be created dynamically whenever you click the external link. Clicking on the link again removes the IFRAME. You can hold down a modifier key (shift, control, or alt) while clicking a specific link to ''temporarily'' bypass the plugin-enhanced IFRAME handling and use the standard link handling behavior for that link.
<<<
!!!!!Configuration
<<<
<<option chkFramedLinks>> display inline frames for all external links
{{{usage: <<option chkFramedLinks>>}}}
<<option chkFramedLinksTag>> display inline frames for external links in tiddlers tagged with: <<option txtFramedLinksTag>>
{{{usage: <<option chkFramedLinksTag>> and <<option txtFramedLinksTag>>}}}
IFRAME size (CSS units: %, em, px, cm, in) - width: <<option txtFrameWidth>> height: <<option txtFrameHeight>>
{{{usage: <<option txtFrameWidth>> <<option txtFrameHeight>>}}}
<<<
!!!!!Examples
<<<
Try these links:
*http://www.TiddlyWiki.com
*http://www.TiddlyTools.com
*http://groups.google.com/group/TiddlyWiki/topics
<<<
!!!!!Revisions
<<<
2008.09.13 [1.1.0] added support to selectively enable embedded IFRAMEs if the containing tiddler is tagged with 'framedLinks'
2007.11.29 [1.0.5] added slider animation and improved CSS handling for IFRAME height/width to maximize display area
2007.11.29 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.FramedLinksPlugin= {major: 1, minor: 1, revision: 0, date: new Date(2008,9,13)};
var co=config.options; // abbreviation
if (co.chkFramedLinks==undefined) co.chkFramedLinks=false;
if (co.chkFramedLinksTag==undefined) co.chkFramedLinksTag=true;
if (co.txtFramedLinksTag==undefined) co.txtFramedLinksTag="framedLinks";
if (co.txtFrameWidth==undefined) co.txtFrameWidth="100%";
if (co.txtFrameHeight==undefined) co.txtFrameHeight="80%";
window.framedLinks_createExternalLink=createExternalLink;
window.createExternalLink=function(place,url)
{
var link=this.framedLinks_createExternalLink.apply(this,arguments);
link.onclick=function(ev) { var e=ev?ev:window.event;
var co=config.options; // abbreviation
var here=story.findContainingTiddler(this);
var enabled=co.chkFramedLinks || co.chkFramedLinksTag && here
&& store.getTiddler(here.getAttribute("tiddler")).isTagged(co.txtFramedLinksTag);
if (!enabled || e.ctrlKey || e.shiftKey || e.altKey) return; // BYPASS
var p=this.parentNode;
var f=this.nextSibling?this.nextSibling.firstChild:null; // get the IFRAME... maybe...
var w=co.txtFrameWidth; if (!w || !w.length) w="100%";
var h=co.txtFrameHeight; if (!h || !h.length) h="80%";
if (h.indexOf("%")) h=(findWindowHeight()*h.replace(/%/,"")/100)+"px"; // calc height as % of window
var showing=f && f.nodeName.toUpperCase()=="IFRAME"; // does IFRAME really exist?
var stretchCell=p.nodeName.toUpperCase()=="TD" && w.indexOf("%")!=-1 && w.replace(/%/,"")>=100;
if (!showing) { // create an iframe
link.style.display="block"; // force IFRAME onto line following link
if (stretchCell) { p.setAttribute("savedWidth",p.style.width); p.style.width="100%"; } // adjust TD so IFRAME stretches
var wrapper=createTiddlyElement(null,"span"); // wrapper for slider animation
wrapper.setAttribute("url",this.href); // for async loading of frame after animation completes
var f=createTiddlyElement(wrapper,"iframe"); // create IFRAME
f.style.backgroundColor="#fff"; f.style.width=w; f.style.height=h;
p.insertBefore(wrapper,this.nextSibling);
function loadURL(wrapper) { var f=wrapper.firstChild; var url=wrapper.getAttribute("url");
var d=f.contentDocument?f.contentDocument:(f.contentWindow?f.contentWindow.document:f.document);
d.open(); d.writeln("<html>connecting to "+url+"</html>"); d.close();
try { f.src=url; } // if the iframe can't handle the href
catch(e) { alert(e.description?e.description:e.toString()); } // ... then report the error
window.scrollTo(0,ensureVisible(wrapper));
}
if (!co.chkAnimate) loadURL(wrapper);
else {
var morph=new Slider(wrapper,true);
morph.callback=loadURL;
morph.properties.push({style: 'width', start: 0, end: 100, template: '%0%'});
anim.startAnimating(morph);
}
} else { // remove iframe
link.style.display="inline"; // restore link style
if (stretchCell) p.style.width=p.getAttribute("savedWidth"); // restore previous width of TD
if (!co.chkAnimate) p.removeChild(f.parentNode);
else {
var morph=new Slider(f.parentNode,false,false,"all");
morph.properties.push({style: 'width', start: 100, end: 0, template: '%0%'});
anim.startAnimating(morph);
}
}
e.cancelBubble=true; if (e.stopPropagation) e.stopPropagation(); return false;
}
return link;
}
//}}}
/***
|Name|FullScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FullScreenPlugin|
|Version|1.1|
|Requires|~TW2.x|
!Description:
Toggle between viewing tiddlers fullscreen and normally. Very handy for when you need more viewing space.
!Demo:
Click the ↕ button in the toolbar for this tiddler. Click it again to turn off fullscreen.
!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Edit the ViewTemplate to add the fullscreen command to the toolbar.
!History:
*25-07-06: ver 1.1
*20-07-06: ver 1.0
!Code
***/
//{{{
var lewcidFullScreen = false;
config.commands.fullscreen =
{
text:" ↕ ",
tooltip:"Fullscreen mode"
};
config.commands.fullscreen.handler = function (event,src,title)
{
if (lewcidFullScreen == false)
{
lewcidFullScreen = true;
setStylesheet('#sidebar, .header, #mainMenu{display:none;} #displayArea{margin:0em 0 0 0 !important;}',"lewcidFullScreenStyle");
}
else
{
lewcidFullScreen = false;
setStylesheet(' ',"lewcidFullScreenStyle");
}
}
config.macros.fullscreen={};
config.macros.fullscreen.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
var label = params[0]||" ↕ ";
var tooltip = params[1]||"Fullscreen mode";
createTiddlyButton(place,label,tooltip,config.commands.fullscreen.handler);
}
var lewcid_fullscreen_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler =function(title,animate,slowly)
{
lewcid_fullscreen_closeTiddler.apply(this,arguments);
if (story.isEmpty() && lewcidFullScreen == true)
config.commands.fullscreen.handler();
}
Slider.prototype.lewcidStop = Slider.prototype.stop;
Slider.prototype.stop = function()
{
this.lewcidStop();
if (story.isEmpty() && lewcidFullScreen == true)
config.commands.fullscreen.handler();
}
//}}}
<<tag Tiddlyspot>>
|<<option pasUploadPassword>>|
|<<upload http://edb.tiddlyspot.com/store.cgi index.html . . edb>>|
|[[Download|http://edb.tiddlyspot.com/download]]|
[[Gratis-Programmer.Dk - Alt gratis!|http://www.gratis-programmer.dk/]]
<<siteMap [[Gratisprogrammer]] . sliders>>
Du kan:
#Ændre titelen ved at klikke på [[SideTitel|SiteTitle]] og skriv en ny titel.
#Ændre eller fjerne undertitlen ved at klikke på [[UnderTitel|SiteSubtitle]] og gør hvad du vil med den.
#Bestemme hvad der viser sig når du åbner Simple Noter ved at åbne DefaultTiddlers og udskifte {{{[[Instruktioner]]}}} med en notetitel omkranset af dobblete firkantede paranteser.
#Når du er sikker på at du ikke længere har brug for dem, kan du slette [[Eksempel emne]], [[Eksempel underemne]] og [[Eksempel note]], [[Avanceret tilpasning]], og denne note, [[Grundlæggende tilpasning]].
/***
|Name|HTMLFormattingPlugin|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.3.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|'HTML' formatter|
|Description|embed wiki syntax formatting inside of HTML content|
The ~HTMLFormatting plugin allows you to ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Documentation
>see [[HTMLFormattingPluginInfo]]
!!!!!Revisions
<<<
2008.10.02 [2.3.0] added use of {{{<nowiki>}}} marker to bypass all wikification inside a specific HTML block
2008.09.19 [2.2.0] in wikifyTextNodes(), don't wikify the contents of STYLE nodes (thanks to MorrisGray for bug report)
| see [[HTMLFormattingPluginInfo]] for additional revision details |
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.HTMLFormattingPlugin= {major: 2, minor: 3, revision: 0, date: new Date(2008,10,2)};
// find the formatter for HTML and replace the handler
initHTMLFormatter();
function initHTMLFormatter()
{
for (var i=0; i<config.formatters.length && config.formatters[i].name!="html"; i++);
if (i<config.formatters.length) config.formatters[i].handler=function(w) {
if (!this.lookaheadRegExp) // fixup for TW2.0.x
this.lookaheadRegExp = new RegExp(this.lookahead,"mg");
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
var html=lookaheadMatch[1];
// if <nowiki> is present, just let browser handle it!
if (html.indexOf('<nowiki>')!=-1)
createTiddlyElement(w.output,"span").innerHTML=html;
else {
// if <hide linebreaks> is present, suppress wiki-style literal handling of newlines
if (html.indexOf('<hide linebreaks>')!=-1) html=html.replace(/\n/g,' ');
// remove all \r's added by IE textarea and mask newlines and macro brackets
html=html.replace(/\r/g,'').replace(/\n/g,'\\n').replace(/<</g,'%%(').replace(/>>/g,')%%');
// create span, let browser parse HTML
var e=createTiddlyElement(w.output,"span"); e.innerHTML=html;
// then re-render text nodes as wiki-formatted content
wikifyTextNodes(e);
}
w.nextMatch = this.lookaheadRegExp.lastIndex; // continue parsing
}
}
}
// wikify #text nodes that remain after HTML content is processed (pre-order recursion)
function wikifyTextNodes(theNode)
{
function unmask(s) { return s.replace(/\%%\(/g,'<<').replace(/\)\%%/g,'>>').replace(/\\n/g,'\n'); }
switch (theNode.nodeName.toLowerCase()) {
case 'style': case 'option': case 'select':
theNode.innerHTML=unmask(theNode.innerHTML);
break;
case 'textarea':
theNode.value=unmask(theNode.value);
break;
case '#text':
var txt=unmask(theNode.nodeValue);
var newNode=createTiddlyElement(null,"span");
theNode.parentNode.replaceChild(newNode,theNode);
wikify(txt,newNode);
break;
default:
for (var i=0;i<theNode.childNodes.length;i++)
wikifyTextNodes(theNode.childNodes.item(i)); // recursion
break;
}
}
//}}}
|Name|HTMLFormattingPluginInfo|
|Source|http://www.TiddlyTools.com/#HTMLFormattingPlugin|
|Documentation|http://www.TiddlyTools.com/#HTMLFormattingPluginInfo|
|Version|2.3.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for HTMLFormattingPlugin|
The ~HTMLFormatting plugin allows you to freely ''mix wiki-style formatting syntax within HTML formatted content'' by extending the action of the standard TiddlyWiki formatting handler.
!!!!!Usage
<<<
The shorthand Wiki-style formatting syntax of ~TiddlyWiki is very convenient and enables most content to be reasonably well presented. However, there are times when tried-and-true HTML formatting syntax allows more more precise control of the content display.
When a tiddler is about to be displayed, ~TiddlyWiki looks for tiddler content contained within {{{<html>}}} and {{{</html>}}} markers. When present, the TiddlyWiki core simply passes this content directly to the browser's internal "rendering engine" to process as ~HTML-formatted content. However, TiddlyWiki does not also process the HTML source content for any embedded wiki-formatting syntax it may contain. This means that while you can use HTML formatted content, you cannot mix wiki-formatted content within the HTML formatting.
This plugin extends the TiddlyWiki core processing so that, after the HTML formatting has been processed, all the pieces of text occuring within the HTML block are then processed one piece at a time, so that normal wiki-style formatting can be applied to the individual text pieces.
Note: To bypass this extended processing for a specific section of HTML content, embed ''{{{<nowiki>}}}'' //anywhere// inside the {{{<html>...</html>}}} delimiters, and wiki formatting will not be applied to that content.
<<<
!!!!!Line breaks
<<<
One major difference between Wiki formatting and HTML formatting is how "line breaks" are processed. Wiki formatting treats all line breaks as literal content to be displayed //as-is//. However, because HTML normally ignores line breaks and actually processes them as simple "word separators" instead, many people who write HTML include extra line breaks in their documents, just to make the "source code" easier to read.
Even though you can use HTML tags within your tiddler content, the default treatment for line breaks still follows the Wiki-style rule (i.e., all new lines are displayed as-is). When adding HTML content to a tiddler (especially if you cut-and-paste it from another web page), you should take care to avoid adding extra line breaks to the text.
If removing all the extra line breaks from your HTML content would be a big hassle, you can quickly //override the default Wiki-style line break rule// so that the line breaks use the standard HTML rules, by placing ''{{{<hide linebreaks>}}}'' //anywhere// within the HTML content. This automatically converts all line breaks to spaces before rendering the content, so that the literal line breaks will be processed as simple word-breaks instead.
Note: this does //not// alter the actual tiddler content that is stored in the document, just the manner in which it is displayed. Any line breaks contained in the tiddler will still be there when you edit its content. Also, to include a literal line break when the ''<{{{hide linebreaks}}}>'' tag is present, you will need to use a ''<{{{br}}}>'' or ''<{{{p}}}>'' HTML tag instead of simply typing a line break.
<<<
!!!!!How it works
<<<
The TW core support for HTML does not let you put ANY wiki-style syntax (including TW macros) *inside* the {{{<html>...</html>}}} block. Everything between {{{<html>}}} and {{{</html>}}} is handed to the browser for processing and that is it.
However, not all wiki syntax can be safely passed through the browser's parser. Specifically, any TW macros inside the HTML will get 'eaten' by the browser since the macro brackets, {{{<<...>>}}} use the "<" and ">" that normally delimit the HTML/XML syntax recognized by the browser's parser.
Similarly, you can't use InlineJavascript within the HTML because the {{{<script>...</script>}}} syntax will also be consumed by the browser and there will be nothing left to process afterward. Note: unfortunately, even though the browser removes the {{{<script>...</script>}}} sequence, it doesn't actually execute the embedded javascript code that it removes, so any scripts contained inside of <html> blocks in TW are currently being ignored. :-(
As a work-around to allow TW *macros* (but not inline scripts) to exist inside of <html> formatted blocks of content, the plugin first converts the {{{<<}}} and {{{>>}}} into "%%(" and ")%%", making them "indigestible" so they can pass unchanged through the belly of the beast (the browser's HTML parser).
After the browser has done its job, the wiki syntax sequences (including the "undigested" macros) are contained in #text nodes in the browser-generated DOM elements. The plugin then recursively locates and processes each #text node, converts the %%( and )%% back into {{{<<}}} and {{{>>}}}, passes the result to wikify() for further rendering of the wiki-formatted syntax into a containing SPAN that replaces the previous #text node. At the end of this process, none of the encoded %%( and )%% sequences remain in the rendered tiddler output.
<<<
!!!!!Revisions
<<<
2008.10.02 [2.3.0] added use of {{{<nowiki>}}} marker to bypass all wikification inside a specific HTML block
2008.09.19 [2.2.0] in wikifyTextNodes(), don't wikify the contents of STYLE nodes (thanks to MorrisGray for bug report)
2008.04.26 [*.*.*] plugin size reduction: more documentation moved to HTMLFormattingInfo
2008.01.08 [*.*.*] plugin size reduction: documentation moved to HTMLFormattingInfo
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.06.14 [2.1.5] in formatter, removed call to e.normalize(). Creates an INFINITE RECURSION error in Safari!!!!
2006.09.10 [2.1.4] update formatter for 2.1 compatibility (use this.lookaheadRegExp instead of temp variable)
2006.05.28 [2.1.3] in wikifyTextNodes(), decode the *value* of TEXTAREA nodes, but don't wikify() its children. (thanks to "ayj" for bug report)
2006.02.19 [2.1.2] in wikifyTextNodes(), put SPAN element into tiddler DOM (replacing text node), BEFORE wikifying the text content. This ensures that the 'place' passed to any macros is correctly defined when the macro is evaluated, so that calls to story.findContainingTiddler(place) will work as expected. (Thanks for bug report from GeoffSlocock)
2006.02.05 [2.1.1] wrapped wikifier hijack in init function to eliminate globals and avoid FireFox 1.5.0.1 crash bug when referencing globals
2005.12.01 [2.1.0] don't wikify #TEXT nodes inside SELECT and TEXTAREA elements
2005.11.06 [2.0.1] code cleanup
2005.10.31 [2.0.0] replaced hijack wikify() with hijack config.formatters["html"] and simplified recursive WikifyTextNodes() code
2005.10.09 [1.0.2] combined documentation and code into a single tiddler
2005.08.05 [1.0.1] moved HTML and CSS definitions into plugin code instead of using separate tiddlers
2005.07.26 [1.0.1] Re-released as a plugin. Added <{{{html}}}>...</{{{nohtml}}}> and <{{{hide newlines}}}> handling
2005.06.26 [1.0.0] Initial Release (as code adaptation - pre-dates TiddlyWiki plugin architecture!!)
<<<
/***
|Name|HaloscanMacro|
|Created by|JimSpeth|
|Location|http://end.com/~speth/HaloscanMacro.html|
|Version|1.1.0|
|Requires|~TW2.x|
!Description
Comment and trackback support for TiddlyWiki (via Haloscan).
!History
* 16-Feb-06, version 1.1.0, drastic changes, now uses settings from haloscan account config
* 31-Jan-06, version 1.0.1, fixed display of counts for default tiddlers
* 30-Jan-06, version 1.0, initial release
!Examples
|!Source|!Output|h
|{{{<<haloscan comments>>}}}|<<haloscan comments>>|
|{{{<<haloscan trackbacks>>}}}|<<haloscan trackbacks>>|
!Installation
Register for a [[Haloscan|http://www.haloscan.com]] account. It's free and painless.
Install the HaloscanMacro in a new tiddler with a tag of systemConfig (save and reload to activate).
In the macro configuration code (below), change //YourName// to your Haloscan account name.
Use the macro somewhere in a tiddler (see ViewTemplate for an example).
!Settings
You can adjust various options for your account in the member configuration area of Haloscan's web site. The macro will use these settings when formatting the links.
!Code
***/
//{{{
/* change "YourName" to your Haloscan account name */
config.macros.haloscan = {account: "maans66", baseURL: "http://www.haloscan.com/load/"};
var haloscanLoaded = 0;
config.macros.haloscan.load = function ()
{
if (haloscanLoaded == 1)
return;
account = config.macros.haloscan.account;
if (!account || (account == "Your Name"))
account = store.getTiddlerText("SiteTitle");
var el = document.createElement('script');
el.language = 'JavaScript';
el.type = 'text/javascript';
el.src = config.macros.haloscan.baseURL + account;
document.documentElement.childNodes[0].appendChild(el);
haloscanLoaded = 1;
}
config.macros.haloscan.load();
/* this totally clobbers document.write, i hope that's ok */
var safeWrite = function(s)
{
document.written = s;
return s;
};
document.write = safeWrite;
config.macros.haloscan.refreshDefaultTiddlers = function ()
{
var start = store.getTiddlerText("DefaultTiddlers");
if (start)
{
var titles = start.readBracketedList();
for (var t=titles.length-1; t>=0; t--)
story.refreshTiddler(titles[t], DEFAULT_VIEW_TEMPLATE, 1);
}
}
var haloscanRefreshed = 0;
config.macros.haloscan.handler = function (place, macroName, params, wikifier, paramString, tiddler)
{
if (typeof HaloScan == 'undefined')
{
if (haloscanRefreshed == 0)
{
setTimeout("config.macros.haloscan.refreshDefaultTiddlers()", 1);
haloscanRefreshed = 1;
}
return;
}
var id = story.findContainingTiddler(place).id.substr(7);
var hs_search = new RegExp('\\W','gi');
id = id.replace(hs_search,"_");
account = config.macros.haloscan.account;
if (!account || (account == "daveboyd"))
account = store.getTiddlerText("SiteTitle");
var haloscanError = function (msg)
{
createTiddlyError(place, config.messages.macroError.format(["HaloscanMacro"]), config.messages.macroErrorDetails.format(["HaloscanMacro", msg]));
}
if (params.length == 1)
{
if (params[0] == "comments")
{
postCount(id);
commentsLabel = document.written;
commentsPrompt = "Comments on this tiddler";
var commentsHandler = function(e) { HaloScan(id); return false; };
var commentsButton = createTiddlyButton(place, commentsLabel, commentsPrompt, commentsHandler);
}
else if (params[0] == "trackbacks")
{
postCountTB(id);
trackbacksLabel = document.written;
trackbacksPrompt = "Trackbacks for this tiddler";
var trackbacksHandler = function(e) { HaloScanTB(id); return false; };
var trackbackButton = createTiddlyButton(place, trackbacksLabel, trackbacksPrompt, trackbacksHandler);
}
else
haloscanError("unknown parameter: " + params[0]);
}
else if (params.length == 0)
haloscanError("missing parameter");
else
haloscanError("bad parameter count");
}
//}}}
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{
window.hideWhenLastTest = false;
window.removeElementWhen = function(test,place) {
window.hideWhenLastTest = test;
if (test) {
removeChildren(place);
place.parentNode.removeChild(place);
}
};
merge(config.macros,{
hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( eval(paramString), place);
}},
showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !eval(paramString), place);
}},
hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAny(params), place);
}},
showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAny(params), place);
}},
hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.tags.containsAll(params), place);
}},
showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !tiddler.tags.containsAll(params), place);
}},
hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
}},
showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
}},
hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title == params[0], place);
}},
showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( tiddler.title != params[0], place);
}},
'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
removeElementWhen( !window.hideWhenLastTest, place);
}}
});
//}}}
/***
|''Name:''|HistoryPlugin|
|''Description:''|Limits to only one tiddler open. Manages an history stack and provides macro to navigate in this history (<<history>><<back>><<forward>>).|
|''Version:''|1.0.0|
|''Date:''|2008-03-23|
|''Source:''|http://tiddlywiki.bidix.info/#HistoryPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.3.0|
***/
//{{{
Story.prototype.tiddlerHistory = [];
Story.prototype.historyCurrentPos = -1;
Story.prototype.currentTiddler = null;
Story.prototype.maxPos = 11;
Story.prototype.old_history_displayTiddler = Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
title = ((typeof title === "string") ? title : title.title);
//SinglePageMode
if (this.currentTiddler) this.closeTiddler(this.currentTiddler);
if (template == 2) {
//switch to Edit mode : don't manage
story.old_history_displayTiddler(null,title,template,animate,slowly);
return;
}
// if same tiddler no change
if (this.tiddlerHistory[this.historyCurrentPos] == title) {
this.currentTiddler = title;
story.old_history_displayTiddler(null,title,template,animate,slowly);
return;
}
if (this.historyCurrentPos == this.tiddlerHistory.length -1) {
// bottom of stack
this.tiddlerHistory.push(title);
if (this.tiddlerHistory.length > 11) {
this.tiddlerHistory.shift();
} else {
this.historyCurrentPos += 1;
}
} else {
// middle of stack
this.historyCurrentPos += 1;
if (this.tiddlerHistory[this.historyCurrentPos] != title) {
// path change => cut history
this.tiddlerHistory[this.historyCurrentPos] = title;
var a = [];
for(var i = 0; i <= this.historyCurrentPos;i++) {
a[i] = this.tiddlerHistory[i];
}
this.tiddlerHistory = a;
}
}
this.currentTiddler = title;
story.old_history_displayTiddler(null,title,template,animate,true);
scrollTo(0, 1);
}
Story.prototype.old_history_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,slowly)
{
this.currentTiddler = null;
story.old_history_closeTiddler.apply(this,arguments);
}
config.macros.history = {};
config.macros.history.action = function(event) {
var popup = Popup.create(this);
if(popup)
{
if (!story.tiddlerHistory.length)
createTiddlyText(popup,"No history");
else
{
var c = story.tiddlerHistory.length;
for (i=0; i<c;i++ )
{
var elmt = createTiddlyElement(popup,"li");
var btn = createTiddlyButton(elmt,story.tiddlerHistory[i],story.tiddlerHistory[i],config.macros.history.onClick);
btn.setAttribute("historyPos",i);
}
}
}
Popup.show(popup,false);
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return false;
}
config.macros.history.handler = function(place,macroName,params)
{
createTiddlyButton(place, 'historie', 'historie', config.macros.history.action);
}
config.macros.history.onClick = function(ev)
{
var e = ev ? ev : window.event;
var historyPos = this.getAttribute("historyPos");
story.historyCurrentPos = historyPos -1;
story.displayTiddler(null,story.tiddlerHistory[historyPos]);
return false;
};
config.macros.back = {};
config.macros.back.action = function() {
if (story.historyCurrentPos > 0) {
if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
story.historyCurrentPos = story.historyCurrentPos -2;
story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
} else {
//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
};
return false;
}
config.macros.back.handler = function(place,macroName,params)
{
createTiddlyButton(place, '◄', 'tilbage', config.macros.back.action,"backButton");
}
config.macros.forward = {};
config.macros.forward.action = function() {
if (story.historyCurrentPos < story.tiddlerHistory.length -1) {
if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
//story.historyCurrentPos = story.historyCurrentPos;
story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
} else {
//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
}
return false;
}
config.macros.forward.handler = function(place,macroName,params)
{
createTiddlyButton(place, '►', 'frem', config.macros.forward.action, "ibutton");
}
//}}}
<<siteMap [[Hjælp til selvhjælp]] . sliders>>
[evolved from the original [[blog post|http://jayfresh.wordpress.com/2007/09/24/tiddlychatter-decentralized-collaboration/]] on the subject]
Here’s an illustration of what ~TiddlyChatter is all about:
* Jon and his class have been set some tricky homework, so he creates a stub of what he’s working on and publishes it, mentioning to Liz, his classmate, that they ought to work on this together
* Liz subscribes to Jon’s feed and the stub turns up on Liz’s computer for her to see and/or comment on
* Liz adds a note about a useful resource
* Jon subscribes to Liz’s feed and her note turns up in place on Jon’s computer, which turns out to be very helpful…
This doesn’t sound so different from normal collaboration, but there are a couple of important differences:
* ''work offline:'' Jon’s little bit of work and Liz’s note on it appear on both computers separately, so they can both walk away with their ~TiddlyWikis and only sync-up when they get back online
* ''opt-in:'' If Jon decides Liz is no good as a partner, he can stop watching her feed and he never sees any of the notes Liz makes
** it is only when their teacher, Alice, eventually "opts-in" to Jon's feed (at his request... :() that she will see the result of the group’s work.
* ''decentralized:'' If Ben comes in and subscribes to Jon’s feed, he can make his own comments, and Jon will see them if he subscribes to Ben's feed, regardless of what servers or software Ben is using.
** Extending this slightly, Ben, Liz and Jon can all share and work on the information together; if someone else wants to join the group, it only takes one member to subscribe to the new person's feed for the new content to filter through to the rest of the group.
Password kræves<<getTiddlerPassword hu>><br>
+++[Dorthes vpn hjemmefra]
Jeg har talt med Allan om det (et par gange eller 3). Han kan ikke forstå at det ikke virker længere, eftersom vi har fået hans vpn til at virke.
Jeg aner at jeg kan blive nødt til at få den hjem og geninstallere vpnprogrammet + evt lave en ny vpnlicens til Dorthe.
For at kunne teste det skal jeg desuden have adgang til eksternt internet.
Dorthe må aflevere sin jobbærbare til mig og ikke forvente at få den tilbage før efter en dags tid. Jeg ved ikke om det er ligetil - eftersom det er første gang jeg gør det på denne måde - alt fra 1 - 6 timer?! (i streg..)
Alternativet er at Allan får den med hjem - (han kan måske få det til at virke hurtigere, fordi han lige har fået sit eget til at virke?!) men så er der nok ikke tale om "kun" en dags tid (eller lærertimer for den sags skyld)- desværre.===<br>
+++[Dorthes pc]
Installation af nødvendige drivere til alt hardware, labelprinter, scanner etc etc + Adobe Acrobat - anslået timeforbrug: Fra 2 til 6 timer p.g.a. sandsynligvis problematisk scannerinstallation via netværk - og fordi jeg kan huske Mads havde problemer med både den og labelprinter....===<br>
+++[Microsoft Office 2007]
Hvis vi vil undgå flere problemer med Microsoft Office 2007 - bør vi installere det på alle Stavns pc'er. (Jeg hader at Microsoft vinder kampen - men lukkede formater vinder - igen.... :-(
Vi har brug for Microsoft office 2007 til samtlige medarbejderpc'er for at undgå mere vrøvl (stationære i første omgang)
dvs: Vi flytter de tre elevpc'er fra lokale 13 til Stavn, indlægger et lærerpcimage og installerer Microsoft Office 2007 på dem + de 4 andre:
Lones bærbare, den ekstra på Dorthes kontor, den der er tilbage ovenpå og den bærbare til referater (Skolevejledernes bærbare er jeg lidt i tvivl om har brug for det?).
Det giver en ekstra som evt. kan blive pc'en på viceforstanderkontoret.
I alt: 7 Microsoft Office licenser pris?? (Det kan Allan svare på! - Jeg ved der er under 7000,- og vi må selv installere det)
Anslået timeforbrug = imageindlæsning ca 2 timer pr pc, forskellige hardwareinstallationer - ca ½ t pr pc, OfficePakken (forudsat det er en Fredslund installationscd med den korrekte pakke) ca ½ time pr pc
ialt: 7 * 2½= ca 15 timer (Hvis det er helt problemfrit - og det er det faktisk ''aldrig!!''
Ps: Hov - jeg glemte lærerværelsespc'en - Den skal vel også have Office 2007? - Dvs evt. 8xlicenser og installation...
)===<br>
+++[Timer der er brug for]
Med Dorthes pc og vpn på den bærbare = ca 27 timer
Så har jeg set bort fra sandsynlige ekstra tiltag såsom anskaffelse og reparation af elevpc'er, (jeg ved på forhånd at der er nogle problemer med en af elevpc'erne fra lok. nr 13) der skal overgå til at være lærerpc'er - nye mus, tastaturer - hvad ved jeg - ...===<br>
+++[Forslag0:] Ovenstående - alle Office installationer + Dorthes vpn + Dorthes hardware-drivere og programmer ca 27 timer - Men hvem gør hvad og ikke mindst hvornår?? Hvis det er mig alene - skal jeg bruge en uge på skolen kun på det - og ikke andet (27 timer på denne måde kan IKKE gøres i streg)!!===<br>
+++[Forslag1:] Jeg får Fredslunds installationscd. Han sørger for at vi får de nødvendige licenser. Jeg skal først installere images på de tre elevpcer (2 t x 3 pc'er= 6 t). Derefter kan Peter og Jakob evt. dele installationen af officepakken på alle involverede pc'er mellem sig (½ t pr pc 7x½= 3½ / 2 = 1,75 t pr mand) forbrug i alt= 9½ time... Så er der DKs pc og vpn...
(Dorthes installationer er ikke regnet med her - der er allerede installeret Office 2007)===<br>
+++[Forslag2:] Jeg får Fredslunds installationscd. Han sørger for at vi får de nødvendige licenser. Jeg forbereder en enkelt lærerpc med installation af Office 2007 og laver et image som skal gemmes til serveren. mindst 2½ time - derefter indlæser jeg det nye image (også backup) på alle 6 pcer (-Lones, der er en bærbar og kun skal have Office 2007 installeret) - dvs 6 x 2t= 12 + ½ (LBs) + forberedelse af imaget= 15 timer ialt.(Kun mig - med mindre nogen har lyst til at lære at installere images med Acronis??) ... Så er der DKs pc og vpn..===<br>
+++[Forslag3:] Vi beder Allan gøre det hele - på sin måde (Jeg tvivler på at han hverken har tid eller lyst til den slags - med hans konsulent- og øvrige virksomhed)- til en pris jeg ikke tør regne på og et tidsrum jeg ikke kan drømme om...===<br>
+++[Idas indlogning til BrevPortalen]
Mail d. 11/6 og d. 17/6 + kopi i hånden til Allan://Himmerlands Ungdomsskole (Skolekode 861300) kan ikke logge på
Indberetnings- og brevportalen. Dette har været et problem for skolen sidenportalen blev overflyttet til IBM, skolens IT-mand kan ikke finde nogen
fejl på skolens computerer og mener derfor, at der måske kan være en fejl opsætningsmæssigt på skolen fra ministeriet." Jeg går ud fra, at den fejler mod port 7777.En løsning er, at skolen åbner for tcp port 7777 mod undervisningsministeriets server i firewallen. Ip-adresse er: 92.60.145.80//
Allan har lovet at gøre noget ved det - jeg ved dog ikke endnu hvornår - eller om han har prøvet - Jeg gentager: Han har lovet at gøre noget ved det ..
Ida har iøvrigt muligheden for at gøre det hun skal hjemmefra (hendes eget internet) - og har sagt at det gør hun så...
===<br>
+++[Ullas netforbindelse]
Jeg har talt med Allan om at der er vigtigt at Ullas netforbindelse er med i elektrikertilbuddet. evt. seperat fordi hun SKAL have kablet netforbindelse inden vi starter efter sommerferien. Han siger at det er en rigtig dårlig ide at lave en løsning hvor hun får en internetforbindelse udenom netværket. Jeg går ud fra at Allan har fat i den ende nu...
===<br>
+++[SkolePlan]
Jeg har mailkorresponderet med Torben Bjerg
Han siger at vi kan installere SP på liges så mange pc'er vi har lyst til - men at det kun er en bruger ad gangen som har ,ulighed for at rette og ændre i data. Det vil ændre sig når SkolePlan går over til Sql (og lidt senere MySql- dss EdbBrugsen bruger)
Torben bekræftede alle de planer Allan har fortalt om:
+++[Svar fra Torben Bjerg]
Hej Måns!
Det er korrekt, at SkolePlan efter sommerferien kommer i ny version, hvor
databasen overgår til en SQL database. Det er dog i første omgang ikke
MySql, men Microsoft Sql (den gratis express version).
Det er ligeledes korrekt, at der er indledt et samarbejde med EDB Brugsen,
som ifølge hensigtserklæring skal munde ud i datamæssig integration mellem
de to systemer inden årsskiftet, således at data indtastet i det ene system
umiddelbart kan genbruges i det andet system uden yderligere indtastning for
brugernes vedkommende. Da EDB Brugsen har valgt MySql, er det også på
projektet at benytte denne database til SkolePlan. Integrationen til EDB
Brugsen samt udvikling af diverse webmoduler står dog forrest på
prioritetslisten.
Den nuværende version af SkolePlan må installeres på et vilkårligt antal af
skolens pc'er, og det samme gælder naturligvis også den næste version.
Den nuværende version er ikke en flerbrugerversion, men den kan dog anvendes
på flere pc'er samtidigt - blot er det kun muligt at redigere på én maskine
adgangen. Et vilkårligt antal pc'er kan således fint læse i SkolePlans data
samtidigt.
Når SkolePlan anvendes på en pc, skal den pågældende windowsbrugerkonto have
fuld redigeringsret til den mappe, hvor SkolePlan er installeret, samt til
brugerens egen "document and settings" mappe. Udover dette er der ikke
særlige krav for anvendelse af SkolePlan.
Jeg takker også for de tilsendte inspirationer, som ser meget spændende ud,
og som også læner sig fint op af de ideer, som er på tegnebrættet. Som
udgangspunkt vil udviklingen dog ske i velkendte værktøjer, hvor der er fuld
kontrol over alle dele af løsningerne, og hvor der vil være ægte
flerbrugermulighed.
med venlig hilsen
Torben Bjerg
DataGiraffen
mail: mail@datagiraffen.dk
web: skoleplan.dk.
===
Jeg synes vi skal købe SkolePlan med det samme... - så Dan kan komme i gang med det på skolen...
===<br>
+++[Licenser & Mads]
Vi har alle købte "Licenskort" til Office 2007 - i huset (Jeg skulle lige finde dem).
Kaspersky Licensen har vi på serveren i form af en faktura, to keys og (vistnok)tre forskellige installationspakker. Alt ligger på FILSRV under Install-drevet i mappen Kaspersky. - Her har vi ikke noget "ude at hænge med Mads"===<br>
+++[Ang NT's "mandagspc"]
Det er principielt forkert at Mads ikke returnerer den til os - på den anden side har han selv haft så mange udgifter forbundet med den - at jeg ville lade den gå - hvis jeg skulle bestemme.
Den har personligt kostet ham et nyt bundkort + harddisk (stort set hele pc'ens værdi)- mod at jeg installerede det. Det kom desværre aldrig til at virke... - og tilfældighedernes spil gør at den står hos ham og ikke hos os. Mads har alt i alt (når vi ser fremad på de priser som venter os)- sparet skolen for at skulle tage DYRE beslutninger de seneste fire fem år - Lad principperne gælde hvor det er realistisk at vinde noget . - Det er det ikke her - efter min mening===<br>
Mvh Måns
Kan du li' ''~No-Brainer Notes''? Hvis du kan, kan du hjælpe os på denne måde:
* [[Besøg vores hjemmeside|http://www.giffmex.org]]
* [[Læs om den missions agency vi tilhører, CRWM|http://www.crcna.org/pages/crwm.cfm]]
* [[Donér til CRWM|http://www.crcna.org/pages/crwm_donate_online.cfm]]
* [[Vores Amazon ønskeliste|https://www.amazon.com/gp/registry/wishlist/1OTJM9IE7SPVS/ref=wl_web/]]
* PayPal til vores hjemmeside:<html><form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input name="cmd" type="hidden" value="_s-xclick" /> <input alt="PayPal - The safer, easier way to pay online!" name="submit" src="https://www.paypal.com/en_US/i/btn/btn_donate_LG.gif" type="image" /><img src="https://www.paypal.com/en_US/i/scr/pixel.gif" border="0" alt="" width="1" height="1" />
<input name="encrypted" type="hidden" value="-----BEGIN PKCS7-----MIIHRwYJKoZIhvcNAQcEoIIHODCCBzQCAQExggEwMIIBLAIBADCBlDCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb20CAQAwDQYJKoZIhvcNAQEBBQAEgYCDOphPrfxixGLSFLAVYRgOAIIMNkhG/fVpBpfPkFZ+/otUKEu2UHrY0szrTCsf73EmPs1hEqXAevosf4f3wmMQGaQ/+dxpooMXJJjv4Y2b74SuehERvjBeBrIOJ6eVVJyTRqTYVACX48cdtp9K8u/qFPEf389dSFw79O0qSSw2YDELMAkGBSsOAwIaBQAwgcQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIvazyO9DMtDGAgaCV7RZqlbC45beBnYKwrZ/t12EFK0DQViCLvSD1OMX0VNiCuXK2lxtlpTzi0ZujHXrRjPZg6zZc5dMsL//Ervy+zUBl6jpsQg5UxqponKYcNnWXjErastgJdYP3Yy5l95L1MwsHnxzhvANg3cIuYhVOsvDNxc933cEdwMSBKI2Q9Kg6oixC49A6FTYW/Xgp2xfdINr7ema6Vgk9V3pge1xjoIIDhzCCA4MwggLsoAMCAQICAQAwDQYJKoZIhvcNAQEFBQAwgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMB4XDTA0MDIxMzEwMTMxNVoXDTM1MDIxMzEwMTMxNVowgY4xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLUGF5UGFsIEluYy4xEzARBgNVBAsUCmxpdmVfY2VydHMxETAPBgNVBAMUCGxpdmVfYXBpMRwwGgYJKoZIhvcNAQkBFg1yZUBwYXlwYWwuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBR07d/ETMS1ycjtkpkvjXZe9k+6CieLuLsPumsJ7QC1odNz3sJiCbs2wC0nLE0uLGaEtXynIgRqIddYCHx88pb5HTXv4SZeuv0Rqq4+axW9PLAAATU8w04qqjaSXgbGLP3NmohqM6bV9kZZwZLR/klDaQGo1u9uDb9lr4Yn+rBQIDAQABo4HuMIHrMB0GA1UdDgQWBBSWn3y7xm8XvVk/UtcKG+wQ1mSUazCBuwYDVR0jBIGzMIGwgBSWn3y7xm8XvVk/UtcKG+wQ1mSUa6GBlKSBkTCBjjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAkNBMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtQYXlQYWwgSW5jLjETMBEGA1UECxQKbGl2ZV9jZXJ0czERMA8GA1UEAxQIbGl2ZV9hcGkxHDAaBgkqhkiG9w0BCQEWDXJlQHBheXBhbC5jb22CAQAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCBXzpWmoBa5e9fo6ujionW1hUhPkOBakTr3YCDjbYfvJEiv/2P+IobhOGJr85+XHhN0v4gUkEDI8r2/rNk1m0GA8HKddvTjyGw/XqXa+LSTlDYkqI8OwR8GEYj4efEtcRpRYBxV8KxAW93YDWzFGvruKnnLbDAF6VR5w/cCMn5hzGCAZowggGWAgEBMIGUMIGOMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxFDASBgNVBAoTC1BheVBhbCBJbmMuMRMwEQYDVQQLFApsaXZlX2NlcnRzMREwDwYDVQQDFAhsaXZlX2FwaTEcMBoGCSqGSIb3DQEJARYNcmVAcGF5cGFsLmNvbQIBADAJBgUrDgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMDgwMzIzMTU0MDU4WjAjBgkqhkiG9w0BCQQxFgQUN7zDTYDrAL6cj3fOJ2lKbzKgmcIwDQYJKoZIhvcNAQEBBQAEgYAsUnYV6vvQecisJkhmmfNmG2xemtFm7FfXCJZe+5sNDBiIgy/By44dLPor/j3KAmFsH27u4ORRVGgaYkG0/0Ga7ch1AZaMNCnrXQ8Yw6//ltBN+DPl7RWQ3hbgcPwbVarqkNM67LQ/Scfb22CKMAnKt4vjIeaWAnPySHVsYcqcpg==-----END PKCS7-----" /></form></html>
<<siteMap [[IT]] . sliders>>
[[Edb Noter]]
!!Opfølgning til sidste lærermøde(d.19/3-09):
*''Binni påpegede at man kunne undersøge muligheden for at elever kan få deres egen internetforbindelse via et mobilt usb-modem - og tale med TDC om at levere en stor antenne/god forbindelse og "dongles" til alle elever. På denne måde vil skolen ikke skulle udvide - men vil kunne forlange/forvente at kommende elever selv har internettet med på skolen.''
**Binni fortalte også at der er blevet mere almindeligt at lave bærbare computere uden egen harddisk - men med nødvendig netværks/internetopkobling for at kunne køre programmer. Disse computere er bl.a. strømbesparende...
***Binni har også et forslag om at lave et seperat internetnetværk til det trådløse baseret på en evt. ny microsoft 2003 server med ISA, der kan administrere og logge alle brugere. Det er et avanceret firewallsystem, hvor man gradvist åbner for porte og ingen kan få adgang til internettet uden behørigt logon.
***Binni foreslår også at vi bruger "repeatere" til hurtigt at kunne udvide det trådløses rækkevidde - uden at være afhængig af evt. kabeltrækning til elevgange etc.
*''Elev Jeppe Albrechtsen har udarbejdet et forslag til hvordan man dækker skolens behov for trådløst internet og hans forslag indholder en lignenede løsning dog baseret på en ny firewallløsning (ny pc), der er lavet af samme firma som har leveret vores nuværende routere (Zyxel).''
*''Konsulent Tommy Gregersen har påpeget at vores nuværende trådløse dækning i klassefløjen slet ikke kan levere nok internet til alle vore elever.''
**Han foreslår at vi udvider med et accesspoint pr. klasseværelse.
***Hvis vi vil have trådløst ud på elevgangene skal vi påregne et accesspoint pr etage pr. gang - og ikke kun et pr. 2 gange (som jeg har foreslået ved en tidligere lejlighed).
*''Skolens uploadhastighed er for lille - og det er nødvendigt at tage kontakt til TDC for at få at vide om vi kan få mere (uden nødvendigvis at opgradere til fiber..) - ''
**Jeg fik at vide for ca 1 år siden at vi havde den kraftigste forbindelse vi kunne få - på ledningsnettet - så måske er en konvertering til fiber - nødvendig!!
***Fuldstændig konvertering til fiber implicerer såkaldte konverteringsbokse - og evt. udskiftning af hele telefonsystemet - fra analog til IP..
*''Jeg har bedt Tommy Gregersen undersøge mulighederne for at oprette et selvstændigt (logget) trådløst net, baseret på fiber - således at vi beholder det nuværende netværk til kontor/administration og lærere.''
****Et problem i at have et seperat net til trådløst og internet - er manglende forbindelse til lokale printere.
*****Binni foreslår at vi evt. køber printere med usbstik - så elever kan gå til en printer med deres usb og printe ud når de er på skolen.
*****Jeg forestiller mig at man evt. kan koble vores nuværende netværksprintere til et evt. nyt netværk og lade en evt. ny server tage sig af distributionen.<br>//Dog vil det nok betyde at disse printere kun kan benyttes når man er på det trådløse...//
Mvh MM
Use ~TiddlyWiki built-in importer (below) or, <<importTiddlers link 'Use ImportTiddlersPlugin control panel...'>>
<<importTiddlers core>>
/***
|Name|ImportTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.3.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|config.macros.importTiddlers.handler|
|Description|interactive controls for import/export with filtering.|
This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents. An interactive control panel lets you pick a document to import from, and then select which tiddlers to import, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles. Automatically add tags to imported tiddlers so they are easy to find later on. Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Documentation
<<<
see [[ImportTiddlersPluginInfo]] for details
<<<
!!!!!interactive control panel:
<<<
<<importTiddlers inline>>
{{clear{
^^(see also: [[ImportTiddlers]] shadow tiddler)^^}}}
<<<
!!!!!Installation Notes
<<<
* As of 6/27/2007, "patch" functions that provide backward-compatibility with TW2.1.x and earlier have been split into a separate [[ImportTiddlersPluginPatch]] tiddler to reduce installation overhead for //this// plugin. You only need to install the additional plugin tiddler when using ImportTiddlersPlugin in documents using TW2.1.x or earlier.
* As of 3/21/2007, the interactive {{{<<importTiddlers>>}}} and non-interactive {{{<<loadTiddlers>>}}} macro definitions and related code have been split into separate [[ImportTiddlersPlugin]] and [[LoadTiddlersPlugin]] to permit selective installation of either the interactive and/or non-interactive macro functions.
* Quick Installation Tip: If you are using an unmodified version of TiddlyWiki (core release version <<version>>), you can get a new, empty TiddlyWiki with the Import Tiddlers plugin pre-installed (''[[download from here|TW+ImportExport.html]]''), and then simply import all your content from your old document into this new, empty document.
<<<
!!!!!Revisions
<<<
2008.08.12 [4.3.3] rewrite backstage and shadow tiddler definitions for easier customization
|please see [[ImportTiddlersPluginInfo]] for additional revision details|
2005.07.20 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.ImportTiddlersPlugin= {major: 4, minor: 3, revision: 3, date: new Date(2008,8,12)};
//}}}
//{{{
// IE needs explicit global scoping for functions/vars called from browser events
window.onClickImportButton=onClickImportButton;
window.refreshImportList=refreshImportList;
// default cookie/option values
if (!config.options.chkImportReport) config.options.chkImportReport=true;
// default shadow definition
config.shadowTiddlers.ImportTiddlers="Use ~TiddlyWiki built-in importer (below) or, ";
config.shadowTiddlers.ImportTiddlers+="<<importTiddlers link 'Use ImportTiddlersPlugin control panel...'>>\n";
config.shadowTiddlers.ImportTiddlers+="<<importTiddlers core>>";
// use shadow tiddler content in backstage panel
if (config.tasks) config.tasks.importTask.content="<<tiddler ImportTiddlers>>" // TW2.2 or above
// $(...) function: 'shorthand' convenience syntax for document.getElementById()
if (typeof($)=="undefined") { // avoid redefinition
function $() {
var elements=new Array();
for (var i=0; i<arguments.length; i++) {
var element=arguments[i];
if (typeof element=='string') element=document.getElementById(element);
if (arguments.length==1) return element;
elements.push(element);
}
return elements;
}
}
//}}}
//{{{
merge(config.macros.importTiddlers,{
label: "import tiddlers",
prompt: "Copy tiddlers from another document",
openMsg: "Opening %0",
openErrMsg: "Could not open %0 - error=%1",
readMsg: "Read %0 bytes from %1",
foundMsg: "Found %0 tiddlers in %1",
filterMsg: "Filtered %0 tiddlers matching '%1'",
summaryMsg: "%0 tiddler%1 in the list",
summaryFilteredMsg: "%0 of %1 tiddler%2 in the list",
plural: "s are",
single: " is",
countMsg: "%0 tiddlers selected for import",
processedMsg: "Processed %0 tiddlers",
importedMsg: "Imported %0 of %1 tiddlers from %2",
loadText: "please load a document...",
closeText: "close", // text for close button when file is loaded
doneText: "done", // text for close button when file is not loaded
startText: "import", // text for import button
stopText: "stop", // text for import button while importing
local: true, // default to import from local file
src: "", // path/filename or URL of document to import (retrieved from SiteUrl tiddler)
proxy: "", // URL for remote proxy script (retrieved from SiteProxy tiddler)
useProxy: false, // use specific proxy script in front of remote URL
inbound: null, // hash-indexed array of tiddlers from other document
newTags: "", // text of tags added to imported tiddlers
addTags: true, // add new tags to imported tiddlers
listsize: 10, // # of lines to show in imported tiddler list
importTags: true, // include tags from remote source document when importing a tiddler
keepTags: true, // retain existing tags when replacing a tiddler
sync: false, // add 'server' fields to imported tiddlers (for sync function)
lastFilter: "", // most recent filter (URL hash) applied
lastAction: null, // most recent collision button performed
index: 0, // current processing index in import list
sort: "" // sort order for imported tiddler listbox
});
//}}}
//{{{
// replace core macro handler
if (config.macros.importTiddlers.coreHandler==undefined)
config.macros.importTiddlers.coreHandler=config.macros.importTiddlers.handler; // save built-in handler
config.macros.importTiddlers.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
if (!params[0] || params[0].toLowerCase()=='core') { // default to built in
if (config.macros.importTiddlers.coreHandler)
config.macros.importTiddlers.coreHandler.apply(this,arguments);
else
createTiddlyButton(place,this.label,this.prompt,onClickImportMenu);
} else if (params[0]=='link') { // show link to floating panel
createTiddlyButton(place,params[1]||this.label,params[2]||this.prompt,onClickImportMenu);
} else if (params[0]=='inline') {// show panel as INLINE tiddler content
createImportPanel(place);
$("importPanel").style.position="static";
$("importPanel").style.display="block";
} else if (config.macros.loadTiddlers)
config.macros.loadTiddlers.handler(place,macroName,params); // any other params: loadtiddlers
}
//}}}
//{{{
// Handle link click to create/show/hide control panel
function onClickImportMenu(e)
{
if (!e) var e = window.event;
var parent=resolveTarget(e).parentNode;
var panel = $("importPanel");
if (panel==undefined || panel.parentNode!=parent)
panel=createImportPanel(parent);
var isOpen = panel.style.display=="block";
if(config.options.chkAnimate)
anim.startAnimating(new Slider(panel,!isOpen,e.shiftKey || e.altKey,"none"));
else
panel.style.display = isOpen ? "none" : "block" ;
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return(false);
}
//}}}
//{{{
// Create control panel: HTML, CSS
function createImportPanel(place) {
var cmi=config.macros.importTiddlers; // abbreviation
var panel=$("importPanel");
if (panel) { panel.parentNode.removeChild(panel); }
setStylesheet(cmi.css,"importTiddlers");
panel=createTiddlyElement(place,"span","importPanel",null,null)
panel.innerHTML=cmi.html;
refreshImportList();
var siteURL=store.getTiddlerText("SiteUrl"); if (!siteURL) siteURL="";
$("importSourceURL").value=siteURL;
cmi.src=siteURL;
var siteProxy=store.getTiddlerText("SiteProxy"); if (!siteProxy) siteProxy="SiteProxy";
$("importSiteProxy").value=siteProxy;
cmi.proxy=siteProxy;
if (config.browser.isGecko) { // FF3 FIXUP
$("fileImportSource").style.display="none";
$("importLocalPanelFix").style.display="block";
}
return panel;
}
//}}}
//{{{
config.macros.importTiddlers.css = '\
#importPanel {\
display: none; position:absolute; z-index:11; width:35em; right:105%; top:3em;\
background-color: #eee; color:#000; font-size: 8pt; line-height:110%;\
border:1px solid black; border-bottom-width: 3px; border-right-width: 3px;\
padding: 0.5em; margin:0em; -moz-border-radius:1em;\
}\
#importPanel a, #importPanel td a { color:#009; display:inline; margin:0px; padding:1px; }\
#importPanel table { width:100%; border:0px; padding:0px; margin:0px; font-size:8pt; line-height:110%; background:transparent; }\
#importPanel tr { border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel td { color:#000; border:0px;padding:0px;margin:0px; background:transparent; }\
#importPanel select { width:100%;margin:0px;font-size:8pt;line-height:110%;}\
#importPanel input { width:98%;padding:0px;margin:0px;font-size:8pt;line-height:110%}\
#importPanel .box { border:1px solid #000; background-color:#eee; padding:3px 5px; margin-bottom:5px; -moz-border-radius:5px;}\
#importPanel .topline { border-top:1px solid #999; padding-top:2px; margin-top:2px; }\
#importPanel .rad { width:auto; }\
#importPanel .chk { width:auto; margin:1px;border:0; }\
#importPanel .btn { width:auto; }\
#importPanel .btn1 { width:98%; }\
#importPanel .btn2 { width:48%; }\
#importPanel .btn3 { width:32%; }\
#importPanel .btn4 { width:23%; }\
#importPanel .btn5 { width:19%; }\
#importPanel .importButton { padding: 0em; margin: 0px; font-size:8pt; }\
#importPanel .importListButton { padding:0em 0.25em 0em 0.25em; color: #000000; display:inline }\
#backstagePanel #importPanel { left:10%; right:auto; }\
';
//}}}
//{{{
config.macros.importTiddlers.html = '\
<!-- source and report -->\
<table><tr><td align=left>\
import from\
<input type="radio" class="rad" name="importFrom" id="importFromFile" value="file" CHECKED\
onclick="onClickImportButton(this,event)" title="show file controls"> local file\
<input type="radio" class="rad" name="importFrom" id="importFromWeb" value="http"\
onclick="onClickImportButton(this,event)" title="show web controls"> web server\
</td><td align=right>\
<input type=checkbox class="chk" id="chkImportReport" checked\
onClick="config.options[\'chkImportReport\']=this.checked;"> create report\
</td></tr></table>\
\
<div class="box" id="importSourcePanel" style="margin:.5em">\
<div id="importLocalPanel" style="display:block;margin-bottom:2px;"><!-- import from local file -->\
enter or browse for source path/filename<br>\
<input type="file" id="fileImportSource" size=57 style="width:100%"\
onKeyUp="config.macros.importTiddlers.src=this.value"\
onChange="config.macros.importTiddlers.src=this.value;$(\'importLoad\').onclick()">\
<div id="importLocalPanelFix" style="display:none"><!-- FF3 FIXUP -->\
<input type="text" id="fileImportSourceFix" style="width:90%"\
title="Enter a path/file to import"\
onKeyUp="config.macros.importTiddlers.src=this.value"\
onChange="config.macros.importTiddlers.src=this.value; $(\'importLoad\').onclick()">\
<input type="button" id="fileImportSourceFixButton" style="width:7%" value="..."\
title="Select a path/file to import"\
onClick="var r=config.macros.importTiddlers.askForFilename(this); if (!r||!r.length) return;\
$(\'fileImportSourceFix\').value=r;\
config.macros.importTiddlers.src=r;\
$(\'importLoad\').onclick()">\
</div><!--end FF3 FIXUP-->\
</div><!--end local-->\
<div id="importHTTPPanel" style="display:none;margin-bottom:2px;"><!-- import from http server -->\
<table><tr><td align=left>\
enter a URL or <a href="javascript:;" id="importSelectFeed"\
onclick="onClickImportButton(this,event)" title="select a pre-defined \'systemServer\' URL">\
select a server</a><br>\
</td><td align=right>\
<input type="checkbox" class="chk" id="importUsePassword"\
onClick="config.macros.importTiddlers.usePassword=this.checked;\
config.macros.importTiddlers.showPanel(\'importIDPWPanel\',this.checked,true);">password\
<input type="checkbox" class="chk" id="importUseProxy"\
onClick="config.macros.importTiddlers.useProxy=this.checked;\
config.macros.importTiddlers.showPanel(\'importSiteProxy\',this.checked,true);">proxy\
</td></tr></table>\
<input type="text" id="importSiteProxy" style="display:none;margin-bottom:1px" onfocus="this.select()" value="SiteProxy"\
onKeyUp="config.macros.importTiddlers.proxy=this.value"\
onChange="config.macros.importTiddlers.proxy=this.value;">\
<input type="text" id="importSourceURL" onfocus="this.select()" value="SiteUrl"\
onKeyUp="config.macros.importTiddlers.src=this.value"\
onChange="config.macros.importTiddlers.src=this.value;">\
<div id="importIDPWPanel" style="text-align:center;margin-top:2px;display:none";>\
username: <input type=text id="txtImportID" style="width:25%" \
onChange="config.options.txtRemoteUsername=this.value;">\
password: <input type=password id="txtImportPW" style="width:25%" \
onChange="config.options.txtRemotePassword=this.value;">\
</div><!--end idpw-->\
</div><!--end http-->\
</div><!--end source-->\
\
<div class="box" id="importSelectPanel" style="display:none;margin:.5em;">\
<table><tr><td align=left>\
select:\
<a href="javascript:;" id="importSelectAll"\
onclick="onClickImportButton(this);return false;" title="SELECT all tiddlers">\
all</a>\
<a href="javascript:;" id="importSelectNew"\
onclick="onClickImportButton(this);return false;" title="SELECT tiddlers not already in destination document">\
added</a>\
<a href="javascript:;" id="importSelectChanges"\
onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been updated in source document">\
changes</a>\
<a href="javascript:;" id="importSelectDifferences"\
onclick="onClickImportButton(this);return false;" title="SELECT tiddlers that have been added or are different from existing tiddlers">\
differences</a>\
</td><td align=right>\
<a href="javascript:;" id="importListSmaller"\
onclick="onClickImportButton(this);return false;" title="SHRINK list size">\
– </a>\
<a href="javascript:;" id="importListLarger"\
onclick="onClickImportButton(this);return false;" title="GROW list size">\
+ </a>\
<a href="javascript:;" id="importListMaximize"\
onclick="onClickImportButton(this);return false;" title="MAXIMIZE/RESTORE list size">\
= </a>\
</td></tr></table>\
<select id="importList" size=8 multiple\
onchange="setTimeout(\'refreshImportList(\'+this.selectedIndex+\')\',1)">\
<!-- NOTE: delay refresh so list is updated AFTER onchange event is handled -->\
</select>\
<div style="text-align:center">\
<a href="javascript:;"\
title="click for help using filters..."\
onclick="alert(\'A filter consists of one or more space-separated combinations of:\\n\\ntiddler titles\\ntag:[[tagvalue]]\\ntag:[[tag expression]] (requires MatchTagsPlugin)\\nstory:[[TiddlerName]]\\nsearch:[[searchtext]]\\n\\nUse a blank filter for all tiddlers.\')"\
>filter</a>\
<input type="text" id="importLastFilter" style="margin-bottom:1px; width:65%"\
title="Enter a combination of one or more filters. Use a blank filter for all tiddlers."\
onfocus="this.select()" value=""\
onKeyUp="config.macros.importTiddlers.lastFilter=this.value"\
onChange="config.macros.importTiddlers.lastFilter=this.value;">\
<input type="button" id="importApplyFilter" style="width:20%" value="apply"\
title="filter list of tiddlers to include only those that match certain criteria"\
onclick="onClickImportButton(this)">\
</div>\
</div><!--end select-->\
\
<div class="box" id="importOptionsPanel" style="text-align:center;margin:.5em;display:none;">\
apply tags: <input type=checkbox class="chk" id="chkImportTags" checked\
onClick="config.macros.importTiddlers.importTags=this.checked;">from source \
<input type=checkbox class="chk" id="chkKeepTags" checked\
onClick="config.macros.importTiddlers.keepTags=this.checked;">keep existing \
<input type=checkbox class="chk" id="chkAddTags" \
onClick="config.macros.importTiddlers.addTags=this.checked;\
config.macros.importTiddlers.showPanel(\'txtNewTags\',this.checked,true);\
if (this.checked) $(\'txtNewTags\').focus();">add tags<br>\
<input type=text id="txtNewTags" style="margin-top:4px;display:none;" size=15\ onfocus="this.select()" \
title="enter tags to be added to imported tiddlers" \
onKeyUp="config.macros.importTiddlers.newTags=this.value;\
$(\'chkAddTags\').checked=this.value.length>0;" autocomplete=off>\
<nobr><input type=checkbox class="chk" id="chkSync" \
onClick="config.macros.importTiddlers.sync=this.checked;">\
link imported tiddlers to source document (for sync later)</nobr>\
</div><!--end options-->\
\
<div id="importButtonPanel" style="text-align:center">\
<input type=button id="importLoad" class="importButton btn3" value="open"\
title="load listbox with tiddlers from source document"\
onclick="onClickImportButton(this)">\
<input type=button id="importOptions" class="importButton btn3" value="options..."\
title="set options for tags, sync, etc."\
onclick="onClickImportButton(this)">\
<input type=button id="importStart" class="importButton btn3" value="import"\
title="start/stop import of selected source tiddlers into current document"\
onclick="onClickImportButton(this)">\
<input type=button id="importClose" class="importButton btn3" value="done"\
title="clear listbox or hide control panel"\
onclick="onClickImportButton(this)">\
</div>\
\
<div class="none" id="importCollisionPanel" style="display:none;margin:.5em 0 .5em .5em;">\
<table><tr><td style="width:65%" align="left">\
<table><tr><td align=left>\
tiddler already exists:\
</td><td align=right>\
<input type=checkbox class="chk" id="importApplyToAll" \
onclick="$(\'importRename\').disabled=this.checked;"\
checked>apply to all\
</td></tr></table>\
<input type=text id="importNewTitle" size=15 autocomplete=off">\
</td><td style="width:34%" align="center">\
<input type=button id="importMerge"\
class="importButton" style="width:47%" value="merge"\
title="append the incoming tiddler to the existing tiddler"\
onclick="onClickImportButton(this)"><!--\
--><input type=button id="importSkip"\
class="importButton" style="width:47%" value="skip"\
title="do not import this tiddler"\
onclick="onClickImportButton(this)"><!--\
--><br><input type=button id="importRename"\
class="importButton" style="width:47%" value="rename"\
title="rename the incoming tiddler"\
onclick="onClickImportButton(this)"><!--\
--><input type=button id="importReplace"\
class="importButton" style="width:47%" value="replace"\
title="discard the existing tiddler"\
onclick="onClickImportButton(this)">\
</td></tr></table>\
</div><!--end collision-->\
';
//}}}
//{{{
// process control interactions
function onClickImportButton(which,event)
{
var cmi=config.macros.importTiddlers; // abbreviation
var list = $('importList');
if (!list) return;
var thePanel = $('importPanel');
var theCollisionPanel = $('importCollisionPanel');
var theNewTitle = $('importNewTitle');
var count=0;
switch (which.id)
{
case 'importFromFile': // show local panel
case 'importFromWeb': // show HTTP panel
cmi.local=(which.id=='importFromFile');
cmi.showPanel('importLocalPanel',cmi.local);
cmi.showPanel('importHTTPPanel',!cmi.local);
break;
case 'importOptions': // show/hide options panel
cmi.showPanel('importOptionsPanel',$('importOptionsPanel').style.display=='none');
break;
case 'fileImportSource':
case 'importLoad': // load import source into hidden frame
importReport(); // if an import was in progress, generate a report
cmi.inbound=null; // clear the imported tiddler buffer
refreshImportList(); // reset/resize the listbox
if (cmi.src=="") break;
// Load document, read it's DOM and fill the list
cmi.loadRemoteFile(cmi.src,cmi.filterTiddlerList);
break;
case 'importSelectFeed': // select a pre-defined systemServer feed URL
var p=Popup.create(which); if (!p) return;
var tids=store.getTaggedTiddlers('systemServer');
if (!tids.length)
createTiddlyText(createTiddlyElement(p,'li'),'no pre-defined server feeds');
for (var t=0; t<tids.length; t++) {
var u=store.getTiddlerSlice(tids[t].title,"URL");
var d=store.getTiddlerSlice(tids[t].title,"Description");
if (!d||!d.length) d=store.getTiddlerSlice(tids[t].title,"description");
if (!d||!d.length) d=u;
createTiddlyButton(createTiddlyElement(p,'li'),tids[t].title,d,
function(){
var u=this.getAttribute('url');
$('importSourceURL').value=u;
config.macros.importTiddlers.src=u;
$('importLoad').onclick();
},
null,null,null,{url:u});
}
Popup.show(p,false);
event.cancelBubble = true;
if (event.stopPropagation) event.stopPropagation();
return(false);
// create popup with feed list
// onselect, insert feed URL into input field.
break;
case 'importSelectAll': // select all tiddler list items (i.e., not headings)
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
if (list.options[t].value=="") continue;
list.options[t].selected=true;
count++;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
$('importStart').disabled=!count;
break;
case 'importSelectNew': // select tiddlers not in current document
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value=="") continue;
list.options[t].selected=!store.tiddlerExists(list.options[t].value);
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
$('importStart').disabled=!count;
break;
case 'importSelectChanges': // select tiddlers that are updated from existing tiddlers
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value==""||!store.tiddlerExists(list.options[t].value)) continue;
for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified>0); // updated tiddler
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
$('importStart').disabled=!count;
break;
case 'importSelectDifferences': // select tiddlers that are new or different from existing tiddlers
importReport(); // if an import was in progress, generate a report
for (var t=0,count=0; t < list.options.length; t++) {
list.options[t].selected=false;
if (list.options[t].value=="") continue;
if (!store.tiddlerExists(list.options[t].value)) { list.options[t].selected=true; count++; continue; }
for (var i=0; i<cmi.inbound.length; i++) // find matching inbound tiddler
{ var inbound=cmi.inbound[i]; if (inbound.title==list.options[t].value) break; }
list.options[t].selected=(inbound.modified-store.getTiddler(list.options[t].value).modified!=0); // changed tiddler
count+=list.options[t].selected?1:0;
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
$('importStart').disabled=!count;
break;
case 'importApplyFilter': // filter list to include only matching tiddlers
importReport(); // if an import was in progress, generate a report
clearMessage();
if (!cmi.all) // no tiddlers loaded = "0 selected"
{ displayMessage(cmi.countMsg.format([0])); return false; }
var hash=$('importLastFilter').value;
cmi.inbound=cmi.filterByHash("#"+hash,cmi.all);
refreshImportList(); // reset/resize the listbox
break;
case 'importStart': // initiate the import processing
importReport(); // if an import was in progress, generate a report
$('importApplyToAll').checked=false;
$('importStart').value=cmi.stopText;
if (cmi.index>0) cmi.index=-1; // stop processing
else cmi.index=importTiddlers(0); // or begin processing
importStopped();
break;
case 'importClose': // unload imported tiddlers or hide the import control panel
// if imported tiddlers not loaded, close the import control panel
if (!cmi.inbound) { thePanel.style.display='none'; break; }
importReport(); // if an import was in progress, generate a report
cmi.inbound=null; // clear the imported tiddler buffer
refreshImportList(); // reset/resize the listbox
break;
case 'importSkip': // don't import the tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
theImported.status='skipped after asking'; // mark item as skipped
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index+1); // resume with NEXT item
importStopped();
break;
case 'importRename': // change name of imported tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
theImported.status = 'renamed from '+theImported.title; // mark item as renamed
theImported.set(theNewTitle.value,null,null,null,null); // change the tiddler title
theItem.value = theNewTitle.value; // change the listbox item text
theItem.text = theNewTitle.value; // change the listbox item text
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with THIS item
importStopped();
break;
case 'importMerge': // join existing and imported tiddler content
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
var theExisting = store.getTiddler(theItem.value);
var theText = theExisting.text+'\n----\n^^merged from: ';
theText +='[['+cmi.src+'#'+theItem.value+'|'+cmi.src+'#'+theItem.value+']]^^\n';
theText +='^^'+theImported.modified.toLocaleString()+' by '+theImported.modifier+'^^\n'+theImported.text;
var theDate = new Date();
var theTags = theExisting.getTags()+' '+theImported.getTags();
theImported.set(null,theText,null,theDate,theTags);
theImported.status = 'merged with '+theExisting.title; // mark item as merged
theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
theImported.status += ' by '+theExisting.modifier;
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with this item
importStopped();
break;
case 'importReplace': // substitute imported tiddler for existing tiddler
cmi.lastAction=which;
var theItem = list.options[cmi.index];
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==theItem.value) break;
var theImported = cmi.inbound[j];
var theExisting = store.getTiddler(theItem.value);
theImported.status = 'replaces '+theExisting.title; // mark item for replace
theImported.status += ' - '+theExisting.modified.formatString("MM/DD/YYYY 0hh:0mm:0ss");
theImported.status += ' by '+theExisting.modifier;
theCollisionPanel.style.display='none';
cmi.index=importTiddlers(cmi.index); // resume with THIS item
importStopped();
break;
case 'importListSmaller': // decrease current listbox size, minimum=5
if (list.options.length==1) break;
list.size-=(list.size>5)?1:0;
cmi.listsize=list.size;
break;
case 'importListLarger': // increase current listbox size, maximum=number of items in list
if (list.options.length==1) break;
list.size+=(list.size<list.options.length)?1:0;
cmi.listsize=list.size;
break;
case 'importListMaximize': // toggle listbox size between current and maximum
if (list.options.length==1) break;
list.size=(list.size==list.options.length)?cmi.listsize:list.options.length;
break;
}
}
//}}}
//{{{
config.macros.importTiddlers.showPanel=function(place,show,skipAnim) {
if (typeof place == "string") var place=$(place);
if (!place||!place.style) return;
if(!skipAnim && anim && config.options.chkAnimate) anim.startAnimating(new Slider(place,show,false,"none"));
else place.style.display=show?"block":"none";
}
//}}}
//{{{
function refreshImportList(selectedIndex)
{
var cmi=config.macros.importTiddlers; // abbreviation
var list = $("importList");
if (!list) return;
// if nothing to show, reset list content and size
if (!cmi.inbound)
{
while (list.length > 0) { list.options[0] = null; }
list.options[0]=new Option(cmi.loadText,"",false,false);
list.size=cmi.listsize;
// toggle buttons and panels
$('importLoad').disabled=false;
$('importLoad').style.display='inline';
$('importStart').disabled=true;
$('importOptions').disabled=true;
$('importOptions').style.display='none';
$('fileImportSource').disabled=false;
$('importFromFile').disabled=false;
$('importFromWeb').disabled=false;
$('importStart').value=cmi.startText;
$('importClose').value=cmi.doneText;
$('importSelectPanel').style.display='none';
$('importOptionsPanel').style.display='none';
return;
}
// there are inbound tiddlers loaded...
// toggle buttons and panels
$('importLoad').disabled=true;
$('importLoad').style.display='none';
$('importOptions').style.display='inline';
$('importOptions').disabled=false;
$('fileImportSource').disabled=true;
$('importFromFile').disabled=true;
$('importFromWeb').disabled=true;
$('importClose').value=cmi.closeText;
if ($('importSelectPanel').style.display=='none')
cmi.showPanel('importSelectPanel',true);
// get the sort order
if (!selectedIndex) selectedIndex=0;
if (selectedIndex==0) cmi.sort='title'; // heading
if (selectedIndex==1) cmi.sort='title';
if (selectedIndex==2) cmi.sort='modified';
if (selectedIndex==3) cmi.sort='tags';
if (selectedIndex>3) {
// display selected tiddler count
for (var t=0,count=0; t < list.options.length; t++) {
if (!list.options[t].selected) continue;
if (list.options[t].value!="")
count+=1;
else { // if heading is selected, deselect it, and then select and count all in section
list.options[t].selected=false;
for ( t++; t<list.options.length && list.options[t].value!=""; t++) {
list.options[t].selected=true;
count++;
}
}
}
clearMessage(); displayMessage(cmi.countMsg.format([count]));
}
$('importStart').disabled=!count;
if (selectedIndex>3) return; // no refresh needed
// get the alphasorted list of tiddlers
var tiddlers=cmi.inbound;
tiddlers.sort(function (a,b) {if(a['title'] == b['title']) return(0); else return (a['title'] < b['title']) ? -1 : +1; });
// clear current list contents
while (list.length > 0) { list.options[0] = null; }
// add heading and control items to list
var i=0;
var indent=String.fromCharCode(160)+String.fromCharCode(160);
if (cmi.all.length==tiddlers.length)
var summary=cmi.summaryMsg.format([tiddlers.length,(tiddlers.length!=1)?cmi.plural:cmi.single]);
else
var summary=cmi.summaryFilteredMsg.format([tiddlers.length,cmi.all.length,(cmi.all.length!=1)?cmi.plural:cmi.single]);
list.options[i++]=new Option(summary,"",false,false);
list.options[i++]=new Option(((cmi.sort=="title" )?">":indent)+' [by title]',"",false,false);
list.options[i++]=new Option(((cmi.sort=="modified")?">":indent)+' [by date]',"",false,false);
list.options[i++]=new Option(((cmi.sort=="tags")?">":indent)+' [by tags]',"",false,false);
// output the tiddler list
switch(cmi.sort) {
case "title":
for(var t = 0; t < tiddlers.length; t++)
list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title,false,false);
break;
case "modified":
// sort descending for newest date first
tiddlers.sort(function (a,b) {if(a['modified'] == b['modified']) return(0); else return (a['modified'] > b['modified']) ? -1 : +1; });
var lastSection = "";
for(var t = 0; t < tiddlers.length; t++) {
var tiddler = tiddlers[t];
var theSection = tiddler.modified.toLocaleDateString();
if (theSection != lastSection) {
list.options[i++] = new Option(theSection,"",false,false);
lastSection = theSection;
}
list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title,false,false);
}
break;
case "tags":
var theTitles = {}; // all tiddler titles, hash indexed by tag value
var theTags = new Array();
for(var t=0; t<tiddlers.length; t++) {
var title=tiddlers[t].title;
var tags=tiddlers[t].tags;
if (!tags || !tags.length) {
if (theTitles["untagged"]==undefined) { theTags.push("untagged"); theTitles["untagged"]=new Array(); }
theTitles["untagged"].push(title);
}
else for(var s=0; s<tags.length; s++) {
if (theTitles[tags[s]]==undefined) { theTags.push(tags[s]); theTitles[tags[s]]=new Array(); }
theTitles[tags[s]].push(title);
}
}
theTags.sort();
for(var tagindex=0; tagindex<theTags.length; tagindex++) {
var theTag=theTags[tagindex];
list.options[i++]=new Option(theTag,"",false,false);
for(var t=0; t<theTitles[theTag].length; t++)
list.options[i++]=new Option(indent+indent+theTitles[theTag][t],theTitles[theTag][t],false,false);
}
break;
}
list.selectedIndex=selectedIndex; // select current control item
if (list.size<cmi.listsize) list.size=cmi.listsize;
if (list.size>list.options.length) list.size=list.options.length;
}
//}}}
//{{{
// re-entrant processing for handling import with interactive collision prompting
function importTiddlers(startIndex)
{
var cmi=config.macros.importTiddlers; // abbreviation
if (!cmi.inbound) return -1;
var list = $('importList');
if (!list) return;
var t;
// if starting new import, reset import status flags
if (startIndex==0)
for (var t=0;t<cmi.inbound.length;t++)
cmi.inbound[t].status="";
for (var i=startIndex; i<list.options.length; i++)
{
// if list item is not selected or is a heading (i.e., has no value), skip it
if ((!list.options[i].selected) || ((t=list.options[i].value)==""))
continue;
for (var j=0;j<cmi.inbound.length;j++)
if (cmi.inbound[j].title==t) break;
var inbound = cmi.inbound[j];
var theExisting = store.getTiddler(inbound.title);
// avoid redundant import for tiddlers that are listed multiple times (when 'by tags')
if (inbound.status=="added")
continue;
// don't import the "ImportedTiddlers" history from the other document...
if (inbound.title=='ImportedTiddlers')
continue;
// if tiddler exists and import not marked for replace or merge, stop importing
if (theExisting && (inbound.status.substr(0,7)!="replace") && (inbound.status.substr(0,5)!="merge"))
return i;
// assemble tags (remote + existing + added)
var newTags = "";
if (cmi.importTags)
newTags+=inbound.getTags() // import remote tags
if (cmi.keepTags && theExisting)
newTags+=" "+theExisting.getTags(); // keep existing tags
if (cmi.addTags && cmi.newTags.trim().length)
newTags+=" "+cmi.newTags; // add new tags
inbound.set(null,null,null,null,newTags.trim());
// set the status to 'added' (if not already set by the 'ask the user' UI)
inbound.status=(inbound.status=="")?'added':inbound.status;
// set sync fields
if (cmi.sync) {
if (!inbound.fields) inbound.fields={}; // for TW2.1.x backward-compatibility
inbound.fields["server.page.revision"]=inbound.modified.convertToYYYYMMDDHHMM();
inbound.fields["server.type"]="file";
inbound.fields["server.host"]=(cmi.local?"file://":"")+cmi.src;
}
// do the import!
store.suspendNotifications();
store.saveTiddler(inbound.title, inbound.title, inbound.text, inbound.modifier, inbound.modified, inbound.tags, inbound.fields, true, inbound.created);
store.fetchTiddler(inbound.title).created = inbound.created; // force creation date to imported value (needed for TW2.1.x and earlier)
store.resumeNotifications();
}
return(-1); // signals that we really finished the entire list
}
function importStopped()
{
var cmi=config.macros.importTiddlers; // abbreviation
var list = $('importList');
var theNewTitle = $('importNewTitle');
if (!list) return;
if (cmi.index==-1){
$('importStart').value=cmi.startText;
importReport(); // import finished... generate the report
} else {
// import collision...
// show the collision panel and set the title edit field
$('importStart').value=cmi.stopText;
cmi.showPanel('importCollisionPanel',true);
theNewTitle.value=list.options[cmi.index].value;
if ($('importApplyToAll').checked
&& cmi.lastAction
&& cmi.lastAction.id!="importRename") {
onClickImportButton(cmi.lastAction);
}
}
}
//}}}
//{{{
function importReport()
{
var cmi=config.macros.importTiddlers; // abbreviation
if (!cmi.inbound) return;
// if import was not completed, the collision panel will still be open... close it now.
var panel=$('importCollisionPanel'); if (panel) panel.style.display='none';
// get the alphasorted list of tiddlers
var tiddlers = cmi.inbound;
// gather the statistics
var count=0; var total=0;
for (var t=0; t<tiddlers.length; t++) {
if (!tiddlers[t].status || !tiddlers[t].status.trim().length) continue;
if (tiddlers[t].status.substr(0,7)!="skipped") count++;
total++;
}
// generate a report
if (total) displayMessage(cmi.processedMsg.format([total]));
if (count && config.options.chkImportReport) {
// get/create the report tiddler
var theReport = store.getTiddler('ImportedTiddlers');
if (!theReport) { theReport= new Tiddler(); theReport.title = 'ImportedTiddlers'; theReport.text = ""; }
// format the report content
var now = new Date();
var newText = "On "+now.toLocaleString()+", "+config.options.txtUserName
newText +=" imported "+count+" tiddler"+(count==1?"":"s")+" from\n[["+cmi.src+"|"+cmi.src+"]]:\n";
if (cmi.addTags && cmi.newTags.trim().length)
newText += "imported tiddlers were tagged with: \""+cmi.newTags+"\"\n";
newText += "<<<\n";
for (var t=0; t<tiddlers.length; t++) if (tiddlers[t].status) newText += "#[["+tiddlers[t].title+"]] - "+tiddlers[t].status+"\n";
newText += "<<<\n";
// update the ImportedTiddlers content and show the tiddler
theReport.text = newText+((theReport.text!="")?'\n----\n':"")+theReport.text;
theReport.modifier = config.options.txtUserName;
theReport.modified = new Date();
store.saveTiddler(theReport.title, theReport.title, theReport.text, theReport.modifier, theReport.modified, theReport.tags, theReport.fields);
story.displayTiddler(null,theReport.title,1,null,null,false);
story.refreshTiddler(theReport.title,1,true);
}
// reset status flags
for (var t=0; t<cmi.inbound.length; t++) cmi.inbound[t].status="";
// mark document as dirty and let display update as needed
if (count) { store.setDirty(true); store.notifyAll(); }
// always show final message when tiddlers were actually loaded
if (count) displayMessage(cmi.importedMsg.format([count,tiddlers.length,cmi.src.replace(/%20/g," ")]));
}
//}}}
//{{{
// // File and XMLHttpRequest I/O
config.macros.importTiddlers.askForFilename=function(here) {
var msg=here.title; // use tooltip as dialog box message
var path=getLocalPath(document.location.href);
var slashpos=path.lastIndexOf("/"); if (slashpos==-1) slashpos=path.lastIndexOf("\\");
if (slashpos!=-1) path = path.substr(0,slashpos+1); // remove filename from path, leave the trailing slash
var file="";
var result="";
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeOpen);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XPSP2 IE only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { // fallback
var result=prompt(msg,path+file);
}
}
return result;
}
config.macros.importTiddlers.loadRemoteFile = function(src,callback) {
if (src==undefined || !src.length) return null; // filename is required
var original=src; // URL as specified
var hashpos=src.indexOf("#"); if (hashpos!=-1) src=src.substr(0,hashpos); // URL with #... suffix removed (needed for IE)
clearMessage();
displayMessage(this.openMsg.format([src.replace(/%20/g," ")]));
if (src.substr(0,5)!="http:" && src.substr(0,5)!="file:") { // if not a URL, read from local filesystem
var txt=loadFile(src);
if (!txt) { // file didn't load, might be relative path.. try fixup
var pathPrefix=document.location.href; // get current document path and trim off filename
var slashpos=pathPrefix.lastIndexOf("/"); if (slashpos==-1) slashpos=pathPrefix.lastIndexOf("\\");
if (slashpos!=-1 && slashpos!=pathPrefix.length-1) pathPrefix=pathPrefix.substr(0,slashpos+1);
src=pathPrefix+src;
if (pathPrefix.substr(0,5)!="http:") src=getLocalPath(src);
var txt=loadFile(src);
}
if (!txt) { // file still didn't load, report error
displayMessage(config.macros.importTiddlers.openErrMsg.format([src.replace(/%20/g," "),"(filesystem error)"]));
} else {
displayMessage(config.macros.importTiddlers.readMsg.format([txt.length,src.replace(/%20/g," ")]));
if (callback) callback(true,original,convertUTF8ToUnicode(txt),src,null);
}
} else {
var name=config.options.txtRemoteUsername; var pass=config.options.txtRemotePassword;
var xhr=doHttp("GET",src,null,null,name,pass,callback,original,null)
if (!xhr) displayMessage(config.macros.importTiddlers.openErrMsg.format([src,"(XMLHTTPRequest error)"]));
}
}
config.macros.importTiddlers.readTiddlersFromHTML=function(html)
{
var remoteStore=new TiddlyWiki();
remoteStore.importTiddlyWiki(html);
return remoteStore.getTiddlers("title");
}
config.macros.importTiddlers.filterTiddlerList=function(success,params,txt,src,xhr) {
var cmi=config.macros.importTiddlers; // abbreviation
var src=src.replace(/%20/g," ");
if (!success) { displayMessage(cmi.openErrMsg.format([src,xhr.status])); return; }
cmi.all = cmi.readTiddlersFromHTML(txt);
var count=cmi.all?cmi.all.length:0;
var querypos=src.lastIndexOf("?"); if (querypos!=-1) src=src.substr(0,querypos);
displayMessage(cmi.foundMsg.format([count,src]));
cmi.inbound=cmi.filterByHash(params,cmi.all); // use full URL including hash (if any)
$("importLastFilter").value=cmi.lastFilter;
window.refreshImportList(0);
}
config.macros.importTiddlers.filterByHash=function(src,tiddlers)
{
var hashpos=src.lastIndexOf("#"); if (hashpos==-1) return tiddlers;
var hash=src.substr(hashpos+1); if (!hash.length) return tiddlers;
var tids=[];
var params=hash.parseParams("anon",null,true,false,false);
for (var p=1; p<params.length; p++) {
switch (params[p].name) {
case "anon":
case "open":
tids.pushUnique(params[p].value);
break;
case "tag":
if (store.getMatchingTiddlers) { // for boolean expressions - see MatchTagsPlugin
var r=store.getMatchingTiddlers(params[p].value,null,tiddlers);
for (var t=0; t<r.length; t++) tids.pushUnique(r[t].title);
} else for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].isTagged(params[p].value))
tids.pushUnique(tiddlers[t].title);
break;
case "story":
for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].title==params[p].value) {
tiddlers[t].changed();
for (var s=0; s<tiddlers[t].links.length; s++)
tids.pushUnique(tiddlers[t].links[s]);
break;
}
break;
case "search":
for (var t=0; t<tiddlers.length; t++)
if (tiddlers[t].text.indexOf(params[p].value)!=-1)
tids.pushUnique(tiddlers[t].title);
break;
}
}
var matches=[];
for (var t=0; t<tiddlers.length; t++)
if (tids.contains(tiddlers[t].title))
matches.push(tiddlers[t]);
displayMessage(config.macros.importTiddlers.filterMsg.format([matches.length,hash]));
config.macros.importTiddlers.lastFilter=hash;
return matches;
}
//}}}
/***
|Name|ImportTiddlersPluginInfo|
|Source|http://www.TiddlyTools.com/#ImportTiddlersPlugin|
|Documentation|http://www.TiddlyTools.com/#ImportTiddlersPluginInfo|
|Version|4.3.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|documentation for ImportTiddlersPlugin|
This plugin lets you selectively combine tiddlers from any two TiddlyWiki documents. An interactive control panel lets you pick a document to import from, and then select which tiddlers to import, with prompting for skip, rename, merge or replace actions when importing tiddlers that match existing titles. Automatically add tags to imported tiddlers so they are easy to find later on. Generates a detailed report of import 'history' in ImportedTiddlers.
!!!!!Usage
<<<
{{{<<importTiddlers>>}}} or {{{<<importTiddlers core>>}}}
invokes the built-in importTiddlers macro (TW2.1.x+). If installed in documents using TW2.0.x or earlier, fallback is to use 'link' display (see below)
{{{<<importTiddlers link label tooltip>>}}}
The ''link'' keyword creates an "import tiddlers" link that when clicked to show/hide import control panel. ''label'' and ''tooltip'' are optional text parameters (enclosed in quotes or {{{[[...]]}}}, and allow you to override the default display text for the link and the mouseover help text, respectively.
{{{<<importTiddlers inline>>}}}
creates import control panel directly in tiddler content
<<importTiddlers inline>>
Press ''[browse]'' to select a TiddlyWiki document file to import, and then press ''[open]''. Alternatively, you can type in the path/filename or a remote document URL (starting with http://). When you have entered the desired source location, press ''[load]'' to retrieve the tiddlers from the remote source. //Note: There may be some delay to permit the browser time to access and load the document before updating the listbox with the titles of all tiddlers that are available to be imported.//
Select one or more titles from the listbox (hold CTRL or SHIFT while clicking to add/remove the highlight from individual list items). You can press ''[select all]'' to quickly highlight all tiddler titles in the list. Use the ''[-]'', ''[+]'', or ''[=]'' links to adjust the listbox size so you can view more (or less) tiddler titles at one time. When you have chosen the tiddlers you want to import and entered any extra tags, press ''[import]'' to begin copying them to the current TiddlyWiki document.
''select: all, new, changes, or differences''
You can click on ''all'', ''new'', ''changes'', or ''differences'' to automatically select a subset of tiddlers from the list. This makes it very quick and easy to find and import just the updated tiddlers you are interested in:
>''"all"'' selects ALL tiddlers from the import source document, even if they have not been changed.
>''"new"'' selects only tiddlers that are found in the import source document, but do not yet exist in the destination document
>''"changes"'' selects only tiddlers that exist in both documents but that are newer in the source document
>''"differences"'' selects all new and existing tiddlers that are different from the destination document (even if destination tiddler is newer)
''Import Tagging:''
Tiddlers that have been imported can be automatically tagged, so they will be easier to find later on, after they have been added to your document. New tags are entered into the "add tags" input field, and then //added// to the existing tags for each tiddler as it is imported.
''Skip, Rename, Merge, or Replace:''
When importing a tiddler whose title is identical to one that already exists, the import process pauses and the tiddler title is displayed in an input field, along with four push buttons: ''[skip]'', ''[rename]'', ''[merge]'' and ''[replace]''.
To bypass importing this tiddler, press ''[skip]''. To import the tiddler with a different name (so that both the tiddlers will exist when the import is done), enter a new title in the input field and then press ''[rename]''. Press ''[merge]'' to combine the content from both tiddlers into a single tiddler. Press ''[replace]'' to overwrite the existing tiddler with the imported one, discarding the previous tiddler content.
//Note: if both the title ''and'' modification date/////time match, the imported tiddler is assumed to be identical to the existing one, and will be automatically skipped (i.e., not imported) without asking.//
''Import Report History''
When tiddlers are imported, a report is generated into ImportedTiddlers, indicating when the latest import was performed, the number of tiddlers successfully imported, from what location, and by whom. It also includes a list with the title, date and author of each tiddler that was imported.
When the import process is completed, the ImportedTiddlers report is automatically displayed for your review. If more tiddlers are subsequently imported, a new report is //added// to ImportedTiddlers, above the previous report (i.e., at the top of the tiddler), so that a reverse-chronological history of imports is maintained.
If a cumulative record is not desired, the ImportedTiddlers report may be deleted at any time. A new ImportedTiddlers report will be created the next time tiddlers are imported.
Note: You can prevent the ImportedTiddlers report from being generated for any given import activity by clearing the "create a report" checkbox before beginning the import processing.
<<<
!!!!!Revisions
<<<
2008.08.12 [4.3.3] rewrite backstage and shadow tiddler definitions for easier customization
2008.08.05 [4.3.2] rewrote loadRemoteFile() to eliminate use of platform-specific fileExists() function
2008.06.29 [4.3.1] More layout/animation work for simpler sequential interaction. Code reduction/cleanup
2008.06.28 [4.3.0] HTML and CSS cleanup and tweaks to layout. Added animation to panels
2008.06.22 [4.2.0] For FireFox, use HTML with separate text+button control instead of type='file' control
2008.06.05 [4.1.0] in filterByHash(), added support for boolean tag expressions using getMatchingTiddlers() (defined by MatchTagsPlugin)
2008.05.12 [4.0.2] automatically tweak the backstage "import" task to add the ImportTiddlers control panel as an optional alternative to the standard import wizard. (Moved from BackstageTweaks).
2008.04.30 [4.0.1] trim #... suffix for loading files/URLs in IE
2008.04.30 [4.0.0] added source filtering (using URL paramifiers). Also, abbreviations for code-size reduction.
2008.04.13 [3.9.0] added 'apply to all' checkbox for collision processing
2008.03.26 [3.8.0] added support for selecting pre-defined systemServer URLs
2008.03.25 [3.7.0] added support for setting 'server' fields on imported tiddlers (for later synchronizing of changes)
2008.01.03 [3.6.0] in loadRemoteFile(), use lower-level doHttp() instead of loadRemoteFile() in order to support username/password access to remote server
2007.10.30 [3.5.6] update [[ImportTiddlers]] shadow tiddler definition to include "inline" link, so the plugin control panel is displayed instead of the standard core interface.
2007.06.27 [3.5.5] added missing 'fields' params to saveTiddler() calls. Fixes problem where importing tiddlers would lose the custom fields. Also, moved functions for backward-compatibility with TW2.1.x to separate [[ImportTiddlersPluginPatch2.1.x]] tiddler, reducing the size of //this// plugin tiddler by a significant amount.
2007.06.25 [3.5.4] added calls to store.suspendNotifications() and store.resumeNotifications(). Eliminates redisplay processing overhead DURING import activities
2007.04.29 [3.5.3] if refreshImportList() when inbound tiddlers are loaded, change "close" button to "done", and disable certain controls to creates a modal condition, so that actions that reload tiddlers cannot be performed unless "done" is first pressed to end the mode..
2007.04.28 [3.5.2] in handler(), added param support for custom link label/prompt
2007.04.19 [3.5.1] in readTiddlersFromHTML(), for TW2.2 and above, use importTiddlyWiki() (new core functionality) to get tiddlers from remote file content. Also, copied updated TW21Loader.prototype.internalizeTiddler() definition from TW2.2b5 so plugin can read tiddlers from TW2.2+ even when running under TW2.1.x
2007.03.22 [3.5.0] in refreshImportList(), add handling for 'select section' when a heading is selected. Makes it really easy to import by tag or date!
2007.03.21 [3.4.0] split loadTiddlers functionality into separate plugin (see [[LoadTiddlersPlugin]])
2007.03.20 [3.3.1] tweak to previous change to allow relative file references via http: (bypasses getLocalPath() so remote URL will be used)
2007.03.20 [3.3.0] added support for local, relative file references: in loadRemoteFile(), check for fileExists(). If not found, prepend relative path location and try again. Allows use of simple "foo.html" file references with importTiddlers and/or loadTiddlers macros
2007.02.24 [3.2.1] re-labeled control panel "open" button to "load" to avoid confusion with "open" button in system-provided Browse... dialog. (i.e., "browse, open, open" becomes "browse, open, load")
2007.02.09 [3.2.0] loadTiddlers: added support for "noReload" tag (prevents overwriting existing tiddler, even if inbound tiddler is newer)
2007.02.08 [3.1.3] loadTiddlers: added missing code and documentation for "newTags" handling (a feature change from long, long ago that somehow got lost!)
2006.11.14 [3.1.2] fix macro handler parameter declaration (double-pasted param list corrupts IE)
2006.11.13 [3.1.1] use apply() method to invoke hijacked core handler
2006.11.13 [3.1.0] hijack TW2.1 built-in importTiddlers.handler() so it can co-exist with the plugin interface 'panel'. Use macro without params (or use 'core' keyword) to display built-in core interface. Use new "link" param to embed "import tiddlers" link that shows floating panel when clicked. Renamed a few plugin utility functions so they don't collide with core internal functions. More code restructuring to come.
2006.10.12 [3.0.8] in readTiddlersFromHTML(), fallback to find end of store area by matching "/body" when POST-BODY-START is not present (backward compatibility for older documents)
2006.09.10 [3.0.7] in readTiddlersFromHTML(), find end of store area by matching "POST-BODY-START" instead of "/body"
2006.08.16 [3.0.6] Use higher-level store.saveTiddler() instead of store.addTiddler() to avoid conflicts with ZW and other adaptations that hijack low-level tiddler handling. Also, in CreateImportPanel(), no longer register notify to "refresh listbox after every tiddler change" (left over from old 'auto-filtered' list handling). Thanks to Bob McElrath for report/solution.
2006.07.29 [3.0.5] added noChangeMsg to loadTiddlers processing. if not 'quiet' mode, reports skipped tiddlers.
2006.04.18 [3.0.4] in loadTiddlers.handler, fixed parsing of "prompt:" param. Also, corrected parameters mismatch in loadTiddlers() callback function definition (order of params was wrong, resulting in filters NOT being applied)
2006.04.12 [3.0.3] moved many display messages to macro properties for easier L10N translations via 'lingo' definitions.
2006.04.12 [3.0.2] additional refactoring of 'core candidate' code. Proposed API now defines "loadRemoteFile()" for XMLHttpRequest processing with built in fallback for handling local filesystem access, and readTiddlersFromHTML() to process the resulting source HTML content.
2006.04.04 [3.0.1] in refreshImportList(), when using [by tags], tiddlers without tags are now included in a new "untagged" psuedo-tag list section
2006.04.04 [3.0.0] Separate non-interactive {{{<<importTiddlers...>>}}} macro functionality for incorporation into TW2.1 core and renamed as {{{<<loadTiddlers>>}}} macro. New parameters for loadTiddlers: ''label:text'' and ''prompt:text'' for link creation, ''ask'' for filename/URL, ''tag:text'' for filtering, "confirm" for accept/reject of individual inbound tiddlers. Also, ImportedTiddlers report generator output has been simplified and "importReplace/importPublic" tags and associated "force" param (which were rarely, if ever, used) has been dropped.
2006.03.30 [2.9.1] when extracting store area from remote URL, look for "</body>" instead of "</body>\n</html>" so it will match even if the "\n" is absent from the source.
2006.03.30 [2.9.0] added optional 'force' macro param. When present, autoImportTiddlers() bypasses the checks for importPublic and importReplace. Based on a request from Tom Otvos.
2006.03.28 [2.8.1] in loadImportFile(), added checks to see if 'netscape' and 'x.overrideMimeType()' are defined (IE does *not* define these values, so we bypass this code)
Also, when extracting store area from remote URL, explicitly look for "</body>\n</html>" to exclude any extra content that may have been added to the end of the file by hosting environments such as GeoCities. Thanks to Tom Otvos for finding these bugs and suggesting some fixes.
2006.02.21 [2.8.0] added support for "tiddler:TiddlerName" filtering parameter in auto-import processing
2006.02.21 [2.7.1] Clean up layout problems with IE. (Use tables for alignment instead of SPANs styled with float:left and float:right)
2006.02.21 [2.7.0] Added "local file" and "web server" radio buttons for selecting dynamic import source controls in ImportPanel. Default file control is replaced with URL text input field when "web server" is selected. Default remote document URL is defined in SiteURL tiddler. Also, added option for prepending SiteProxy URL as prefix to remote URL to mask cross-domain document access (requires compatible server-side script)
2006.02.17 [2.6.0] Removed "differences only" listbox display mode, replaced with selection filter 'presets': all/new/changes/differences. Also fixed initialization handling for "add new tags" so that checkbox state is correctly tracked when panel is first displayed.
2006.02.16 [2.5.4] added checkbox options to control "import remote tags" and "keep existing tags" behavior, in addition to existing "add new tags" functionality.
2006.02.14 [2.5.3] FF1501 corrected unintended global 't' (loop index) in importReport() and autoImportTiddlers()
2006.02.10 [2.5.2] corrected unintended global variable in importReport().
2006.02.05 [2.5.1] moved globals from window.* to config.macros.importTiddlers.* to avoid FireFox 1.5.0.1 crash bug when referencing globals
2006.01.18 [2.5.0] added checkbox for "create a report". Default is to create/update the ImportedTiddlers report. Clear the checkbox to skip this step.
2006.01.15 [2.4.1] added "importPublic" tag and inverted default so that auto sharing is NOT done unless tagged with importPublic
2006.01.15 [2.4.0] Added support for tagging individual tiddlers with importSkip, importReplace, and/or importPrivate to control which tiddlers can be overwritten or shared with others when using auto-import macro syntax. Defaults are to SKIP overwriting existing tiddlers with imported tiddlers, and ALLOW your tiddlers to be auto-imported by others.
2006.01.15 [2.3.2] Added "ask" parameter to confirm each tiddler before importing (for use with auto-importing)
2006.01.15 [2.3.1] Strip TW core scripts from import source content and load just the storeArea into the hidden IFRAME. Makes loading more efficient by reducing the document size and by preventing the import document from executing its TW initialization (including plugins). Seems to resolve the "Found 0 tiddlers" problem. Also, when importing local documents, use convertUTF8ToUnicode() to convert the file contents so support international characters sets.
2006.01.12 [2.3.0] Reorganized code to use callback function for loading import files to support event-driven I/O via an ASYNCHRONOUS XMLHttpRequest. Let's processing continue while waiting for remote hosts to respond to URL requests. Added non-interactive 'batch' macro mode, using parameters to specify which tiddlers to import, and from what document source. Improved error messages and diagnostics, plus an optional 'quiet' switch for batch mode to eliminate //most// feedback.
2006.01.11 [2.2.0] Added "[by tags]" to list of tiddlers, based on code submitted by BradleyMeck
2006.01.09 [2.1.1] When a URL is typed in, and then the "open" button is pressed, it generates both an onChange event for the file input and a click event for open button. This results in multiple XMLHttpRequest()'s which seem to jam things up quite a bit. I removed the onChange handling for file input field. To open a file (local or URL), you must now explicitly press the "open" button in the control panel.
2006.01.08 [2.1.0] IMPORT FROM ANYWHERE!!! re-write getImportedTiddlers() logic to either read a local file (using local I/O), OR... read a remote file, using a combination of XML and an iframe to permit cross-domain reading of DOM elements. Adapted from example code and techniques courtesy of Jonny LeRoy.
2006.01.06 [2.0.2] When refreshing list contents, fixed check for tiddlerExists() when "show differences only" is selected, so that imported tiddlers that don't exist in the current file will be recognized as differences and included in the list.
2006.01.04 [2.0.1] When "show differences only" is NOT checked, import all tiddlers that have been selected even when they have a matching title and date.
2005.12.27 [2.0.0] Update for TW2.0
Defer initial panel creation and only register a notification function when panel first is created
2005.12.22 [1.3.1] tweak formatting in importReport() and add 'discard report' link to output
2005.12.03 [1.3.0] Dynamically create/remove importPanel as needed to ensure only one instance of interface elements exists, even if there are multiple instances of macro embedding. Also, dynamically create/recreate importFrame each time an external TW document is loaded for importation (reduces DOM overhead and ensures a 'fresh' frame for each document)
2005.11.29 [1.2.1] fixed formatting of 'detail info' in importReport()
2005.11.11 [1.2.0] added 'inline' param to embed controls in a tiddler
2005.11.09 [1.1.0] only load HTML and CSS the first time the macro handler is called. Allows for redundant placement of the macro without creating multiple instances of controls with the same ID's.
2005.10.25 [1.0.5] fixed typo in importReport() that prevented reports from being generated
2005.10.09 [1.0.4] combined documentation with plugin code instead of using separate tiddlers
2005.08.05 [1.0.3] moved CSS and HTML definitions into plugin code instead of using separate tiddlers
2005.07.27 [1.0.2] core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet()
2005.07.23 [1.0.1] added parameter checks and corrected addNotification() usage
2005.07.20 [1.0.0] Initial Release
<<<
config.macros.importWorkspaceMulti = {};
config.macros.importWorkspaceMulti.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
// this uses the existing importWorkspace mechanism to import each systemServer tiddler returned by the filter in params[0], where the filter is of the form used by Tiddlywiki.prototype.filterTiddlers
// currently only supports tag filters i.e. filters of the form [tag[filterTag]]
// protects against importing your own feeds
// console.log("in handler");
if (params[0]) {
var filter = params[0];
}
this.importAll(filter);
};
config.macros.importWorkspaceMulti.importAll = function(filter) {
// 23/10/07: The next two lines should work when the core filterTiddlers function is sorted out
// var extended_filter = filter+" [tag[systemServer]]";
// var workspace_tiddlers = store.filterTiddlers(extended_filter);
var sysServer_tiddlers = store.getTaggedTiddlers("systemServer");
var workspace_tiddlers = [];
if(!filter) {
// if there is no filter, just import from all tiddlers with a systemServer tag
// prompt first though...
var sysList = "";
for (var i=0;i<sysServer_tiddlers.length;i++) {
sysList = sysList + "\n" + sysServer_tiddlers[i].title;
workspace_tiddlers.push(sysServer_tiddlers[i]);
}
if(!confirm("are you sure you want to import from all these tiddlers?\n\n" + sysServerTiddlers)) {
return false;
};
} else {
// console.log(sysServer_tiddlers);
// console.log(filter);
var regex_tagFilter = /\[tag\[([\w ]+?)\]\]/mg;
var match = regex_tagFilter.exec(filter);
if (match) {
var mini_filter = match[1];
// console.log(match);
} else {
// console.log("no match");
}
for (var i=0;i<sysServer_tiddlers.length;i++) {
// ownPath/feedPath specific to .html/.xml
// can make feedPath general to any extension if we improve the regex
// we assume ownPath is always a .html file
var ownPath = document.location.href.replace(/.html$/,"");
// console.log(ownPath);
var feedPath = store.getTiddlerSlice(sysServer_tiddlers[i].title,"URL").replace(/.xml$/,"");
// console.log(feedPath);
if (ownPath != feedPath) {
if (sysServer_tiddlers[i].isTagged(mini_filter)) {
// console.log("tag match with: " + sysServer_tiddlers[i].title);
workspace_tiddlers.push(sysServer_tiddlers[i]);
}
}
}
}
// console.log(workspace_tiddlers);
// run through the systemServer tiddlers, importing as we go
for (var i=0;i<workspace_tiddlers.length;i++) {
var title = workspace_tiddlers[i].title;
var fields = {};
fields['server.type'] = store.getTiddlerSlice(title,'Type');
fields['server.host'] = store.getTiddlerSlice(title,'URL');
fields['server.workspace'] = store.getTiddlerSlice(title,'Workspace');
fields['server.filter'] = store.getTiddlerSlice(title,'TiddlerFilter');
// console.log("about to call importWorkspace with: " + title);
config.macros.importWorkspace.getTiddlers.call(config.macros.importWorkspace,fields);
}
};
/***
|''Name:''|ImportWorkspacePlugin|
|''Description:''|Commands to access hosted TiddlyWiki data|
|''Author:''|Martin Budden (mjbudden (at) gmail (dot) com)|
|''Source:''|http://www.martinswiki.com/#AdaptorMacrosPlugin |
|''CodeRepository:''|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ImportWorkspacePlugin.js |
|''Version:''|0.0.1|
|''Date:''|Aug 23, 2007|
|''Comments:''|Please make comments at http://groups.google.co.uk/group/TiddlyWikiDev |
|''License:''|[[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]] |
|''~CoreVersion:''|2.2.0|
|''Tag for import''|<<option txtImportTag>>|
|''Import workspace on startup''|<<option chkImportWorkspaceOnStartup>>|
|''Label for go button''|<<option txtImportLabel>>|
***/
// CHANGE: I have removed this line to tailor this plugin to select systemServer tiddlers by tag:
// |''Feed for import - DON'T USE''|<<option txtImportFeed>>|
//{{{
// Ensure that the plugin is only installed once.
if(!version.extensions.ImportWorkspacePlugin) {
version.extensions.ImportWorkspacePlugin = {installed:true};
if(config.options.txtImportTag == undefined)
{config.options.txtImportTag = 'published';}
if(config.options.chkImportWorkspaceOnStartup == undefined)
{config.options.chkImportWorkspaceOnStartup = false;}
if(config.options.txtImportLabel == undefined)
{config.options.txtImportLabel = 'Check for new stuff';}
config.messages.hostOpened = "Host '%0' opened";
config.messages.workspaceOpened = "Workspace '%0' opened";
config.messages.workspaceTiddlers = "%0 tiddlers in workspace, importing %1 of them";
config.messages.tiddlerImported = 'Tiddler: "%0" imported';
// import all the tiddlers from a given workspace on a given host
config.macros.importWorkspace = {};
merge(config.macros.importWorkspace,{
label: "import workspace",
prompt: "Import tiddlers in workspace",
done: "Tiddlers imported"});
config.macros.importWorkspace.init = function()
{
var customFields = config.defaultCustomFields;
if(!customFields['server.type']) {
var tag = config.options.txtImportTag;
var title = "";
if(tag=='') {
var tiddlers = store.getTaggedTiddlers("systemServer");
if(tiddlers.length==0)
return;
title = tiddlers[0].title;
} else {
var tiddlers = store.getTaggedTiddlers(tag);
if(tiddlers.length==0)
return;
title = tiddlers[0].title;
}
config.defaultCustomFields['server.type'] = store.getTiddlerSlice(title,'Type');
config.defaultCustomFields['server.host'] = store.getTiddlerSlice(title,'URL');
config.defaultCustomFields['server.workspace'] = store.getTiddlerSlice(title,'Workspace');
config.defaultCustomFields['server.filter'] = store.getTiddlerSlice(title,'TiddlerFilter');
}
if(config.options.chkImportWorkspaceOnStartup)
config.macros.importWorkspace.getTiddlers(customFields);
};
// I'm finding that this runs before the init function!
// My evidence for this is through config.log calls, and I assume that they execute in the order they are called
config.macros.importWorkspace.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
params = paramString.parseParams('anon',null,true,false,false);
var customFields = getParam(params,'fields',false);
if(!customFields) {
customFields = config.defaultCustomFields;
}
if(!customFields['server.type']) {
var title = "";
var tag = config.options.txtImportTag;
if (tag=='') {
title = getParam(params,'anon');
if(!title) {
var tiddlers = store.getTaggedTiddlers("systemServer");
if(tiddlers.length>0)
title = tiddlers[0].title;
}
} else {
// if we get here, the user has not provided field params and they have not been
// set in the init function, and we have a tag to use for looking up a tiddler
var tiddlers = store.getTaggedTiddlers(tag);
if(tiddlers.length==0)
return;
title = tiddlers[0].title;
}
if(title) {
customFields = {};
customFields['server.type'] = store.getTiddlerSlice(title,'Type');
customFields['server.host'] = store.getTiddlerSlice(title,'URL');
customFields['server.workspace'] = store.getTiddlerSlice(title,'Workspace');
customFields['server.filter'] = store.getTiddlerSlice(title,'TiddlerFilter');
}
}
customFields = String.encodeHashMap(customFields);
if(config.options.txtImportLabel) this.label = config.options.txtImportLabel;
var btn = createTiddlyButton(place,this.label,this.prompt,this.onClick);
btn.setAttribute('customFields',customFields);
};
config.macros.importWorkspace.onClick = function(e)
{
// clearMessage();
// displayMessage("Starting import...");
var customFields = this.getAttribute('customFields');
var fields = customFields ? customFields.decodeHashMap() : config.defaultCustomFields;
config.macros.importWorkspace.getTiddlers(fields);
};
config.macros.importWorkspace.getTiddlers = function(fields)
{
if(!fields['server.type']) {
var tiddlers = store.getTaggedTiddlers("systemServer");
var title = tiddlers[0].title;
fields = {};
fields['server.type'] = store.getTiddlerSlice(title,'Type');
fields['server.host'] = store.getTiddlerSlice(title,'URL');
fields['server.workspace'] = store.getTiddlerSlice(title,'Workspace');
fields['server.filter'] = store.getTiddlerSlice(title,'TiddlerFilter');
}
var serverType = fields['server.type'];
if(!serverType)
serverType = fields['wikiformat'];
if(!serverType)
return false;
var adaptor = new config.adaptors[serverType];
if(adaptor) {
var context = {};
context.host = fields['server.host'];
context.workspace = fields['server.workspace'];
context.adaptor = adaptor;
context.filter = fields['server.filter'];
var ret = adaptor.openHost(context.host,context,null,config.macros.importWorkspace.openHostCallback);
if(typeof ret == "string") {
displayMessage("error with http request: " + ret);
}
}
};
config.macros.importWorkspace.openHostCallback = function(context,userParams)
{
// displayMessage(config.messages.hostOpened.format([context.host]));
//window.setTimeout(context.adaptor.openWorkspace,0,context.workspace,context,config.macros.importWorkspace.openWorkspaceCallback);
if (context.status !== true) {
displayMessage("error opening feed: " + context.statusText);
}
context.adaptor.openWorkspace(context.workspace,context,userParams,config.macros.importWorkspace.openWorkspaceCallback);
};
config.macros.importWorkspace.openWorkspaceCallback = function(context,userParams)
{
// displayMessage(config.messages.workspaceOpened.format([context.workspace]));
//window.setTimeout(context.adaptor.openWorkspace,0,context.workspace,context,config.macros.importWorkspace.getTiddlerListCallback);
// displayMessage("using import filter: " + context.filter);
context.adaptor.getTiddlerList(context,userParams,config.macros.importWorkspace.getTiddlerListCallback,context.filter);
};
config.macros.importWorkspace.getTiddlerListCallback = function(context,userParams)
{
if(context.status) {
var tiddlers = context.tiddlers;
if (tiddlers.length === 0) {
displayMessage("nothing to import from " + context.adaptor.host);
}
var sortField = 'modified';
tiddlers.sort(function(a,b) {return a[sortField] < b[sortField] ? +1 : (a[sortField] == b[sortField] ? 0 : -1);});
var length = tiddlers.length;
if(userParams && userParams.maxCount && length > userParams.maxCount)
length = userParams.maxCount;
// displayMessage(config.messages.workspaceTiddlers.format([tiddlers.length,length]));
var import_count = 0;
for(var i=0; i<length; i++) {
tiddler = tiddlers[i];
var local_tiddler = store.fetchTiddler(tiddler.title);
// if the tiddler exists locally, don't overwrite unless the text is different
if(!local_tiddler || local_tiddler.text != tiddler.text) {
context.adaptor.getTiddler(tiddler.title,null,null,config.macros.importWorkspace.getTiddlerCallback);
import_count++;
displayMessage("writing tiddler: " + tiddler.title);
}
}
if (import_count === 0) {
displayMessage("nothing imported from " + context.adaptor.host);
}
}
};
config.macros.importWorkspace.getTiddlerCallback = function(context,userParams)
{
// displayMessage("getting " + context.tiddler.title);
if(context.status) {
var tiddler = context.tiddler;
// add in an extended field to save unread state
tiddler.fields["unread"] = "true";
store.saveTiddler(tiddler.title,tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.fields,true,tiddler.created);
story.refreshTiddler(tiddler.title,1,true);
} else {
displayMessage(context.statusText);
}
story.refreshAllTiddlers();
};
} // end of 'install only once'
//}}}
On 4. marts 2009 11:01:51, DitNavn imported 9 tiddlers from
[[http://sang.tiddlyspot.com|http://sang.tiddlyspot.com]]:
<<<
#[[CrossIndexingMacro]] - added
#[[DataTiddlerPlugin]] - replaces DataTiddlerPlugin - 10/27/2008 15:23:00 by DitNavn
#[[EditTemplate]] - replaces EditTemplate - 10/26/2008 22:43:00 by DitNavn
#[[HideWhenPlugin]] - replaces HideWhenPlugin - 9/21/2008 06:18:00 by YourName
#[[InlineJavascriptPlugin]] - replaces InlineJavascriptPlugin - 9/21/2008 06:18:00 by YourName
#[[NestedSlidersPlugin(withGiffmexTweak)]] - replaces NestedSlidersPlugin(withGiffmexTweak) - 9/21/2008 06:25:00 by YourName
#[[NewTopicTemplate]] - replaces NewTopicTemplate - 10/27/2008 15:26:00 by DitNavn
#[[SliderFrame]] - replaces SliderFrame - 10/26/2008 23:49:00 by DitNavn
#[[TopicNote]] - replaces TopicNote - 10/26/2008 22:35:00 by DitNavn
<<<
----
On 21. januar 2009 19:55:19, MaMa imported 36 tiddlers from
[[http://simplenoter.tiddlyspot.com/|http://simplenoter.tiddlyspot.com/]]:
<<<
#[[Avanceret tilpasning]] - replaces Avanceret tilpasning - 10/26/2008 20:33:00 by DitNavn
#[[ColorPalette]] - replaces ColorPalette - 9/21/2008 06:21:00 by YourName
#[[DataTiddlerPlugin]] - replaces DataTiddlerPlugin - 10/27/2008 15:23:00 by DitNavn
#[[EditTemplate]] - replaces EditTemplate - 10/26/2008 22:43:00 by DitNavn
#[[ExtendTagButtonPlugin]] - replaces ExtendTagButtonPlugin - 9/21/2008 06:18:00 by YourName
#[[ForEachTiddlerPlugin]] - replaces ForEachTiddlerPlugin - 9/21/2008 06:16:00 by YourName
#[[FormTiddlerMacro]] - replaces FormTiddlerMacro - 10/27/2008 15:20:00 by DitNavn
#[[FormTiddlerPlugin]] - replaces FormTiddlerPlugin - 10/27/2008 15:19:00 by DitNavn
#[[HideWhenPlugin]] - replaces HideWhenPlugin - 9/21/2008 06:18:00 by YourName
#[[HistoryPlugin]] - replaces HistoryPlugin - 9/21/2008 06:21:00 by YourName
#[[InlineJavascriptPlugin]] - replaces InlineJavascriptPlugin - 9/21/2008 06:18:00 by YourName
#[[NestedSlidersPlugin(withGiffmexTweak)]] - replaces NestedSlidersPlugin(withGiffmexTweak) - 9/21/2008 06:25:00 by YourName
#[[NewHerePlugin]] - replaces NewHerePlugin - 9/21/2008 06:15:00 by YourName
#[[NewTopicTemplate]] - replaces NewTopicTemplate - 10/27/2008 15:26:00 by DitNavn
#[[NoteNote]] - replaces NoteNote - 10/26/2008 22:43:00 by DitNavn
#[[PageTemplate]] - replaces PageTemplate - 9/22/2008 16:48:00 by YourName
#[[QuickEditPlugin]] - replaces QuickEditPlugin - 10/9/2008 17:56:00 by YourName
#[[QuickEditToolbar]] - replaces QuickEditToolbar - 10/9/2008 17:56:00 by YourName
#[[QuickEdit_align]] - replaces QuickEdit_align - 10/9/2008 17:56:00 by YourName
#[[QuickEdit_color]] - replaces QuickEdit_color - 10/9/2008 17:56:00 by YourName
#[[QuickEdit_font]] - replaces QuickEdit_font - 10/9/2008 17:56:00 by YourName
#[[QuickEdit_fontList]] - replaces QuickEdit_fontList - 10/9/2008 18:10:00 by YourName
#[[QuickEdit_format]] - replaces QuickEdit_format - 10/9/2008 18:10:00 by YourName
#[[QuickEdit_image]] - replaces QuickEdit_image - 10/9/2008 17:57:00 by YourName
#[[QuickEdit_link]] - replaces QuickEdit_link - 10/9/2008 17:57:00 by YourName
#[[QuickOpenTagPlugin]] - replaces QuickOpenTagPlugin - 9/21/2008 06:19:00 by YourName
#[[SinglePageModePlugin]] - replaces SinglePageModePlugin - 9/21/2008 06:16:00 by YourName
#[[SiteMapMacro]] - replaces SiteMapMacro - 9/29/2008 04:33:00 by YourName
#[[StyleSheet]] - replaces StyleSheet - 10/9/2008 17:45:00 by YourName
#[[TagglyTaggingPlugin]] - replaces TagglyTaggingPlugin - 9/21/2008 06:15:00 by YourName
#[[ToggleRightSidebar]] - replaces ToggleRightSidebar - 9/21/2008 06:20:00 by YourName
#[[ToggleTagPlugin]] - replaces ToggleTagPlugin - 9/21/2008 06:15:00 by YourName
#[[ToolbarCommands]] - replaces ToolbarCommands - 10/27/2008 00:03:00 by DitNavn
#[[TopicNote]] - replaces TopicNote - 10/26/2008 22:35:00 by DitNavn
#[[ViewTemplate]] - replaces ViewTemplate - 1/17/2009 10:39:00 by MaMa
#[[zzConfigOptions]] - replaces zzConfigOptions - 10/26/2008 21:23:00 by DitNavn
<<<
----
On 21. januar 2009 19:50:14, MaMa imported 1 tiddler from
[[http://simplenoter.tiddlyspot.com/|http://simplenoter.tiddlyspot.com/]]:
<<<
#[[HideWhenPlugin]] - replaces HideWhenPlugin - 9/21/2008 06:18:00 by YourName
<<<
----
On 18. januar 2009 10:26:33, DitNavn imported 26 tiddlers from
[[C:\Documents and Settings\mama\Skrivebord\tiddlychatter.html|C:\Documents and Settings\mama\Skrivebord\tiddlychatter.html]]:
<<<
#[[After installing]] - added
#[[BUGS]] - added
#[[ChatterFeed]] - added
#[[Core patches]] - added
#[[How TiddlyChatter works - an example scenario]] - added
#[[ImportWorkspaceMulti]] - added
#[[ImportWorkspacePlugin]] - added
#[[InstallTiddlyChatter]] - added
#[[NotesPlugin]] - added
#[[RSSAdaptor]] - added
#[[RSSrender plugin]] - added
#[[StyleSheetTiddlyChatter]] - added
#[[TiddlyChatter]] - added
#[[TiddlyChatter flow]] - added
#[[TiddlyChatterDocumentation]] - added
#[[TiddlyChatterPackage]] - added
#[[TiddlyChatterPublishing]] - added
#[[TiddlyChatterReading]] - added
#[[Unread]] - added
#[[Welcome to TiddlyChatter]] - added
#[[applyTiddlyChatterStyles]] - added
#[[lv]] - added
#[[publicViewTemplate]] - added
#[[stickyOptionsPlugin]] - added
#[[tiddlyChatterPublishing]] - added
#[[tiddlyChatterSetup code]] - added
<<<
----
On 2. november 2008 00:31:39, DitNavn imported 16 tiddlers from
[[C:\Documents and Settings\mama\Dokumenter\Arbejde\Guitar\GuitarScrapBog.html|C:\Documents and Settings\mama\Dokumenter\Arbejde\Guitar\GuitarScrapBog.html]]:
<<<
#[[Anmeldelse]] - added
#[[Bibliografi]] - added
#[[Bibliography]] - added
#[[Bibliography feature]] - added
#[[BogArkiv]] - added
#[[DataTiddlerPlugin]] - added
#[[Efter forfatter]] - added
#[[Efter tema]] - added
#[[Efter titel]] - added
#[[FormTiddlerMacro]] - added
#[[FormTiddlerPlugin]] - added
#[[NewBibEntryTemplate]] - added
#[[NewTopicTemplate]] - added
#[[Ondskaben]] - added
#[[SideBarOptions]] - replaces SideBarOptions - 10/26/2008 19:15:00 by DitNavn
#[[TiddlyHomeMenu]] - added
<<<
----
On 26. oktober 2008 23:41:52, DitNavn imported 1 tiddler from
[[http://www.giffmex.org/nttag/1petertags.html|http://www.giffmex.org/nttag/1petertags.html]]:
<<<
#[[TagCloudPlugin]] - added
<<<
----
On 26. oktober 2008 21:19:36, DitNavn imported 1 tiddler from
[[$url$|$url$]]:
<<<
#[[Tiddlyspot]] - added
<<<
----
On 26. oktober 2008 21:17:46, DitNavn imported 1 tiddler from
[[C:\Documents and Settings\mama\Skrivebord\Udtalelser\mms.html|C:\Documents and Settings\mama\Skrivebord\Udtalelser\mms.html]]:
<<<
#[[TspotSetupPlugin]] - added
<<<
----
On 26. oktober 2008 19:00:23, DitNavn imported 2 tiddlers from
[[C:\Documents and Settings\mama\Skrivebord\Udtalelser\mms.html|C:\Documents and Settings\mama\Skrivebord\Udtalelser\mms.html]]:
<<<
#[[SnapshotPlugin]] - added
#[[SnapshotPluginInfo]] - added
<<<
----
On 26. oktober 2008 18:50:05, DitNavn imported 52 tiddlers from
[[C:\Documents and Settings\mama\Skrivebord\NBN\nobrainernotes.html|C:\Documents and Settings\mama\Skrivebord\NBN\nobrainernotes.html]]:
<<<
#[[Acknowledgements & license]] - added
#[[Advanced customization]] - added
#[[Basic customization]] - added
#[[CloseOnCancelPlugin]] - added
#[[ColorPalette]] - added
#[[DefaultTiddlers]] - replaces DefaultTiddlers - 10/13/2008 23:29:00 by DitNavn
#[[EditTemplate]] - added
#[[ExtendTagButtonPlugin]] - added
#[[ForEachTiddlerPlugin]] - added
#[[HideWhenPlugin]] - added
#[[HistoryPlugin]] - added
#[[How you can help]] - added
#[[InlineJavascriptPlugin]] - added
#[[Instructions]] - added
#[[MainMenu]] - replaces MainMenu - 10/13/2008 23:29:00 by DitNavn
#[[NestedSlidersPlugin(withGiffmexTweak)]] - added
#[[NewHerePlugin]] - added
#[[NoteNote]] - added
#[[PageTemplate]] - added
#[[QuickEditPlugin]] - added
#[[QuickEditToolbar]] - added
#[[QuickEdit_align]] - added
#[[QuickEdit_color]] - added
#[[QuickEdit_font]] - added
#[[QuickEdit_fontList]] - added
#[[QuickEdit_format]] - added
#[[QuickEdit_image]] - added
#[[QuickEdit_link]] - added
#[[QuickOpenTagPlugin]] - added
#[[Sample note]] - added
#[[Sample subtopic]] - added
#[[Sample topic]] - added
#[[SaveCloseTiddlerPlugin]] - added
#[[SearchOptions plugin tweaks]] - added
#[[SearchOptionsPlugin]] - added
#[[SearchOptionsPlugin tweaks]] - added
#[[SearchResults]] - added
#[[SideBarOptions]] - added
#[[SinglePageModePlugin]] - added
#[[SiteMapMacro]] - added
#[[SiteSubtitle]] - added
#[[SiteTitle]] - added
#[[SliderFrame]] - added
#[[StyleSheet]] - added
#[[TagglyTaggingPlugin]] - added
#[[ToggleRightSidebar]] - added
#[[ToggleTagPlugin]] - added
#[[ToolbarCommands]] - added
#[[TopMenu]] - added
#[[TopicNote]] - added
#[[ViewTemplate]] - replaces ViewTemplate - 10/15/2008 01:40:00 by DitNavn
#[[zzConfigOptions]] - added
<<<
----
On 17. oktober 2008 18:46:58, DitNavn imported 8 tiddlers from
[[C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\empty.html|C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\empty.html]]:
<<<
#[[LoadRemoteFileThroughProxy]] - replaces LoadRemoteFileThroughProxy - 3/18/2007 22:55:00 by BidiX
#[[PasswordOptionPlugin]] - replaces PasswordOptionPlugin - 2/24/2008 11:23:00 by BidiX
#[[TiddlyHomeSetupPlugin]] - replaces TiddlyHomeSetupPlugin - 8/4/2007 22:27:00 by BidiX
#[[TiddlyHomeSystemTW]] - replaces TiddlyHomeSystemTW - 5/29/2007 13:22:00 by BidiX
#[[UploadPlugin]] - replaces UploadPlugin - 8/12/2008 07:46:00 by BDi
#[[UploadTiddlerPlugin]] - replaces UploadTiddlerPlugin - 8/20/2008 21:58:00 by BidiX
#[[UploadToHomeMacro]] - replaces UploadToHomeMacro - 5/29/2007 15:25:00 by BidiX
#[[admin]] - replaces admin - 7/28/2007 17:49:00 by BidiX
<<<
----
On 15. oktober 2008 14:43:30, DitNavn imported 2 tiddlers from
[[C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\Templates med Wysiwyg\buksetrolden_wysiwyg.html|C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\Templates med Wysiwyg\buksetrolden_wysiwyg.html]]:
<<<
#[[FramedLinksPlugin]] - added
#[[FullScreenPlugin]] - added
<<<
----
On 15. oktober 2008 14:40:11, DitNavn imported 1 tiddler from
[[C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\Templates med Wysiwyg\buksetrolden_wysiwyg.html|C:\Documents and Settings\mama\Dokumenter\Arbejde\Wikis oversat\TiddlyHomePackage_0.1.3\Templates til nettet\Templates med Wysiwyg\buksetrolden_wysiwyg.html]]:
<<<
#[[SplashScreenPlugin]] - added
<<<
!!!Uden touchscreen<html><div align="center"><iframe src="http://www.clicksalg.dk/PartDetail.aspx?q=p:2046933;c:36167;r:kelkoo" frameborder="0" width="100%" height="600"></iframe></div></html>
!!!Med touchscreen<html><div align="center"><iframe src="http://www.clicksalg.dk/PartDetail.aspx?q=p:2201037;c:36167;r:kelkoo" frameborder="0" width="100%" height="600"></iframe></div></html>
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link. Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed). Thanks to Xavier Verges for suggestion and preliminary code.
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 9, revision: 2, date: new Date(2008,3,3)};
config.formatters.push( {
name: "inlineJavascript",
match: "\\<script",
lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
handler: 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 src=lookaheadMatch[1];
var label=lookaheadMatch[2];
var tip=lookaheadMatch[3];
var key=lookaheadMatch[4];
var show=lookaheadMatch[5];
var code=lookaheadMatch[6];
if (src) { // load a script library
// make script tag, set src, add to body to execute, then remove for cleanup
var script = document.createElement("script"); script.src = src;
document.body.appendChild(script); document.body.removeChild(script);
}
if (code) { // there is script code
if (show) // show inline script code in tiddler output
wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
if (label) { // create a link to an 'onclick' script
// add a link, define click handler, save code in link (pass 'place'), set link attributes
var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
link.code="function _out(place){"+fixup+"\n};_out(this);"
link.tiddler=w.tiddler;
link.onclick=function(){
this.bufferedHTML="";
try{ var r=eval(this.code);
if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
if(this.bufferedHTML.length)
s.innerHTML=this.bufferedHTML;
if((typeof(r)==="string")&&r.length) {
wikify(r,s,null,this.tiddler);
return false;
} else return r!==undefined?r:false;
} catch(e){alert(e.description||e.toString());return false;}
};
link.setAttribute("title",tip||"");
var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
link.setAttribute("href",URIcode);
link.style.cursor="pointer";
if (key) link.accessKey=key.substr(0,1); // single character only
}
else { // run inline script code
var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
var code="function _out(place){"+fixup+"\n};_out(w.output);"
try { var out=eval(code); } catch(e) { out=e.description?e.description:e.toString(); }
if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
}
}
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
}
} )
//}}}
// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
if(limit > 0) text = text.substr(0,limit);
var wikifier = new Wikifier(text,formatter,null,tiddler);
return wikifier.wikifyPlain();
}
//}}}
# If you are planning to use ~TiddlyChatter with your ~TiddlySpot ~TiddlyWiki, make sure to remember to download a local copy so you can import tiddlers
# To get hold of the set of tiddlers needed for ~TiddlyChatter, you need to use the ~ImportPlugin (often via the backstage area) in your own ~TiddlyWiki. When asked for the type of server, choose "File" and for the URL to download from, use this URL and then click "open":
#* http://tiddlychatter.tiddlyspot.com/index.html
# You don't need to bother setting a value for the workspace, just click "open" again. When you are presented with the list of tiddlers, choose the ones tagged <<tag TiddlyChatterPackage>>. You can check in TiddlyChatterDocumentation to see which other plugins are used and which are modified. I have made an effort to make sure that any modifications are backwards-compatible and that overwriting the originals you already have is safe. If you have any problems, please report them on the [[TiddlyWikiDev|http://groups.google.com/TiddlyWikiDev]] Google Group.
Once you have ~TiddlyChatter installed on your own ~TiddlyWiki, you get a [[feed|TiddlyChatterPackage]] to use for future synchronisation with this version of ~TiddlyChatter.
Simple Noter er en fuldstændig simpel måde at tage og organisere noter. Dave Gifford lavede den til sine seminarieelever, og har gjort den tilgængelig for alle. (MM har oversat og tilføjet nogle ekstra plugins.red) Originalen kan ses [[her.|http://www.giffmex.org/nobrainernotes.html]]
!Hvordan bruger man Simple Noter:
#''Notatteknik i SN'': i en nøddeskal, du laver noter som hører til emner og underemner, og finder dem hurtigt igen, enten med søgefunktionen, eller via Emne indekset, som opdateres automatisk.
##''Fra top til bund metoden:'' Klik på 'Nyt hovedemne' øverst //(kan ses i den udgave af SN du har gemt til din pc)// og følg de instruktioner som gives. 'Emne' indekset til venstre vil automatisk tilføje emner og noter til Emne indekset. Klik på 'genopfrisk' knappen for at se de nye tilføjelser til menuen. Klik på pilene (►) for at åbne forskellige niveauer i indekset.
##''Fra bunden og op metoden'': Klik på 'Ny note' foroven //(kan ses i den udgave af SN du har gemt til din pc)// og følg de instruktioner , der gives om at lave en note og arbejd dig op ad emne- og underemnekæden.
#''Navigation i SN'': Der er fire måder at navigere igennem Simple Noter:
##Søg efter en note gennem søgevinduet.
##Se dine noter igennem via Emne indekset til venstre.
##Brug history, frem- og tilbageknapperne for at finde noter du lige har brugt.
##Åben sidepanelet for at se lister over noter efter titel, dato ændret og efter tags.
#''Formatering i Simple Noter''
##Når en note eller et emne er i edit-mode, kan du bruge knapper til at formater valgt tekst eller tilføje links og billeder.
!Hvordan man downloader Simple Noter:
Du kan downloade lige så mange kopier af Simple Noter som du ønsker, gratis.
# [[Klik her|http://simplenoter.tiddlyspot.com/download]] og vælg //gem// eller hent den originale 'No-brainerNotes' [[højreklik her|http://www.giffmex.org/nobrainernotes.html]] og vælg 'Gem linkmål som', 'Gem link som', eller lignende. Giv din fil et nyt filnavn og læg den hvor du vil.
#Hvis du bruger en anden browser end Firefox, vil du få brug for [[klik her|http://www.tiddlywiki.com/TiddlySaver.jar]], gem ~TiddlySaver filen, og læg den //samme sted// som din Simple Noter-fil. ~TiddlySaver er en Java applet som giver dig mulighed for at gemme ændringer i forskellige browsere som ikke understøtter at man kan gemme ændringer til lokale filer.
!Andre instruktioner
*[[Grundlæggende tilpasning]]
*[[Avanceret tilpasning]]
For at se hvordan man formaterer tekst i ~TiddlyWiki, kan du læse "Special formatting" sektionen af [[denne tutorial|http://www.giffmex.org/twfortherestofus.html]].
(Red.(MM)) Udover [[HurtigEdit|QuickEditToolbar]] som er indbygget i denne udgave af ~TiddlyWiki, fra starten, har jeg tilføjet wikibar og wysiwyg. For at kunne bruge wysiwyg lokalt - dvs. efter du har downloadet filen til din pc, - skal du downloade [[denne zipfil|http://maans.newp.dk/fckeditor.zip]], pakke mappen ud og lægge mappen (ikke indholdet, men hele mappen) samme sted som du har din tiddlywiki-fil.
rapport vedr. Projekt It læring 2006-2007
Forfattere:
Karin Levinsen
+++[Birgitte Holm Sørensen]...<html><div <span class='menubox' style='float:left;margin:0em'<div align="center"><iframe src="http://www.dpu.dk/site.aspx?p=5290&init=birgitte" frameborder="0" width="750px" height="500"scrolling="no"></iframe></div></html>===
[[Link|https://pure.dpu.dk/ws/fbspretrieve/210/Rapport_PIL_2008.pdf]]
<html><div <span class='menubox' style='float:center;margin:0em'<div align="center"><iframe src="https://pure.dpu.dk/ws/fbspretrieve/210/Rapport_PIL_2008.pdf" frameborder="0" width="100%" height="800"></iframe></div></html>
<html>
17. jan 2009 kl. 22:57
<h1>It-udstyr for millioner samler støv på skolerne </h1>
<h3 style="color: rgb(102, 102, 102); font-size: 13px; font-family: verdana;">
Bøger og fotokopier er fortsat lærernes foretrukne redskaber i undervisningen, trods store investeringer i digitalt udstyr
Af Dorrit Saietz
<div style="overflow: hidden; width: 460px;">
<img src="http://multimedia.pol.dk/archive/00313/skole_18-01-2009_I4_313888c.jpg" border="0">
</div>
<div class="billedetekst_top" style="padding-top: 3px;">
Kristine Langstrup, der er klasselærer for 9.b ogg it-vejleder på Usserød Skole, tilhører det mindretal af lærere, der bruger de nye smartboards. - Foto: Jacob Ehrbahn
Der står flere og nyere computere end nogensinde i danske skolers
klasselokaler. Danmark ligger nemlig helt i top, når det gælder
investeringer i it-udstyr i skolen.</b><br>
<br>
Men lærerne udnytter langtfra de mange muligheder, som det dyre udstyr giver,
viser en ny undersøgelse, som Det nationale forskningscenter DREAM og
Nationalt videnscenter for læremidler offentliggør mandag. Den nye
undersøgelse viser samme ringe udnyttelsesgrad som en tilsvarende
undersøgelse fra 1995.<br>
<br>
»Bøger og tavlen er stadig de foretrukne værktøjer i de danske skoler, og når
it anvendes, udnyttes mediets mange muligheder slet ikke«, siger professor
Kirsten Drotner fra Syddansk Universitet, som er en af forskerne bag
rapporten. <br>
<br>
»Vi ser stort set ingen ændring i måden, eleverne tilegner sig ny viden på.
Det er tankevækkende, at det står så ringe til, og også overraskende, at
lande som eksempelvis Norge, Canada og England er langt foran Danmark på det
her felt«, siger hun.<br>
<br>
<b>De fleste lærere anvender aldrig hjemmesider</b><br>
I undersøgelsen er et stort antal dansk- og matematiklærere fra folkeskolens
8. klasser og fra gymnasier blevet spurgt, hvilke undervisningsmidler de
bruger i timerne.
<br><br>
52 procent af dansklærerne og 77 procent af matematiklærerne anvender aldrig
hjemmesider i undervisningen. Tilsvarende bruger 59 og 78 procent af lærerne
aldrig digitale av-materialer. Når det gælder den nye generation af web 2.0
tjenester – f.eks. blogs, wikis og fildelingstjenester – er andelen af
ikke-brugere helt oppe på 89 og 99 procent.<br>
<br>
»Det mest overraskende er, at vi fik næsten de samme svar, da vi spurgte
lærerne i en tilsvarende undersøgelse i 1995. I de mellemliggende 13 år har
der været en massiv investering og en rigtig flot indsats fra
Undervisningsministeriet især på folkeskolens område, og alligevel er der
sket meget lidt«, siger Kirsten Drotner.<br>
<br>
Hun efterlyser, at skolen sætter langt mere konkrete mål for at gøre eleverne
til aktive brugere af de nye digitale medier. De skal ikke bare kunne søge
på hjemmesider og skrive i tekstbehandling, men selv kunne skabe og dele
viden.<br>
<br>
»Det her er noget, vi skal kunne, ligesom vi skal kunne læse, skrive og regne.
Det er en myte, at vi har en generation af børn og unge, som bare kan det
her med it,« siger hun.<br>
<b><br>
Nyuddannede lærere mangler også it-kundskaber</b><br>
Selv nyuddannede lærere mangler ofte it-kundskaber, og det har rejst kritik af
seminarierne. Men, siger lektor og it-vejleder Jens Stig Olsen fra
læreruddannelsen i Hjørring, »man kan trække hesten til truget, men man kan
ikke tvinge den til at drikke«.<br>
<br>
»Vi bruger mange kræfter på at opfordre de studerende til at tage det
it-pædagogiske kørekort, mens de er hos os. Men ud af en årgang på 80
studerende er det typisk omkring 20, der starter på det, og kun 5-6 stykker,
der fuldfører«, siger han.<br>
<br>
Hans indtryk er, at de studerende prioriterer tiden benhårdt, og at de fag,
hvor de skal bestå eksamen, kommer i første række.
<br><br>
<b>Skoleleder-formand vil tvinge lærerne</b><br>
Formand for skolelederne Anders Balle opfordrer sine medlemmer til at gå meget
mere kontant til værks. Lærerne skal tvinges til at sætte sig ind i de mange
digitale undervisningsprogrammer og bruge dem.<br>
<br>
»Der er en tendens til, at det skal være sådan lidt frivilligt. Det skal det
måske i en fase, men den skal være så kort som mulig. For man får først de
sidste med, når det næsten bliver en tvangsforanstaltning«, siger han.
<br><br>
<b>Undervisningsministeren vil overveje at give et skub</b><br>
Undervisningsminister Bertel Haarder (V) siger, at han vil læse undersøgelsen
med stor opmærksomhed:
<br><br>
»Den svarer dog ikke til mit indtryk, men det er måske, fordi jeg har besøgt
skoler, som i særlig grad har gjort it til en helt naturlig del af
undervisningen. Men vi skal da overveje, om vi skal sætte yderligere skub i
udviklingen af gode undervisningsprogrammer«.
</div></div></div></html>
Source: [[It-udstyr for millioner samler støv på skolerne - Politiken.dk|http://politiken.dk/uddannelse/article631455.ece]]
<<miniBrowser hidecontrols http://janeknight.typepad.com/pick/>>
<<miniBrowser hidecontrols http://feedproxy.google.com/JanesE-learningPickOfTheDay>>
<html><div align="center"><iframe src="http://mail.h-u.dk/webmail" frameborder="0" width="100%" height="375"></iframe></div></html>
/%
Titel: [[Kaspersky]]
Type: Installationsprogram
!Beskrivelse
Antivirusbeskyttelse
Behøver ingen kode
[[Hent|http://files.getdropbox.com/u/1064531/HU-Kav.exe]]
!end
%/
++++[Kræver password for at kunne læses: ]
----
[[Se her|TabelSliceScript]]
<<tiddler TabelSliceScript>>
===
Anybody have a suggestion on how to use custom classes for table cells within the twocolumns class?
There seems to be a problem with using styles inside a table within the twocolumns class (from Eric's stylesheet shortcuts). What I am trying to accomplish is to have two tables side by side and to apply custom style sheet classes for cells in the table.
In the example code below Table Test One works correctly. Test Two works correctly. Table Test Three and Table Test Four fail in that the redTest class seems to break apart the cell from the rest of the table.
This example is online at http://cadfael.tiddlyspot.com/ in the tiddler TwoColumnsTableTest.
Min løsning=
----
|>| !{{redtest{Table Test One}}} |
| www | xxxx |
| yyy | zzz |
{{twocolumns{
{{redtest{Test Two}}}
|~|>|f
|>| !{{redtest{Table Test Three}}} |
| www | xxxx |
| yyy | zzz |
|~|>|f
|>| !{{redtest{Table Test Four}}} |
| www | xxxx |
| yyy | zzz |
}}}
<html><p>For at komme i gang med denne tomme tiddlywiki, skal du ændre på de følgende tiddlere:</p><p>* SiteTitle & SiteSubtitle: Sidens titel og undertitel, som vist øverst (efter de er gemt, vil de også vise sig i browserens titelmenu)</p><p>* MainMenu: er hovedmenuen (er oftest placeret til venstre)</p><p>* DefaultTiddlers: Indeholder navnene på de tiddlere du vilhave skal starte op når du åbner TiddlyWiki</p><p>Du skal også skrive dit brugernavn for at signere dine redigeringer: <<option txtUserName>></p></html>
✗ Forbindelse mellem det nye og mixen ca. 5.000 kr.
➢ Hele den nye fløj kommer på med stik til mange kabler
➢ Timer på trådløse routere ca. 500 kr.
➢ Trådløse routere på hele skolen ca. 6.000 kr.
<<comments>>
<html><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/ypCTmtIa_DQ&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/ypCTmtIa_DQ&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></html>
<html><b><u>Grafik</u></b><ul><li>The Gimp - <a href="http://gimp.org" target="_blank">http://gimp.org</a> - et godt gratis alternativ til Photoshop<br>
</li><li>RedEye - <a href="http://www.jdmcox.com/" target="_blank">http://www.jdmcox.com/</a> - Fjernelse af røde øjne<br>
</li><li>Photofiltre - <a href="http://photofiltre.com" target="_blank">http://photofiltre.com</a> - Simpel billederedigering<br>
</li><li>PhotoGadget - <a href="http://www.download.com/Photo-Gadget/3000-2192_4-10396428.html?tag=lst-0-" target="_blank">http://www.download.com/Photo-Gadget/300...html?tag=lst-0-</a> - Resize billeder fra contextmenu<br>
</li><li>Google Sketchup - <a href="http://sketchup.google.com" target="_blank">http://sketchup.google.com</a> - Gratis 3d modellering<br>
</li><li>Blender - <a href="http://www.blender.org" target="_blank">http://www.blender.org</a> - rigtigt professionelt tool til 3D<br>
</li><li>IrfanView - <a href="http://www.irfanview.com" target="_blank">http://www.irfanview.com</a> - Resize af billeder - Batch Conversion/Rename<br>
</li><li>Club8 Furnish - <a href="http://www.boconcept.dk/Indret_med_Furnish%C2%AE-64198.aspx" target="_blank">http://www.boconcept.dk/Indret_med_Furnish%C2%AE-64198.aspx</a> - Boligindretning<br>
</li><li> Picasa - <a href="http://picasa.google.com/" target="_blank">http://picasa.google.com/</a> - Billedbehandlingsprogram<br>
</li><li>Scribus - <a href="http://www.scribus.net/" target="_blank">http://www.scribus.net/</a> - opensource svar på InDesign<br>
</li><li>Inkscape - <a href="http://www.inkscape.org/" target="_blank">http://www.inkscape.org/</a> - opensurce svar på Illustrator<br></li></ul><br>
<b><u>Lyd og video</u></b><br>
<ul><li>Winamp - <a href="http://winamp.com" target="_blank">http://winamp.com</a> - Afspilning af lyd og video <br>
</li><li>VLC mediaplayer – <a href="http://videolan.org" target="_blank">http://videolan.org</a> – afspilning af video filer i næsten alle formater<br>
</li><li>VirtualDub - <a href="http://www.virtualdub.com" target="_blank">http://www.virtualdub.com</a> - Perfekt til basal video redigering<br>
</li><li>Audiacity - lyd redigering - <a href="http://audacity.sourceforge.net" target="_blank">http://audacity.sourceforge.net</a> - rigtig godt alternativ til fx Adobe Audition<br>
</li><li>Media Player Classic - <a href="http://sourceforge.net/project/showfiles.php?group_id=82303&package_id=84358&release_id=403110" target="_blank">http://sourceforge.net/project/showfiles...lease_id=403110</a> - Godt alternativ til WMP<br>
</li><li>Radiocenter Database - <a href="http://tank.adsl.dk/radiocenter" target="_blank">http://tank.adsl.dk/radiocenter</a> - Program til at lytte til netradio uden at besøge hjemmesider.<br>
</li><li>QuickTime Alternative - <a href="http://www.free-codecs.com/download/QuickTime_Alternative.htm" target="_blank">http://www.free-codecs.com/download/Quic...Alternative.htm</a> - Alternativ QuickTime<br>
</li><li>Real Alternative - <a href="http://www.free-codecs.com/download/Real_Alternative.htm" target="_blank">http://www.free-codecs.com/download/Real_Alternative.htm</a> - Alternativ RealPlayer<br>
</li><li>Fraps - <a href="http://www.fraps.com" target="_blank">www.fraps.com</a> - Lille program der gør det muligt at aflæse FPS, optage video og tage screenshots i spil.<br>
</li><li>Asftools - <a href="http://www.geocities.com/myasftools" target="_blank">http://www.geocities.com/myasftools</a> - Editer WMV, trække lyd ud, konvertere til .avi osv osv.<br>
</li><li>AC3 Filter - <a href="http://ac3filter.net" target="_blank">http://ac3filter.net</a> - lydfilter til afspilning af video<br>
</li><li>DBPowerAmp - <a href="http://www.dbpoweramp.com" target="_blank">http://www.dbpoweramp.com</a> - konvertering af musikfiler<br>
</li><li>AutoGK - <a href="http://www.autogk.me.uk" target="_blank">http://www.autogk.me.uk</a> - konverter DVD til andre formater<br>
</li><li>Exact Audio Copy (EAC) - <a href="http://www.exactaudiocopy.de" target="_blank">http://www.exactaudiocopy.de</a> - CD Backup<br>
</li><li>LAME - <a href="http://lame.sourceforge.net" target="_blank">http://lame.sourceforge.net</a> - Mp3 Codec<br>
</li><li>FLAC (Free Lossless Audio Codec) - <a href="http://flac.sourceforge.net" target="_blank">http://flac.sourceforge.net</a> - Ta' backup af dine cd'er i høj kvalitet<br>
</li><li>FLAC Plugin til WinAMP - <a href="http://www.winamp.com/plugins/details.php?id=131643" target="_blank">http://www.winamp.com/plugins/details.php?id=131643</a> - Afspil dine .flac filer med winamp.<br>
</li><li>Xvid - <a href="http://www.xvid.org" target="_blank">http://www.xvid.org</a> - Xvid codec.<br>
</li><li>FFDShow - <a href="http://sourceforge.net/projects/ffdshow" target="_blank">http://sourceforge.net/projects/ffdshow</a> - Se videoklip i de gængse formater.<br>
</li><li>x264 - <a href="http://x264.nl" target="_blank">http://x264.nl</a> - opensource AVC/H.264 codec<br>
</li><li>winLAME - <a href="http://winlame.sourceforge.net/" target="_blank">http://winlame.sourceforge.net/</a> - Windows App til mp3 encoding ( bruger LAME ) med nem og overskuelig GUI. <br>
</li><li>Mov2Avi - <a href="http://www.divx-digest.com/software/mov2avi.html" target="_blank">http://www.divx-digest.com/software/mov2avi.html</a> - konverter mov filer til avi<br>
</li><li>iTunes <a href="http://itunes.com" target="_blank">http://itunes.com</a> - Afspilning af lyd og video<br></li></ul><br>
<b><u>System</u></b><br>
<ul><li>AutoResizer - <a href="http://www.southbaypc.com/AutoSizer" target="_blank">http://www.southbaypc.com/AutoSizer</a> - bestem hvilke programmer der skal åbne i fuld skærm<br>
</li><li>FileZilla - <a href="http://sourceforge.net/project/showfiles.php?group_id=21558" target="_blank">http://sourceforge.net/project/showfiles.php?group_id=21558</a> - FTP klient<br>
</li><li>SmartFTP - <a href="http://www.smartftp.com" target="_blank">http://www.smartftp.com</a> - FTP klient<br>
</li><li>CesarFTP - <a href="http://www.aclogic.com" target="_blank">http://www.aclogic.com</a> - FTP server <br>
</li><li>MS Powertoys - <a href="http://www.microsoft.com/windowsxp/downloads/powertoys/xppowertoys.mspx" target="_blank">http://www.microsoft.com/windowsxp/downl...ppowertoys.mspx</a> - Forskellige hjælpeprogrammer til Windows<br>
</li><li>MS Bootvis - <a href="http://www.majorgeeks.com/download.php?det=664" target="_blank">http://www.majorgeeks.com/download.php?det=664</a> - Program til at optimere din opstart<br>
</li><li>7-Zip - <a href="http://www.7-zip.org" target="_blank">http://www.7-zip.org</a> - Udpakningsprogram til ZIP, RAR, CAB, ISO, osv<br>
</li><li>UltraVNC - <a href="http://ultravnc.sourceforge.net" target="_blank">http://ultravnc.sourceforge.net</a> - Remote Desktop<br>
</li><li>WinMTR - <a href="http://winmtr.sourceforge.net" target="_blank">http://winmtr.sourceforge.net</a> - Pinger en ip 100 gange så man kan finde ud af om ens ping hopper ved en bestemt ip<br>
</li><li>Rambooster - <a href="http://www.sci.fi/%7Eborg/rambooster" target="_blank">http://www.sci.fi/~borg/rambooster</a> - Optimer ram (note: der er stor uenighed om denne slags programmer virker)<br>
</li><li> CDBurner XP Pro - <a href="http://www.cdburnerxp.se" target="_blank">http://www.cdburnerxp.se</a> - godt alternativ til fx nero<br>
</li><li>ImgBurn - <a href="http://www.imgburn.com" target="_blank">http://www.imgburn.com</a> - Brænd .iso, .img osv Bedste program lige til det formål. <br>
</li><li>Litestep - <a href="http://litestep.net" target="_blank">http://litestep.net</a> - Alternativ til Explore<br>
</li><li>Sun Java - <a href="http://www.sun.com/java" target="_blank">http://www.sun.com/java</a> - Java plugin<br>
</li><li>SysInternals - <a href="http://www.sysinternals.com" target="_blank">http://www.sysinternals.com</a> - ??<br>
</li><li>HJsplit - <a href="http://www.freebyte.com/hjsplit" target="_blank">http://www.freebyte.com/hjsplit</a> - Deler dine filer op i mindre og samler igen<br>
</li><li>Empty Temp Folders - <a href="http://www.danish-shareware.dk/soft/emptemp/" target="_blank">http://www.danish-shareware.dk/soft/emptemp/</a> - Program til at holde styr på Cookies og midlertidige filer.<br>
</li><li>PowerMenu - <a href="http://www.veridicus.com/tummy/programming/powermenu/" target="_blank">http://www.veridicus.com/tummy/programming/powermenu/</a> - Kan ændre programmers prioriteter direkte på processlinjen. Kan også ændre deres gennemsigtighed, få dem til at være øverst hele tiden og minimere til systembakken.<br>
</li><li>TPTest - <a href="http://www.internetkvalitetsguide.dk/StreamSpeed_Download.asp" target="_blank">http://www.internetkvalitetsguide.dk/Str...ed_Download.asp</a> - Test hastigheden på din internetforbindelse med IT og telestyrrelsens TPTest<br>
</li><li>Wallpaper Changer - <a href="http://tinnes.org.uk/wallpaper/index.html" target="_blank">http://tinnes.org.uk/wallpaper/index.html</a> - Skift din baggrund hver gang du rebooter automatisk<br>
</li><li>Scanner. - <a href="http://www.steffengerlach.de/freeware/" target="_blank">http://www.steffengerlach.de/freeware/</a> - Harddisk skanner, der gør det let at finde ud af hvor pladsen på harddisken blev af.<br>
</li><li>Therename.- <a href="http://www.herve-thouzard.com/modules/wfsection/article.php?articleid=1" target="_blank">http://www.herve-thouzard.com/modules/wf...php?articleid=1</a> - Batch renamer med masser af muligheder.<br></li></ul><br>
<b><u>Udvikling</u></b><br>
<ul><li>PHPDesigner - <a href="http://www.mpsoftware.dk/phpdesigner.php" target="_blank">http://www.mpsoftware.dk/phpdesigner.php</a> Genialt program til at kode i - syntax highlighting mm<br>
</li><li>Notepad++ <a href="http://notepad-plus.sourceforge.net/uk/site.htm" target="_blank">http://notepad-plus.sourceforge.net/uk/site.htm</a> - En erstatning til den indbygget notepad - giver dig syntax highlighting og mange andre funktioner<br>
</li><li>Stones Webwriter - <a href="http://www.webwriter.dk" target="_blank">http://www.webwriter.dk</a> - Et udmærket WYSIWYG html editor </li></ul></html>
Source: [[Tweak.dk : Software : Liste over gratisprogrammer : Side|http://www.tweak.dk/forum/thread.php?threadid=72780&sid=001f2d5710846f08b5cf83d55c24f3ce]]
<html><b><u>Kontor mm</u></b><br>
<ul><li>OpenOffice - <a href="http://openoffice.org" target="_blank">http://openoffice.org</a> - alternativ til Microsoft Office med alt hvad hjertet kan begære inden for office<br>
</li><li>Firefox – <a href="http://www.mozilla.com/firefox" target="_blank">http://www.mozilla.com/firefox</a> - browser – godt alternativ til IE<br>
</li><li>Thunderbird - <a href="http://www.mozilla.com/thunderbird" target="_blank">http://www.mozilla.com/thunderbird</a> - e-mail klient med RSS reader og effektivt spamfilter system<br>
</li><li>Opera - <a href="http://www.opera.com" target="_blank">http://www.opera.com</a> - Et andet gratis browser alternativ<br>
</li><li> Feedreader (RSS) - <a href="http://www.feedreader.com" target="_blank">http://www.feedreader.com</a> - RSS feed reader<br>
</li><li> RSS Owl - <a href="http://www.rssowl.org" target="_blank">http://www.rssowl.org</a> - RSS læser<br>
</li><li> Reinlendar - <a href="http://www.rainlendar.net" target="_blank">http://www.rainlendar.net</a> - Desktop-kalender, huskeliste, noter<br>
</li><li>CutePDF - <a href="http://www.cutepdf.com/Products/CutePDF/writer.asp" target="_blank">http://www.cutepdf.com/Products/CutePDF/writer.asp</a> - Lav PDF filer via print menuen<br>
</li><li>Adobe Acrobat Reader - <a href="http://www.adobe.com/dk/products/acrobat/readstep2.html" target="_blank">http://www.adobe.com/dk/products/acrobat/readstep2.html</a> - Læs pdf filer<br>
</li><li>LaTeX - <a href="http://www.latex-project.org" target="_blank">http://www.latex-project.org</a> - tekstbehandling. Men ikke ligesom Word.<br></li></ul><br>
<b><u>Sikkerhed</u></b><br>
<ul><li> Avast Antivirus - <a href="http://www.avast.com/eng/download-avast-home.html" target="_blank">http://www.avast.com/eng/download-avast-home.html</a> – en udmærket gratis antivirus scanner<br>
</li><li>AVG Antivirus - <a href="http://free.grisoft.com/doc/1" target="_blank">http://free.grisoft.com/doc/1</a> - En anden gratis virusscanner<br>
</li><li>Kerio Personal Firewall - <a href="http://www.sunbelt-software.com/Kerio-Download.cfm" target="_blank">http://www.sunbelt-software.com/Kerio-Download.cfm</a> – en rigtig god software firewall<br>
</li><li>Zone alarm - <a href="http://www.zonelabs.com" target="_blank">http://www.zonelabs.com</a> - en anden gratis personlig firewall<br>
</li><li>Ccleaner - <a href="http://www.filehippo.com/download_ccleaner" target="_blank">http://www.filehippo.com/download_ccleaner</a> - Ryd op i dine cookies osv<br>
</li><li>Super Anti Spyware (SAS) - <a href="http://www.superantispyware.com" target="_blank">http://www.superantispyware.com</a> - fjernelse af utøj på Pc'en – gratis udgaven er rigeligt til de fleste<br>
</li><li>Ad Aware - <a href="http://www.lavasoftusa.com" target="_blank">http://www.lavasoftusa.com</a> - Spyware fjerner.<br>
</li><li>Spybot Search & Destroy - <a href="http://www.safer-networking.org" target="_blank">http://www.safer-networking.org</a> - Spyware fjerner.<br>
</li><li>AntiVir antivirus - <a href="http://www.free-av.com" target="_blank">http://www.free-av.com</a> - Tysk antivirus findes på engelsk<br>
</li><li>SPAMfighter - <a href="http://www.spamfighter.com" target="_blank">www.spamfighter.com</a> - Gratis spamfilter til Outlook Express osv. <br>
</li><li>Comodo Personal Firewall - <a href="http://www.comodo.com" target="_blank">www.comodo.com</a> - Firewall til power-brugeren<br>
</li><li>Active Virus Shield - <a href="http://www.activevirusshield.com/antivirus/freeav" target="_blank">http://www.activevirusshield.com/antivirus/freeav</a> - Gratisversion af Kaspersky Antivira<br>
</li><li>Sygate Personal Firewall - <a href="http://www.downloadcentral.dk/file.php?fileid=367" target="_blank">http://www.downloadcentral.dk/file.php?fileid=367</a> - Software firewall<br>
</li><li>StartupList - <a href="http://www.snapfiles.com/get/startuplist.html" target="_blank">http://www.snapfiles.com/get/startuplist.html</a> - Få styr på de programmer der starter op med windows<br>
</li><li>Housecall - <a href="http://housecall.trendmicro.com/" target="_blank">http://housecall.trendmicro.com/</a> - Online virusscanner.<br>
</li><li>Adeona - <a href="http://adeona.cs.washington.edu/index.html%20" target="_blank">http://adeona.cs.washington.edu/index.html </a> - gratis open source trackingsoftware til at installere på din bærbar eller mac laptop, som derefter kan spores hvis den bliver stjålet. Har "snapshot kamera funktion" til mac laptops med indbygget webcam.<br>
<br></li></ul><br>
<b><u>Spil</u></b><br>
<ul><li>Trackmania Nations - <a href="http://www.trackmanianations.com" target="_blank">http://www.trackmanianations.com</a> - Bilspil hvor man kan køre mod mennesker fra alle mulige lande.<br>
</li><li>Wolfenstein: Enemy Territory - <a href="http://enemy-territory.4players.de:1041" target="_blank">http://enemy-territory.4players.de:1041</a> - Gratis FPS<br>
</li><li>The Age of Pirates - <a href="http://www.ageofpirates.co.uk" target="_blank">http://www.ageofpirates.co.uk</a> - online browser baseret spil.<br>
</li><li>Frets On Fire - <a href="http://louhi.kempele.fi/%7Eskyostil/uv/fretsonfire/" target="_blank">http://louhi.kempele.fi/~skyostil/uv/fretsonfire/</a> - Gratis klon af spillet guiatr Hero. Spil guitar med dit keyboard. Flere sange på <a href="http://www.fretsonfire.net." target="_blank">www.fretsonfire.net.</a><br>
</li><li>America's Army: Special Forces - <a href="http://www.americasarmy.com" target="_blank">http://www.americasarmy.com</a> - Det kendte America`s Army - Godt skydespil som kan spilles online<br>
</li><li>FEAR Combat - <a href="http://www.joinfear.com" target="_blank">http://www.joinfear.com</a> - Gratis Multiplayer version af Fear<br>
</li><li>War§ow - <a href="http://www.warsow.net/" target="_blank">http://www.warsow.net/</a> - gratis UT/Quake lign. FPS orienteret mod e-sports. <br></li></ul><br>
<b><u>Chat mm</u></b><br>
<ul><li>GAIM - <a href="http://gaim.sourceforge.net/downloads.php" target="_blank">http://gaim.sourceforge.net/downloads.php</a> - Log på yahoo, icq, msn osv fra et program<br>
</li><li>X-Chat - <a href="http://silverex.info/download" target="_blank">http://silverex.info/download</a> - Gratis IRC klient<br>
</li><li>X-fire - <a href="http://www.xfire.com" target="_blank">www.xfire.com</a> - Chat program der integrere mulighed for at joine de spil som ens kontakter spiller.<br>
</li><li>MSN Messenger - <a href="http://messenger.msn.com" target="_blank">http://messenger.msn.com</a> - populær IM klient<br>
</li><li>ICQ - <a href="http://icq.com" target="_blank">http://icq.com</a> - IM klient der var meget populær i 90erne<br>
</li><li>VZZ-mIrc - <a href="http://www.vzz.dk" target="_blank">http://www.vzz.dk</a> - IRC klient<br>
</li><li>aMSN - <a href="http://sourceforge.net/projects/amsn" target="_blank">http://sourceforge.net/projects/amsn</a> - Multiplatforms MSN klient<br>
</li><li>Skype - <a href="http://www.skype.com" target="_blank">http://www.skype.com</a> - Instant Messaging, Telefoni.<br>
</li><li>Yahoo! Messenger - <a href="http://messenger.yahoo.com/" target="_blank">http://messenger.yahoo.com/</a> - IM klient.<br></li></ul><br>
<b><u>Server software samt moduler</u></b><br>
<ul><li>Apache Webserver - <a href="http://apache.org" target="_blank">http://apache.org</a> - Meget udbredt webserver til mange platforme<br>
</li><li>mySQL - <a href="http://mysql.com" target="_blank">http://mysql.com</a> - Opensource database server, arbejder godt sammen med Apache<br>
</li><li>PHP - <a href="http://php.net" target="_blank">http://php.net</a> - Server side scripting sprog<br>
</li><li>Xitami - <a href="http://xitami.com" target="_blank">http://xitami.com</a> - Lightweight webserver med support for PHP<br>
</li><li>Wampserver - <a href="http://www.wampserver.com" target="_blank">http://www.wampserver.com</a> - Apache, mySQL, PHP mm i en indstallation<br>
</li><li>xampp - <a href="http://www.apachefriends.org/en/xampp-windows.html" target="_blank">http://www.apachefriends.org/en/xampp-windows.html</a> - Apache, mySQL, PHP mm i en indstallation<br>
</li><li>WarFTP Server - <a href="http://www.warftp.org" target="_blank">http://www.warftp.org</a> - Opsæt din egen FTP server<br>
</li><li>Lighttpd - <a href="http://www.lighttpd.net" target="_blank">http://www.lighttpd.net</a> - letvægts webserver<br>
</li><li>phpMyAdmin - <a href="http://www.phpmyadmin.net" target="_blank">http://www.phpmyadmin.net</a> - mySQL frontend - håndter mysql gennem din browser<br></li></ul><br>
<b><u>Andet</u></b><br>
<ul><li>MP3 Book Helper - <a href="http://mp3bookhelper.sourceforge.net" target="_blank">http://mp3bookhelper.sourceforge.net</a> - Sæt ID3 tags i din MP3-samling <br>
</li><li>Mess Patch - <a href="http://mess.be" target="_blank">http://mess.be</a> - Tweak MSN<br>
</li><li>Messenger Plus! Live - <a href="http://www.msgpluslive.net/" target="_blank">http://www.msgpluslive.net/</a> - Tilføjer mange ekstra funktioner til Messenger Live. Note: Under installationen skal man ikke give sin støtte til programmet - ellers installerer den adware. <br>
</li><li>Uxtheme Multi-patcher 5.0 - <a href="http://www.softpedia.com/get/System/OS-Enhancements/UXTheme-MultiPatcher.shtml" target="_blank">http://www.softpedia.com/get/System/OS-E...tiPatcher.shtml</a> - Gør det muligt at bruge tredjeparts temaer til dit Windows XP<br>
</li><li>WinHTTrack - <a href="http://www.httrack.com" target="_blank">http://www.httrack.com</a> - downloader hele hjemmesider<br>
</li><li>Azureus - <a href="http://sourceforge.net/projects/azureus" target="_blank">http://sourceforge.net/projects/azureus</a> - Meget benyttet bittorrentklient.<br>
</li><li>µTorrent - <a href="http://www.utorrent.com" target="_blank">http://www.utorrent.com</a> - Letvægts bittorrentklient<br>
</li><li>a-patch - <a href="http://apatch.org" target="_blank">http://apatch.org</a> - Patch til MSN.<br>
</li><li>DVD Profiler - <a href="http://www.intervocative.com/Downloads.aspx" target="_blank">http://www.intervocative.com/Downloads.aspx</a> - Program til at holde styr på DVD samlingen.<br>
</li><li>Google Toolbar - <a href="http://toolbar.google.com/T4/intl/da/?rd=f" target="_blank">http://toolbar.google.com/T4/intl/da/?rd=f</a> og <a href="http://www.google.com/tools/firefox/toolbar/FT2/intl/da/" target="_blank">http://www.google.com/tools/firefox/toolbar/FT2/intl/da/</a> - Browserplugin til både IE og FF.<br>
</li><li>Google Desktop - <a href="http://desktop.google.com/?promo=mp-gds-v1-1" target="_blank">http://desktop.google.com/?promo=mp-gds-v1-1</a> - Program til søgning på computeren. Fuldtekstsøgning indenfor bl.a. emails, filer, musik, fotos, chats, Gmail, websider, som du har besøgt, m.v.<br>
</li><li>Google Earth - <a href="http://earth.google.com/" target="_blank">http://earth.google.com/</a> - Find dit eget hus, heller et helt andet sted. Planlæg en rejse og få kørselsvejledninger.<br>
</li><li>Google Web Accelerator - <a href="http://webaccelerator.google.com/" target="_blank">http://webaccelerator.google.com/</a> - Sæt fart på din browsing. <br>
</li><li>Adgangforalle Fjernbetjening <a href="http://www.Adgangforalle.dk" target="_blank">http://www.Adgangforalle.dk</a> - Fjernbetjening der kan læse tekeststykker højt. God for ordblinde, dovne mm.<br>
</li><li>Atomic Clock Sync - <a href="http://www.worldtimeserver.com/atomic-clock" target="_blank">http://www.worldtimeserver.com/atomic-clock</a> - Program til at automatisk synkronisere computerens ur med et atomur. </li></ul></html>
Source: [[Tweak.dk : Software : Liste over gratisprogrammer : Side|http://www.tweak.dk/forum/thread.php?threadid=72780&sid=001f2d5710846f08b5cf83d55c24f3ce]]
<html>Da der ikke har været stor success med webapplikationer i denne tråd er disse flyttet til <a href="http://www.tweak.dk/forum/thread.php?threadid=75966&sid=" target="_blank">Hjemmeside Design og kode </a><br>
<br>
<u><b>Internet Browsere</b></u><br>
Add-On's, temaer og andet godt til de forskellige browsere på markedet.<br>
<br>
<u>Firefox</u><br>
<ul><li>Adblock - <a href="https://addons.mozilla.org/firefox/10/" target="_blank">https://addons.mozilla.org/firefox/10/</a> - Fjern reklame - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/adblock/adblock-0.5.3.043-fx+fl+mz+ns.xpi" target="_blank">Installer nu</a><br>
</li><li>Adblock Filterset.G Updater - <a href="https://addons.mozilla.org/firefox/1136/" target="_blank">https://addons.mozilla.org/firefox/1136/</a> - Hold din adblock opdateret med en af de bedste blocklister - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/adblock_filterset.g_updater/adblock_filterset.g_updater-0.3.0.5-fx+fl+mz+ns.xpi" target="_blank">Installer nu </a><br>
</li><li>Adblock Plus - <a href="https://addons.mozilla.org/firefox/1865/" target="_blank">https://addons.mozilla.org/firefox/1865/</a> - Fjern reklame - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/adblock_plus/adblock_plus-0.7.2.4-fx+fl+zm+tb.xpi" target="_blank">Installer nu </a><br>
</li><li>CustomizeGoogle - <a href="https://addons.mozilla.org/firefox/743/" target="_blank">https://addons.mozilla.org/firefox/743/</a> - Modificer google søgeresulater med ekstra info - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/customizegoogle/customizegoogle-0.55-fx+fl.xpi" target="_blank">installer nu </a><br>
</li><li>Download Statusbar - <a href="https://addons.mozilla.org/firefox/26/" target="_blank">https://addons.mozilla.org/firefox/26/</a> - i<a href="http://releases.mozilla.org/pub/mozilla.org/extensions/download_statusbar/download_statusbar-0.9.4.5.1-fx.xpi" target="_blank">nstaller nu </a><br>
</li><li>FasterFox - <a href="https://addons.mozilla.org/firefox/1269/" target="_blank">https://addons.mozilla.org/firefox/1269/</a> - Fart på din firefox - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/fasterfox/fasterfox-2.0.0-fx.xpi" target="_blank">installer nu </a><br>
</li><li>Firefox Extension Backup Extension(FEBE) - <a href="https://addons.mozilla.org/firefox/2109/" target="_blank">https://addons.mozilla.org/firefox/2109/</a> - Tag backup af din Firefox - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/firefox_extension_backup_extension_febe_/firefox_extension_backup_extension_febe_-4.0.4-fx-windows.xpi" target="_blank">Installer nu </a><br>
</li><li>ForecastFox - <a href="https://addons.mozilla.org/firefox/398/" target="_blank">https://addons.mozilla.org/firefox/398/</a> - Få vejret i firefox - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/forecastfox/forecastfox-0.9.3.1-fx+fl+mz+ns+zm.xpi" target="_blank">Installer nu </a><br>
</li><li>Gmail Manager - <a href="https://addons.mozilla.org/firefox/1320/" target="_blank">https://addons.mozilla.org/firefox/1320/</a> - Håndter flere gmailkonti - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/gmail_manager/gmail_manager-0.5.3-fx+fl+mz+ns+zm.xpi" target="_blank">Installer nu </a><br>
</li><li>IE Tab - <a href="https://addons.mozilla.org/firefox/1419/" target="_blank">https://addons.mozilla.org/firefox/1419/</a> - Åben sider i et IE tab i Firefox - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/ie_tab/ie_tab-1.3.0.20070110-fx+fl+mz+zm-windows.xpi" target="_blank">Installer nu </a><br>
</li><li>Tab Mix Plus - <a href="https://addons.mozilla.org/firefox/1122/" target="_blank">https://addons.mozilla.org/firefox/1122/</a> - Lav om på dine tabs - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/tab_mix_plus/tab_mix_plus-0.3.5.2-fx.xpi" target="_blank">installer nu </a><br>
</li><li>VideoDownloader - <a href="https://addons.mozilla.org/firefox/2390/" target="_blank">https://addons.mozilla.org/firefox/2390/</a> - Download videoer fra sider som YouTube, Metacafe, Google video, osv. - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/videodownloader/videodownloader-1.1.1-fx.xpi" target="_blank">Installer nu</a> <br>
</li><li>ChatZilla - <a href="https://addons.mozilla.org/firefox/16/" target="_blank">https://addons.mozilla.org/firefox/16/</a> - Letvægts IRC klient - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/chatzilla/chatzilla-0.9.77-fx+fl+mz+zm.xpi" target="_blank">installer nu</a><br>
</li><li>Firefox Google Bookmarks - <a href="https://addons.mozilla.org/firefox/2448/" target="_blank">https://addons.mozilla.org/firefox/2448/</a> - Hent dine google bookmarks fra enhver computer (kræver google konto) - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/firefox_google_bookmarks/firefox_google_bookmarks-0.2.2-fx+fl.xpi" target="_blank">installer nu </a><br>
</li><li>Webdeveloper toolbar - <a href="https://addons.mozilla.org/firefox/60/" target="_blank">https://addons.mozilla.org/firefox/60/</a> - Forskellige værktøjer til webudviklere/designere - <a href="http://releases.mozilla.org/pub/mozilla.org/extensions/web_developer/web_developer-1.0.2-fx+fl.xpi" target="_blank">installer nu</a></li></ul><br>
<br>
<br>
<u>IE</u><br>
<br>
<br>
<u>Safari</u><br>
<br>
<br>
<u>Opera</u><br>
<ul><li>Opera Widgets - <a href="http://widgets.opera.com/" target="_blank">http://widgets.opera.com/</a> - Mini-programmer, med utallige funktioner. <br>
</li><li>Opera Customize - <a href="http://my.opera.com/community/customize/" target="_blank">http://my.opera.com/community/customize/</a> - Side hvor mange forskellige tilpasningsværktøjer/funktioner kan downloades. <br></li></ul><br>
<br>
<br>
<u>Avant</u><br>
<br>
<br>
<u>Netscape </u></html>
Source: [[Tweak.dk : Software : Liste over gratisprogrammer : Side|http://www.tweak.dk/forum/thread.php?threadid=72780&sid=001f2d5710846f08b5cf83d55c24f3ce]]
<html>Til alle dem som engang imellem savner at køre nogle af de programmer Vista bare ikke vil køre, så har Microsoft frigivet en udgave af Microsoft Virtual Machine 2007 der er Vista kompatibel og GRATIS!!<br>
-jeg stødte på det her:<br>
<a href="http://lifehacker.com/software/windows/g...l-pc-238071.php" target="_blank">http://lifehacker.com/software/windows/g...l-pc-238071.php</a><br>
og her<br>
<a href="http://www.microsoft.com/downloads/detai...&displaylang=en" target="_blank">http://www.microsoft.com/downloads/detai...&displaylang=en</a><br>
og her<br>
<a href="http://www.microsoft.com/windows/product...pc/default.mspx" target="_blank">http://www.microsoft.com/windows/product...pc/default.mspx</a><br>
</html>
Source: [[Tweak.dk : Software : Liste over gratisprogrammer : Side|http://www.tweak.dk/forum/thread.php?threadid=72780&sid=001f2d5710846f08b5cf83d55c24f3ce]]
NB: Silverlight skal installeres i IE - men så virker det også i FF
<html><iframe width="800px" height="900px" frameborder="0" src="http://www.ix-m.com/gps/MoveFullPlayback.aspx?back=1&movieID=35435_14012009233926&embed=1&play=0"></iframe></html>
1. Skriv en sms til mit telefonnr med indholdet: 1234 (Hvis du tilføjer -V optages desuden en 5 min lang video. //Videooptagelse er med lyd - det er almindelig broadcasting ikke//) Stop fjernbetjent broadcast igen: Send blot en sms mere med 1234 [[FriSms|http://m.frisms.dk/index.php]] //vis i siden//: <<option chkFramedLinks>>
2. Skriv maans (name) og 262521 som login klik på Live Link- og du ser et broadcast fra mit kamera + et kort med GPS position.
Hvis jeg har uploadet videoklip kan du klikke på dem fra startsiden og se telefonens GPSposition + evt. rute og hastighed.
Ps: 2 forudsætninger:
*Silverlight skal installeres i IE - men så virker det også i FF
*LiveMediaGPS skal være tændt på min telefon - dvs jeg skal have accepteret at der er internetforbindelse..
Nu skal jeg blot have fundet en måde at fjernaktivere selve programmet LiveMediaGPS på telefonen - så har jeg alletiders vagthund ;-)
<html><iframe width="900px" height="600px" frameborder="0" scrolling="no" src="http://www.ix-m.com/gps"></iframe></html>
<<miniBrowser hidecontrols http://digitalyouth.ischool.berkeley.edu/files/report/digitalyouth-TwoPageSummary.pdf>>
/***
|''Name:''|LoadRemoteFileThroughProxy (previous LoadRemoteFileHijack)|
|''Description:''|When the TiddlyWiki file is located on the web (view over http) the content of [[SiteProxy]] tiddler is added in front of the file url. If [[SiteProxy]] does not exist "/proxy/" is added. |
|''Version:''|1.1.0|
|''Date:''|mar 17, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#LoadRemoteFileHijack|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
***/
//{{{
version.extensions.LoadRemoteFileThroughProxy = {
major: 1, minor: 1, revision: 0,
date: new Date("mar 17, 2007"),
source: "http://tiddlywiki.bidix.info/#LoadRemoteFileThroughProxy"};
if (!window.bidix) window.bidix = {}; // bidix namespace
if (!bidix.core) bidix.core = {};
bidix.core.loadRemoteFile = loadRemoteFile;
loadRemoteFile = function(url,callback,params)
{
if ((document.location.toString().substr(0,4) == "http") && (url.substr(0,4) == "http")){
url = store.getTiddlerText("SiteProxy", "/proxy/") + url;
}
return bidix.core.loadRemoteFile(url,callback,params);
}
//}}}
Dette er mit offentlige chatterfeed
<html><div align="center"><iframe src="http://mail.h-u.dk/mailadmin/users/login.php" frameborder="0" width="100%" height="375"></iframe></div></html>
<html><div align="center"><iframe src="http://mail.h-u.dk/mailadmin/login.php" frameborder="0" width="100%" height="375"></iframe></div></html>
{{bluey{Emne indeks}}}@@padding-left:0.5em;font-size:7pt;<script label="(genopfrisk)">
story.forEachTiddler(function(t,e)
{story.refreshTiddler(t,null,true)});
refreshDisplay();
return false;
</script>@@
<<forEachTiddler
where
'tiddler.tags.contains("Emner")'
script
'
function getFirstLine(s) {
var m = s.match(/\s*(.*)/);
return m != null && m.length >= 1 ? m[1] : "";
}
'
write
'getFirstLine(tiddler.text)'
>>
----
[img[alt_text|http://maans.newp.dk/Billeder/images/notebook.gif]]
Signér med <<option txtUserName>>
*[[TiddlyChatter]]
iframes +++
iFrames:<<forEachTiddler where 'tiddler.tags.contains("iframe")>>===<br><<slider chktagSky tagSky "Tags »">>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<script type="text/javascript" src="http://maans.newp.dk/fckeditor/fckeditor.js"></script>
<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>Edb Noter</b> er i gang med at loade<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Bruger Javascript - bedst i Firefox.</span>
<link rel="shortcut icon" href="http://files.getdropbox.com/u/1064531/icon.png" type="image/vnd.microsoft.icon" />
<link rel="icon" href="http://files.getdropbox.com/u/1064531/icon.png" type="image/vnd.microsoft.icon" /> </div>
<!--}}}-->
/***
|Name|MenuEditPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#MenuEditPlugin|
|Version|0.2|
|Requires|~TW2.x|
!Description:
Adds 'doubleclick to edit source' to the MainMenu, SideBarOptions, and SideBarTabs
!History
*20-07-06: version 0.2: hijacked restart, no need to put a macro in the mainMenu anymore.
*28-04-06: version 0.1: working.
!Code
***/
//{{{
window.restart_lewcid_menuedit = restart;
window.restart = function () {
window.restart_lewcid_menuedit();
var menus = new Array("topMenu","sidebarOptions","sidebarTabs","contentFooter","mainMenu");
for(var t=0; t<menus.length; t++){
if (document.getElementById(menus[t]))
{var menu = document.getElementById(menus[t]);
menu.ondblclick = window.onMenuDblClick;}}
}
window.onMenuDblClick = function(e){
if (!e) var e = window.event;
story.displayTiddler(null,this.getAttribute("tiddler"),2,false,null)
e.cancelBubble = true;
if (e.stopPropagation) e.stopPropagation();
return false;
}
//}}}
/***
|Name|MiniBrowserPlugin|
|Source|http://www.TiddlyTools.com/#MiniBrowserPlugin|
|Version|1.4.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|PlayerPlugin (optional, recommended)|
|Overrides||
|Options|##Configuration|
|Description|embedded browser-in-browser with favorites lists and media support|
!!!!!Usage
<<<
{{{<<miniBrowser noplayer expand hidecontrols URL TiddlerName TiddlerName TiddlerName...>>}}}
* ''noplayer'' (optional)<br>disables support for embedded media player (using [[PlayerPlugin]], if installed)
* ''expand'' (optional)<br>displays minibrowser controls on two lines instead of one for increased readability, especially when long titles or URLs are displayed.
* ''hidecontrols'' (optional)<br>hide initial display of minibrowser controls (except for 'show controls' checkbox)<br>//note: if no initial URL is specified, controls will be shown anyway//
* ''URL'' (optional)<br>specifies an initial URL to open when the mini browser is rendered
* ''TiddlerName'', ''TiddlerName''... (optional)<br>indicates one or more tiddlers containing "HR-separated" lists of favorites.<br>//notes: if no tiddler is specified, [[MiniBrowserList]] is used by default. In addition, when adding/deleting favorites, the plugin automatically updates [[MiniBrowserList]], regardless of any alternative lists of favorites stored in separate tiddlers. After changes to [[MiniBrowserList]] are made, you can then use cut/paste to manually move entries from that tiddler into other tiddlers.//
<<<
!!!!!Configuration
<<<
Default mini browser size:
width: <<option txtMiniBrowserWidth>> height: <<option txtMiniBrowserHeight>>
<<<
!!!!!Example
>{{{<<miniBrowser>>}}}<br>{{smallform small{<<miniBrowser>>}}}
>{{{<<miniBrowser expand>>}}}<br>{{smallform small{<<miniBrowser expand>>}}}
>{{{<<miniBrowser hidecontrols http://www.TiddlyWiki.com>>}}}<br>{{smallform small{<<miniBrowser hidecontrols http://www.TiddlyWiki.com>>}}}
!!!!!Revisions
<<<
2008.09.30 [1.4.0] removed hard-coded 8pt fontsize. Added optional "expand" display mode to show controls on two lines instead of one for increased readability.
2008.09.16 [1.3.1] fixed getWikifiedData() when using IE (remove \r and multiple \n)
2008.08.12 [1.3.0] added support for wikifying content from favorites lists to enable use of forEachTiddler or inline script output to generate lists on the fly.
2008.08.06 [1.2.2] corrected size control buttons to use fixed width
2008.04.07 [1.2.1] added txtMiniBrowserWidth and txtMiniBrowserHeight. cleanup init handling (somewhat)
2008.04.06 [1.2.0] added support for specifying initial URL to view (suggested by Richard Berg). When opening a URL, select matching entry (if any) in bookmarks droplist. Added support for hiding minibrowser controls.
2008.01.19 [1.1.0] added support for optional extra favorites lists stored in separate tiddlers
2007.10.15 [1.0.0] combined MiniBrowser and MediaCenter inline scripts and converted to true plugin
2006.03.01 [0.0.0] inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.MiniBrowserPlugin={major: 1, minor: 4, revision: 0, date: new Date(2008,9,30)};
//}}}
//{{{
config.shadowTiddlers.MiniBrowser="<<miniBrowser>>";
//}}}
//{{{
if (config.options.txtMiniBrowserWidth==undefined) config.options.txtMiniBrowserWidth="100%";
if (config.options.txtMiniBrowserHeight==undefined) config.options.txtMiniBrowserHeight="480";
//}}}
//{{{
config.macros.miniBrowser= {
favoritesList:
"MiniBrowserList",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var noPlayer=params[0]&¶ms[0].toLowerCase()=="noplayer"; if (noPlayer) params.shift();
if (!config.macros.player) noPlayer=true; // if PlayerPlugin not installed
var expand=params[0]&¶ms[0].toLowerCase()=="expand"; if (expand) params.shift();
var hideControls=params[0]&¶ms[0].toLowerCase()=="hidecontrols"; if (hideControls) params.shift();
var url=(params[0]&&!store.tiddlerExists(params[0]))?params.shift():"";
hideControls=hideControls&&url.length; // if no initial URL, then show controls anyway
var w=config.options.txtMiniBrowserWidth;
var h=config.options.txtMiniBrowserHeight;
// create form
var guid=new Date().getTime()+Math.random().toString(); // globally unique ID
var html=this.html;
html=html.replace(/%id%/g,guid);
html=html.replace(/%noplayer%/g,noPlayer?"true":"");
html=html.replace(/%hidecontrols%/g,hideControls?"none":"block");
html=html.replace(/%bookmarksize%/g,expand?"70%":"20%");
html=html.replace(/%urlsize%/g,expand?"69.5%":"20%");
html=html.replace(/%linebreak%/g,expand?"<br>":"");
html=html.replace(/%favorites%/g,params[0]||config.macros.miniBrowser.favoritesList);
createTiddlyElement(place,"span").innerHTML=html;
// init form
document.getElementById("minibrowser_controls_"+guid).style.display=hideControls?"none":"block";
document.getElementById("minibrowser_resize_"+guid).style.display=hideControls?"none":"block";
document.getElementById("minibrowser_togglecontrols_"+guid).checked=!hideControls;
document.getElementById("minibrowser_form_"+guid).url.value=url;
document.getElementById("minibrowser_form_"+guid).w.value=w;
document.getElementById("minibrowser_form_"+guid).h.value=h;
if (noPlayer) { // hide "type" list no PlayerPlugin
document.getElementById("minibrowser_type_"+guid).style.display="none";
document.getElementById("minibrowser_url_"+guid).style.width="36%";
}
// load bookmarks droplist from HR-separated tiddler contents
var b=document.getElementById("minibrowser_bookmarks_"+guid);
while (b.options[1]) b.options[1]=null; // clear list but leave 'prompt' item
var p; while (p=params.shift()) this.getFavorites(b,p); // load custom bookmarks
if (b.length<2) this.getFavorites(b,config.macros.miniBrowser.favoritesList); // default list
// load initial URL (if any)
var place=document.getElementById("minibrowser_player_"+guid);
this.load(place,guid,"","",w,h,true,noPlayer);
this.go(document.getElementById("minibrowser_form_"+guid));
},
getFavorites: function(list,tid) {
var txt=store.getTiddlerText(tid); if (!txt||!txt.trim().length) return;
txt=this.getWikifiedData(txt);
var parts=txt.split("\n----\n");
for (var p=0; p<parts.length; p++) {
var lines=parts[p].split("\n");
var label=lines.shift()||""; // 1st line=display text
var value=lines.shift()||""; // 2nd line=item value
var indent=value&&value.length?"\xa0\xa0":"";
list.options[list.length]=new Option(indent+label,value,false,false);
}
},
getWikifiedData: // wikify tiddler content, then extract text WITH newlines and HRs included
function(txt) {
var e=createTiddlyElement(document.body,"div"); wikify(txt,e);
var breaks=e.getElementsByTagName("br");
for (var b=0; b<breaks.length; b++)
breaks[b].parentNode.insertBefore(document.createTextNode("\n"),breaks[b]);
var lines=e.getElementsByTagName("hr");
for (var l=0; l<lines.length; l++)
lines[l].parentNode.insertBefore(document.createTextNode("----\n"),lines[l]);
var items=e.getElementsByTagName("li");
for (var i=0; i<items.length; i++)
items[i].parentNode.insertBefore(document.createTextNode("\n"),items[i]);
var txt=getPlainText(e);
removeNode(e);
return txt.replace(/\r*/g,"").replace(/\n\n/g,"\n");
},
load: function(place,id,type,url,w,h,showcontrols,noPlayer) {
if (noPlayer) {
if (!place) place=document.getElementById(id).parentNode;
place.innerHTML="<iframe name='"+id+"' id='"+id+"' \
src='"+url+"' width='"+w+"' height='"+h+"' \
style='background:#fff;border:1px solid'></iframe>"
} else
config.macros.player.loadURL(place,id,type,url,w,h,showcontrols);
},
go: function(f) {
var url=f.url.value.trim();
if (!url.length) url=f.url.value=f.bookmarks.value.trim();
if (!url.length) { this.done(f); return false; }
var id=f.playerID.value;
document.getElementById("minibrowser_player_"+id).style.display="block";
document.getElementById("minibrowser_controls2_"+id).style.display="block";
this.load(null,id,f.type.value,f.url.value,f.w.value,f.h.value,f.ctrls.checked,f.noPlayer.value=="true");
var matched=false; for (var i=0; i<f.bookmarks.options.length; i++) // select matching bookmark
if (f.bookmarks.options[i].value==url) { f.bookmarks.selectedIndex=i; matched=true; break; }
if (!matched) f.bookmarks.selectedIndex=0;
f.done.disabled=false;
return false;
},
done: function(f) {
var id=f.playerID.value;
this.load(null,id,null,null,f.w.value,0,f.ctrls.checked,f.noPlayer.value=="true");
document.getElementById("minibrowser_player_"+id).style.display="none";
document.getElementById("minibrowser_controls2_"+id).style.display="none";
f.done.disabled=true;
return false;
},
fit: function(place) {
var trim=89; // fudge factor to account for the other controls + padding + borders. ADJUST THIS VALUE TO FIT LAYOUT
var t=story.findContainingTiddler(place);
if (!t) { t=place; while (t && t.className!='floatingPanel') t=t.parentNode; } if (!t) return;
var w="100%"; // horizontal stretching via CSS works, but vertical stretching doesn't... so:
var h=t.offsetHeight-trim; // workaround: get containing panel/tiddler height and subtract "trim" height
var f=place.form;
this.load(null,f.playerID.value,f.type.value,f.url.value,w,h,f.ctrls.checked,f.noPlayer.value=="true"); // reload player with new size
place.form.w.value=w; place.form.h.value=h; // update width/height input fields
},
add: function(place,title) {
var v=place.value; if (!v.length) return;
var d=prompt("Please enter a description for\n"+place.value); if (!d || !d.length) return;
var who=config.options.txtUserName;
var when=new Date();
var tid=store.getTiddler(title);
var txt="%0\n%1\n----\n%2".format([d,v,tid?tid.text:""]);
store.saveTiddler(title,title,txt,who,when,tid?tid.tags:[],tid?tid.fields:{});
if (!tid) story.displayTiddler(story.findContainingTiddler(place),title);
else story.refreshTiddler(title,1,true);
var here=story.findContainingTiddler(place);
if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
},
del: function(place,title) {
var v=place.value; if (!v.length) return;
var d=place.options[place.selectedIndex].text; if (!d.length) return;
if (!confirm("Are you sure you want to remove this favorite?\n\n"+d+"\n"+v)) return;
var tid=store.getTiddler(title); if (!tid) return;
var who=config.options.txtUserName;
var when=new Date();
var pat='%0\n%1\n----\n'.format([d.replace(/\xa0/g,''),v]); var re=new RegExp(pat,"i");
var txt=tid.text.replace(re,"");
store.saveTiddler(title,title,txt,who,when,tid?tid.tags:[],tid?tid.fields:{});
story.refreshTiddler(title,1,true);
var here=story.findContainingTiddler(place);
if (here) story.refreshTiddler(here.getAttribute("tiddler"),1,true);
},
html: "<form id='minibrowser_form_%id%' style='display:block;margin:0;padding:0' onsubmit='return config.macros.miniBrowser.go(this);'><!-- \
--><nobr><input type='hidden' name='playerID' value='%id%'><input type='hidden' name='noPlayer' value='%noplayer%'><!-- \
--><div id='minibrowser_controls_%id%' style='display:%hidecontrols%'><!-- \
--><input type='button' value='<' title='back' style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].history.go(-1)}catch(e){window.history.go(-1)}' ><!-- \
--><input type='button' value='>' title='forward' style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].history.go(+1)}catch(e){window.history.go(+1)}'><!-- \
--><input type='button' value='+' title='refresh'style='width:3%' \
onclick='try{window.frames[\"player_%id%\"].location.reload()}catch(e){;}'><!-- \
--><input type='button' value='x' title='stop'style='width:3%' \
onclick='window.stop()'><!-- \
--><select name='bookmarks' id='minibrowser_bookmarks_%id%' size='1' style='width:%bookmarksize%' \
onchange='this.form.url.value=this.value; return config.macros.miniBrowser.go(this.form);'><!-- \
--><option value=''>bookmarks...</option><!-- \
--></select><!-- \
--><input type='button' value='add' title='add URL to the bookmarks' style='width:6%' \
favorites=\"%favorites%\" \
onclick='config.macros.miniBrowser.add(this.form.url,this.getAttribute(\"favorites\"));'><!-- \
--><input type='button' value='del' title='remove URL from the bookmarks' style='width:6%' \
favorites=\"%favorites%\" \
onclick='config.macros.miniBrowser.del(this.form.bookmarks,this.getAttribute(\"favorites\"));'><!-- \
--><input type='button' value='edit' title='edit the bookmarks list' style='width:6%' \
favorites=\"%favorites%\" \
onclick='story.displayTiddler(null,this.getAttribute(\"favorites\"),2)'><!-- \
-->%linebreak%<!-- \
--><select name='type' id='minibrowser_type_%id%' size='1' style='width:12%' \
onchange='var opt=this.options; for (var i=0; i<opt.length; i++) \
if (i==this.selectedIndex) opt[i].text=opt[i].text.replace(/\xa0\xa0/,\"√\"); \
else opt[i].text=opt[i].text.replace(/√/,\"\xa0\xa0\"); \
if (this.selectedIndex==0) opt[1].text=opt[1].text.replace(/\xa0\xa0/,\"√\");'><!-- \
--><option value=''>type...</option><!-- \
--><option value=''>√ auto-detect</option><!-- \
--><option value='iframe'> web page</option><!-- \
--><option value='windows'> windows media</option><!-- \
--><option value='realone'> real one</option><!-- \
--><option value='quicktime'> quicktime</option><!-- \
--><option value='flash'> flash</option><!-- \
--><option value='image'> jpg/gif/png</option><!-- \
--></select><!-- \
--><input type='text' name='url' id='minibrowser_url_%id%' size='60' value='' style='width:%urlsize%' \
onfocus='this.select()'><!-- \
--><input type='submit' value='go' title='view URL in embedded player' style='width:6%'><!-- \
--><input type='button' value='open' title='view URL in a separate player' style='width:6%' \
onclick='if (this.form.url.value.length) window.open(this.form.url.value)'><!-- \
--><input type='button' value='done' name='done' disabled title='disconnect from URL' style='width:6%' \
onclick='return config.macros.miniBrowser.done(this.form);'><!-- \
--></div><!-- \
--><div id='minibrowser_player_%id%' style='display:none;text-align:center'></div><!-- \
--><span id='minibrowser_controls2_%id%' style='margin-top:2px;display:none;'><!-- \
--><div id='minibrowser_resize_%id%' style='display:%hidecontrols%;float:right'><!-- \
--> size: <input type='text' name='w' size='3' value='' style='' \
onfocus='this.select()'><!-- \
-->x<input type='text' name='h' size='3' value='' style='' \
onfocus='this.select()'><!-- \
--> <input type='submit' value='set' style='width:5em' \
onclick='var f=this.form; \
if(!f.w.value.trim().length) f.w.value=config.options.txtMiniBrowserWidth; \
if(!f.h.value.trim().length) f.h.value=config.options.txtMiniBrowserHeight; \
config.options.txtMiniBrowserWidth=f.w.value; config.options.txtMiniBrowserHeight=f.h.value; \
saveOptionCookie(\"txtMiniBrowserWidth\"); saveOptionCookie(\"txtMiniBrowserHeight\");'><!-- \
--><input type='submit' value='reset' style='width:5em' \
onclick='var f=this.form; f.ctrls.checked=true; f.w.value=\"100%\"; f.h.value=\"480\"; \
config.options.txtMiniBrowserWidth=f.w.value; config.options.txtMiniBrowserHeight=f.h.value; \
saveOptionCookie(\"txtMiniBrowserWidth\"); saveOptionCookie(\"txtMiniBrowserHeight\");'><!-- \
--><input type='button' value='fit' title='resize player to fit containing window' style='width:5em' \
onclick='config.macros.miniBrowser.fit(this)'><!-- \
--></div><!-- \
--> <input type='checkbox' name='ctrls' id='minibrowser_togglecontrols_%id%' title='toggle minibrowser controls' CHECKED \
onclick='document.getElementById(\"minibrowser_controls_%id%\").style.display=this.checked?\"block\":\"none\"; \
document.getElementById(\"minibrowser_resize_%id%\").style.display=this.checked?\"block\":\"none\";' \
><a href='' title='toggle minibrowser controls' \
onclick='this.previousSibling.click();return false;'>show controls</a><!-- \
--></span><!-- \
--></nobr></form> \
"
}
//}}}
[[MixedInk|http://www.mixedink.com/main.php]] - Skriv og bedøm materialer sammen (video) (overs.: Måns og Google translate)
Skrevet af Allen Stern - November 12, 2008
[[MixedInk|http://www.mixedink.com/main.php]] er et værktøj som selskabet beskriver således: "tillader store grupper at brainstorme sammen og skabe et endeligt, mest populært dokument." Ud fra hvad jeg kan fortælle, skriver du nogle ord i et vindue og derefter viser [[MixedInk|http://www.mixedink.com/main.php]] dig relateret indhold, som du kan trække ind i dit dokument. Når du har trukket indhold ind i dit dokument, redigerer og publicerer du det. Nu kan folk stemme på dit dokument og hjælpe netværket med at skabe det mest populære dokument ved at "planke". Typer af indhold på [[MixedInk|http://www.mixedink.com/main.php]] kaldes "planks".
|<<tiddler MixedInkMeetup>>|<<tiddler MixedInkDemo>>|
<html><object width="400" height="302"><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=2674991&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" /><embed src="http://vimeo.com/moogaloop.swf?clip_id=2674991&server=vimeo.com&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="400" height="302"></embed></object><br /><a href="http://vimeo.com/">MixedInk Demo</a> from <a href="http://vimeo.com/user884270">MixedInk</a> on <a href="http://vimeo.com">Vimeo</a>.</html>
<html></p><p align="center">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" id="viddler_475e24d9" width="545" height="451"><param name="movie" value="http://www.viddler.com/player/475e24d9/"><param name="allowScriptAccess" value="always"><param name="allowFullScreen" value="true"><embed src="http://www.viddler.com/player/475e24d9/" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" name="viddler_475e24d9" width="545" height="451"></object>
</p>
<div class="outbrain_rating">
<script language="JavaScript">
var OutbrainPermaLink = 'http://www.centernetworks.com/mixedink';
var OB_demoMode = false;
var OB_langJS = 'http://widgets.outbrain.com/lang_en_cn.js';
var OB_showRec = true;
var OB_self_posts = true;
if ( typeof(OB_Script)!='undefined' )
OutbrainStart();
else
{
var OB_Script = true;
var str = "<script src='http://widgets.outbrain.com/OutbrainRater.js' type='text/javascript'></"+"script>";
document.write(str);
}
</script><span class="outbrainGlobalClass"></span><div id="outbrain_container_1_bottom" class="div-wrapper" style="padding: 0pt 0pt 5px; clear: both;"><div class="voterDiv" style="display: block;" id="OutbrainVoterDiv_1_bottom"><table class="table-css" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; border-spacing: 0px; width: 100%;" border="0" cellpadding="0" cellspacing="0"><tbody style="border: medium none ; width: 100%;" class="outbrain-tbody-css"><tr style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; border-spacing: 0px; width: 100%; vertical-align: middle;"><td style="border: medium none ; margin: 0pt; padding: 5px 0pt 0pt; background: transparent none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; border-spacing: 0px; width: 100px; vertical-align: middle;"><div id="rates_1_bottom" class="rates" style="margin: 0pt; padding: 0pt; background: transparent url(http://widgets.outbrain.com/matrix.png) repeat scroll -672px top; height: 30px; width: 96px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><div class="star-span" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; position: static; float: left; border-spacing: 0px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: pointer; width: 19px; height: 30px; line-height: 30px;" _vote="1" onmouseout="outbrain_template_manager.templates[0].mouseOutSpan(0,1);" onclick="outbrain_template_manager.templates[0].mouseClicked(this,1);" onmouseover="outbrain_template_manager.templates[0].mouseOverSpan(0,this,1);"> </div><div class="star-span" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; position: static; float: left; border-spacing: 0px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: pointer; width: 19px; height: 30px; line-height: 30px;" _vote="2" onmouseout="outbrain_template_manager.templates[0].mouseOutSpan(0,1);" onclick="outbrain_template_manager.templates[0].mouseClicked(this,1);" onmouseover="outbrain_template_manager.templates[0].mouseOverSpan(0,this,1);"> </div><div class="star-span" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; position: static; float: left; border-spacing: 0px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: pointer; width: 19px; height: 30px; line-height: 30px;" _vote="3" onmouseout="outbrain_template_manager.templates[0].mouseOutSpan(0,1);" onclick="outbrain_template_manager.templates[0].mouseClicked(this,1);" onmouseover="outbrain_template_manager.templates[0].mouseOverSpan(0,this,1);"> </div><div class="star-span" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; position: static; float: left; border-spacing: 0px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: pointer; width: 19px; height: 30px; line-height: 30px;" _vote="4" onmouseout="outbrain_template_manager.templates[0].mouseOutSpan(0,1);" onclick="outbrain_template_manager.templates[0].mouseClicked(this,1);" onmouseover="outbrain_template_manager.templates[0].mouseOverSpan(0,this,1);"> </div><div class="star-span" style="border: medium none ; margin: 0pt; padding: 0pt; background: transparent none repeat scroll 0% 0%; position: static; float: left; border-spacing: 0px; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; cursor: pointer; width: 19px; height: 30px; line-height: 30px;" _vote="5" onmouseout="outbrain_template_manager.templates[0].mouseOutSpan(0,1);" onclick="outbrain_template_manager.templates[0].mouseClicked(this,1);" onmouseover="outbrain_template_manager.templates[0].mouseOverSpan(0,this,1);"> </div></div></td></tr></tbody></table></div></div></div></span></div></html>
Kilde: [[meetup : CenterNetworks|http://www.centernetworks.com/tag/meetup]]
[[Download MiniRelay|http://www.netvicious.com/miniRelay/miniRelay.zip]]
[[Hjemmeside (klik på link)|http://www.pendriveapps.com/portable-smtp-server-mini-relay/]]
miniRelay is a free and very easy little personal smtp server to send mails out of our machine without use our ISP smtp server that could have limits of mail size or other one.
You only need to configure in your mail client the smtp server as 127.0.0.1. Before sending an email you should have miniRelay started.
Kilde: [[miniRelay 0.9.77d free download|http://freewareapp.com/minirelay_download/]]
Dokumentation:
<html><div align="center"><iframe src="http://www.blat.net/miniRelay/docs.html" frameborder="0" width="100%" height="600"></iframe></div></html>
Se her: [[Cell Phones - Time to Lift the Ban on Mobiles in the School Setting?|http://www.openeducation.net/2009/02/08/cell-phones-time-to-lift-the-ban-on-mobiles-in-the-school-setting/]]
eller her (pdf-fil - //højreklik for at downloade//): [[How mobile phones help learning in secondary schools|http://emergingtechnologies.becta.org.uk/upload-dir/downloads/page_documents/research/lsri_report.pdf]]
<<slider chksliderkommentarer kommentarer "Tråd »">>
Mvh MM
<html><object width="480" height="360"><param name="movie" value="http://voicethread.com/book.swf?b=361062"></param><param name="wmode" value="transparent"></param><embed src="http://voicethread.com/book.swf?b=361062" type="application/x-shockwave-flash" wmode="transparent" width="480" height="360"></embed></object><img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzUzMDczMTY*NjMmcHQ9MTIzNTMwNzMyMDgyMSZwPTIwNjQyMSZkPWIzNjEwNjImZz*yJnQ9Jm89NmVkNzVkOWJiNTEwNDk4Nzg2MTMyYzcyM2NhNTg1MDI=.gif" /></html>
<html><p>Hej<br /><br />Jeg har installeret Moodle og Claroline/ny udgave (privat)<br />De kan ses/afprøves her<br /><br /><br /> <a target="_blank" href="http://m&aring;ns.dk/moodle">http://måns.dk/moodle</a><br /> <a target="_blank" href="http://m&aring;ns.dk/claroline">http://måns.dk/claroline</a><br /><br />Her er en side med instruktionsvideoer i [[hvordan man bruger Moodle|http://surferjet.com/onlineclasses/Moodle/Moodle.htm]].<br /><br />Og en blog med flere ressourcer: [[Human &raquo; Moodle tutorials (2 Minute Moodles)|http://human.edublogs.org/moodle-tutorials-2-minute-moodles/]]<br /><br />Jeg har vedh&aelig;ftet en powerpointpr&aelig;sentation - som kan redigeres og<br />&aelig;ndres s&aring; den passer til os.<br /><br />Det er et forsøg på at beskrive Moodles muligheder med Legoklodser!<br /><br />Jeg har også uploadet [[præsentationen til VoiceThread|http://voicethread.com/share/361062/]] - så kan man<br />kommentere de enkelte slides et fælles sted (Voicethread kræver at<br />man laver en bruger for at kunne kommentere - I kan bare bruge<br /><a href="http://h-u.dk/webmail/src/compose.php?send_to=mama%40himmerlands-ungdomsskole.dk">mama@himmerlands-ungdomsskole.dk</a> + havbro - I skal blot huske at lave<br />en ny identitet - så alle ikke tror at det kun er mig som<br />kommenterer....</p><</html><<tiddler Moodle>>
[[Kilde:|http://www.youtube.com/watch?v=WvCIv5KCbeE]]<html><div align="center"><iframe src="http://www.youtube.com/watch?v=WvCIv5KCbeE" frameborder="0" width="100%" height="600"></iframe></div></html>
<html><center><object width="560" height="340"><param name="movie" value="http://www.youtube.com/v/WvCIv5KCbeE&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/WvCIv5KCbeE&hl=en&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"></embed></object></center></html>
Allans oplæg:
<<getTiddlerPassword fredslund>>
Mine spørgsmål:
# SkolePlan & EdbBrugsen?
# Vores internetforbindelse - isdn eller fax - asdl - lysleder??
# Trådløst til alle?
# Brugere - elever/lærere
# Infosystem..
# Undervisningsportal
# Support - teknikere
# Indkøb - langtidsplanlægning
# Andet...
<<siteMap [[Møder]] . sliders>>
/***
''NestedSlidersPlugin for TiddlyWiki version 1.2.x and 2.0''
^^author: Eric Shulman
source: http://www.TiddlyTools.com/#NestedSlidersPlugin
license: [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]^^
Quickly make any tiddler content into an expandable 'slider' panel, without needing to create a separate tiddler to contain the slider content. Optional syntax allows ''default to open'', ''custom button label/tooltip'' and ''automatic blockquote formatting.''
You can also 'nest' these sliders as deep as you like (see complex nesting example below), so that expandable 'tree-like' hierarchical displays can be created. This is most useful when converting existing in-line text content to create in-line annotations, footnotes, context-sensitive help, or other subordinate information displays.
For more details, please click on a section headline below:
++++!!!!![Configuration]>
Debugging messages for 'lazy sliders' deferred rendering:
<<option chkDebugLazySliderDefer>> show debugging alert when deferring slider rendering
<<option chkDebugLazySliderRender>> show debugging alert when deferred slider is actually rendered
===
++++!!!!![Usage]>
When installed, this plugin adds new wiki syntax for embedding 'slider' panels directly into tiddler content. Use {{{+++}}} and {{{===}}} to delimit the slider content. Additional optional syntax elements let you specify
*default to open
*cookiename
*heading level
*floater (with optional CSS width value)
*mouse auto rollover
*custom label/tooltip/accesskey
*automatic blockquote
*deferred rendering
The complete syntax, using all options, is:
//{{{
++++(cookiename)!!!!!^width^*[label=key|tooltip]>...
content goes here
===
//}}}
where:
* {{{+++}}} (or {{{++++}}}) and {{{===}}}^^
marks the start and end of the slider definition, respectively. When the extra {{{+}}} is used, the slider will be open when initially displayed.^^
* {{{(cookiename)}}}^^
saves the slider opened/closed state, and restores this state whenever the slider is re-rendered.^^
* {{{!}}} through {{{!!!!!}}}^^
displays the slider label using a formatted headline (Hn) style instead of a button/link style^^
* {{{^width^}}} (or just {{{^}}})^^
makes the slider 'float' on top of other content rather than shifting that content downward. 'width' must be a valid CSS value (e.g., "30em", "180px", "50%", etc.). If omitted, the default width is "auto" (i.e., fit to content)^^
* {{{*}}}^^
automatically opens/closes slider on "rollover" as well as when clicked^^
* {{{[label=key|tooltip]}}}^^
uses custom label/tooltip/accesskey. {{{=key}}} and {{{|tooltip}}} are optional. 'key' is must be a ''single letter only''. Default labels/tootips are: ">" (more) and "<" (less), with no default access key assignment.^^
* {{{">"}}} //(without the quotes)//^^
automatically adds blockquote formatting to slider content^^
* {{{"..."}}} //(without the quotes)//^^
defers rendering of closed sliders until the first time they are opened. //Note: deferred rendering may produce unexpected results in some cases. Use with care.//^^
//Note: to make slider definitions easier to read and recognize when editing a tiddler, newlines immediately following the {{{+++}}} 'start slider' or preceding the {{{===}}} 'end slider' sequence are automatically supressed so that excess whitespace is eliminated from the output.//
===
++++!!!!![Examples]>
simple in-line slider:
{{{
+++
content
===
}}}
+++
content
===
----
use a custom label and tooltip:
{{{
+++[label|tooltip]
content
===
}}}
+++[label|tooltip]
content
===
----
content automatically blockquoted:
{{{
+++>
content
===
}}}
+++>
content
===
----
all options combined //(default open, cookie, heading, sized floater, rollover, label/tooltip/key, blockquoted, deferred)//
{{{
++++(testcookie)!!!^30em^*[label=Z|click or press Alt-Z to open]>...
content
===
}}}
++++(testcookie)!!!^30em^*[label=Z|click or press Alt-Z to open]>...
content
===
----
complex nesting example:
{{{
+++^[get info...=I|click for information or press Alt-I]
put some general information here, plus a floating slider with more specific info:
+++^10em^[view details...|click for details]
put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
===
===
}}}
+++^[get info...=I|click for information or press Alt-I]
put some general information here, plus a floating slider with more specific info:
+++^10em^[view details...|click for details]
put some detail here, which could include a rollover with a +++^25em^*[glossary definition]explaining technical terms===
===
===
----
nested floaters
>menu: <<tiddler NestedSlidersExample>>
(see [[NestedSlidersExample]] for definition)
----
===
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''NestedSlidersPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
''2006.05.11 - 1.9.0'' added optional '^width^' syntax for floating sliders and '=key' syntax for setting an access key on a slider label
''2006.05.09 - 1.8.0'' in onClickNestedSlider(), when showing panel, set focus to first child input/textarea/select element
''2006.04.24 - 1.7.8'' in adjustSliderPos(), if floating panel is contained inside another floating panel, subtract offset of containing panel to find correct position
''2006.02.16 - 1.7.7'' corrected deferred rendering to account for use-case where show/hide state is tracked in a cookie
''2006.02.15 - 1.7.6'' in adjustSliderPos(), ensure that floating panel is positioned completely within the browser window (i.e., does not go beyond the right edge of the browser window)
''2006.02.04 - 1.7.5'' add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
''2006.01.18 - 1.7.4'' only define adjustSliderPos() function if it has not already been provided by another plugin. This lets other plugins 'hijack' the function even when they are loaded first.
''2006.01.16 - 1.7.3'' added adjustSliderPos(place,btn,panel,panelClass) function to permit specialized logic for placement of floating panels. While it provides improved placement for many uses of floating panels, it exhibits a relative offset positioning error when used within *nested* floating panels. Short-term workaround is to only adjust the position for 'top-level' floaters.
''2006.01.16 - 1.7.2'' added button property to slider panel elements so that slider panel can tell which button it belongs to. Also, re-activated and corrected animation handling so that nested sliders aren't clipped by hijacking Slider.prototype.stop so that "overflow:hidden" can be reset to "overflow:visible" after animation ends
''2006.01.14 - 1.7.1'' added optional "^" syntax for floating panels. Defines new CSS class, ".floatingPanel", as an alternative for standard in-line ".sliderPanel" styles.
''2006.01.14 - 1.7.0'' added optional "*" syntax for rollover handling to show/hide slider without requiring a click (Based on a suggestion by tw4efl)
''2006.01.03 - 1.6.2'' When using optional "!" heading style, instead of creating a clickable "Hn" element, create an "A" element inside the "Hn" element. (allows click-through in SlideShowPlugin, which captures nearly all click events, except for hyperlinks)
''2005.12.15 - 1.6.1'' added optional "..." syntax to invoke deferred ('lazy') rendering for initially hidden sliders
removed checkbox option for 'global' application of lazy sliders
''2005.11.25 - 1.6.0'' added optional handling for 'lazy sliders' (deferred rendering for initially hidden sliders)
''2005.11.21 - 1.5.1'' revised regular expressions: if present, a single newline //preceding// and/or //following// a slider definition will be suppressed so start/end syntax can be place on separate lines in the tiddler 'source' for improved readability. Similarly, any whitespace (newlines, tabs, spaces, etc.) trailing the 'start slider' syntax or preceding the 'end slider' syntax is also suppressed.
''2005.11.20 - 1.5.0'' added (cookiename) syntax for optional tracking and restoring of slider open/close state
''2005.11.11 - 1.4.0'' added !!!!! syntax to render slider label as a header (Hn) style instead of a button/link style
''2005.11.07 - 1.3.0'' removed alternative syntax {{{(((}}} and {{{)))}}} (so they can be used by other
formatting extensions) and simplified/improved regular expressions to trim multiple excess newlines
''2005.11.05 - 1.2.1'' changed name to NestedSlidersPlugin
more documentation
''2005.11.04 - 1.2.0'' added alternative character-mode syntax {{{(((}}} and {{{)))}}}
tweaked "eat newlines" logic for line-mode {{{+++}}} and {{{===}}} syntax
''2005.11.03 - 1.1.1'' fixed toggling of default tooltips ("more..." and "less...") when a non-default button label is used
code cleanup, added documentation
''2005.11.03 - 1.1.0'' changed delimiter syntax from {{{(((}}} and {{{)))}}} to {{{+++}}} and {{{===}}}
changed name to EasySlidersPlugin
''2005.11.03 - 1.0.0'' initial public release
<<<
!!!!!Credits
<<<
This feature was implemented by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]] with initial research and suggestions from RodneyGomes, GeoffSlocock, and PaulPetterson.
<<<
!!!!!Code
***/
//{{{
version.extensions.nestedSliders = {major: 1, minor: 9, revision: 0, date: new Date(2006,5,11)};
//}}}
//{{{
// options for deferred rendering of sliders that are not initially displayed
if (config.options.chkDebugLazySliderDefer==undefined) config.options.chkDebugLazySliderDefer=false;
if (config.options.chkDebugLazySliderRender==undefined) config.options.chkDebugLazySliderRender=false;
// default styles for 'floating' class
setStylesheet(".floatingPanel { position:absolute; z-index:10; padding:0.5em; margin:0em; \
background-color:#eee; color:#000; border:1px solid #000; text-align:left; }","floatingPanelStylesheet");
//}}}
//{{{
config.formatters.push( {
name: "nestedSliders",
match: "\\n?\\+{3}",
terminator: "\\s*\\={3}\\n?",
lookahead: "\\n?\\+{3}(\\+)?(\\([^\\)]*\\))?(\\!*)?(\\^(?:[^\\^\\*\\[\\>]*\\^)?)?(\\*)?(\\[[^\\]]*\\])?(\\>)?(\\.\\.\\.)?\\s*",
handler: 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)
{
// location for rendering button and panel
var place=w.output;
// default to closed, no cookie, no accesskey
var show="none"; var title=" ►"; var tooltip="show"; var cookie=""; var key="";
// extra "+", default to open
if (lookaheadMatch[1])
{ show="block"; title="◄"; tooltip="hide"; }
// cookie, use saved open/closed state
if (lookaheadMatch[2]) {
cookie=lookaheadMatch[2].trim().slice(1,-1);
cookie="chkSlider"+cookie;
if (config.options[cookie]==undefined)
{ config.options[cookie] = (show=="block") }
if (config.options[cookie])
{ show="block"; title="◄"; tooltip="hide"; }
else
{ show="none"; title=" ►"; tooltip="show"; }
}
// parse custom label/tooltip/accesskey: [label=X|tooltip]
if (lookaheadMatch[6]) {
title = lookaheadMatch[6].trim().slice(1,-1);
var pos=title.indexOf("|");
if (pos!=-1) { tooltip = title.substr(pos+1,title.length); title=title.substr(0,pos); }
if (title.substr(title.length-2,1)=="=") { key=title.substr(title.length-1,1); title=title.slice(0,-2); }
if (pos==-1) tooltip += " "+title; // default tooltip: "show/hide <title>"
}
// create the button
if (lookaheadMatch[3]) { // use "Hn" header format instead of button/link
var lvl=(lookaheadMatch[3].length>6)?6:lookaheadMatch[3].length;
var btn = createTiddlyElement(createTiddlyElement(place,"h"+lvl,null,null,null),"a",null,null,title);
btn.onclick=onClickNestedSlider;
btn.setAttribute("href","javascript:;");
btn.setAttribute("title",tooltip);
}
else
var btn = createTiddlyButton(place,title,tooltip,onClickNestedSlider);
btn.sliderCookie = cookie; // save the cookiename (if any) in the button object
btn.keyparam=key; // save the access key letter ("" if none)
if (key.length) {
btn.setAttribute("accessKey",key); // init access key
btn.onfocus=function(){this.setAttribute("accessKey",this.keyparam);}; // **reclaim** access key on focus
}
// "non-click" MouseOver open/close slider
if (lookaheadMatch[5]) btn.onmouseover=onClickNestedSlider;
// create slider panel
var panelClass=lookaheadMatch[4]?"floatingPanel":"sliderPanel";
var panel=createTiddlyElement(place,"div",null,panelClass,null);
panel.style.display = show;
if (lookaheadMatch[4] && lookaheadMatch[4].length>2) panel.style.width=lookaheadMatch[4].slice(1,-1); // custom width
panel.button = btn; // so the slider panel know which button it belongs to
btn.sliderPanel=panel;
// render slider (or defer until shown)
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
if ((show=="block")||!lookaheadMatch[8]) {
// render now if panel is supposed to be shown or NOT deferred rendering
w.subWikify(lookaheadMatch[7]?createTiddlyElement(panel,"blockquote"):panel,this.terminator);
// align slider/floater position with button
adjustSliderPos(place,btn,panel,panelClass);
}
else {
var src = w.source.substr(w.nextMatch);
var endpos=findMatchingDelimiter(src,"+++","===");
panel.setAttribute("raw",src.substr(0,endpos));
panel.setAttribute("blockquote",lookaheadMatch[7]?"true":"false");
panel.setAttribute("rendered","false");
w.nextMatch += endpos+3;
if (w.source.substr(w.nextMatch,1)=="\n") w.nextMatch++;
if (config.options.chkDebugLazySliderDefer) alert("deferred '"+title+"':\n\n"+panel.getAttribute("raw"));
}
}
}
}
)
// TBD: ignore 'quoted' delimiters (e.g., "{{{+++foo===}}}" isn't really a slider)
function findMatchingDelimiter(src,starttext,endtext) {
var startpos = 0;
var endpos = src.indexOf(endtext);
// check for nested delimiters
while (src.substring(startpos,endpos-1).indexOf(starttext)!=-1) {
// count number of nested 'starts'
var startcount=0;
var temp = src.substring(startpos,endpos-1);
var pos=temp.indexOf(starttext);
while (pos!=-1) { startcount++; pos=temp.indexOf(starttext,pos+starttext.length); }
// set up to check for additional 'starts' after adjusting endpos
startpos=endpos+endtext.length;
// find endpos for corresponding number of matching 'ends'
while (startcount && endpos!=-1) {
endpos = src.indexOf(endtext,endpos+endtext.length);
startcount--;
}
}
return (endpos==-1)?src.length:endpos;
}
//}}}
//{{{
window.onClickNestedSlider=function(e)
{
if (!e) var e = window.event;
var theTarget = resolveTarget(e);
var theLabel = theTarget.firstChild.data;
var theSlider = theTarget.sliderPanel
var isOpen = theSlider.style.display!="none";
// if using default button labels, toggle labels
if (theLabel==">") theTarget.firstChild.data = "◄";
else if (theLabel=="<") theTarget.firstChild.data = "►";
// if using default tooltips, toggle tooltips
if (theTarget.getAttribute("title")=="show")
theTarget.setAttribute("title","hide");
else if (theTarget.getAttribute("title")=="hide")
theTarget.setAttribute("title","show");
if (theTarget.getAttribute("title")=="show "+theLabel)
theTarget.setAttribute("title","hide "+theLabel);
else if (theTarget.getAttribute("title")=="hide "+theLabel)
theTarget.setAttribute("title","show "+theLabel);
// deferred rendering (if needed)
if (theSlider.getAttribute("rendered")=="false") {
if (config.options.chkDebugLazySliderRender)
alert("rendering '"+theLabel+"':\n\n"+theSlider.getAttribute("raw"));
var place=theSlider;
if (theSlider.getAttribute("blockquote")=="true")
place=createTiddlyElement(place,"blockquote");
wikify(theSlider.getAttribute("raw"),place);
theSlider.setAttribute("rendered","true");
}
// show/hide the slider
if(config.options.chkAnimate)
anim.startAnimating(new Slider(theSlider,!isOpen,e.shiftKey || e.altKey,"none"));
else
theSlider.style.display = isOpen ? "none" : "block";
// if showing panel, set focus to first 'focus-able' element in panel
if (theSlider.style.display!="none") {
var ctrls=theSlider.getElementsByTagName("*");
for (var c=0; c<ctrls.length; c++) {
var t=ctrls[c].tagName.toLowerCase();
if (t=="input" || t=="textarea" || t=="select")
{ ctrls[c].focus(); break; }
}
}
if (this.sliderCookie && this.sliderCookie.length)
{ config.options[this.sliderCookie]=!isOpen; saveOptionCookie(this.sliderCookie); }
// align slider/floater position with target button
adjustSliderPos(theSlider.parentNode,theTarget,theSlider,theSlider.className);
return false;
}
// hijack animation handler 'stop' handler so overflow is visible after animation has completed
Slider.prototype.coreStop = Slider.prototype.stop;
Slider.prototype.stop = function() { this.coreStop(); this.element.style.overflow = "visible"; }
// adjust panel position based on button position
if (window.adjustSliderPos==undefined) window.adjustSliderPos=function(place,btn,panel,panelClass) {
if (panelClass=="floatingPanel") {
var left=0;
var top=btn.offsetHeight;
if (place.style.position!="relative") {
var left=findPosX(btn);
var top=findPosY(btn)+btn.offsetHeight;
var p=place; while (p && p.className!='floatingPanel') p=p.parentNode;
if (p) { left-=findPosX(p); top-=findPosY(p); }
}
if (left+panel.offsetWidth > getWindowWidth()) left=getWindowWidth()-panel.offsetWidth-10;
panel.style.left=left+"px"; panel.style.top=top+"px";
}
}
function getWindowWidth() {
if(document.width!=undefined)
return document.width; // moz (FF)
if(document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) )
return document.documentElement.clientWidth; // IE6
if(document.body && ( document.body.clientWidth || document.body.clientHeight ) )
return document.body.clientWidth; // IE4
if(window.innerWidth!=undefined)
return window.innerWidth; // IE - general
return 0; // unknown
}
//}}}
a)Hvordan og hvornår skal vores adgang til Internettet og skolens lokale
netværk / portal være?
✗ Trådløst netværk på hele skolen?
✗ Trådløst netværk hele døgnet?
✗ Trådløst netværk i en tidsbegrænset periode?
✗ Elevernes adgang til ovenstående?
✗ Hvad gør andre skoler?
<<comments>>
<html>
<style>
.rolodex table {
border: 0px solid;
background-color:#eeeff;
}
.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
<span class="rolodex">
<table>
<tr>
<td align="right"><b>Forfatter(e):</b></td>
<td colspan="3"><input name=author type=text style="width:300%" /></td></tr>
<tr>
<td align="right"><b>Titel:</b></td>
<td colspan="3"><input name=booktitle type=text style="width:300%" /></td></tr>
<tr>
<td align="right"><b>Bibliografiske data:</b></td>
<td colspan="3"><input name=bibdata type=text style="width:300%" /></td></tr>
<tr>
<td align="right"><b>Tema:</b></td>
<td colspan="3"><input name=primtopic type=text style="width:300%" /></td></tr>
<tr>
<td align="right"><b>Ejer jeg den?</b></td>
<input name=mine type=checkbox /></td></tr>
<tr>
<td align="right"><b>Hvor jeg har den:</b></td>
<td colspan="3"><input name=wherekept type=text style="width:300%" /></td></tr>
<tr>
</span> </html>
! Om bogen/artiklen og links:
/***
|Name:|NewHerePlugin|
|Description:|Creates the new here and new journal macros|
|Version:|3.0 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#NewHerePlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
merge(config.macros, {
newHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newTiddler "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
},
newJournalHere: {
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
wikify("<<newJournal "+paramString+" tag:[["+tiddler.title+"]]>>",place,null,tiddler);
}
}
});
//}}}
<html>
<style>
.rolodex table {
border: 0px solid;
background-color:#eeeff;
}
.rolodex tr, .rolodex td {
border: 0px solid;
}
</style>
<span class="rolodex">
<table>
<tr>
<td align="right"><b>Underemne:</b></td>
<td colspan="3"><input name=notetopic type=text style="width:300%" /></td></tr>
<tr>
<td align="right"><b>Kilde:</b></td>
<td colspan="3"><input name=abpp type=text style="width:300%" /></td></tr>
<tr>
</span> </html>
!Noter
<!--{{{-->
<a style="color: #5566ff">Det ser ud som om du er ved at lave eller ændre en ny note fra bunden og op!<br>
Skriv notens titel i tekstfeltet øverst, og notens tekst herunder. <br>
Tilføj det emne denne note hører under i det næstøverste tekstfelt. <br>
Anvend [[dobbelte firkantede paranteser]] til at omkranse flere-ords emner. <br>
Brug denne drop-down menu:<b><span macro='tagChooser'></span></b> til at vælge dinne nuværende emner og andre tags</a>
<!--}}}-->
/***
|''Name:''|NotesPlugin|
|''Description:''||
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#NotesPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''||
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|
!!Usage:
*
***/
// /%
//!BEGIN-PLUGIN-CODE
function createTiddlyElement(theParent,theElement,theID,theClass,theText,attribs)
{
var e = document.createElement(theElement);
if(theClass != null)
e.className = theClass;
if(theID != null)
e.setAttribute("id",theID);
if(theText != null)
e.appendChild(document.createTextNode(theText));
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent != null)
theParent.appendChild(e);
return e;
}
function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey,attribs)
{
var theButton = document.createElement("a");
if(theAction) {
theButton.onclick = theAction;
theButton.setAttribute("href","javascript:;");
}
if(theTooltip)
theButton.setAttribute("title",theTooltip);
if(theText)
theButton.appendChild(document.createTextNode(theText));
if(theClass)
theButton.className = theClass;
else
theButton.className = "button";
if(theId)
theButton.id = theId;
if(attribs){
for(var n in attribs){
e.setAttribute(n,attribs[n]);
}
}
if(theParent)
theParent.appendChild(theButton);
if(theAccessKey)
theButton.setAttribute("accessKey",theAccessKey);
return theButton;
}
config.macros.notes={
cancelWarning: "Are you sure you want to abandon changes to your notes for '%0'?",
addLabel: "add notes",
editLabel: "edit notes",
editTitle: "double click to edit",
saveLabel: "save notes",
saveTitle: "double click to save",
cancelLabel: "cancel",
heading: "Notes",
suffix: "Notes"+config.options.txtUserName,
tags: "Notes",
saveNotes: function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
if (theTarget.nodeName.toLowerCase() == "textarea")
return false;
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
story.setDirty(title,false);
var box = document.getElementById("notesContainer"+title);
// if 'save notes' is clicked on, notesBox is this.parentNode
var notesBox = this.parentNode;
if (this.getAttribute("noteCount")) {
// if notesBox has been double-clicked, notesBox is this
notesBox = this;
}
var noteCount = notesBox.getAttribute("noteCount");
var textarea = document.getElementById("notesTextArea"+noteCount+title);
if(textarea.getAttribute("oldText")!=textarea.value){
var suffix = box.getAttribute("suffix");
var t = store.getTiddler(title+"-"+suffix+noteCount);
// this line changed to split the tags attribute
store.saveTiddler(title+"-"+suffix+noteCount,title+"-"+suffix+noteCount,textarea.value,config.options.txtUserName,new Date(),t?t.tags:box.getAttribute("tags").split(" "),t?t.fields:{});
}
story.refreshTiddler(title,1,true);
return false;
},
editNotes: function(notesBox,box,tiddler){
removeChildren(notesBox);
story.setDirty(tiddler,true);
notesBox.title = this.saveTitle;
notesBox.ondblclick = this.saveNotes;
// Q: this cancel button doesn't appear to work! Is this what you meant to do?
createTiddlyButton(notesBox,this.cancelLabel,this.cancelLabel,this.saveNotes,"cancelNotesButton");
createTiddlyButton(notesBox,this.saveLabel,this.saveLabel,this.saveNotes,"saveNotesButton");
wikify("!!"+box.getAttribute("heading")+"\n",notesBox);
addClass(notesBox,"editor");
var wrapper1 = createTiddlyElement(null,"fieldset",null,"fieldsetFix");
var wrapper2 = createTiddlyElement(wrapper1,"div");
var e = createTiddlyElement(wrapper2,"textarea","notesTextArea"+notesBox.getAttribute("noteCount")+tiddler);
var v = store.getValue(tiddler+"-"+box.getAttribute("suffix")+notesBox.getAttribute("noteCount"),"text");
if(!v)
v = "";
e.value = v;
e.setAttribute("oldText",v);
var rows = 10;
var lines = v.match(/\n/mg);
var maxLines = Math.max(parseInt(config.options.txtMaxEditRows),5);
if(lines != null && lines.length > rows)
rows = lines.length + 5;
rows = Math.min(rows,maxLines);
e.setAttribute("rows",rows);
notesBox.appendChild(wrapper1);
},
editNotesButtonOnclick: function(e){
var title = story.findContainingTiddler(this).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
var notesBox = this.parentNode;
config.macros.notes.editNotes(notesBox,box,title);
return false;
},
addNotesButtonOnclick: function(e){
var title = story.findContainingTiddler(this).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
var oldNoteCount = box.getAttribute("notesCount");
var notesBox = createTiddlyElement(box,"div",null,"TiddlerNotes",null,{noteCount:oldNoteCount++});
notesBox.ondblclick = config.macros.notes.ondblclick;
removeNode(this);
config.macros.notes.editNotes(notesBox,box,title);
return false;
},
ondblclick : function(ev){
e = ev? ev : window.event;
var theTarget = resolveTarget(e);
var title = story.findContainingTiddler(theTarget).getAttribute("tiddler");
var box = document.getElementById("notesContainer"+title);
var notesBox = this;
config.macros.notes.editNotes(notesBox,box,title);
e.cancelBubble = true;
if(e.stopPropagation) e.stopPropagation();
return false;
},
handler : function(place,macroName,params,wikifier,paramString,tiddler){
params = paramString.parseParams("anon",null,true,false,false);
var heading = getParam(params,"heading",this.heading);
// tags can be a space-separated string of tags
// this parameter allows you to specify an identiying tag for the note
// then we inherit the parent's tags
// when we create the Notes box, we use tags as its tags attribute
var tags_string = getParam(params,"tags",this.tags);
var tags = tags_string.split(" ");
for (var i=0;i<tiddler.tags.length;i++) {
if (!tags.contains(tiddler.tags[i])) {
tags_string += " " + tiddler.tags[i].toString();
}
}
var suffix = getParam(params,"suffix",this.suffix);
// Get the notes tiddlers for this tiddler, count them, make the count an attribute on the box
var notes_tiddlers = store.getTaggedTiddlers("notes");
var notes = [];
var notesCount = 0;
for (var i=0;i<notes_tiddlers.length;i++) {
if (notes_tiddlers[i].title != tiddler.title && notes_tiddlers[i].title.indexOf(tiddler.title) != -1) {
notes.push(notes_tiddlers[i]);
notesCount++;
}
}
// sort the notes by modified date to get the most recent in notes[0]
notes.sort(function(a,b){
return a.modified > b.modified ? -1 : (a.modified == b.modified ? 0 : 1);
});
var box = createTiddlyElement(place,"div","notesContainer"+tiddler.title,"TiddlerNotes",null,{"source":tiddler.title,params:paramString,heading:heading,tags:tags_string,suffix:suffix,notesCount:notesCount});
// if there aren't any notes, show "No notes"
// if there are notes, show "Notes (latest by xxx)"
// if you added the notes, show "Notes (latest by you)"
// REMOVED: var notes_tiddler = store.fetchTiddler(tiddler.title+"-"+suffix);
var heading_extension = "";
if (notes[0] && notes[0].modifier) {
if (notes[0].modifier != config.options.txtUserName) {
heading_extension = " (latest by " + notes[0].modifier + ")";
} else {
heading_extension = " (latest by you)";
}
wikify("!!"+heading+heading_extension+"\n",box);
} else {
wikify("//No notes//\n",box);
}
box.title=this.editTitle;
// These lines unnecessary with createTiddlyElement that takes an object of attributes
//box.setAttribute("source",tiddler.title);
//box.setAttribute("params",paramString);
//box.setAttribute("heading",heading);
//box.setAttribute("tags",tags_string);
//box.setAttribute("suffix",suffix);
// REMOVED: box.ondblclick = this.ondblclick;
for (var i=0;i<notes.length;i++) {
var notesBox = createTiddlyElement(box,"div",null,"TiddlerNotes",null,{noteCount:i});
notesBox.ondblclick = this.ondblclick;
wikify("<<tiddler [["+notes[i].title+"]]>>\n",notesBox);
createTiddlyElement(notesBox,"span",null,"subtitle","at "+notes[i].modified+" by "+notes[i].modifier);
createTiddlyButton(notesBox,this.editLabel,this.editLabel,this.editNotesButtonOnclick,"editNotesButton");
}
// add 'add notes' button
createTiddlyButton(box,this.addLabel,this.addLabel,this.addNotesButtonOnclick,"editNotesButton");
}
};
/* CHANGE: 09/10/07 - not sure why this is needed
Story.prototype.old_notes_closeTiddler = Story.prototype.closeTiddler;
Story.prototype.closeTiddler = function(title,animate,unused){
if(story.isDirty(title)) {
if(!confirm(config.macros.notes.cancelWarning.format([title])))
return false;
}
return this.old_notes_closeTiddler.apply(this,arguments);
}
*/
setStylesheet(".TiddlerNotes {\n"+ " background:#eee;\n"+ " border:1px solid #ccc;\n"+ " padding:10px;\n"+ " margin:15px;\n"+ "}\n"+ "\n"+ ".cancelNotesButton,.editNotesButton, .saveNotesButton {\n"+ " float:right;\n"+ " border:1px solid #ccc;\n"+ " padding:2px 5px;\n"+ "}\n"+ "\n"+ ".saveNotesButton{\n"+ " margin-right:0.5em;\n"+ "}\n"+ "\n"+ ".TiddlerNotes.editor textarea{\n"+ " border:1px solid #ccc;\n"+ "}","NotesPluginStyles");
//sliders
//keyboard shortcuts
// ids..
// ids..
//!END-PLUGIN-CODE
// %/
[img[http://www.modtryk.dk/pngs/titel/9788773948026.png]]<<formTiddler NewBibEntryTemplate>>
<data>{"author":"Jan Guillou","booktitle":"Ondskaben","primtopic":"Ondskab","mine":false,"wherekept":"Jeg har vist givet den væk?!","bibdata":"ISBN: 9788776070014"}</data>
/%
Titel: [[OpenVpnProgram]]
Type: Installationsprogram
!Beskrivelse
Program til at lave vpnforbindelse til skolens netværk.
Kræver certifikat.
[[Hent|http://files.getdropbox.com/u/1064531/openvpn-2.0.9-gui-1.0.3-install.exe]]
!end
%/
<!--{{{-->
<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 id='topMenu'><span class='topMenu' refresh='content' tiddler='TopMenu'></span></div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' force='true' 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:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
major: 1, minor: 0, revision: 2,
date: new Date("Apr 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
coreVersion: '2.2.0 (Beta 5)'
};
config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");
merge(config.macros.option.types, {
'pas': {
elementType: "input",
valueField: "value",
eventName: "onkeyup",
className: "pasOptionInput",
typeValue: config.macros.option.passwordInputType,
create: function(place,type,opt,className,desc) {
// password field
config.macros.option.genericCreate(place,'pas',opt,className,desc);
// checkbox linked with this password "save this password on this computer"
config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);
// text savePasswordCheckboxLabel
place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
},
onChange: config.macros.option.genericOnChange
}
});
merge(config.optionHandlers['chk'], {
get: function(name) {
// is there an option linked with this chk ?
var opt = name.substr(3);
if (config.options[opt])
saveOptionCookie(opt);
return config.options[name] ? "true" : "false";
}
});
merge(config.optionHandlers, {
'pas': {
get: function(name) {
if (config.options["chk"+name]) {
return encodeCookie(config.options[name].toString());
} else {
return "";
}
},
set: function(name,value) {config.options[name] = decodeCookie(value);}
}
});
// need to reload options to load passwordOptions
loadOptionsCookie();
/*
if (!config.options['pasPassword'])
config.options['pasPassword'] = '';
merge(config.optionsDesc,{
pasPassword: "Test password"
});
*/
//}}}
a)Hvordan kommunikerer vi med hinanden, forældre, elever?
b)Hvordan opbevarer / deler vi filer?
c) Hvordan sikrer vi at alle computere taler samme sprog?
✗ Claroline – hvad kan det bruges til – hvad kan det ikke bruges til?
✗ Hjemmesiden?
✗ Wiki? - hvad kan det bruges til – hvad kan det ikke bruges til?
✗ Formål / behov?
✗ Hvad gør andre skoler?
<<comments>>
/***
|Name|QuickEditPlugin|
|Source|http://www.TiddlyTools.com/#QuickEditPlugin|
|Documentation|http://www.TiddlyTools.com/#QuickEditPlugin|
|Version|2.4.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Support functions for ~QuickEdit package: styles, utility functions, and 'toggleQuickEdit' command|
!!!!!Revisions
<<<
2008.09.07 [2.4.1] added removeOptionCookie() function for compatibility with [[CookieManagerPlugin]]
2008.05.17 [2.4.0] copied code from StickyPopupPlugin to remove dependency
2008.05.12 [2.3.0] added "toggleQuickEdit" command handler (replaces inline script command)
2008.01.11 [2.2.0] converted from inline script
2007.03.29 [1.0.0] initial release (as inline script)
<<<
!!!!!Code
***/
//{{{
version.extensions.QuickEditPlugin= {major: 2, minor: 4, revision: 1, date: new Date(2008,9,7)};
// SET STYLESHEET (for toolbar button style)
setStylesheet(".quickEdit a { border:2px outset ButtonFace; -moz-appearance:button; padding:0px 3px; \
background-color:ButtonFace; color:ButtonText !important; line-height:200%; font-weight:normal; }", "quickEditStyles");
// if removeOptionCookie() function is not defined by TW core, define it here.
if (window.removeOptionCookie===undefined) {
window.removeOptionCookie=function(cookie) {
var ex=new Date(); ex.setTime(ex.getTime()-1000); // immediately expire cookie
document.cookie = cookie+"=novalue; path=/; expires="+ex.toGMTString();
}
}
// UTILITY FUNCTIONS
config.quickEdit = {
getField: function(where) {
var here=story.findContainingTiddler(where); if (!here) return null;
var e=story.getTiddlerField(here.getAttribute("tiddler"),"text");
if (e&&e.getAttribute("edit")=="text") return e;
return null;
},
setSelection: function(where,newtext) {
var e=this.getField(where); if (!e) return false;
e.focus(); replaceSelection(e,newtext);
return false;
},
wrapSelection: function(where,before,after) {
var e=this.getField(where); if (!e) return false;
e.focus(); replaceSelection(e,before+config.quickEdit.getSelection(e)+after);
return false;
},
getSelection: function(e) {
var seltext="";
if (e&&e.setSelectionRange)
seltext=e.value.substr(e.selectionStart,e.selectionEnd-e.selectionStart);
else if (document.selection) {
var range = document.selection.createRange();
if (range.parentElement()==e) seltext=range.text
}
return seltext;
},
promptForFilename: function(msg,path,file) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeOpen);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='jpg';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterImages);
if (picker.show()!=nsIFilePicker.returnCancel)
var result="file:///"+picker.file.persistentDescriptor.replace(/\\/g,'/');
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|JPG files|*.jpg|GIF files|*.gif|PNG files|*.png|';
s.FilterIndex=1; // default to JPG files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
}
}
//}}}
//{{{
if (config.options.chkShowQuickEdit===undefined) config.options.chkShowQuickEdit=false;
config.commands.toggleQuickEdit = {
hideReadOnly: true,
getText: function() { return config.options.chkShowQuickEdit?'\u221Aquickedit':'quickedit'; },
tooltip: 'show QuickEdit toolbar buttons',
handler: function(event,src,title) {
config.options.chkShowQuickEdit=!config.options.chkShowQuickEdit;
config.macros.option.propagateOption("chkShowQuickEdit","checked", config.options.chkShowQuickEdit,"input");
// save cookie when toolbar shown, remove cookie when toolbar hidden
if (config.options.chkShowQuickEdit) saveOptionCookie("chkShowQuickEdit");
else removeOptionCookie("chkShowQuickEdit");
// set link and title based on option state
src.innerHTML=config.commands.toggleQuickEdit.getText();
// refresh all actively displayed tiddler editor(s)
story.forEachTiddler(function(t,e){if (story.isDirty(t)) refreshElements(e);});
return false;
}
};
//}}}
// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
Popup.stickyPopup_onDocumentClick = function(ev)
{
// if click is in a sticky popup, ignore it so popup will remain visible
var e = ev ? ev : window.event; var target = resolveTarget(e);
var p=target; while (p) {
if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
else p=p.parentNode;
}
if (!p) // not in sticky popup (or sticky popups disabled)... use normal click handling
Popup.onDocumentClick(ev);
return true;
};
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
/%
|Name|QuickEditToolbar|
|Source|http://www.TiddlyTools.com/#QuickEditToolbar|
|Version|2.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin, InlineJavascriptPlugin|
|Optional|QuickEdit_replace, QuickEdit_split, QuickEdit_link, QuickEdit_macro, QuickEdit_image, QuickEdit_tiddler, QuickEdit_file, QuickEdit_format, QuickEdit_sort|
|Overrides||
|Description|quickly insert TiddlyWiki tiddler links or common formatting sequences directly into tiddler content|
Usage (in EditTemplate): <div macro='tiddler QuickEditToolbar with: show'></div>
where "show" is an OPTIONAL keyword to force the toolbar to be displayed regardless of the current 'toggle' state
%/<<tiddler HideTiddlerTags>>/%
TOOLBAR DEFINITIONS BEGIN HERE...
= = = = = = = = = = = = = = = = =
%/{{hidden fine center quickEdit{
<script>
// note: always show toolbar when directly viewing the tiddler containing the actual toolbar definition!
var here=story.findContainingTiddler(place); if (here) var tid=here.getAttribute("tiddler");
var show="$1"!="$"+"1"||config.options.chkShowQuickEdit||tid=="QuickEditToolbar"
place.style.display=show?"block":"none";
</script>/%
%/<<tiddler QuickEdit_replace>>/%
%/<<tiddler QuickEdit_split>>/%
%/<<tiddler QuickEdit_sort>>/%
%/<<tiddler QuickEdit_tiddler>>/%
%/<<tiddler QuickEdit_file>>/%
%/ /% (SPACER)
%/<<tiddler QuickEdit_format>>/%
%/<<tiddler QuickEdit_align>>/%
%/<<tiddler QuickEdit_color>>/%
%/<<tiddler QuickEdit_font>>/%
%/<<tiddler QuickEdit_css>>/%
%/ /% (SPACER)
%/<<tiddler QuickEdit_link>>/%
%/<<tiddler QuickEdit_macro>>/%
%/<<tiddler QuickEdit_image>>/%
%/}}}
/%
|Name|QuickEdit_align|
|Source|http://www.TiddlyTools.com/#QuickEdit_align|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button for text alignment|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_align>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_align'></span>
**** ALIGNMENT ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="align text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select text alignment...','');
s.onchange=function(){
config.quickEdit.wrapSelection(this.button,'{{'+this.value+'{','}}}');
Popup.remove(); return false;
};
s.options[s.length]=new Option('left','left');
s.options[s.length-1].title='{{left{...}}}';
s.options[s.length]=new Option('center','center');
s.options[s.length-1].title='{{center{...}}}';
s.options[s.length]=new Option('right','right');
s.options[s.length-1].title='{{right{...}}}';
s.options[s.length]=new Option('justify','justify');
s.options[s.length-1].title='{{justify{...}}}';
s.options[s.length]=new Option('float left','float left');
s.options[s.length-1].title='{{floatleft{...}}}';
s.options[s.length]=new Option('float right','float right');
s.options[s.length-1].title='{{floatright{...}}}';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>align</a></html>
/%
|Name|QuickEdit_color|
|Source|http://www.TiddlyTools.com/#QuickEdit_color|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition of toolbar button for "color" command|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_color>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_color'></span>
**** COLOR ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="text/background color - @@color:#RGB;background-color:#RGB;...@@"
onclick="var p=Popup.create(this,null,'popup sticky smallform'); if (!p) return false;
p.style.padding='2px';
function hex(d) { return '0123456789ABCDEF'.substr(d,1); }
var fg=createTiddlyElement(p,'select'); fg.button=this;
fg.style.width='12em';
fg.options[0]=new Option('text color...','');
fg.options[1]=new Option('\xa0 or enter a value','_ask');
fg.options[2]=new Option('\xa0 or use default color','');
for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
var label=hex(r)+hex(g)+hex(b);
fg.options[fg.length]=new Option(label,'#'+label);
fg.options[fg.length-1].style.color='#'+label;
}
fg.onchange=function(){ var val=this.value;
if (val=='_ask') { val=prompt('Enter a CSS color value');
if (!val||!val.length) return false; }
this.options[0].value=val; this.options[0].text=val.length?'text: '+val:'text color...';
var bg=this.nextSibling;
for (var i=3;i<bg.options.length;i++) bg.options[i].style.color=val;
var preview=this.nextSibling.nextSibling.nextSibling;
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
var fg=this.value; if (fg.length) fg='color:'+fg+';';
var bg=this.nextSibling.value; if (bg.length) bg='background-color:'+bg+';';
if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
removeChildren(preview); wikify(t,preview);
this.selectedIndex=0; return false;
};
var bg=createTiddlyElement(p,'select'); bg.button=this;
bg.style.width='12em';
bg.options[0]=new Option('background color...','');
bg.options[1]=new Option('\xa0 or enter a value','_ask');
bg.options[2]=new Option('\xa0 or use default color','');
for (var r=0;r<16;r+=3) for (var g=0;g<16;g+=3) for (var b=0;b<16;b+=3) {
var label=hex(15-r)+hex(15-g)+hex(15-b);
bg.options[bg.length]=new Option(label,'#'+label);
bg.options[bg.length-1].style.backgroundColor='#'+label;
}
bg.onchange=function(){ var val=this.value;
if (val=='_ask') { val=prompt('Enter a CSS color value');
if (!val||!val.length) return false; }
this.options[0].value=val;
this.options[0].text=val.length?'background: '+val:'background color...';
var fg=this.previousSibling;
for (var i=3;i<fg.options.length;i++) fg.options[i].style.backgroundColor=val;
var preview=this.nextSibling.nextSibling;
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (!t.length) t='~AaBbCcDdEeFfGgHhIiJj 1234567890';
var fg=this.previousSibling.value; if (fg.length) fg='color:'+fg+';';
var bg=this.value; if (bg.length) bg='background-color:'+bg+';';
if (fg.length||bg.length) t='@@'+fg+bg+t+'@@';
removeChildren(preview); wikify(t,preview);
this.selectedIndex=0; return false;
};
var b=createTiddlyElement(p,'input',null,null,null,{type:'button'}); b.button=this;
b.value='ok'; b.style.width='4em';
b.onclick=function() {
var fg=this.previousSibling.previousSibling.value; if (fg.length) fg='color:'+fg+';';
var bg=this.previousSibling.value; if (bg.length) bg='background-color:'+bg+';';
var t=config.quickEdit.getSelection(config.quickEdit.getField(this.button));
t=t.replace(/^@@(color\:.+;)?(background-color\:.+;)?/,'').replace(/@@$/,'');
if (fg.length||bg.length) config.quickEdit.setSelection(this.button,'@@'+fg+bg+t+'@@');
Popup.remove(); return false;
};
var preview=createTiddlyElement(p,'div',null,'viewer'); var s=preview.style;
s.border='1px solid'; s.margin='2px'; s.width='24em'; s.padding='3px'; s.MozBorderRadius='3px';
s.overflow='hidden'; s.textAlign='center'; s.whiteSpace='normal';
var t=config.quickEdit.getSelection(config.quickEdit.getField(this));
wikify(t.length?t:'~AaBbCcDdEeFfGgHhIiJj 1234567890',preview);
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>color</a></html>
/%
|Name|QuickEdit_font|
|Source|http://www.TiddlyTools.com/#QuickEdit_font|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button that set font-family CSS attribute|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_font>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_macro'></span>
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="set font-family CSS attribute - @@font-family:facename;...@@"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a font family...','');
s.onchange=function(){
if (this.value=='_edit')
story.displayTiddler(story.findContainingTiddler(this.button),'QuickEdit_fontList',DEFAULT_EDIT_TEMPLATE);
else
config.quickEdit.wrapSelection(this.button,'@@font-family:\x22'+this.value+'\x22;','@@');
Popup.remove(); return false;
};
var fonts=store.getTiddlerText('QuickEdit_fontList','').split('\n');
for (var i=0; i<fonts.length; i++) {
if (!fonts[i].length) continue;
s.options[s.length]=new Option(fonts[i],fonts[i]);
s.options[s.length-1].style.fontFamily=fonts[i];
}
s.options[s.length]=new Option('[Edit font list...]','_edit');
s.options[s.length-1].title='enter fonts, one per line...';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>font</a></html>
Arial,helvetica,sans-serif
Times New Roman,times,serif
Verdana,sans-serif
Courier,monospaced
/%
|Name|QuickEdit_format|
|Source|http://www.TiddlyTools.com/#QuickEdit_format|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios (*This version has been slightly modified by Dave Gifford*)|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar button for text formatting|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_format>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_format'></span>
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="''bold''" accesskey="B"
onclick="config.quickEdit.wrapSelection(this,'\x27\x27','\x27\x27'); return false;"
> B </a></html>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="//italics//" accesskey="I"
onclick="config.quickEdit.wrapSelection(this,'//','//'); return false;"
> I </a></html>/%
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink" title="__underline__" accesskey="U"
onclick="config.quickEdit.wrapSelection(this,'__','__'); return false;"
> U </a></html>/%
%/ /% SPACER
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="format text"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select text format...','');
s.onchange=function(){
var parts=this.value.split(',');
config.quickEdit.wrapSelection(this.button,parts[0],parts[1]);
Popup.remove(); return false;
};
s.options[s.length]=new Option('superscript','^^,^^');
s.options[s.length-1].title='^^superscript^^';
s.options[s.length]=new Option('subscript','~~,~~');
s.options[s.length-1].title='~~subcript~~';
s.options[s.length]=new Option('blockquote','\n\<\<\<\n,\n\<\<\<\n');
s.options[s.length-1].title='indented blockquote - \<\<\<';
s.options[s.length]=new Option('monospaced','{{{,}}}');
s.options[s.length-1].title='inline monospaced text - {{{...}}}';
s.options[s.length]=new Option('pre','\n{{{\n,\n}}}\n');
s.options[s.length-1].title='multi-line monospaced text box - {{{...}}}';
s.options[s.length]=new Option('heading 1','\n!,\n');
s.options[s.length-1].title='H1 heading - !';
s.options[s.length]=new Option('heading 2','\n!!,\n');
s.options[s.length-1].title='H2 heading - !';
s.options[s.length]=new Option('heading 3','\n!!!,\n');
s.options[s.length-1].title='H3 heading - !';
s.options[s.length]=new Option('heading 4','\n!!!!,\n');
s.options[s.length-1].title='H4 heading - !';
s.options[s.length]=new Option('heading 5','\n!!!!!,\n');
s.options[s.length-1].title='H5 heading - !';
s.options[s.length]=new Option('comment','/%,%/');
s.options[s.length-1].title='comment (hidden content) - /%...%/';
s.options[s.length]=new Option('HTML','<html>,<\x2fhtml>');
s.options[s.length-1].title='HTML syntax - <html>...<\x2fhtml>';
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>format</a></html>
/%
|Name|QuickEdit_image|
|Source|http://www.TiddlyTools.com/#QuickEdit_image|
|Version|2.2.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|definition for toolbar buttons that insert embedded image references|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_image>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_image'></span>
**** INSERT IMAGE ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="embed an image (jpg/gif/png) - [img[tooltip|URL]] or [img[tooltip|path/to/file.ext]]"
onclick="var fn=config.quickEdit.promptForFilename('Enter/select an image file',getLocalPath(document.location.href),'');
if (!fn) return false; /* cancelled by user */
var tip=prompt('Enter a tooltip for this image',''); if (!tip) tip=''; else tip+='|';
return config.quickEdit.setSelection(this,'[img['+tip+fn+']]');"
>image</a></html>
/%
|Name|QuickEdit_link|
|Source|http://www.TiddlyTools.com/#QuickEdit_link|
|Version|2.2.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.2|
|Type|script|
|Requires|QuickEditPlugin|
|Overrides||
|Description|toolbar button that inserts a ~PrettyTiddlyLink to a tiddler or external file|
Usage:
QuickEditToolbar: <<tiddler QuickEdit_link>>
OR
EditTemplate: <span class='toolbar' macro='tiddler QuickEdit_link'></span>
**** INSERT LINK ****
%/<html><hide linebreaks><a href="javascript:;" class="tiddlyLink"
title="add a 'PrettyLink' to another tiddler - [[link text|TiddlerName]]"
onclick="var p=Popup.create(this); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=this;
s.options[0]=new Option('select a tiddler or file...','');
s.onchange=function(){
var title=this.value; var txt=title;
if (title=='_file') {
title=config.quickEdit.promptForFilename('Select a file',
getLocalPath(document.location.href),'');
if (!title) { this.selectedIndex=0; this.focus(); return false; }
var txt=title.substr(title.lastIndexOf('/')+1);
}
var txt=prompt('Enter the text to display for this link',txt);
if (!txt) { this.selectedIndex=0; this.focus(); return false; }
config.quickEdit.setSelection(this.button,'[['+txt+'|'+title+']]');
Popup.remove(); return false;
};
s.options[s.length]=new Option('[browse for file...]','_file');
var tids=store.getTiddlers('title');
for (var t=0; t<tids.length; t++) {
s.options[s.length]=new Option(tids[t].title,tids[t].title);
s.options[s.length-1].title=tids[t].getSubtitle();
}
var s=createTiddlyElement(p,'select');
s.options[0]=new Option('match tag...','');
s.onchange=function(){
var tag=this.value;
var tids=tag.length?store.getTaggedTiddlers(tag,'title'):store.getTiddlers('title');
var list=this.previousSibling;
while (list.length) list.options[0]=null;
var prompt='select a tiddler or file...';
if (tag.length) prompt='select a tagged tiddler ['+tids.length+' matches]...';
list.options[0]=new Option(prompt,'');
if (!tag.length) list.options[list.length]=new Option('[browse for file...]','_file');
for (var t=0; t<tids.length; t++) {
list.options[list.length]=new Option(tids[t].title,tids[t].title);
list.options[list.length-1].title=tids[t].getSubtitle();
}
};
var tags=store.getTags();
for (var t=0; t<tags.length; t++) s.options[s.length]=new Option(tags[t][0],tags[t][0]);
Popup.show(p,false);
event.cancelBubble=true;if(event.stopPropagation)event.stopPropagation();return false;"
>link</a></html>
/***
|Name:|QuickOpenTagPlugin|
|Description:|Changes tag links to make it easier to open tags as tiddlers|
|Version:|3.0.1 ($Rev: 3861 $)|
|Date:|$Date: 2008-03-08 10:53:09 +1000 (Sat, 08 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#QuickOpenTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
***/
//{{{
config.quickOpenTag = {
dropdownChar: (document.all ? "\u25bc" : "\u25be"), // the little one doesn't work in IE?
createTagButton: function(place,tag,excludeTiddler) {
// little hack so we can do this: <<tag PrettyTagName|RealTagName>>
var splitTag = tag.split("|");
var pretty = tag;
if (splitTag.length == 2) {
tag = splitTag[1];
pretty = splitTag[0];
}
var sp = createTiddlyElement(place,"span",null,"quickopentag");
createTiddlyText(createTiddlyLink(sp,tag,false),pretty);
var theTag = createTiddlyButton(sp,config.quickOpenTag.dropdownChar,
config.views.wikified.tag.tooltip.format([tag]),onClickTag);
theTag.setAttribute("tag",tag);
if (excludeTiddler)
theTag.setAttribute("tiddler",excludeTiddler);
return(theTag);
},
miniTagHandler: function(place,macroName,params,wikifier,paramString,tiddler) {
var tagged = store.getTaggedTiddlers(tiddler.title);
if (tagged.length > 0) {
var theTag = createTiddlyButton(place,config.quickOpenTag.dropdownChar,
config.views.wikified.tag.tooltip.format([tiddler.title]),onClickTag);
theTag.setAttribute("tag",tiddler.title);
theTag.className = "miniTag";
}
},
allTagsHandler: function(place,macroName,params) {
var tags = store.getTags(params[0]);
var filter = params[1]; // new feature
var ul = createTiddlyElement(place,"ul");
if(tags.length == 0)
createTiddlyElement(ul,"li",null,"listTitle",this.noTags);
for(var t=0; t<tags.length; t++) {
var title = tags[t][0];
if (!filter || (title.match(new RegExp('^'+filter)))) {
var info = getTiddlyLinkInfo(title);
var theListItem =createTiddlyElement(ul,"li");
var theLink = createTiddlyLink(theListItem,tags[t][0],true);
var theCount = " (" + tags[t][1] + ")";
theLink.appendChild(document.createTextNode(theCount));
var theDropDownBtn = createTiddlyButton(theListItem," " +
config.quickOpenTag.dropdownChar,this.tooltip.format([tags[t][0]]),onClickTag);
theDropDownBtn.setAttribute("tag",tags[t][0]);
}
}
},
// todo fix these up a bit
styles: [
"/*{{{*/",
"/* created by QuickOpenTagPlugin */",
".tagglyTagged .quickopentag, .tagged .quickopentag ",
" { margin-right:1.2em; border:1px solid #eee; padding:2px; padding-right:0px; padding-left:1px; }",
".quickopentag .tiddlyLink { padding:2px; padding-left:3px; }",
".quickopentag a.button { padding:1px; padding-left:2px; padding-right:2px;}",
"/* extra specificity to make it work right */",
"#displayArea .viewer .quickopentag a.button, ",
"#displayArea .viewer .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink, ",
"#mainMenu .quickopentag a.tiddyLink ",
" { border:0px solid black; }",
"#displayArea .viewer .quickopentag a.button, ",
"#mainMenu .quickopentag a.button ",
" { margin-left:0px; padding-left:2px; }",
"#displayArea .viewer .quickopentag a.tiddlyLink, ",
"#mainMenu .quickopentag a.tiddlyLink ",
" { margin-right:0px; padding-right:0px; padding-left:0px; margin-left:0px; }",
"a.miniTag {font-size:150%;} ",
"#mainMenu .quickopentag a.button ",
" /* looks better in right justified main menus */",
" { margin-left:0px; padding-left:2px; margin-right:0px; padding-right:0px; }",
"#topMenu .quickopentag { padding:0px; margin:0px; border:0px; }",
"#topMenu .quickopentag .tiddlyLink { padding-right:1px; margin-right:0px; }",
"#topMenu .quickopentag .button { padding-left:1px; margin-left:0px; border:0px; }",
"/*}}}*/",
""].join("\n"),
init: function() {
// we fully replace these builtins. can't hijack them easily
window.createTagButton = this.createTagButton;
config.macros.allTags.handler = this.allTagsHandler;
config.macros.miniTag = { handler: this.miniTagHandler };
config.shadowTiddlers["QuickOpenTagStyles"] = this.styles;
store.addNotification("QuickOpenTagStyles",refreshStyles);
}
}
config.quickOpenTag.init();
//}}}
/***
|Title|RSSAdaptor|
|Summary|Server adaptor for talking to RSS 2.0 files|
|Description|Based on FileAdaptor|
|Version of product it works with|2.2.5|
|Version of component|1.0|
|Explanation of how it can be used and modified|This supports the server adaptor interface, a description of which can be found at: http://tiddlywiki.com/#ServerAdaptorMechanism|
|Examples where it can be seen working|The RSSAdator is used in this RSS Reader: (link to come)|
***/
//{{{
function RSSAdaptor()
{
this.host = null;
this.store = null;
this.context = null;
return this;
}
RSSAdaptor.NotLoadedError = "RSS file has not been loaded";
RSSAdaptor.serverType = 'RSS';
// Use the line below instead of the line above if you want to override the local file adaptor
// RSSAdaptor.serverType = 'file';
// Open the specified host/server
// Return true if successful, error string if not
RSSAdaptor.prototype.openHost = function(host,context,userParams,callback)
{
this.host = host;
if(!context)
context = {};
context.adaptor = this;
context.callback = callback;
context.userParams = userParams;
var ret = loadRemoteFile(host,RSSAdaptor.openHostCallback,context);
return typeof(ret) == "string" ? ret : true;
};
RSSAdaptor.openHostCallback = function(status,context,responseText,url,xhr)
{
var adaptor = context.adaptor;
context.status = status;
if(!status) {
context.statusText = "Error reading file: " + xhr.statusText;
} else {
// CHANGE this bit to store RSS file appropriately (as part of the adaptor?) - DONE
// We're just storing the plain text rather than bring XML into it
adaptor.store = responseText;
// OLD CODE
// Load the content into a TiddlyWiki() object
// adaptor.store = new TiddlyWiki();
// if(!adaptor.store.importTiddlyWiki(responseText))
// context.statusText = config.messages.invalidFileError.format([url]);
}
context.callback(context,context.userParams);
};
// Gets the list of workspaces on a given server
// Sets context.workspaces, which is a list of workspaces
// Returns true if successful, error string if not (or it should)
// Default for RSS file as we don't have a workspace
RSSAdaptor.prototype.getWorkspaceList = function(context,userParams,callback)
{
if(!context)
context = {};
context.workspaces = [{title:"(default)"}];
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// Open the specified workspace
// Returns true if successful, error string if not (or it should)
// Trivial in the case of RSS file where we don't have a workspace
RSSAdaptor.prototype.openWorkspace = function(workspace,context,userParams,callback)
{
if(!context)
context = {};
context.status = true;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// Gets the list of tiddlers within a given workspace
// Returns true if successful, error string if not (or it should)
// Sets context.tiddlers, which is an array of tiddlers
// Set these variables if possible:
// title: tiddler.title, modified: tiddler.modified, modifier: tiddler.modifier, text: tiddler.text, tags: tiddler.tags, size: tiddler.text
// For RSS each item is a tiddler
RSSAdaptor.prototype.getTiddlerList = function(context,userParams,callback,filter)
{
if(!this.store)
return RSSAdaptor.NotLoadedError;
if(!context)
context = {};
context.tiddlers = [];
// First thing to do is strip out any \r characters in the file, as TiddlyWiki doesn't deal with them
this.store = this.store.replace(/\r+/mg,"");
// regex_item matches on the items
var regex_item = /<item>(.|\n)*?<\/item>/mg;
// regex_title matches for the titles
var regex_title = /<title>(.|\n)*?<\/title>/mg;
var regex_guid = /<guid>(.|\n)*?<\/guid>/mg;
var regex_wiki = /<tw:wikitext>(.|\n)*?<\/tw:wikitext>/mg;
var regex_desc = /<description>(.|\n)*?<\/description>/mg;
var regex_category = /<category>(.|\n)*?<\/category>/mg;
var regex_link = /<link>(\S|\n)*?<\/link>/mg;
var regex_pubDate = /<pubDate>(.|\n)*?<\/pubDate>/mg;
var regex_author = /<author>(.|\n)*?<\/author>/mg;
var item_match = this.store.match(regex_item);
// check for filter and then implement tag filter if of the form [tag[public stuff]]
// filter syntax: [tag[tag1 tag2 ...]]
// tags in the same set of brackets are all compulsory
// TO-DO: support bracketed list, where multi-word tags are of the form [two words]
if (filter) {
var filter_regex = /\[(\w+)\[([ \w]+)\]\]/;
var filter_match = filter_regex.exec(filter);
if (filter_match) {
// filter_match[2] is a space-seperated string of the tags to match on
var tags_to_match = filter_match[1]=="tag" ? filter_match[2].split(" ") : null;
} else {
displayMessage("no match: check regex in filter");
}
}
for (var i=0;i<item_match.length;i++) {
// create a new Tiddler in context.tiddlers with the finished item object
// grab a title
var item = {};
var title = item_match[i].match(regex_title);
if (title)
item.title = title[0].replace(/^<title>|<\/title>$/mg,"");
else {
// something went wrong grabbing the title, grab the guid instead
title = item_match[i].match(regex_guid);
displayMessage("problem with getting title: " + item_match[i])
if (title)
item.title = title[0].replace(/^<guid>|<\/guid>$/mg,"");
else {
item.title = new Date();
displayMessage("problem with getting title AND guid: " + item_match[i]);
}
}
// This line makes sure any html-encoding in the title is reversed
item.title = item.title.htmlDecode();
// There is a problem with the title, which is that it is not formatted, so characters like ' are not converted at render time
// renderHtmlText() extends String and sorts out the problem
item.title = item.title.renderHtmlText();
// grab original wikitext if it is there as an extended field
wikitext = item_match[i].match(regex_wiki);
if (wikitext) {
item.text = wikitext[0].replace(/^<tw:wikitext>|<\/tw:wikitext>$/mg,"");
item.text = item.text.htmlDecode();
} else {
// grab a description
desc = item_match[i].match(regex_desc);
if (desc) {
item.text = desc[0].replace(/^<description>|<\/description>$/mg,"");
} else {
item.text = "empty, something seriously wrong with this item";
// displayMessage("description empty for item: " + item.title);
}
}
var t = new Tiddler(item.title);
if (wikitext) {
t.text = item.text;
} else {
t.text = "<html>" + item.text.renderHtmlText() + "</html>";
}
// grab the categories
category = item_match[i].match(regex_category);
if (category) {
item.categories = [];
for (var j=0;j<category.length;j++) {
item.categories[j] = category[j].replace(/^<category>|<\/category>$/mg,"");
}
t.tags = item.categories;
} else {
// displayMessage("no tags for item: " + item.title);
}
// grab the link and put it in a custom field (assumes this is sensible)
// regex_link assumes you can never have whitespace in a link
link = item_match[i].match(regex_link);
if (link) {
item.link = link[0].replace(/^<link>|<\/link>$/mg,"");
} else {
item.link = "#";
// displayMessage("link empty for item: " + item.title);
}
t.fields["link to original"] = item.link;
// grab date created
pubDate = item_match[i].match(regex_pubDate);
if (pubDate) {
pubDate = pubDate[0].replace(/^<pubDate>|<\/pubDate>$/mg,"");
item.pubDate = new Date(pubDate);
} else {
item.pubDate = new Date();
// displayMessage("pubDate empty for item: " + item.title);
}
t.created = item.pubDate;
// grab author
author = item_match[i].match(regex_author);
if (author) {
author = author[0].replace(/^<author>|<\/author>$/mg,"");
item.author = author;
} else {
item.author = "anonymous";
// displayMessage("author empty for item: " + item.title);
}
t.modifier = item.author;
// check to see that we have a filter to use
if (filter_match) {
if(t.isTaggedAllOf(tags_to_match)) {
context.tiddlers.push(t);
}
} else {
// with no filter, we just add all the tiddlers
context.tiddlers.push(t);
}
}
context.status = true;
// Set this.context so that we can refer to the tiddler list even if it is not passed on to us
this.context = context;
window.setTimeout(function() {callback(context,userParams);},10);
return true;
};
// QUERY: what actually calls this and does it always pass in a real tiddler?
RSSAdaptor.prototype.generateTiddlerInfo = function(tiddler)
{
var info = {};
info.uri = tiddler.fields['server.host'] + "#" + tiddler.title;
return info;
};
// Retrieves a tiddler from a given workspace on a given server
// Sets context.tiddler to the requested tiddler
// Context object passed in from importTiddlers is empty so we use this.context
// Returns true if successful, error string if not (or it should)
RSSAdaptor.prototype.getTiddler = function(title,context,userParams,callback)
{
if(!this.store)
return RSSAdaptor.NotLoadedError;
if(!context)
context = {};
// Retrieve the tiddler from the this.context.tiddlers array
for (var i=0; i<this.context.tiddlers.length; i++) {
if (this.context.tiddlers[i].title == title) {
context.tiddler = this.context.tiddlers[i];
}
}
// NOTE: this doesn't add the filter field - is that ok? Probably not...
if(context.tiddler) {
context.tiddler.fields['server.type'] = RSSAdaptor.serverType;
context.tiddler.fields['server.host'] = this.host;
context.tiddler.fields['server.page.revision'] = context.tiddler.modified.convertToYYYYMMDDHHMM();
context.status = true;
} else {
context.status = false;
context.statusText = "error retrieving tiddler: " + title;
return context.statusText;
}
if(context.allowSynchronous) {
context.isSynchronous = true;
callback(context,userParams);
} else {
window.setTimeout(function() {callback(context,userParams);},10);
}
return true;
};
RSSAdaptor.prototype.close = function()
{
delete this.store;
this.store = null;
};
config.adaptors[RSSAdaptor.serverType] = RSSAdaptor;
// Hack to override the importTiddlers local file behaviour
config.macros.importTiddlers.onBrowseChange = function(e)
{
var wizard = new Wizard(this);
var fileInput = wizard.getElement("txtPath");
fileInput.value = "file://" + this.value;
var serverType = wizard.getElement("selTypes");
if(serverType.value != "RSS") {
serverType.value = "file";
}
return false;
};
// renderHtmlText puts a string through the browser render process and then extracts the text
// useful to turn HTML entities into literals such as ' to '
// this method has two passes at the string - the first to convert it to html and the second
// to selectively catch the ASCII-encoded characters without losing the rest of the html
String.prototype.renderHtmlText = function() {
var e = createTiddlyElement(document.body,"div");
e.innerHTML = this;
var text = getPlainText(e);
text = text.replace(/&#[\w]+?;/g,function(word) {
var ee = createTiddlyElement(e,"div");
ee.innerHTML = word;
return getPlainText(ee);
});
removeNode(e);
return text;
};
/* 24/10/07 - NOT USING THIS - extending RSS to include copy of wikitext for a tiddler instead
// RSSunwikify converts html structures into wikitext
// As at 24/10/07, only supports tables
// needed because slice mechanism does not support html table tags
RSSAdaptor.RSSunwikify = function(text) {
console.log(text);
var new_text = "";
var table_regex = /<table(\w|[ "'=])*?>(.|\n)*?<\/table>/mg;
var tr_regex = /<tr(\w|[ "'=])*?>(.|\n)*?<\/tr>/mg;
var td_regex = /<td(\w|[ "'=])*?>(.|\n)*?<\/td>/mg;
var table_match = text.match(table_regex);
if (table_match) {
console.log("found table: " + table_match[0])
var rows = table_match[0].replace(/^<table(\w|[ "'=])*?>|<\/table>$/g,"").match(tr_regex);
if (rows) {
for (var i=0;i<rows.length;i++) {
console.log("found row: " + rows[i]);
var cells = rows[i].replace(/^<tr(\w|[ "'=])*?>|<\/tr>$/g,"").match(td_regex);
if (cells) {
for (var j=0;j<cells.length;j++) {
console.log("found cell: " + cells[j]);
// add pipe and cell content
new_text += "| " + "<html>"+cells[j].replace(/^<td(\w|[ "'=])*?>|<\/td>$/g,"")+"</html>";
}
}
// add pipe and newline at end of row
new_text += "|\n";
}
}
}
console.log(new_text);
return new_text;
}; */
// Test if a tiddler carries any of an array of tags
// Takes an array of tags
// Returns true if there is a match, false if not
Tiddler.prototype.isTaggedAnyOf = function(tag_array)
{
if (tag_array) {
// get a string of this tiddler's tags
var this_tag_list = this.getTags();
// spilt that into an array
var this_tag_array = this_tag_list.split(" ");
// check that all the members of tag_array are contained in this_tag_array
for (var i=0; i<this_tag_array.length; i++) {
for (var j=0; j<tag_array.length; j++) {
if (this_tag_array[i] == tag_array[j]) {
return true;
}
}
}
// if we get to this point, we've not had any matches
return false;
} else {
return false;
}
};
// Test if a tiddler carries all of an array of tags
// Takes an array of tags
// Returns true if all match, false if not
Tiddler.prototype.isTaggedAllOf = function(tag_array)
{
if (tag_array) {
// get a string of this tiddler's tags
var this_tag_list = this.getTags();
// spilt that into an array
var this_tag_array = this_tag_list.split(" ");
// check whether any of the members of tag_array are not contained in this_tag_array
for (var i=0; i<tag_array.length; i++) {
// tag_match is a flag to signal whether we've had a match for a compulsory tag
var tag_match = false;
for (var j=0; j<this_tag_array.length; j++) {
if (tag_array[i] == this_tag_array[j]) {
tag_match = true;
break;
}
}
// if tag_match is still false after we've looked through the tiddler's tags,
// there is a failed match in the compulsory list so we can return false
if (tag_match == false) {
return false;
}
}
// now we've looked through the compulsory tags, return true
// this is valid because we would have returned false by this point anyway if
// there had been no match
return true;
} else {
return false;
}
};
//}}}
//{{{
// Override built-in generateRss to add tw namespace (for wikitext field)
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\" xmlns:tw=\"http://tiddlywiki.org/wikitext/\">");
s.push("<channel>");
s.push("<title" + ">" + wikifyPlain("SiteTitle").htmlEncode() + "</title" + ">");
if(u)
s.push("<link>" + u.htmlEncode() + "</link>");
s.push("<description>" + wikifyPlain("SiteSubtitle").htmlEncode() + "</description>");
s.push("<language>en-us</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 " + version.major + "." + version.minor + "." + version.revision + "</generator>");
// The body
var tiddlers = store.getTiddlers("modified","excludeLists");
var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
for (var t=tiddlers.length-1; t>=n; t--)
s.push(tiddlers[t].saveToRss(u));
// And footer
s.push("</channel>");
s.push("</rss>");
// Save it all
return s.join("\n");
}
// Override built-in saveToRss to include author and wikitext fields
Tiddler.prototype.saveToRss = function(url)
{
var s = [];
s.push("<item>");
s.push("<title" + ">" + this.title.htmlEncode() + "</title" + ">");
s.push("<tw:wikitext" + ">" + this.text.htmlEncode() + "</tw:wikitext" + ">");
s.push("<description>" + wikifyStatic(this.text,null,this).htmlEncode() + "</description>");
for(var t=0; t<this.tags.length; t++)
s.push("<category>" + this.tags[t] + "</category>");
s.push("<link>" + url + "#" + encodeURIComponent(String.encodeTiddlyLink(this.title)) + "</link>");
s.push("<pubDate>" + this.modified.toGMTString() + "</pubDate>");
s.push("<author>" + this.modifier + "</author>");
s.push("</item>");
return s.join("\n");
};
//}}}
/***
|Name:|SaveCloseTiddlerPlugin|
|Description:|Provides two extra toolbar commands, saveCloseTiddler and cancelCloseTiddler|
|Version:|3.0 ($Rev: 5502 $)|
|Date:|$Date: 2008-06-10 23:31:39 +1000 (Tue, 10 Jun 2008) $|
|Source:|http://mptw.tiddlyspot.com/#SaveCloseTiddlerPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
To use these you must add them to the tool bar in your EditTemplate
***/
//{{{
merge(config.commands,{
saveCloseTiddler: {
text: 'færdig/luk',
tooltip: 'Gem ændringer til denne tiddler og luk den',
handler: function(ev,src,title) {
var closeTitle = title;
var newTitle = story.saveTiddler(title,ev.shiftKey);
if (newTitle)
closeTitle = newTitle;
return config.commands.closeTiddler.handler(ev,src,closeTitle);
}
},
cancelCloseTiddler: {
text: 'fortryd/luk',
tooltip: 'Fortryd ændringer til denne tiddler og luk den',
handler: function(ev,src,title) {
// the same as closeTiddler now actually
return config.commands.closeTiddler.handler(ev,src,title);
}
}
});
//}}}
//{{{
window.reportSearchResults=function(text,matches)
{
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="\n";
// numbered list of links to matching tiddlers
body+="\n<<<";
for(var t=0;t<matches.length;t++) {
var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
body+="\n# "+date+"[["+matches[t].title+"]]";
}
body+="\n<<<\n";
// create/update the tiddler
var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch");
store.addTiddler(tiddler); story.closeTiddler(title);
// use alternate "search again" label in <<search>> macro
var oldprompt=config.macros.search.label;
config.macros.search.label="search again";
// render/refresh tiddler
story.displayTiddler(null,title,1);
store.notify(title,true);
// restore standard search label
config.macros.search.label=oldprompt;
}
//}}}
/***
|Name|SearchOptionsPlugin|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|2.6.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.search, TiddlyWiki.prototype.search, config.macros.search.onKeyPress|
|Description|extend core search function with additional user-configurable options|
Extend core search function with additional user-configurable options including generating a ''list of matching tiddlers'' instead of immediately displaying all matches.
!!!!!Documentation
>see [[SearchOptionsPluginInfo]]
!!!!!Configuration
<<<
<<option chkSearchTitles>> Search in titles
<<option chkSearchText>> Search in tiddler text
<<option chkSearchTags>> Search in tags
<<option chkSearchFields>> Search in data fields
<<option chkSearchShadows>> Search shadow tiddlers
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchByDate>> Sort matching tiddlers by date
<<option chkSearchList>> Show list of matches in [[SearchResults]]
<<option chkSearchIncremental>> Incremental (key-by-key) searching
<<<
!!!!!Revisions
<<<
2007.02.17 [2.6.1] added redefinition of config.macros.search.onKeyPress() to restore check to bypass key-by-key searching (i.e., when chkSearchIncremental==false), which had been unintentionally removed with v2.6.0
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.searchOptions = {major: 2, minor: 6, revision: 1, date: new Date(2007,2,17)};
if (config.options.chkSearchTitles===undefined) config.options.chkSearchTitles=true;
if (config.options.chkSearchText===undefined) config.options.chkSearchText=true;
if (config.options.chkSearchTags===undefined) config.options.chkSearchTags=true;
if (config.options.chkSearchFields===undefined) config.options.chkSearchFields=true;
if (config.options.chkSearchTitlesFirst===undefined) config.options.chkSearchTitlesFirst=false;
if (config.options.chkSearchList===undefined) config.options.chkSearchList=false;
if (config.options.chkSearchByDate===undefined) config.options.chkSearchByDate=false;
if (config.options.chkSearchIncremental===undefined) config.options.chkSearchIncremental=true;
if (config.options.chkSearchShadows===undefined) config.options.chkSearchShadows=false;
if (config.optionsDesc) {
config.optionsDesc.chkSearchTitles="Search in tiddler titles";
config.optionsDesc.chkSearchText="Search in tiddler text";
config.optionsDesc.chkSearchTags="Search in tiddler tags";
config.optionsDesc.chkSearchFields="Search in tiddler data fields";
config.optionsDesc.chkSearchShadows="Search in shadow tiddlers";
config.optionsDesc.chkSearchTitlesFirst="Search results show title matches first";
config.optionsDesc.chkSearchList="Search results show list of matching tiddlers";
config.optionsDesc.chkSearchByDate="Search results sorted by modification date ";
config.optionsDesc.chkSearchIncremental="Incremental searching";
} else {
config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchTitles>> Search in tiddler titles"
+"\n<<option chkSearchText>> Search in tiddler text"
+"\n<<option chkSearchTags>> Search in tiddler tags"
+"\n<<option chkSearchFields>> Search in tiddler data fields"
+"\n<<option chkSearchShadows>> Search in shadow tiddlers"
+"\n<<option chkSearchTitlesFirst>> Search results show title matches first"
+"\n<<option chkSearchList>> Search results show list of matching tiddlers"
+"\n<<option chkSearchByDate>> Search results sorted by modification date"
+"\n<<option chkSearchIncremental>> Incremental searching";
}
if (config.macros.search.reportTitle==undefined)
config.macros.search.reportTitle="SearchResults";
config.macros.search.onKeyPress = function(e)
{
if(!e) var e = window.event;
switch(e.keyCode)
{
case 13: // Ctrl-Enter
case 10: // Ctrl-Enter on IE PC
config.macros.search.doSearch(this);
break;
case 27: // Escape
this.value = "";
clearMessage();
break;
}
if (config.options.chkSearchIncremental) {
if(this.value.length > 2)
{
if(this.value != this.getAttribute("lastSearchText"))
{
if(config.macros.search.timeout)
clearTimeout(config.macros.search.timeout);
var txt = this;
config.macros.search.timeout = setTimeout(function() {config.macros.search.doSearch(txt);},500);
}
}
else
{
if(config.macros.search.timeout)
clearTimeout(config.macros.search.timeout);
}
}
}
//}}}
//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
var matches = store.search(highlightHack,config.options.chkSearchByDate?"modified":"title","excludeSearch");
if (config.options.chkSearchByDate) matches=matches.reverse(); // most recent changes first
var q = useRegExp ? "/" : "'";
clearMessage();
if (!matches.length) {
if (config.options.chkSearchList) discardSearchResults();
displayMessage(config.macros.search.failureMsg.format([q+text+q]));
} else {
if (config.options.chkSearchList)
reportSearchResults(text,matches);
else {
var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
this.closeAllTiddlers(); story.displayTiddlers(null,titles);
displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
}
}
highlightHack = null;
}
TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
{
var candidates = this.reverseLookup("tags",excludeTag,false,sortField);
// scan for matching titles first...
var results = [];
if (config.options.chkSearchTitles) {
for(var t=0; t<candidates.length; t++)
if(candidates[t].title.search(searchRegExp)!=-1)
results.push(candidates[t]);
if (config.options.chkSearchShadows)
for (var t in config.shadowTiddlers)
if ((t.search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.push((new Tiddler()).assign(t,config.shadowTiddlers[t]));
}
// then scan for matching text, tags, or field data
for(var t=0; t<candidates.length; t++) {
if (config.options.chkSearchText && candidates[t].text.search(searchRegExp)!=-1)
results.pushUnique(candidates[t]);
if (config.options.chkSearchTags && candidates[t].tags.join(" ").search(searchRegExp)!=-1)
results.pushUnique(candidates[t]);
if (config.options.chkSearchFields && store.forEachField!=undefined) // requires TW2.1 or above
store.forEachField(candidates[t],
function(tid,field,val) { if (val.search(searchRegExp)!=-1) results.pushUnique(candidates[t]); },
true); // extended fields only
}
// then check for matching text in shadows
if (config.options.chkSearchShadows)
for (var t in config.shadowTiddlers)
if ((config.shadowTiddlers[t].search(searchRegExp)!=-1) && !store.tiddlerExists(t))
results.pushUnique((new Tiddler()).assign(t,config.shadowTiddlers[t]));
// if not 'titles first', or sorting by modification date, re-sort results to so titles, text, tag and field matches are mixed together
if(!sortField) sortField = "title";
var bySortField=function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; }
if (!config.options.chkSearchTitlesFirst || config.options.chkSearchByDate) results.sort(bySortField);
return results;
}
// REPORT GENERATOR
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="\n";
// summary: nn tiddlers found matching '...', options used
body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
body+="^^//searched in:// ";
body+=(config.options.chkSearchTitles?"''titles'' ":"");
body+=(config.options.chkSearchText?"''text'' ":"");
body+=(config.options.chkSearchTags?"''tags'' ":"");
body+=(config.options.chkSearchFields?"''fields'' ":"");
body+=(config.options.chkSearchShadows?"''shadows'' ":"");
if (config.options.chkCaseSensitiveSearch||config.options.chkRegExpSearch) {
body+=" //with options:// ";
body+=(config.options.chkCaseSensitiveSearch?"''case sensitive'' ":"");
body+=(config.options.chkRegExpSearch?"''text patterns'' ":"");
}
body+="^^";
// numbered list of links to matching tiddlers
body+="\n<<<";
for(var t=0;t<matches.length;t++) {
var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
body+="\n# "+date+"[["+matches[t].title+"]]";
}
body+="\n<<<\n";
// open all matches button
body+="<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"story.displayTiddlers(null,["
for(var t=0;t<matches.length;t++)
body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
body+="],1);\" ";
body+="accesskey=\"O\" ";
body+="value=\"open all matching tiddlers\"></html> ";
// discard search results button
body+="<html><input type=\"button\" href=\"javascript:;\" ";
body+="onclick=\"story.closeTiddler('"+title+"'); store.deleteTiddler('"+title+"'); store.notify('"+title+"',true);\" ";
body+="value=\"discard "+title+"\"></html>";
// search again
body+="\n\n----\n";
body+="<<search \""+text+"\">>\n";
body+="<<option chkSearchTitles>>titles ";
body+="<<option chkSearchText>>text ";
body+="<<option chkSearchTags>>tags";
body+="<<option chkSearchFields>>fields";
body+="<<option chkSearchShadows>>shadows";
body+="<<option chkCaseSensitiveSearch>>case-sensitive ";
body+="<<option chkRegExpSearch>>text patterns";
body+="<<option chkSearchByDate>>sort by date";
// create/update the tiddler
var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch temporary");
store.addTiddler(tiddler); story.closeTiddler(title);
// use alternate "search again" label in <<search>> macro
var oldprompt=config.macros.search.label;
config.macros.search.label="search again";
// render/refresh tiddler
story.displayTiddler(null,title,1);
store.notify(title,true);
// restore standard search label
config.macros.search.label=oldprompt;
}
if (!window.discardSearchResults) window.discardSearchResults=function()
{
// remove the tiddler
story.closeTiddler(config.macros.search.reportTitle);
store.deleteTiddler(config.macros.search.reportTitle);
}
//}}}
//{{{
window.reportSearchResults=function(text,matches)
{
var title=config.macros.search.reportTitle
var q = config.options.chkRegExpSearch ? "/" : "'";
var body="\n";
// numbered list of links to matching tiddlers
body+="\n<<<";
for(var t=0;t<matches.length;t++) {
var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
body+="\n# "+date+"[["+matches[t].title+"]]";
}
body+="\n<<<\n";
// create/update the tiddler
var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch");
store.addTiddler(tiddler); story.closeTiddler(title);
// use alternate "search again" label in <<search>> macro
var oldprompt=config.macros.search.label;
config.macros.search.label="search again";
// render/refresh tiddler
story.displayTiddler(null,title,1);
store.notify(title,true);
// restore standard search label
config.macros.search.label=oldprompt;
}
//}}}
<<<
# [[Acknowledgements & license]]
# [[ForEachTiddlerPlugin]]
# [[InlineJavascriptPlugin]]
# [[Instructions]]
# [[NestedSlidersPlugin(withGiffmexTweak)]]
# [[QuickEditToolbar]]
# [[QuickEdit_format]]
# [[QuickOpenTagPlugin]]
# [[SearchOptions plugin tweaks]]
# [[SearchOptionsPlugin]]
# [[SearchOptionsPlugin tweaks]]
# [[SiteMapMacro]]
# [[TagglyTaggingPlugin]]
# [[ToggleTagPlugin]]
<<<
<<slider chksliderkommentarer kommentarer "Tråd »">><<search>><<closeAll>><<permaview>><<newTiddler>><<newTiddler title: 'Ny IFrame - udskift XXXX herunder med den hjemmeside du vil bruge' text: '<html><div align="center"><iframe src="http://XXXX" frameborder="0" width="100%" height="600"></iframe></div></html>' tag: 'iframe' label:'ny IFrame'>><<newJournal "DD MMM YYYY" "journal">><<newTiddler label:"ny bog/artikel" text:{{"<<formTiddler NewBibEntryTemplate\>\>"}} tag:"authorbook""Bøger">><<saveChanges>><<tiddler TspotSidebar>>{{tuduSlider{<<slider chkBookSummary Bibliografi 'Bibliografi »'>>}}}<<slider chkSliderOptionsPanel OptionsPanel "Muligheder »" "Change TiddlyWiki advanced options">><<option chkShowQuickEdit>><<slider chkSliderGemTilNettet GemTilNettet "Tiddlyspot »">>
<<slider txtMainTabSlider SideBarTabsSlider 'tabs »' 'tiddlers, timeline, all, tags, and more'>>
<<tabs txtMainTab "Tidslinie" "Tidslinie" TabTimeline "Alle" "Alle tiddlere" TabAll "Tags" "Alle tags" TabTags "Flere" "Flere lister" TabMore>>
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.8.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler(), Story.prototype.displayTiddlers()|
|Description|Show tiddlers one at a time with automatic permalink, or always open tiddlers at top/bottom of page.|
This plugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one tiddler displayed at a time.
!!!!!Documentation
>see [[SinglePageModePluginInfo]]
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePageKeepFoldedTiddlers>> Don't auto-close folded tiddlers
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
<<option chkTopOfPageMode>> Always open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)
Notes:
* The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}.
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2008.03.14 [2.8.2] in displayTiddler(), if editing specified tiddler, just move it to top/bottom of story *without* re-rendering (prevents discard of partial edits).
| Please see [[SinglePageModePluginInfo]] for previous revision details |
2005.08.15 [1.0.0] Initial Release. Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts.
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageMode= {major: 2, minor: 8, revision: 2, date: new Date(2008,3,14)};
//}}}
//{{{
config.paramifiers.SPM = { onstart: function(v) {
config.options.chkSinglePageMode=eval(v);
if (config.options.chkSinglePageMode && config.options.chkSinglePagePermalink && !config.browser.isSafari) {
config.lastURL = window.location.hash;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
} };
//}}}
//{{{
if (config.options.chkSinglePageMode==undefined) config.options.chkSinglePageMode=false;
if (config.options.chkSinglePageKeepFoldedTiddlers==undefined) config.options.chkSinglePageKeepFoldedTiddlers=true;
if (config.options.chkSinglePagePermalink==undefined) config.options.chkSinglePagePermalink=true;
if (config.options.chkTopOfPageMode==undefined) config.options.chkTopOfPageMode=false;
if (config.options.chkBottomOfPageMode==undefined) config.options.chkBottomOfPageMode=false;
if (config.options.chkSinglePageAutoScroll==undefined) config.options.chkSinglePageAutoScroll=true;
if (config.optionsDesc) {
config.optionsDesc.chkSinglePageMode="Display one tiddler at a time";
config.optionsDesc.chkSinglePageKeepFoldedTiddlers="Don't auto-close folded tiddlers";
config.optionsDesc.chkSinglePagePermalink="Automatically permalink current tiddler";
config.optionsDesc.chkSinglePageAutoScroll="Automatically scroll tiddler into view (if needed)";
config.optionsDesc.chkTopOfPageMode="Always open tiddlers at the top of the page";
config.optionsDesc.chkBottomOfPageMode="Always open tiddlers at the bottom of the page";
} else {
config.shadowTiddlers.AdvancedOptions += "\
\n<<option chkSinglePageMode>> Display one tiddler at a time \
\n<<option chkSinglePageKeepFoldedTiddlers>> Don't auto-close folded tiddlers \
\n<<option chkSinglePagePermalink>> Automatically permalink current tiddler \
\n<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed) \
\n<<option chkTopOfPageMode>> Always open tiddlers at the top of the page \
\n<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page";
}
//}}}
//{{{
config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
if (!config.options.chkSinglePageMode)
{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
if (config.lastURL == window.location.hash) return; // no change in hash
var tids=convertUTF8ToUnicode(decodeURIComponent(window.location.hash.substr(1))).readBracketedList();
if (tids.length==1) // permalink (single tiddler in URL)
story.displayTiddler(null,tids[0]);
else { // restore permaview or default view
config.lastURL = window.location.hash;
if (!tids.length) tids=store.getTiddlerText("DefaultTiddlers").readBracketedList();
story.closeAllTiddlers();
story.displayTiddlers(null,tids);
}
}
if (Story.prototype.SPM_coreDisplayTiddler==undefined)
Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
{
var opt=config.options;
if (opt.chkSinglePageMode) {
// close all tiddlers except current tiddler, tiddlers being edited, and tiddlers that are folded (optional)
story.forEachTiddler(function(tid,elem) {
if ( tid==title
|| elem.getAttribute("dirty")=="true"
|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
return;
story.closeTiddler(tid);
});
}
else if (opt.chkTopOfPageMode)
arguments[0]=null;
else if (opt.chkBottomOfPageMode)
arguments[0]="bottom";
if (opt.chkSinglePageMode && opt.chkSinglePagePermalink && !config.browser.isSafari) {
window.location.hash = encodeURIComponent(convertUnicodeToUTF8(String.encodeTiddlyLink(title)));
config.lastURL = window.location.hash;
document.title = wikifyPlain("SiteTitle") + " - " + title;
if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
}
var tiddlerElem=document.getElementById(story.idPrefix+title); // ==null unless tiddler is already display
if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
var isTopTiddler=(tiddlerElem.previousSibling==null);
if (!isTopTiddler && (opt.chkSinglePageMode || opt.chkTopOfPageMode))
tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
else if (opt.chkBottomOfPageMode)
tiddlerElem.parentNode.insertBefore(tiddlerElem,null);
else this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
} else
this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
var tiddlerElem=document.getElementById(story.idPrefix+title);
if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
var yPos=ensureVisible(tiddlerElem); // scroll to top of tiddler
var isTopTiddler=(tiddlerElem.previousSibling==null);
if (opt.chkSinglePageMode||opt.chkTopOfPageMode||isTopTiddler)
yPos=0; // scroll to top of page instead of top of tiddler
if (opt.chkAnimate) // defer scroll until 200ms after animation completes
setTimeout("window.scrollTo(0,"+yPos+")",config.animDuration+200);
else
window.scrollTo(0,yPos); // scroll immediately
}
}
if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function() {
// suspend single-page mode (and/or top/bottom display options) when showing multiple tiddlers
var opt=config.options;
var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
this.SPM_coreDisplayTiddlers.apply(this,arguments);
opt.chkBottomOfPageMode=saveBPM;
opt.chkTopOfPageMode=saveTPM;
opt.chkSinglePageMode=saveSPM;
}
//}}}
/***
| Name:|SiteMapMacro|
| Author:|Simon Baird|
| Location:|http://simonbaird.com/mptw/#SiteMapMacro|
| Version:|1.0.3, 15-Mar-06|
!!Examples
See SiteMap and SliderSiteMap for example usage.
!!Parameters
* Name of tiddler to start at
* Max depth (a number)
* Format (eg, nested, see formats below)
* Don't show root flag (anything other than null turns it on)
* Tags - a string containing a bracketed list of tags that we are interested in
!!History
* 1.0.3 (15-Mar-06)
** added tag filtering
* 1.0.2 (15-Mar-06)
** Added json format and dontshowroot option
* 1.0.1 (9-Mar-06)
** Added selectable formats and fixed nested slider format
* 1.0.0 (8-Mar-06)
** first release
***/
//{{{
version.extensions.SiteMapMacro = {
major: 1,
minor: 0,
revision: 3,
date: new Date(2006,3,15),
source: "http://simonbaird.com/mptw/#SiteMapMacro"
};
config.macros.siteMap = {
formats: {
bullets: {
formatString: "%0[[%1]]\n%2",
indentString: "*"
},
// put this in your StyleSheet to make it look good.
// .sliderPanel { margin-left: 2em; }
sliders: {
formatString: "[[%1]]+++\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},
openSliders: {
formatString: "[[%1]]++++\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},
popups: {
formatString: "[[%1]]+++^\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},
// these don't work too well
openPopups: {
formatString: "[[%1]]++++^\n%2===\n\n",
formatStringLeaf: "[[%1]]\n"
},
// this is a little nuts but it works
json: {
formatString: '\n%0{"%1":[%2\n%0]}',
formatStringLeaf: '\n%0"%1"',
indentString: " ",
separatorString: ","
}
},
defaultFormat: "bullets",
treeTraverse: function(title,depth,maxdepth,format,dontshowroot,tags,excludetags) {
var tiddler = store.getTiddler(title);
var tagging = store.getTaggedTiddlers(title);
if (dontshowroot)
depth = 0;
var indent = "";
if (this.formats[format].indentString)
for (var j=0;j<depth;j++)
indent += this.formats[format].indentString;
var childOutput = "";
if (!maxdepth || depth < parseInt(maxdepth))
for (var i=0;i<tagging.length;i++)
if (tagging[i].title != title) {
if (this.formats[format].separatorString && i != 0)
childOutput += this.formats[format].separatorString;
childOutput += this.treeTraverse(tagging[i].title,depth+1,maxdepth,format,null,tags,excludetags);
}
if (childOutput == "" && (
(tags && tags != "" && !tiddler.tags.containsAll(tags.readBracketedList())) ||
(excludetags && excludetags != "" && tiddler.tags.containsAny(excludetags.readBracketedList()))
)
) {
// so prune it cos it doesn't have the right tags and neither do any of it's children
return "";
}
if (dontshowroot)
return childOutput;
if (this.formats[format].formatStringLeaf && childOutput == "") {
// required for nestedSliders
return this.formats[format].formatStringLeaf.format([indent,title,childOutput]);
}
return this.formats[format].formatString.format([indent,title,childOutput]);
},
handler: function (place,macroName,params,wikifier,paramString,tiddler) {
wikify(this.treeTraverse(
params[0] && params[0] != '.' ? params[0] : tiddler.title, 1,
params[1] && params[1] != '.' ? params[1] : null, // maxdepth
params[2] && params[2] != '.' ? params[2] : this.defaultFormat, // format
params[3] && params[3] != '.' ? params[3] : null, // dontshowroot
params[4] && params[4] != '.' ? params[4] : null, // tags
params[5] && params[5] != '.' ? params[5] : null // excludetags
),place);
}
}
//}}}
@@font-family: Verdana, sans-serif;Løst og fast@@
@@font-size: 1.5em;''Edb Noter''@@
http://www.youtube.com/experiencewii
<html><div class="csc-header csc-header-n1"><h1 class="csc-firstHeader">Skoleplan </h1></div> <!-- Header: [end] --> <!-- Text: [begin] --> <p class="bodytext">Skoleplan er et effektivt værktøj til at holde styr på arbejdstid, skemalægning, vagtplan, kalender, omsorgsdage og meget andet. </p> <p class="bodytext">Du kan på <a href="http://www.skoleplan.dk/" target="_blank" onclick="javascript:urchinTracker ('/.external/http/www.skoleplan.dk/'); ">www.skoleplan.dk</a> downloade en fuldt fungerende demo-version, som virker i 30 dage efter installationen. Køber skolen en licens til Skoleplan, kan oprettede data i demo-versionen overføres til licens-versionen. </p> <p class="bodytext">Skoleplan anvendes af mere end 75 efterskoler - blandt andet Femmøller Efterskole, Klank Efterskole, Kragelund Efterskole og Nørre Ørslev Ungdomsskole. </p> <p class="bodytext">Skoleplan koster 10.560 kr. + moms pr. licens. </p> <p class="bodytext">Prisen er inkl. et dagskursus og hotline-hjælp i et år. </p> <p class="bodytext">En vedligeholdelsesaftale koster 1.880 kr. pr. år, der inkluderer alle nye versioner og hotline-hjælp. </p> <p class="bodytext">(Priserne er pr. 1.1.2009 og reguleres hver 1/1) </p> <p class="bodytext">Download brochure <a href="fileadmin/bruger_upload/dokumenter/Foreningen/Skoleplan/Skoleplanstorbrochure.pdf" title="Initiates file download" target="_blank" class="download" onclick="javascript:urchinTracker ('fileadmin/bruger_upload/dokumenter/Foreningen/Skoleplan/Skoleplanstorbrochure.pdf'); ">her</a>. </p> <p class="bodytext">Læs mere om <b>kurser</b> <a href="spkurser/" target="_blank">her</a>.</p><p>Source: [[FSL: Skoleplan|http://www.fsl.dk/skoleplan/]]</p></html>
<<siteMap [[Skriv også titlen på dit nye hovedemne her]] . sliders>>
/***
|Name|SnapshotPlugin|
|Source|http://www.TiddlyTools.com/#SnapshotPlugin|
|Documentation|http://www.TiddlyTools.com/#SnapshotPluginInfo|
|Version|1.1.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|save or print HTML+CSS image of rendered document content|
|Status|ALPHA - DO NOT DISTRIBUTE|
This plugin provides a macro as well as tiddler toolbar commands to create a file or browser window containing the //rendered// CSS-and-HTML that is currently being displayed for selected elements of the current document.
!!!!!Documentation
>see [[SnapshotPluginInfo]]
!!!!!Configuration
<<<
<<option chkSnapshotHTMLOnly>> output HTML only (omit CSS)
<<<
!!!!!Revisions
<<<
2008.05.16 [1.1.1] added try..catch around addEvent/removeEvent calls to avoid error in Opera
2008.04.28 [1.1.0] removed 'viewerHTML' from 'ask' droplist and replaced with toggle for "output HTML only". Removed 'noCSS' parameter and replaced with config.options.chkSnapshotHTMLOnly global option. Added "select a tiddler..." to 'ask' droplist
2008.04.24 [1.0.1] in saveSnap(), convert output from Unicode to UTF before passing to saveFile(). Fixes "unknown name" error in IE's file.Write() function. Added viewerHTML to 'ask' droplist.
2008.04.21 [1.0.0] initial release - derived from [[NewDocumentPlugin]] with many improvements, including: "ask for ID" using droplist of available DOM elements, use "<base href=...>" for correctly resolving image references, wrap 'viewer only' output in class="tiddler viewer" for proper application of inherited CSS styles, snapshotSave and snapshotPrint tiddler toolbar command definitions, and more...
<<<
!!!!!Code
***/
//{{{
version.extensions.SnapshotPlugin= {major: 1, minor: 1, revision: 1, date: new Date(2008,5,16)};
if (config.options.chkSnapshotHTMLOnly===undefined) config.options.chkSnapshotHTMLOnly=false;
config.macros.snapshot = {
snapLabel: "save a snapshot",
printLabel: "print a snapshot",
snapPrompt: "save an HTML image of rendered content",
printPrompt: "print an HTML image of rendered content",
hereID: "here",
viewerID: "viewer",
storyID: "story",
allID: "all",
askID: "ask",
askTiddlerID: "askTiddler",
askDOMID: "askDOM",
askMsg: "select an element...",
hereItem: "tiddler: '%0'",
viewerItem: "tiddler: '%0' (content only)",
storyItem: "story column",
allItem: "entire document",
tiddlerItem: "select a tiddler...",
IDItem: "select a DOM element by ID...",
HTMLItem: "[%0] output HTML only (omit CSS)",
fileMsg: "select or enter a target path/filename",
defaultFilename: "snapshot.html",
okmsg: "snapshot written to %0",
failmsg: "An error occurred while creating %0",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var printing=params[0]&¶ms[0]=="print"; if (printing) params.shift();
params = paramString.parseParams("anon",null,true,false,false);
var id=getParam(params,"id","here");
var label=getParam(params,"label",printing?this.printLabel:this.snapLabel);
var prompt=getParam(params,"prompt",printing?this.printPrompt:this.snapPrompt);
var btn=createTiddlyButton(place,label,prompt, function(ev){
this.setAttribute("snapID",this.getAttribute("startID"));
config.macros.snapshot.go(this,ev)
});
btn.setAttribute("startID",id);
btn.setAttribute("snapID",id);
btn.setAttribute("printing",printing?"true":"false");
btn.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
},
go: function(here,ev) {
var cms=config.macros.snapshot; // abbreviation
var id=here.getAttribute("snapID");
var printing=here.getAttribute("printing")=="true";
var HTMLOnly=here.getAttribute("HTMLOnly")=="true";
if (id==cms.askID||id==cms.askTiddlerID||id==cms.askDOMID) {
cms.askForID(here,ev);
} else {
// get element
if (id==cms.storyID) id="tiddlerDisplay";
if (id==cms.allID) id="contentWrapper";
var snapElem=document.getElementById(id);
if (id==cms.hereID || id==cms.viewerID)
var snapElem=story.findContainingTiddler(here);
if (snapElem && hasClass(snapElem,"tiddler") && (id==cms.viewerID || HTMLOnly)) {
// find viewer class element within tiddler element
var nodes=snapElem.getElementsByTagName("*");
for (var i=0; i<nodes.length; i++)
if (hasClass(nodes[i],"viewer")) { snapElem=nodes[i]; break; }
}
if (!snapElem) // not in a tiddler or no viewer element or unknown ID
{ e.cancelBubble=true; if(e.stopPropagation)e.stopPropagation(); return(false); }
// write or print snapshot
var out=cms.getsnap(snapElem,id,printing,HTMLOnly);
if (printing) cms.printsnap(out); else cms.savesnap(out);
}
return false;
},
askForID: function(here,ev) {
var ev = ev ? ev : window.event;
var cms=config.macros.snapshot; // abbreviation
var id=here.getAttribute("snapID");
var indent='\xa0\xa0\xa0\xa0';
var p=Popup.create(here); if (!p) return false; p.className+=' sticky smallform';
var s=createTiddlyElement(p,'select'); s.button=here;
if (id==cms.askID) {
s.options[s.length]=new Option(cms.askMsg,cms.askID);
var tid=story.findContainingTiddler(here);
if(tid) {
var title=tid.getAttribute("tiddler");
if (here.getAttribute("HTMLOnly")!="true")
s.options[s.length]=new Option(indent+cms.hereItem.format([title]),cms.hereID);
s.options[s.length]=new Option(indent+cms.viewerItem.format([title]),cms.viewerID);
}
s.options[s.length]=new Option(indent+cms.tiddlerItem,cms.askTiddlerID);
s.options[s.length]=new Option(indent+cms.IDItem,cms.askDOMID);
s.options[s.length]=new Option(indent+cms.storyItem,"tiddlerDisplay");
s.options[s.length]=new Option(indent+cms.allItem,"contentWrapper");
}
if (id==cms.askDOMID) {
s.options[s.length]=new Option(cms.IDItem,cms.askDOMID);
var elems=document.getElementsByTagName("*");
var ids=[];
for (var i=0;i<elems.length;i++)
if (elems[i].id.length && elems[i].className!="animationContainer")
ids.push(elems[i].id);
ids.sort();
for (var i=0;i<ids.length;i++) s.options[s.length]=new Option(indent+ids[i],ids[i]);
}
if (id==cms.askTiddlerID) {
s.options[s.length]=new Option(cms.tiddlerItem,cms.askTiddlerID);
var elems=document.getElementsByTagName("div");
var ids=[];
for (var i=0;i<elems.length;i++) { var id=elems[i].id;
if (id.length && id.substr(0,story.idPrefix.length)==story.idPrefix && id!="tiddlerDisplay")
ids.push(id);
}
ids.sort();
for (var i=0;i<ids.length;i++) s.options[s.length]=new Option(indent+ids[i].substr(story.idPrefix.length),ids[i]);
}
s.options[s.length]=new Option(cms.HTMLItem.format([here.getAttribute("HTMLOnly")=="true"?"\u221a":"_"]),cms.HTMLItem);
s.onchange=function(ev){
var ev = ev ? ev : window.event;
var cms=config.macros.snapshot; // abbreviation
var here=this.button;
if (this.value==cms.HTMLItem) {
config.options.chkSnapshotHTMLOnly=!config.options.chkSnapshotHTMLOnly;
here.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.option.propagateOption("chkSnapshotHTMLOnly","checked",
config.options.chkSnapshotHTMLOnly,"input");
} else
here.setAttribute("snapID",this.value);
config.macros.snapshot.go(here,ev);
return false;
};
Popup.show(p,false);
ev.cancelBubble=true;
if(ev.stopPropagation)ev.stopPropagation();
return false;
},
getpath: function() {
// get current path
var path=getLocalPath(window.location.href);
var slashpos=path.lastIndexOf("/");
if (slashpos==-1) slashpos=path.lastIndexOf("\\");
if (slashpos!=-1) path=path.substr(0,slashpos+1); // trim filename
return path;
},
getsnap: function(snapElem,id,printing,HTMLOnly) {
var cms=config.macros.snapshot; // abbreviation
var out="";
out+="<html><head>\n";
if (printing)
out+='<base href="file:///'+cms.getpath().replace(/\\/g,'/')+'"></base>\n';
if (!HTMLOnly) {
var styles=document.getElementsByTagName("style");
for(var i=0; i < styles.length; i++) {
out+="<style>\n";
out+="/* stylesheet="+styles[i].getAttribute("id")+" */\n";
out+=styles[i].innerHTML+"\n\n";
out+="</style>\n";
}
}
out+="</head><body>\n\n<div"+(id==cms.viewerID?" class='tiddler viewer'>":">");
out+=snapElem.innerHTML;
out+="</div>\n\n</body>\n";
out+="</html>";
return out;
},
printsnap: function(out) {
var win=window.open("","_blank","");
win.document.open();
win.document.writeln(out);
win.document.close();
win.focus(); // bring to front
win.print(); // trigger print dialog
},
savesnap: function(out) {
var cms=config.macros.snapshot; // abbreviation
// make sure we are local
if (window.location.protocol!="file:")
{ alert(config.messages.notFileUrlError); return; }
var target=cms.askForFilename(cms.fileMsg,cms.getpath(),cms.defaultFilename);
if (!target) return; // cancelled by user
// if specified file does not include a path, assemble fully qualified path and filename
var slashpos=target.lastIndexOf("/");
if (slashpos==-1) slashpos=target.lastIndexOf("\\");
if (slashpos==-1) target=target+cms.defaultFilename;
var link="file:///"+target.replace(/\\/g,'/'); // link for message text
var ok=saveFile(target,convertUnicodeToUTF8(out));
var msg=ok?cms.okmsg.format([target]):cms.failmsg.format([target]);
clearMessage(); displayMessage(msg,link);
},
askForFilename: function(msg,path,file) {
if(window.Components) { // moz
try {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var nsIFilePicker = window.Components.interfaces.nsIFilePicker;
var picker = Components.classes['@mozilla.org/filepicker;1'].createInstance(nsIFilePicker);
picker.init(window, msg, nsIFilePicker.modeSave);
var thispath = Components.classes['@mozilla.org/file/local;1'].createInstance(Components.interfaces.nsILocalFile);
thispath.initWithPath(path);
picker.displayDirectory=thispath;
picker.defaultExtension='html';
picker.defaultString=file;
picker.appendFilters(nsIFilePicker.filterAll|nsIFilePicker.filterText|nsIFilePicker.filterHTML);
if (picker.show()!=nsIFilePicker.returnCancel) var result=picker.file.persistentDescriptor;
}
catch(e) { alert('error during local file access: '+e.toString()) }
}
else { // IE
try { // XP/Vista only
var s = new ActiveXObject('UserAccounts.CommonDialog');
s.Filter='All files|*.*|Text files|*.txt|HTML files|*.htm;*.html|';
s.FilterIndex=3; // default to HTML files;
s.InitialDir=path;
s.FileName=file;
if (s.showOpen()) var result=s.FileName;
}
catch(e) { var result=prompt(msg,path+file); } // fallback for non-XP IE
}
return result;
}
};
//}}}
// // TOOLBAR DEFINITIONS
//{{{
config.commands.snapshotSave = {
text: "snap",
tooltip: config.macros.snapshot.snapPrompt,
handler: function(ev,src,title) {
src.setAttribute("snapID","ask");
src.setAttribute("printing","false");
src.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.snapshot.go(src,ev);
return false;
}
};
config.commands.snapshotPrint = {
text: "print",
tooltip: config.macros.snapshot.printPrompt,
handler: function(ev,src,title) {
src.setAttribute("snapID","ask");
src.setAttribute("printing","true");
src.setAttribute("HTMLOnly",config.options.chkSnapshotHTMLOnly?"true":"false");
config.macros.snapshot.go(src,ev);
return false;
}
};
//}}}
// // COPIED FROM [[StickyPopupPlugin]] TO ELIMINATE PLUGIN DEPENDENCY
//{{{
if (config.options.chkStickyPopups==undefined) config.options.chkStickyPopups=false;
Popup.stickyPopup_onDocumentClick = function(ev)
{
// if click is in a sticky popup, ignore it so popup will remain visible
var e = ev ? ev : window.event; var target = resolveTarget(e);
var p=target; while (p) {
if (hasClass(p,"popup") && (hasClass(p,"sticky")||config.options.chkStickyPopups)) break;
else p=p.parentNode;
}
if (!p) // not in sticky popup (or sticky popups disabled)... use normal click handling
Popup.onDocumentClick(ev);
return true;
};
try{removeEvent(document,"click",Popup.onDocumentClick);}catch(e){};
try{addEvent(document,"click",Popup.stickyPopup_onDocumentClick);}catch(e){};
//}}}
/***
|Name|SnapshotPluginInfo|
|Source|http://www.TiddlyTools.com/#SnapshotPlugin|
|Documentation|http://www.TiddlyTools.com/#SnapshotPluginInfo|
|Version|1.1.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|documentation|
|Requires||
|Overrides||
|Description|Documentation for SnapshotPlugin|
This plugin provides a macro as well as tiddler toolbar commands that creates a file or opens a new browser window containing the //rendered// HTML and CSS style definitions that are being displayed for selected elements of the current document.
!!!!!Usage:
<<<
As a macro embedded in tiddler content:
{{{
<<snapshot print label:text prompt:text id:elementID|here|viewer|story|all|ask>
}}}
where:
*''print'' //(optional)//<br>when present, causes the snapshot output to be directed to a new browser tab/window instead of saving it to a file. In addition, the print dialog for that tab/window is automatically invoked.
*''label'' //(optional)//<br>is the text to be displayed for the command link generated by the macro
*''prompt'' //(optional)//<br>is the 'tool tip' message displayed when you mouseover the command link
*''id:...'' //(optional)//<br>specifies the document element to be captured, and can be one of:
**''elementID''<br>is a specific DOM element ID, such as "displayArea", "mainMenu", "contentWrapper", etc.
**''here''<br>the containing tiddler in which the macro (or toolbar command) occurs, including the tiddler title and subtitle (date/time/author) information.
**''viewer''<br>same as ''here'', but omits the tiddler title, subtitle and toolbar elements (i.e., it includes //only// the content of the tiddler)
**''story''<br>selects all currently displayed tiddlers (i.e., the 'story column')
**''all''<br>selects the entire document contents, including page header, main menu and sidebar displays
**''ask''<br>when the snapshot command link is clicked, a droplist is displayed so you can choose from several pre-defined elements: "current tiddler", "story column", or "entire document", or "DOM element ID..." When DOM element ID is chosen, the droplist is refreshed to show the individual ID's for all currently rendered DOM elements (at least, the ones that have ID's). For any given DOM element ID, only the portions of the document that are contained //within// the specified DOM element will be transcribed to the resulting snapshot or print output.
//''NOTE: when no parameters are specified, the macro creates a snapshot file using the containing tiddler as the default element.'' (e.g., equivalent to {{{<<snapshot id:here>>}}}//
The snapshot/print functions can also be embedded as tiddler toolbar commands in [[ViewTemplate]]:
{{{
<span class='toolbar' macro='toolbar snapshotSave'></span>
<span class='toolbar' macro='toolbar snapshotPrint'></span>
}}}
* when invoked via toolbar commands, the "id:ask" option is automatically applied, and a droplist of elements to choose from is displayed.
Please note that, although the snapshot/print that is created using the HTML+CSS of the displayed content, ''there is NO javascript code'' written into the snapshot. As a result, the snapshot only ''reproduces the //appearance// of the displayed content, allowing you to //view// or //print// the result'', but does not permit you to interact with it in other ways.
For example, even simple processing (such as mouseover highlighting) will not function from the snapshot. You can't click a TiddlyLink to open other tiddlers, because A) there is no code that handles the click and B) there is no underlying 'storeArea' (and core code) to retrieve and render anything! You also can't use ANY command links, since these also require javascript code (and the core) to operate.
<<<
!!!!!Examples:
<<<
{{{<<snapshot>>}}}: <<snapshot>>
{{{<<snapshot id:mainMenu>>}}}: <<snapshot id:mainMenu>>
{{{<<snapshot print id:story>>}}}: <<snapshot print id:story>>
{{{<<snapshot print id:ask>>}}}: <<snapshot print id:ask>>
{{{<<snapshot print noCSS id:viewer>>}}}: <<snapshot print noCSS id:viewer>>
<<<
!!!!!Configuration
<<<
<<option chkSnapshotHTMLOnly>> output HTML only (omit CSS)
<<<
!!!!!Revisions
<<<
2008.05.16 [1.1.1] added try..catch around addEvent/removeEvent calls to avoid error in Opera
2008.04.28 [1.1.0] removed 'viewerHTML' from 'ask' droplist and replaced with toggle for "output HTML only". Removed 'noCSS' parameter and replaced with config.options.chkSnapshotHTMLOnly global option. Added "select a tiddler..." to 'ask' droplist
2008.04.24 [1.0.1] in saveSnap(), convert output from Unicode to UTF before passing to saveFile(). Fixes "unknown name" error in IE's file.Write() function.
2008.04.21 [1.0.0] initial release - derived from [[NewDocumentPlugin]] with many improvements, including: "ask for ID" using droplist of available DOM elements, use "<base href=...>" for correctly resolving image references, wrap 'viewer only' output in class="tiddler viewer" for proper application of inherited CSS styles, snapshotSave and snapshotPrint tiddler toolbar command definitions, and more...
<<<
/***
''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''
|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.
!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.
!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.
!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release
!Code
***/
//{{{
var old_lewcid_splash_restart=restart;
restart = function()
{ if (document.getElementById("SplashScreen"))
document.getElementById("SplashScreen").style.display = "none";
if (document.getElementById("contentWrapper"))
document.getElementById("contentWrapper").style.display = "block";
old_lewcid_splash_restart();
if (splashScreenInstall)
{if(config.options.chkAutoSave)
{saveChanges();}
displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
}
}
var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
{var siteTitle = store.getTiddlerText("SiteTitle");
var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
if (! store.tiddlerExists("MarkupPreHead"))
{var myTiddler = store.createTiddler("MarkupPreHead");}
else
{var myTiddler = store.getTiddler("MarkupPreHead");}
myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
store.setDirty(true);
var splashScreenInstall = true;
}
//}}}
| Direkte link: [[Behovsanalyse|http://spreadsheets.google.com/viewform?formkey=cHFkeS0tU2FYcDV6c2dGcmRTZl9IUEE6MA..]] | <<tiddler [[Svar på spørgeskemaet]]>> |
|<html><center><iframe src="http://spreadsheets.google.com/embeddedform?key=pqdy--SaXp5zsgFrdSf_HPA" width="410" height="3650" frameborder="0" marginheight="0" marginwidth="0">Indlæser ...</iframe></center></html>| <html><center><iframe src="http://spreadsheets.google.com/gform?key=pqdy--SaXp5zsgFrdSf_HPA#chart" width="510" height="3650" frameborder="0" marginheight="0" marginwidth="0">Indlæser ...</iframe></center></html>|
/*{{{*/
#sidebar { position:fixed; }
#mainMenu { position:fixed; }
#sidebarTabs .tabContents
{ height:25em; overflow:auto; width:92.5%; }
#sidebarTabs .tabContents .tabContents
{ height:21em !important; }
/*FLERE KOLONNER*/
.redtest { color: red; font-size:12pt; }
/* multi-column tiddler content (not supported in Internet Explorer) */
.twocolumns { display:block;
-moz-column-count:2; -moz-column-gap:1em; -moz-column-width:50%; /* FireFox */
-webkit-column-count:2; -webkit-column-gap:1em; -webkit-column-width:50%; /* Safari */
column-count:2; column-gap:1em; column-width:50%; /* Opera */
}
.threecolumns { display:block;
-moz-column-count:3; -moz-column-gap:1em; -moz-column-width:33%; /* FireFox */
-webkit-column-count:3; -webkit-column-gap:1em; -webkit-column-width:33%; /* Safari */
column-count:3; column-gap:1em; column-width:33%; /* Opera */
}
.fourcolumns { display:block;
-moz-column-count:4; -moz-column-gap:1em; -moz-column-width:25%; /* FireFox */
-webkit-column-count:4; -webkit-column-gap:1em; -webkit-column-width:25%; /* Safari */
column-count:4; column-gap:1em; column-width:25%; /* Opera */
}
/*FONT STUFF*/
body {font-family: Verdana; font-size: 10pt;}
h1,h2,h3,h4,h5 { color: #8899ff; background: white; font-family: Verdana; border-bottom: none;}
.editor a {color:#dddddd;}
#editor a {color:#dddddd;}
.nowrap { white-space:nowrap;}
.bluey {font-weight: bold; color: #5566ff; font-size: 1.3em;}
.toolbar a {color:#5566ff;}
.selected .toolbar a {color:#5566ff;}
.selected .toolbar a:hover {color:#5566ff;}
/* SHORTENS THE HEIGHT OF THE HEADER */
.headerShadow {padding: 1em 0em .8em 1em;}
.headerForeground {padding: 1em 0em .8em 1em;}
.siteTitle {font-size:1.5em;}
.siteSubtitle {font-size:1em;}
/*MAINMENU*/
#mainMenu {width: 15.5em; text-align: left; font-size: .85em;}
#displayArea {margin: 0em 15em 0em 15.5em;}
.sliderPanel { margin-left: 1em; }
/*TABLE HEADER*/
.viewer th {color: #000; background-color: #eeeeee;}
/*TIDDLER TOPMARGIN AND BUTTON BORDER*/
a.button{border: 0;}
.viewer { margin-top: .5em; }
.viewer {line-height: 1.7em;}
/*TIDDLER TITLE COLOR MATCH BOTTOM OF HEADER*/
.title {color:[[ColorPalette::PrimaryMid]];}
/*UNORDERED and ORDERED LISTS TWEAK*/
.viewer li {padding-top: 0.5em; padding-bottom: 0.5em;}
/*LINELESS BLOCKQUOTES*/
.viewer blockquote {border-left: 0px; margin-top:0em; margin-bottom:0em; }
/*INVISIBLE TABLE*/
.viewer .invisiblecomm table {border-color: white;}
.viewer .invisiblecomm table td { font-size: 1em; font-family: Verdana; border-color: white; padding: 10px 20px 10px 0px; text-align: left; vertical-align: top; padding: 20px;}
.viewer .invisiblecomm table th { color: #005566; background-color: white; border-color: white; font-family: Verdana; font-size: 1.2em; font-weight: bold; padding: 10px 20px 10px 0px; text-align: left; vertical-align: top;}
.viewer .invisiblecomm table tr.leftColumn { background-color: #bbbbbb; }
/*TOPMENU*/
#topMenu {padding-left: 1em; background-color: #aabbff; color: #110077; font-family: Trebuchet MS, Verdana; font-size: 13pt; line-height: 1.6em;}
#topMenu table td {margin: 10px;}
#topMenu .purple a {color: #0055dd;}
/*ROUNDED CORNERS AND BORDERS*/
.tiddler {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
border-bottom: 3px solid #ccc;
border-right: 3px solid #ccc;
margin: 0.5em;
background:#fff;
padding: 0.5em;
-moz-border-radius: 1em; }
#messageArea {
background-color: #eee;
border-color: #8ab;
border-width: 4px;
border-style: dotted;
font-size: 90%;
padding: 0.5em;
-moz-border-radius: 1em; }
/*TagglyTag styles*/
.tagglyTagged li.listTitle { display:none;}
.tagglyTagged li { display: inline; font-size:90%; }
.tagglyTagged ul { margin:0px; padding:0px; }
.tagglyTagging { padding-top:0.5em; }
.tagglyTagging li.listTitle { display:none;}
.tagglyTagging ul { margin-top:0px; padding-top:0.5em; padding-left:2em; margin-bottom:0px; padding-bottom:0px; }
/* .tagglyTagging .tghide { display:inline; } */
.tagglyTagging { vertical-align: top; margin:0px; padding:0px; }
.tagglyTagging table { margin:0px; padding:0px; }
.tagglyTagging .button { display:none; margin-left:3px; margin-right:3px; }
.tagglyTagging .button, .tagglyTagging .hidebutton { color:#aaa; font-size:90%; border:0px; padding-left:0.3em;padding-right:0.3em;}
.tagglyTagging .button:hover, .hidebutton:hover { background:#eee; color:#888; }
.selected .tagglyTagging .button { display:inline; }
.tagglyTagging .hidebutton { color:white; } /* has to be there so it takes up space. tweak if you're not using a white tiddler bg */
.selected .tagglyTagging .hidebutton { color:#aaa }
.tagglyLabel { color:#aaa; font-size:90%; }
.tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }
.tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}
.tagglyTagging ul ul li {margin-left:0.5em; }
.editLabel { font-size:90%; padding-top:0.5em; }
[[StyleSheetShortcuts]]
/* GIFFMEX TWEAKS TO STYLESHEETPRINT (so that nothing but tiddler title and text are printed) */
@media print {#mainMenu {display: none ! important;}}
@media print {#topMenu {display: none ! important;}}
@media print {#sidebar {display: none ! important;}}
@media print {#messageArea {display: none ! important;}}
@media print {#toolbar {display: none ! important;}}
@media print {.header {display: none ! important;}}
@media print {.tiddler .subtitle {display: none ! important;}}
@media print {.tiddler .toolbar {display; none ! important; }}
@media print {.tiddler .tagging {display; none ! important; }}
@media print {.tiddler .tagged {display; none ! important; }}
@media print {#displayArea {margin: 1em 1em 0em 1em;}}
@media print {.pageBreak {page-break-before: always;}}
/*}}}*/
/*{{{*/
#channelBox {background:#BBBB33;}
#newChannelBox {background:#33BBBB;}
#subscriptionBox {background:#CCCC22;}
#newSubscriptionBox {background:#22CCCC;}
.publishing, .unread {
background-color: #EEEEEE;
border: 1px solid #EEEEEE;
float: right;
margin: 0.5em;
font-size: 0.9em;
padding: 0.25em;
}
.selected .publishing, .selected .unread {
background-color: #CCCCCC;
border: 1px solid #999999;
}
.publishing .button, .unread .button {
border: medium none;
}
.publishing ul {
list-style-image: none;
list-style-position: outside;
list-style-type: none;
margin: 0.25em;
padding: 0pt;
}
tr.tiddlyChatterIncomingRowUnread {
background-color: #C44;
}
/*}}}*/
<html><span>Well done for setting up TiddlyChatter. This is some test content on http://tiddlychatter.tiddlyspot.com - feel free to add some notes...</span></html>
<html>crumbs. chattering!</html>
http://spreadsheets.google.com/gform?key=pqdy--SaXp5zsgFrdSf_HPA#chart
<<getTiddlerPassword turnus>>
<script>
var out=[];
var row='|%0|%1|%2|%3|';
out.push('| # | Titel | Type | Beskrivelse |h'); // headings
var tids=store.getTaggedTiddlers('download');
for (var i=0; i<tids.length; i++) {
var ti=store.getTiddlerSlice(tids[i].title,'Titel');
var ty=store.getTiddlerSlice(tids[i].title,'Type');
var b='<<tiddler [['+tids[i].title+'##Beskrivelse]]>>';
out.push(row.format([i+1,ti,ty,b]));
}
out.push('|sortable|k');out.push('i alt ='+tids.length); // table class
return out.join('\n');
</script>
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.2.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|present a 'cloud' of tags using proportional font display|
!Usage
<<<
{{{<<tagCloud>>}}}
> show all tags in the document
{{{<<tagCloud tag tag tag...>>}}}
> show all tags except those listed as parameters
{{{<<tagCloud =tagvalue>>}}}
> show only tags that are themselves tagged with the indicated tag value (i.e., ~TagglyTagging usage)
<<<
!Examples
<<<
{{{<<tagCloud>>}}}
<<tagCloud>>
----
{{{<<tagCloud =package>>}}}
<<tagCloud =package>>
<<<
!Revisions
<<<
2008.09.05 [1.2.0] ELS: added '=tagname' parameter to include only tags that are themselves tagged with the specified value (i.e., ~TagglyTagging usage)
2008.07.03 [1.1.0] ELS: added 'segments' property to macro object. Extensive code cleanup
<<<
!Code
***/
//{{{
version.extensions.tagCloud = {major: 1, minor: 2 , revision: 0, date: new Date(2008,9,5)};
//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
config.shadowTiddlers.TagCloud="<<tagCloud>>";
setStylesheet("\
.tagCloud span{height: 3.5em;margin: 3px;}\
.tagCloud1{font-size: 80%;}\
.tagCloud2{font-size: 100%;}\
.tagCloud3{font-size: 120%;}\
.tagCloud4{font-size: 150%;}\
.tagCloud5{font-size: 180%;}\
.tagCloud6{font-size: 200%;}\
",
"tagCloudsStyles");
config.macros.tagCloud = {
noTags: "No tag cloud created because there are no tags.",
tooltip: "%1 tiddlers tagged with '%0'",
segments: 5,
handler: function(place,macroName,params) {
var tags=store.getTags();
if (params.length) {
if (params[0].substr(0,1)=="=") {
// include only specifically tagged tags
var tagged=store.getTaggedTiddlers(params[0].substr(1));
for (var t=0; t<tagged.length; t++)
tagged[t]=tagged[t].title;
for (var t=0; t<tags.length; t++)
if (!tagged.contains(tags[t][0])) tags[t][0]="";
} else {
// include all tags except those listed as params
for (var t=0; t<tags.length; t++)
if (params.contains(tags[t][0])) tags[t][0]="";
}
}
// get maximum number of tags to calculate tagCloud segment sizes
var mostTags=0;
for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0)
if (tags[t][1]>mostTags) mostTags=tags[t][1];
var tagSegment=mostTags/config.macros.tagCloud.segments;
// output
var tagCloudWrapper = createTiddlyElement(place,"div",null,"tagCloud",null);
if(!tags.length)
createTiddlyElement(tagCloudWrapper,"span",null,null,this.noTags);
else for (var t=0; t<tags.length; t++) if (tags[t][0].length > 0){
tagCloudWrapper.appendChild(document.createTextNode(" "));
var theTag = createTiddlyButton(tagCloudWrapper,
tags[t][0],this.tooltip.format(tags[t]),onClickTag,
"tagCloudtag tagCloud" + (Math.round(tags[t][1]/tagSegment)+1));
theTag.setAttribute("tag",tags[t][0]);
}
}
};
//}}}
/***
|Name:|TagglyTaggingPlugin|
|Description:|tagglyTagging macro is a replacement for the builtin tagging macro in your ViewTemplate|
|Version:|3.3.1 ($Rev: 6100 $)|
|Date:|$Date: 2008-07-27 01:42:07 +1000 (Sun, 27 Jul 2008) $|
|Source:|http://mptw.tiddlyspot.com/#TagglyTaggingPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!Notes
See http://mptw.tiddlyspot.com/#TagglyTagging
***/
//{{{
merge(String.prototype,{
parseTagExpr: function(debug) {
if (this.trim() == "")
return "(true)";
var anyLogicOp = /(!|&&|\|\||\(|\))/g;
var singleLogicOp = /^(!|&&|\|\||\(|\))$/;
var spaced = this.
// because square brackets in templates are no good
// this means you can use [(With Spaces)] instead of [[With Spaces]]
replace(/\[\(/g," [[").
replace(/\)\]/g,"]] ").
// space things out so we can use readBracketedList. tricky eh?
replace(anyLogicOp," $1 ");
var expr = "";
var tokens = spaced.readBracketedList(false); // false means don't uniq the list. nice one JR!
for (var i=0;i<tokens.length;i++)
if (tokens[i].match(singleLogicOp))
expr += tokens[i];
else
expr += "tiddler.tags.contains('%0')".format([tokens[i].replace(/'/,"\\'")]); // fix single quote bug. still have round bracket bug i think
if (debug)
alert(expr);
return '('+expr+')';
}
});
merge(TiddlyWiki.prototype,{
getTiddlersByTagExpr: function(tagExpr,sortField) {
var result = [];
var expr = tagExpr.parseTagExpr();
store.forEachTiddler(function(title,tiddler) {
if (eval(expr))
result.push(tiddler);
});
if(!sortField)
sortField = "title";
result.sort(function(a,b) {return a[sortField] < b[sortField] ? -1 : (a[sortField] == b[sortField] ? 0 : +1);});
return result;
}
});
config.taggly = {
// for translations
lingo: {
labels: {
asc: "\u2191", // down arrow
desc: "\u2193", // up arrow
title: "title",
modified: "modified",
created: "created",
show: "+",
hide: "-",
normal: "normal",
group: "group",
commas: "commas",
sitemap: "sitemap",
numCols: "cols\u00b1", // plus minus sign
label: "Tagged as '%0':",
exprLabel: "Matching tag expression '%0':",
excerpts: "excerpts",
descr: "descr",
slices: "slices",
contents: "contents",
sliders: "sliders",
noexcerpts: "title only",
noneFound: "(none)"
},
tooltips: {
title: "Click to sort by title",
modified: "Click to sort by modified date",
created: "Click to sort by created date",
show: "Click to show tagging list",
hide: "Click to hide tagging list",
normal: "Click to show a normal ungrouped list",
group: "Click to show list grouped by tag",
sitemap: "Click to show a sitemap style list",
commas: "Click to show a comma separated list",
numCols: "Click to change number of columns",
excerpts: "Click to show excerpts",
descr: "Click to show the description slice",
slices: "Click to show all slices",
contents: "Click to show entire tiddler contents",
sliders: "Click to show tiddler contents in sliders",
noexcerpts: "Click to show entire title only"
},
tooDeepMessage: "* //sitemap too deep...//"
},
config: {
showTaggingCounts: true,
listOpts: {
// the first one will be the default
sortBy: ["title","modified","created"],
sortOrder: ["asc","desc"],
hideState: ["show","hide"],
listMode: ["normal","group","sitemap","commas"],
numCols: ["1","2","3","4","5","6"],
excerpts: ["noexcerpts","excerpts","descr","slices","contents","sliders"]
},
valuePrefix: "taggly.",
excludeTags: ["excludeLists","excludeTagging"],
excerptSize: 50,
excerptMarker: "/%"+"%/",
siteMapDepthLimit: 25
},
getTagglyOpt: function(title,opt) {
var val = store.getValue(title,this.config.valuePrefix+opt);
return val ? val : this.config.listOpts[opt][0];
},
setTagglyOpt: function(title,opt,value) {
if (!store.tiddlerExists(title))
// create it silently
store.saveTiddler(title,title,config.views.editor.defaultText.format([title]),config.options.txtUserName,new Date(),"");
// if value is default then remove it to save space
return store.setValue(title,
this.config.valuePrefix+opt,
value == this.config.listOpts[opt][0] ? null : value);
},
getNextValue: function(title,opt) {
var current = this.getTagglyOpt(title,opt);
var pos = this.config.listOpts[opt].indexOf(current);
// a little usability enhancement. actually it doesn't work right for grouped or sitemap
var limit = (opt == "numCols" ? store.getTiddlersByTagExpr(title).length : this.config.listOpts[opt].length);
var newPos = (pos + 1) % limit;
return this.config.listOpts[opt][newPos];
},
toggleTagglyOpt: function(title,opt) {
var newVal = this.getNextValue(title,opt);
this.setTagglyOpt(title,opt,newVal);
},
createListControl: function(place,title,type) {
var lingo = config.taggly.lingo;
var label;
var tooltip;
var onclick;
if ((type == "title" || type == "modified" || type == "created")) {
// "special" controls. a little tricky. derived from sortOrder and sortBy
label = lingo.labels[type];
tooltip = lingo.tooltips[type];
if (this.getTagglyOpt(title,"sortBy") == type) {
label += lingo.labels[this.getTagglyOpt(title,"sortOrder")];
onclick = function() {
config.taggly.toggleTagglyOpt(title,"sortOrder");
return false;
}
}
else {
onclick = function() {
config.taggly.setTagglyOpt(title,"sortBy",type);
config.taggly.setTagglyOpt(title,"sortOrder",config.taggly.config.listOpts.sortOrder[0]);
return false;
}
}
}
else {
// "regular" controls, nice and simple
label = lingo.labels[type == "numCols" ? type : this.getNextValue(title,type)];
tooltip = lingo.tooltips[type == "numCols" ? type : this.getNextValue(title,type)];
onclick = function() {
config.taggly.toggleTagglyOpt(title,type);
return false;
}
}
// hide button because commas don't have columns
if (!(this.getTagglyOpt(title,"listMode") == "commas" && type == "numCols"))
createTiddlyButton(place,label,tooltip,onclick,type == "hideState" ? "hidebutton" : "button");
},
makeColumns: function(orig,numCols) {
var listSize = orig.length;
var colSize = listSize/numCols;
var remainder = listSize % numCols;
var upperColsize = colSize;
var lowerColsize = colSize;
if (colSize != Math.floor(colSize)) {
// it's not an exact fit so..
upperColsize = Math.floor(colSize) + 1;
lowerColsize = Math.floor(colSize);
}
var output = [];
var c = 0;
for (var j=0;j<numCols;j++) {
var singleCol = [];
var thisSize = j < remainder ? upperColsize : lowerColsize;
for (var i=0;i<thisSize;i++)
singleCol.push(orig[c++]);
output.push(singleCol);
}
return output;
},
drawTable: function(place,columns,theClass) {
var newTable = createTiddlyElement(place,"table",null,theClass);
var newTbody = createTiddlyElement(newTable,"tbody");
var newTr = createTiddlyElement(newTbody,"tr");
for (var j=0;j<columns.length;j++) {
var colOutput = "";
for (var i=0;i<columns[j].length;i++)
colOutput += columns[j][i];
var newTd = createTiddlyElement(newTr,"td",null,"tagglyTagging"); // todo should not need this class
wikify(colOutput,newTd);
}
return newTable;
},
createTagglyList: function(place,title,isTagExpr) {
switch(this.getTagglyOpt(title,"listMode")) {
case "group": return this.createTagglyListGrouped(place,title,isTagExpr); break;
case "normal": return this.createTagglyListNormal(place,title,false,isTagExpr); break;
case "commas": return this.createTagglyListNormal(place,title,true,isTagExpr); break;
case "sitemap":return this.createTagglyListSiteMap(place,title,isTagExpr); break;
}
},
getTaggingCount: function(title,isTagExpr) {
// thanks to Doug Edmunds
if (this.config.showTaggingCounts) {
var tagCount = config.taggly.getTiddlers(title,'title',isTagExpr).length;
if (tagCount > 0)
return " ("+tagCount+")";
}
return "";
},
getTiddlers: function(titleOrExpr,sortBy,isTagExpr) {
return isTagExpr ? store.getTiddlersByTagExpr(titleOrExpr,sortBy) : store.getTaggedTiddlers(titleOrExpr,sortBy);
},
getExcerpt: function(inTiddlerTitle,title,indent) {
if (!indent)
indent = 1;
var displayMode = this.getTagglyOpt(inTiddlerTitle,"excerpts");
var t = store.getTiddler(title);
if (t && displayMode == "excerpts") {
var text = t.text.replace(/\n/," ");
var marker = text.indexOf(this.config.excerptMarker);
if (marker != -1) {
return " {{excerpt{<nowiki>" + text.substr(0,marker) + "</nowiki>}}}";
}
else if (text.length < this.config.excerptSize) {
return " {{excerpt{<nowiki>" + t.text + "</nowiki>}}}";
}
else {
return " {{excerpt{<nowiki>" + t.text.substr(0,this.config.excerptSize) + "..." + "</nowiki>}}}";
}
}
else if (t && displayMode == "contents") {
return "\n{{contents indent"+indent+"{\n" + t.text + "\n}}}";
}
else if (t && displayMode == "sliders") {
return "<slider slide>\n{{contents{\n" + t.text + "\n}}}\n</slider>";
}
else if (t && displayMode == "descr") {
var descr = store.getTiddlerSlice(title,'Description');
return descr ? " {{excerpt{" + descr + "}}}" : "";
}
else if (t && displayMode == "slices") {
var result = "";
var slices = store.calcAllSlices(title);
for (var s in slices)
result += "|%0|<nowiki>%1</nowiki>|\n".format([s,slices[s]]);
return result ? "\n{{excerpt excerptIndent{\n" + result + "}}}" : "";
}
return "";
},
notHidden: function(t,inTiddler) {
if (typeof t == "string")
t = store.getTiddler(t);
return (!t || !t.tags.containsAny(this.config.excludeTags) ||
(inTiddler && this.config.excludeTags.contains(inTiddler)));
},
// this is for normal and commas mode
createTagglyListNormal: function(place,title,useCommas,isTagExpr) {
var list = config.taggly.getTiddlers(title,this.getTagglyOpt(title,"sortBy"),isTagExpr);
if (this.getTagglyOpt(title,"sortOrder") == "desc")
list = list.reverse();
var output = [];
var first = true;
for (var i=0;i<list.length;i++) {
if (this.notHidden(list[i],title)) {
var countString = this.getTaggingCount(list[i].title);
var excerpt = this.getExcerpt(title,list[i].title);
if (useCommas)
output.push((first ? "" : ", ") + "[[" + list[i].title + "]]" + countString + excerpt);
else
output.push("*[[" + list[i].title + "]]" + countString + excerpt + "\n");
first = false;
}
}
return this.drawTable(place,
this.makeColumns(output,useCommas ? 1 : parseInt(this.getTagglyOpt(title,"numCols"))),
useCommas ? "commas" : "normal");
},
// this is for the "grouped" mode
createTagglyListGrouped: function(place,title,isTagExpr) {
var sortBy = this.getTagglyOpt(title,"sortBy");
var sortOrder = this.getTagglyOpt(title,"sortOrder");
var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);
if (sortOrder == "desc")
list = list.reverse();
var leftOvers = []
for (var i=0;i<list.length;i++)
leftOvers.push(list[i].title);
var allTagsHolder = {};
for (var i=0;i<list.length;i++) {
for (var j=0;j<list[i].tags.length;j++) {
if (list[i].tags[j] != title) { // not this tiddler
if (this.notHidden(list[i].tags[j],title)) {
if (!allTagsHolder[list[i].tags[j]])
allTagsHolder[list[i].tags[j]] = "";
if (this.notHidden(list[i],title)) {
allTagsHolder[list[i].tags[j]] += "**[["+list[i].title+"]]"
+ this.getTaggingCount(list[i].title) + this.getExcerpt(title,list[i].title) + "\n";
leftOvers.setItem(list[i].title,-1); // remove from leftovers. at the end it will contain the leftovers
}
}
}
}
}
var allTags = [];
for (var t in allTagsHolder)
allTags.push(t);
var sortHelper = function(a,b) {
if (a == b) return 0;
if (a < b) return -1;
return 1;
};
allTags.sort(function(a,b) {
var tidA = store.getTiddler(a);
var tidB = store.getTiddler(b);
if (sortBy == "title") return sortHelper(a,b);
else if (!tidA && !tidB) return 0;
else if (!tidA) return -1;
else if (!tidB) return +1;
else return sortHelper(tidA[sortBy],tidB[sortBy]);
});
var leftOverOutput = "";
for (var i=0;i<leftOvers.length;i++)
if (this.notHidden(leftOvers[i],title))
leftOverOutput += "*[["+leftOvers[i]+"]]" + this.getTaggingCount(leftOvers[i]) + this.getExcerpt(title,leftOvers[i]) + "\n";
var output = [];
if (sortOrder == "desc")
allTags.reverse();
else if (leftOverOutput != "")
// leftovers first...
output.push(leftOverOutput);
for (var i=0;i<allTags.length;i++)
if (allTagsHolder[allTags[i]] != "")
output.push("*[["+allTags[i]+"]]" + this.getTaggingCount(allTags[i]) + this.getExcerpt(title,allTags[i]) + "\n" + allTagsHolder[allTags[i]]);
if (sortOrder == "desc" && leftOverOutput != "")
// leftovers last...
output.push(leftOverOutput);
return this.drawTable(place,
this.makeColumns(output,parseInt(this.getTagglyOpt(title,"numCols"))),
"grouped");
},
// used to build site map
treeTraverse: function(title,depth,sortBy,sortOrder,isTagExpr) {
var list = config.taggly.getTiddlers(title,sortBy,isTagExpr);
if (sortOrder == "desc")
list.reverse();
var indent = "";
for (var j=0;j<depth;j++)
indent += "*"
var childOutput = "";
if (depth > this.config.siteMapDepthLimit)
childOutput += indent + this.lingo.tooDeepMessage;
else
for (var i=0;i<list.length;i++)
if (list[i].title != title)
if (this.notHidden(list[i].title,this.config.inTiddler))
childOutput += this.treeTraverse(list[i].title,depth+1,sortBy,sortOrder,false);
if (depth == 0)
return childOutput;
else
return indent + "[["+title+"]]" + this.getTaggingCount(title) + this.getExcerpt(this.config.inTiddler,title,depth) + "\n" + childOutput;
},
// this if for the site map mode
createTagglyListSiteMap: function(place,title,isTagExpr) {
this.config.inTiddler = title; // nasty. should pass it in to traverse probably
var output = this.treeTraverse(title,0,this.getTagglyOpt(title,"sortBy"),this.getTagglyOpt(title,"sortOrder"),isTagExpr);
return this.drawTable(place,
this.makeColumns(output.split(/(?=^\*\[)/m),parseInt(this.getTagglyOpt(title,"numCols"))), // regexp magic
"sitemap"
);
},
macros: {
tagglyTagging: {
handler: function (place,macroName,params,wikifier,paramString,tiddler) {
var parsedParams = paramString.parseParams("tag",null,true);
var refreshContainer = createTiddlyElement(place,"div");
// do some refresh magic to make it keep the list fresh - thanks Saq
refreshContainer.setAttribute("refresh","macro");
refreshContainer.setAttribute("macroName",macroName);
var tag = getParam(parsedParams,"tag");
var expr = getParam(parsedParams,"expr");
if (expr) {
refreshContainer.setAttribute("isTagExpr","true");
refreshContainer.setAttribute("title",expr);
refreshContainer.setAttribute("showEmpty","true");
}
else {
refreshContainer.setAttribute("isTagExpr","false");
if (tag) {
refreshContainer.setAttribute("title",tag);
refreshContainer.setAttribute("showEmpty","true");
}
else {
refreshContainer.setAttribute("title",tiddler.title);
refreshContainer.setAttribute("showEmpty","false");
}
}
this.refresh(refreshContainer);
},
refresh: function(place) {
var title = place.getAttribute("title");
var isTagExpr = place.getAttribute("isTagExpr") == "true";
var showEmpty = place.getAttribute("showEmpty") == "true";
removeChildren(place);
addClass(place,"tagglyTagging");
var countFound = config.taggly.getTiddlers(title,'title',isTagExpr).length
if (countFound > 0 || showEmpty) {
var lingo = config.taggly.lingo;
config.taggly.createListControl(place,title,"hideState");
if (config.taggly.getTagglyOpt(title,"hideState") == "show") {
createTiddlyElement(place,"span",null,"tagglyLabel",
isTagExpr ? lingo.labels.exprLabel.format([title]) : lingo.labels.label.format([title]));
config.taggly.createListControl(place,title,"title");
config.taggly.createListControl(place,title,"modified");
config.taggly.createListControl(place,title,"created");
config.taggly.createListControl(place,title,"listMode");
config.taggly.createListControl(place,title,"excerpts");
config.taggly.createListControl(place,title,"numCols");
config.taggly.createTagglyList(place,title,isTagExpr);
if (countFound == 0 && showEmpty)
createTiddlyElement(place,"div",null,"tagglyNoneFound",lingo.labels.noneFound);
}
}
}
}
},
// todo fix these up a bit
styles: [
"/*{{{*/",
"/* created by TagglyTaggingPlugin */",
".tagglyTagging { padding-top:0.5em; }",
".tagglyTagging li.listTitle { display:none; }",
".tagglyTagging ul {",
" margin-top:0px; padding-top:0.5em; padding-left:2em;",
" margin-bottom:0px; padding-bottom:0px;",
"}",
".tagglyTagging { vertical-align: top; margin:0px; padding:0px; }",
".tagglyTagging table { margin:0px; padding:0px; }",
".tagglyTagging .button { visibility:hidden; margin-left:3px; margin-right:3px; }",
".tagglyTagging .button, .tagglyTagging .hidebutton {",
" color:[[ColorPalette::TertiaryLight]]; font-size:90%;",
" border:0px; padding-left:0.3em;padding-right:0.3em;",
"}",
".tagglyTagging .button:hover, .hidebutton:hover, ",
".tagglyTagging .button:active, .hidebutton:active {",
" border:0px; background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]];",
"}",
".selected .tagglyTagging .button { visibility:visible; }",
".tagglyTagging .hidebutton { color:[[ColorPalette::Background]]; }",
".selected .tagglyTagging .hidebutton { color:[[ColorPalette::TertiaryLight]] }",
".tagglyLabel { color:[[ColorPalette::TertiaryMid]]; font-size:90%; }",
".tagglyTagging ul {padding-top:0px; padding-bottom:0.5em; margin-left:1em; }",
".tagglyTagging ul ul {list-style-type:disc; margin-left:-1em;}",
".tagglyTagging ul ul li {margin-left:0.5em; }",
".editLabel { font-size:90%; padding-top:0.5em; }",
".tagglyTagging .commas { padding-left:1.8em; }",
"/* not technically tagglytagging but will put them here anyway */",
".tagglyTagged li.listTitle { display:none; }",
".tagglyTagged li { display: inline; font-size:90%; }",
".tagglyTagged ul { margin:0px; padding:0px; }",
".excerpt { color:[[ColorPalette::TertiaryDark]]; }",
".excerptIndent { margin-left:4em; }",
"div.tagglyTagging table,",
"div.tagglyTagging table tr,",
"td.tagglyTagging",
" {border-style:none!important; }",
".tagglyTagging .contents { border-bottom:2px solid [[ColorPalette::TertiaryPale]]; padding:0 1em 1em 0.5em;",
" margin-bottom:0.5em; }",
".tagglyTagging .indent1 { margin-left:3em; }",
".tagglyTagging .indent2 { margin-left:4em; }",
".tagglyTagging .indent3 { margin-left:5em; }",
".tagglyTagging .indent4 { margin-left:6em; }",
".tagglyTagging .indent5 { margin-left:7em; }",
".tagglyTagging .indent6 { margin-left:8em; }",
".tagglyTagging .indent7 { margin-left:9em; }",
".tagglyTagging .indent8 { margin-left:10em; }",
".tagglyTagging .indent9 { margin-left:11em; }",
".tagglyTagging .indent10 { margin-left:12em; }",
".tagglyNoneFound { margin-left:2em; color:[[ColorPalette::TertiaryMid]]; font-size:90%; font-style:italic; }",
"/*}}}*/",
""].join("\n"),
init: function() {
merge(config.macros,this.macros);
config.shadowTiddlers["TagglyTaggingStyles"] = this.styles;
store.addNotification("TagglyTaggingStyles",refreshStyles);
}
};
config.taggly.init();
//}}}
/***
InlineSlidersPlugin
By Saq Imtiaz
http://tw.lewcid.org/sandbox/#InlineSlidersPlugin
// syntax adjusted to not clash with NestedSlidersPlugin
// added + syntax to start open instead of closed
***/
//{{{
config.formatters.unshift( {
name: "inlinesliders",
// match: "\\+\\+\\+\\+|\\<slider",
match: "\\<slider",
// lookaheadRegExp: /(?:\+\+\+\+|<slider) (.*?)(?:>?)\n((?:.|\n)*?)\n(?:====|<\/slider>)/mg,
lookaheadRegExp: /(?:<slider)(\+?) (.*?)(?:>)\n((?:.|\n)*?)\n(?:<\/slider>)/mg,
handler: function(w) {
this.lookaheadRegExp.lastIndex = w.matchStart;
var lookaheadMatch = this.lookaheadRegExp.exec(w.source)
if(lookaheadMatch && lookaheadMatch.index == w.matchStart ) {
var btn = createTiddlyButton(w.output,lookaheadMatch[2] + " "+"\u00BB",lookaheadMatch[2],this.onClickSlider,"button sliderButton");
var panel = createTiddlyElement(w.output,"div",null,"sliderPanel");
panel.style.display = (lookaheadMatch[1] == '+' ? "block" : "none");
wikify(lookaheadMatch[3],panel);
w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
}
},
onClickSlider : function(e) {
if(!e) var e = window.event;
var n = this.nextSibling;
n.style.display = (n.style.display=="none") ? "block" : "none";
return false;
}
});
//}}}
Det er et privilegie at kunne tilbyde denne ressource gratis. Dette er muligt pga. forskellige menneskers indsats:
Tak til..
*Jeremy Ruston, ~TiddlyWikis skaber. ^^ TiddlyWiki <<version>> © 2008 [[UnaMesa|http://www.unamesa.org/]]^^
*Dem der har lavet de forskellige plugins som bliver brugt i denne version af ~TiddlyWiki. Brug den følgende knap for at se en liste over de plugins der bliver brugt her. Hvert plugin indeholder information om dem der har lavet det. <<tag systemConfig>>
-----
^^<html><a rel="license" href="http://creativecommons.org/licenses/by/3.0/"><img alt="Creative Commons License" style="border-width:0" src="http://i.creativecommons.org/l/by/3.0/88x31.png" /></a><br />No-Brainer Notes is licensed by Dave Gifford under a <a rel="license" href="http://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0 Unported License</a></html>^^
Måns Mårtensson har oversat og lavet modifikationer til ~No-Brainer Notes og valgt at kalde den Simple Noter d. 26/10 2008.
<<getTiddlerPassword fredslund>>
Jeg lovede lige at notere hvad vi snakkede om:
#Prisen på at TDC leverer fibernet efter den gl. ordning. De har sagt ja til at vi må få til den gl. pris: dvs ca. 11.000,- ialt ca. 16.000,- med udgravning og indlæggelse i huset.<br>*Den "nye pris" skulle efter pålydende være på over 100.000!!
#Vi talte om muligheden for at få "sort fiber" - en forbindelse direkte imellem Ranum og Himmerlands efterskole.<br>*Fordele: <br>**Bl.a. deling af diverse hardware og netforbindelse.<br>**Ikke nødvendigt med mere end 1 "serverrum".<br>**Vi talte om evt. fordele og ulemper ved et sådant samarbejde - Vi to er vist enige om at det kun er fordelagtigt for alle - men der skal ledelsesbeslutninger og et ønske om et fhv. tæt økonomisk samarbejde i stand, (omkring edb) før det kan lade sig gøre.
#Vi mangler "desperat" backupløsning da vores aftale med Kikkenborg data udløber pr. d. 1. <br> *Du foreslog en midlertidig lokal løsning i form af 2 backuptyper:<br>*Windows 2003's eget backupsystem til filserveren og <br>*Du vil konfigurere vores Linix "Centos 5 -et eller andet" til også at levere backups til <br>*En ekstern harddisk i serverrummet. (Skal indkøbes!)
#Du mangler stadig at få lavet et "overslag" på prisen af et trådløst netværk over hele skolen. (Elektriker og pedelarbejde indbefattet)
#Du fortalte at I har haft et eventyrligt bryllup ;-)
- Det var vist det vigtigste.
Mvh Måns
/***
|Name|TiddlerPasswordPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerPasswordPlugin|
|Documentation|http://www.TiddlyTools.com/#TiddlerPasswordPluginInfo|
|Version|1.1.3|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|block viewing of tiddler content by prompting for a password before content is displayed|
This plugin blocks viewing of specific tiddler content by prompting for a NON-SECURE, UNENCRYPTED password before the tiddler is displayed. If the correct password is not entered, the tiddler is automatically closed. The process does not prevent tiddler content from being viewed directly from the TiddlyWiki source file's storeArea, nor does it encrypt the tiddler content in any way. Because it is relatively simple to bypass and/or disable the password prompting process, this macro should be thought of as a "latch" rather than a "lock" on a given tiddler.
!!!!!Documentation
> see [[TiddlerPasswordPluginInfo]]
!!!!!Installation Notes
<<<
''As soon as you have installed this plugin, you should change the default admin password in [[TiddlerPasswordPluginConfig]].'' Note: the configuration tiddler is password-protected to prevent the admin password from being viewed (and/or modified) unless the current password is provided. By default, the admin password is set to "admin".
<<<
!!!!!Revisions
<<<
2008.03.10 [*.*.*] plugin size reduction - documentation moved to [[TiddlerPasswordPluginInfo]]
2007.09.13 [1.1.3] adjusted wording of "cancelMsg" text so it can apply to either view-mode or edit-mode activities, and documented usage in ViewTemplate/EditTemplate.
| Please see [[TiddlerPasswordPluginInfo]] for previous revision details |
2006.12.02 [1.0.0] initial release - converted from GetTiddlerPassword inline script
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlerPasswordPlugin= {major: 1, minor: 1, revision: 3, date: new Date(2007,9,13)};
config.macros.getTiddlerPassword = {
msg: "Skriv venligst et password for at læse '%0'",
defaultText: "Skriv password her",
retryMsg: "'%0' er ikke det korrekte password til '%1'. Prøv venligst igen:",
cancelMsg: "desværre du kan ikke få adgang til '%0' uden det rigtige password.",
thanksMsg: "Tak, dit password er blevet accepteret.",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var here=story.findContainingTiddler(place); if (!here) return;
var title=tiddler?tiddler.title:here.getAttribute("tiddler");
var who=here.getAttribute("logID");
var userPass=params[0]?params[0]:""; if (userPass=='-') userPass="";
var msg=params[1]?params[1]:this.msg;
if (who==userPass||who==this.adminPass) return; // already 'logged in'?
var who=prompt(msg.format([title]),this.defaultText); // ask for ID
while (who && who!=userPass && who!=this.adminPass) // not correct ID?
who=prompt(this.retryMsg.format([who,title]),this.defaultText); // ask again
if (who==userPass||who==this.adminPass) // correct ID? mark tiddler logged in...
{ here.setAttribute("logID",who); alert(this.thanksMsg); }
else // incorrect ID (e.g., entry cancelled by user)...
{ story.closeTiddler(here.getAttribute("tiddler")); alert(this.cancelMsg.format([title])); }
}
}
// default admin password (may be overridden in TiddlerPasswordPluginConfig)
if (config.macros.getTiddlerPassword.adminPass==undefined)
config.macros.getTiddlerPassword.adminPass="admin";
//}}}
// // Tiddler Admin Password Configuration... <<getTiddlerPassword>> /% rest of tiddler will not be displayed without password... %/
//{{{
config.macros.getTiddlerPassword.adminPass="kultur";
//}}}
// {{small{NOTE: after changing the password, save-and-reload the document for the change to take effect}}} //
How to get going with TiddlyChatter, graphically...
|!Timeline|!Publisher 1 (P1)|!|!Publisher 2 (P2)|
|!initial setup|download or import [[TiddlyChatter|http://tiddlychatter.tiddlyspot.com]]||download or import [[TiddlyChatter|http://tiddlychatter.tiddlyspot.com]]|
|!create content|new tiddler [[FooBar]]|||
|!mark as candidate for publishing|add tag "public" to [[FooBar]] (automated via [[TiddlyChatter Control Panel]] > {{{Create}}})|||
|!confirm publishing|add tag "published" to [[FooBar]] (automated via {{{Publish}}} button)|||
|!publishing|{{{Save to Web}}} (also creating the RSS feed)|text-align:center;→||
|!subscribe to chatter feed|||[[TiddlyChatter Control Panel]] > {{{Manage}}} > {{{New Subscription}}}<br>→ enter URL of P1's TiddlyWiki (not its RSS feed)<br>{{{Go}}} > select feeds to subscribe to > {{{Subscribe}}}|
|!retrieve chatter|||[[TiddlyChatter Control Panel]] > {{{Get}}}<br>[[TiddlyChatter Control Panel]] will display recent changes as a list of tiddlers|
|!commenting on chatter contents|||open imported [[FooBar]] and select {{{Add Notes}}}|
|!publishing comments||text-align:center;←|{{{Save to Web}}} (cf. steps of P1)|
Thanks to FND for this.
|Title|TiddlyChatter|
|Summary|Opt-in, decentralized collaboration|
|Description|This component spans several javascript files and depends on a number of other plugins|
|Version of product it works with|2.2.6|
|Version of component|0.75|
|Image illustrating it working||
|Explanation of how it can be used and modified|see below for necessary plugins|
|Examples where it can be seen working|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/verticals/TiddlyChatter/examples/tiddlychatter0-5.html|
|Links to reviews and discussion|http://jayfresh.wordpress.com/category/tiddlychatter/ http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/ac0532d241e2cb1a http://groups.google.com/group/TiddlyWikiDev/browse_thread/thread/f6e11d6c56d26817/5c204eaed61855f2|
!!The following plugins are built for TiddlyChatter:
|[[lv]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/verticals/TiddlyChatter/js/lv.js]] |
|[[tiddlyChatterSetup code]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/TiddlyChatter/js/tiddlyChatterSetup_code.js]] |
|[[tiddlyChatterPublishing]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/TiddlyChatter/js/tiddlyChatterPublishing.js]] |
|[[applyTiddlyChatterStyles]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/verticals/TiddlyChatter/js/applyTiddlyChatterStyles.js]] |
!!The following plugins are modified and patch discussions are ongoing with plugin authors:
|NotesPlugin |by SaqImtiaz |[[original source|http://tw.lewcid.org/#NotesPlugin]] |[[modified source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/TiddlyChatter/NotesPlugin_JRL.js]] |
|ImportWorkspacePlugin |by Martin Budden |[[original source|http://svn.tiddlywiki.org/Trunk/contributors/MartinBudden/adaptors/ImportWorkspacePlugin.js]] | [[modified source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/TiddlyChatter/ImportWorkspacePlugin_JRL.js]] |
|[[Core patches]] |by various |[[original source dir|http://svn.tiddlywiki.org/Trunk/core/js]] | |
!!The following plugins are used without modification:
|[[ImportWorkspaceMulti]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/ImportWorkspaceMulti/js/importWorkspaceMulti.js]] |
|[[RSSAdaptor|RSSAdaptor]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/RSSAdaptor/js/rssadaptor.js]] |
|[[RSSRender|RSSrender plugin]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/RSSAdaptor/js/RSSRender.js]] |
|TaggedTemplateTweak |by EricShulman |[[source|http://www.TiddlyTools.com/#TaggedTemplateTweak]] |
|[[stickyOptionsPlugin]] |by SaqImtiaz |[[source|http://tw.lewcid.org/#StickyOptionsPlugin]] |
|[[Unread]] |by JonLister |[[source|http://svn.tiddlywiki.org/Trunk/contributors/JonathanLister/components/Unread/js/Unread.js]] |
!!The following tiddlers are not plugins, but are part of the config:
[[publicViewTemplate]]
StyleSheetTiddlyChatter
ChatterFeed
!!The following tiddlers provide additional information or run plugins:
[[TiddlyChatter]]
[[Welcome to TiddlyChatter]]
[[Setting up TiddlyChatter]]
[[How TiddlyChatter works - an example scenario]]
[[TiddlyChatterDocumentation]]
|''Type:''|file|
|''URL:''|http://tiddlychatter.tiddlyspot.com/index.html|
|''Workspace:''||
|''TiddlerFilter:''|[tag[TiddlyChatterPackage]]|
To create a piece of Chatter, you have a couple of options:
* Hit "Create" on the TiddlyChatter control panel, edit and save
* Create a new tiddler and tag it with "public"
This creates a Chatter ready for publishing into your ChatterFeed after you've finished drafting it - click "Publish" to get it into your feed.
At this point, you might be wondering how to get your content updates up onto the web and into the hands of your subscribers:
* Using the "Save to web" feature of TiddlySpot is the simplest at the moment, especially because other TiddlySpot TiddlyWikis will be able to download your Chatter directly, instead of them having to download and run a local version.
* If you have BidiX's [[UploadPlugin|http://tiddlywiki.bidix.info/#UploadPlugin]] and a php server, you can set up a store that will accept uploads directly from TiddlyWiki
* If you have *any form* of static file hosting available to you, posting your ChatterFeed (and your TiddlyWiki) on there is totally fine
We recognise that this is a frustrating area, but we're not alone in trying to solve it.
[Addition:] 1/11/07 - I just found [[yoyko|http://www.chaosindex.com/yoyko/index.html]], who provide a hosted store for TiddlyWikis
!Subscribing to other people's Chatter
To read someone's else Chatter, you have to be subscribed to their ChatterFeed:
* From the TiddlyChatter control panel, click Manage > New Subscription
* Enter the URL of the TiddlyWiki publishing the ChatterFeed you want to subscribe to
* When the list of available feeds appears, put a check in the box next to the one you want and click "subscribe"
When it comes to downloading other people's Chatter, you generally need to be viewing your TiddlyWiki as a local file for the remote calls to work. This isn't true if you're only working with TiddlyWikis running on TiddlySpot, as their proxy sorts everything out, which is grand.
Hitting "Get" from the control panel downloads your updates. New content is displayed in red and the number of notes on a tiddler is shown in brackets next to the tiddler's title.
!Adding and publishing comments
After you've read an imported tiddler and want to add a comment, clicking on "add notes" opens a box to type in your note. Clicking "save notes" saves the note and publishes it into your ChatterFeed. Various ways to get your feed out onto the web where people can see it are discussed in [[this tiddler|TiddlyChatterPublishing]].
<<tiddler TiddlyHomeSidebar>>
/***
|''Name:''|TiddlyHomeSetupPlugin|
|''Description:''|Check and setup all components|
|''Version:''|1.1.0|
|''Date:''|Aug 04, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#TiddlyHomeSetupPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|UploadToHomeMacro|
***/
//{{{
version.extensions.TiddlyHomeSetupPlugin = {
major: 1, minor: 1, revision: 0,
date: new Date("Aug 04, 2007"),
source: 'http://tiddlywiki.bidix.info/#TiddlyHomeSetupPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info)',
coreVersion: '2.2.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.getParamsFromTiddler = function(tiddlerTitle, sliceNames) {
tiddlerTitle = (tiddlerTitle ? tiddlerTitle:this.messages.homeParamsTiddler);
if (!store.tiddlerExists(tiddlerTitle) && !store.isShadowTiddler(tiddlerTitle)) {
throw(config.macros.uploadToHome.messages.tiddlerNotFound.toString().format([tiddlerTitle]));
}
return sliceValues = store.getTiddlerSlices(tiddlerTitle,sliceNames);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
bidix.checkPlugin('UploadPlugin',4,1,0);
config.macros.upload.authenticateUser = false; // authentication check by .htaccess
// default TiddlyHomeParameters in shadows
// user can overide this
merge(config.shadowTiddlers,{
'TiddlyHomeParameters':[
"|owner:|$owner$|",
"|site:|$site$|",
"|url:|$url$|",
"|rootUrl:|$rootUrl$|"
].join("\n")});
// get config from TiddlyHomeParameters
config.tiddlyHome = {};
merge(config.tiddlyHome, bidix.getParamsFromTiddler('TiddlyHomeParameters',['user','site','url','rootUrl']));
config.shadowTiddlers.TiddlyHomeParameters += [
"!Usefull url for your site",
"* " + config.tiddlyHome.url + "backup: List of backup files",
"* " + config.tiddlyHome.url + "download.php : to download thisTiddlyWiki",
"* " + config.tiddlyHome.url + "index.xml : your RSSFeed",
"* " + config.tiddlyHome.url + "news.php : to display your RSSFeed",
"!Access and change data",
"* " + config.tiddlyHome.rootUrl + "Site : Site properties",
"* " + config.tiddlyHome.rootUrl + "#User : User properties",
"!More Information on TiddlyHome",
"* " + config.tiddlyHome.rootUrl + " for your hosting service",
"*http://TiddlyHome.bidix.info/ for BidiX's TiddlyHome Package"
].join("\n");
// add TiddlyHomeSidebar in SideBarOptions
config.shadowTiddlers.SideBarOptions = config.shadowTiddlers.SideBarOptions.replace(/(<<saveChanges>>)/,
"$1<<tiddler TiddlyHomeSidebar>>");
merge(config.shadowTiddlers,{
// link to favicon.ico
'MarkupPreHead': [
"<!--{{{-->",
"<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>",
"<link rel=\"shortcut icon\"href=\"" +
config.tiddlyHome.rootUrl +
"_th/images/favicon.ico\" type=\"image/vnd.microsoft.icon\" />",
"<link rel=\"icon\" href=\"" +
config.tiddlyHome.rootUrl +
"_th/images/favicon.ico\" type=\"image/vnd.microsoft.icon\" /> ",
"<!--}}}-->"
].join("\n"),
'SiteProxy': [
"proxy.php?url="
].join("\n"),
'SiteUrl': config.tiddlyHome.url,
// tweaks to UploadToHomeMacro parameters
'HomeParameters': [
"|UploadUserName:||",
"|UploadStoreUrl:|" + config.tiddlyHome.url + "store.php|",
"|UploadDir:|.|",
"|UploadFilename:|index.html|",
"|UploadBackupDir:|backup|"
].join("\n"),
'TiddlyHomeSidebar':[
"<<uploadToHome>><html><a href=" +
config.tiddlyHome.url + "download.php class='button'>download</a></html>"
].join("\n")
});
// Options tweaks
//config.options.txtUserName = config.tiddlyHome.user;
config.options.pasUploadPassword = '';
config.options.txtBackupFolder = "backup";
config.options.chkSaveBackups = true;
config.options.chkAutoSave = false;
config.options.chkRegExpSearch = false;
config.options.chkCaseSensitiveSearch = false;
config.options.chkAnimate = false;
config.options.chkGenerateAnRssFeed = true;
config.options.chkSaveEmptyTemplate = false;
//}}}
|URL:|http://TiddlyHome.bidix.info/systemServer/TiddlyHomeSystem.html|
|Description|Repository for TiddlyHome system ressources |
|Author:|BidiX|
<<tiddler TspotControls>>
<<miniBrowser hidecontrols http://tidsjournal.tiddlyspot.com>>
/%
|Name|ToggleRightSidebar|
|Source|http://www.TiddlyTools.com/#ToggleRightSidebar|
|Version|2.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|show/hide right sidebar (MainMenu)|
Usage: <<tiddler ToggleRightSidebar with: "label">>
Config settings:
config.options.chkShowRightSidebar (false)
config.options.txtToggleRightSideBarLabelShow (►)
config.options.txtToggleRightSideBarLabelHide (◄)
%/<script label="$1" title="show/hide right sidebar content">
var co=config.options;
if (co.chkShowRightSidebar=='undefined') co.chkShowRightSidebar=true;
co.chkShowRightSidebar=!co.chkShowRightSidebar;
var sb=document.getElementById('sidebar'); if (!sb) return;
sb.style.display=co.chkShowRightSidebar?'block':'none';
document.getElementById('displayArea').style.marginRight=co.chkShowRightSidebar?'':'1em';
saveOptionCookie('chkShowRightSidebar');
var labelShow=co.txtToggleRightSideBarLabelShow||(config.browser.isSafari?'◀':'◄');
var labelHide=co.txtToggleRightSideBarLabelHide||'►';
if (typeof(place)!='undefined' && '$1'=='$'+'1') {
place.innerHTML=co.chkShowRightSidebar?labelHide:labelShow;
place.title=(co.chkShowRightSidebar?'hide':'show')+' right sidebar';
}
var sm=document.getElementById('storyMenu'); if (sm) config.refreshers.content(sm);
</script><script>
var co=config.options;
if (co.chkShowRightSidebar=='undefined') co.chkShowRightSidebar=true;
var sb=document.getElementById('sidebar'); if (!sb) return;
sb.style.display=co.chkShowRightSidebar?'block':'none';
document.getElementById('displayArea').style.marginRight=co.chkShowRightSidebar?'':'1em';
if ('$1'=='$'+'1') {
var labelShow=co.txtToggleRightSideBarLabelShow||(config.browser.isSafari?'◀':'◄');
var labelHide=co.txtToggleRightSideBarLabelHide||'►';
place.lastChild.innerHTML=co.chkShowRightSidebar?labelHide:labelShow;
place.lastChild.title=(co.chkShowRightSidebar?'hide':'show')+' right sidebar';
}
</script>
/***
|Name:|ToggleTagPlugin|
|Description:|Makes a checkbox which toggles a tag in a tiddler|
|Version:|3.1.0 ($Rev: 4907 $)|
|Date:|$Date: 2008-05-13 03:15:46 +1000 (Tue, 13 May 2008) $|
|Source:|http://mptw.tiddlyspot.com/#ToggleTagPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
!!Usage
{{{<<toggleTag }}}//{{{TagName TiddlerName LabelText}}}//{{{>>}}}
* TagName - the tag to be toggled, default value "checked"
* TiddlerName - the tiddler to toggle the tag in, default value the current tiddler
* LabelText - the text (gets wikified) to put next to the check box, default value is '{{{[[TagName]]}}}' or '{{{[[TagName]] [[TiddlerName]]}}}'
(If a parameter is '.' then the default will be used)
* TouchMod flag - if non empty then touch the tiddlers mod date. Note, can set config.toggleTagAlwaysTouchModDate to always touch mod date
!!Examples
|Code|Description|Example|h
|{{{<<toggleTag>>}}}|Toggles the default tag (checked) in this tiddler|<<toggleTag>>|
|{{{<<toggleTag TagName>>}}}|Toggles the TagName tag in this tiddler|<<toggleTag TagName>>|
|{{{<<toggleTag TagName TiddlerName>>}}}|Toggles the TagName tag in the TiddlerName tiddler|<<toggleTag TagName TiddlerName>>|
|{{{<<toggleTag TagName TiddlerName 'click me'>>}}}|Same but with custom label|<<toggleTag TagName TiddlerName 'click me'>>|
|{{{<<toggleTag . . 'click me'>>}}}|dot means use default value|<<toggleTag . . 'click me'>>|
!!Notes
* If TiddlerName doesn't exist it will be silently created
* Set label to '-' to specify no label
* See also http://mgtd-alpha.tiddlyspot.com/#ToggleTag2
!!Known issues
* Doesn't smoothly handle the case where you toggle a tag in a tiddler that is current open for editing
* Should convert to use named params
***/
//{{{
if (config.toggleTagAlwaysTouchModDate == undefined) config.toggleTagAlwaysTouchModDate = false;
merge(config.macros,{
toggleTag: {
createIfRequired: true,
shortLabel: "[[%0]]",
longLabel: "[[%0]] [[%1]]",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var tiddlerTitle = tiddler ? tiddler.title : '';
var tag = (params[0] && params[0] != '.') ? params[0] : "checked";
var title = (params[1] && params[1] != '.') ? params[1] : tiddlerTitle;
var defaultLabel = (title == tiddlerTitle ? this.shortLabel : this.longLabel);
var label = (params[2] && params[2] != '.') ? params[2] : defaultLabel;
var touchMod = (params[3] && params[3] != '.') ? params[3] : "";
label = (label == '-' ? '' : label); // dash means no label
var theTiddler = (title == tiddlerTitle ? tiddler : store.getTiddler(title));
var cb = createTiddlyCheckbox(place, label.format([tag,title]), theTiddler && theTiddler.isTagged(tag), function(e) {
if (!store.tiddlerExists(title)) {
if (config.macros.toggleTag.createIfRequired) {
var content = store.getTiddlerText(title); // just in case it's a shadow
store.saveTiddler(title,title,content?content:"",config.options.txtUserName,new Date(),null);
}
else
return false;
}
if ((touchMod != "" || config.toggleTagAlwaysTouchModDate) && theTiddler)
theTiddler.modified = new Date();
store.setTiddlerTag(title,this.checked,tag);
return true;
});
}
}
});
//}}}
|~ViewToolbar|fullscreen newHere closeTiddler +editTiddler editHtml deleteTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler saveCloseTiddler -cancelTiddler cancelCloseTiddler deleteTiddler|
|invisiblecomm|k
|{{purple{[[Instruktioner]]}}}||@@padding-left: 20px;<<newTiddler title: 'Skriv titlen på dit nye hovedemne her' tag: 'Emner' label: 'Nyt hovedemne' text: {{store.getTiddlerText("SliderFrame")}} label: 'Nyt hovedemne'>>@@||padding-left: 20px;<<newTiddler title: 'Ny note' tag: 'Note' label:'Ny note'>>||@@padding-left: 20px;{{purple nowrap{<<search>>}}}@@||@@padding-left: 20px;{{purple{<<back>>}}}@@||{{purple{<<history >>}}}||{{purple{<<forward>>}}}|@@padding-left: 20px;{{purple{<<tiddler ToggleRightSidebar with: "(Sidepanel)">>}}}@@|
<!--{{{-->
<a style="color: #5566ff">Det ser ud som om du er ved at lave eller ændre pået hieraki af emner oppefra og ned!<br>Tilføj navnet på emnet både i øverste tekstfelt, og i sitemap slideren herunder.<br>Klik 'færdig', klik derefter på 'ny her' knappen for at lave underemner og noter indenfor dette emne.<br>Hvis du vil tilføje tekst herunder, så gør det under linien med sitemap slideren.</a>
<!--}}}-->
/***
Description: Contains the stuff you need to use Tiddlyspot
Note, you also need UploadPlugin, PasswordOptionPlugin and LoadRemoteFileThroughProxy
from http://tiddlywiki.bidix.info for a complete working Tiddlyspot site.
***/
//{{{
// edit this if you are migrating sites or retrofitting an existing TW
config.tiddlyspotSiteId = 'edb';
// make it so you can by default see edit controls via http
config.options.chkHttpReadOnly = false;
window.readOnly = false; // make sure of it (for tw 2.2)
window.showBackstage = true; // show backstage too
// disable autosave in d3
if (window.location.protocol != "file:")
config.options.chkGTDLazyAutoSave = false;
// tweak shadow tiddlers to add upload button, password entry box etc
with (config.shadowTiddlers) {
SiteUrl = 'http://'+config.tiddlyspotSiteId+'.tiddlyspot.com';
SideBarOptions = SideBarOptions.replace(/(<<saveChanges>>)/,"$1<<tiddler TspotSidebar>>");
OptionsPanel = OptionsPanel.replace(/^/,"<<tiddler TspotOptions>>");
DefaultTiddlers = DefaultTiddlers.replace(/^/,"[[WelcomeToTiddlyspot]] ");
MainMenu = MainMenu.replace(/^/,"[[WelcomeToTiddlyspot]] ");
}
// create some shadow tiddler content
merge(config.shadowTiddlers,{
'WelcomeToTiddlyspot':[
"This document is a ~TiddlyWiki from tiddlyspot.com. A ~TiddlyWiki is an electronic notebook that is great for managing todo lists, personal information, and all sorts of things.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //What now?// @@ Before you can save any changes, you need to enter your password in the form below. Then configure privacy and other site settings at your [[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]] (your control panel username is //" + config.tiddlyspotSiteId + "//).",
"<<tiddler TspotControls>>",
"See also GettingStarted.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working online// @@ You can edit this ~TiddlyWiki right now, and save your changes using the \"save to web\" button in the column on the right.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Working offline// @@ A fully functioning copy of this ~TiddlyWiki can be saved onto your hard drive or USB stick. You can make changes and save them locally without being connected to the Internet. When you're ready to sync up again, just click \"upload\" and your ~TiddlyWiki will be saved back to tiddlyspot.com.",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Help!// @@ Find out more about ~TiddlyWiki at [[TiddlyWiki.com|http://tiddlywiki.com]]. Also visit [[TiddlyWiki.org|http://tiddlywiki.org]] for documentation on learning and using ~TiddlyWiki. New users are especially welcome on the [[TiddlyWiki mailing list|http://groups.google.com/group/TiddlyWiki]], which is an excellent place to ask questions and get help. If you have a tiddlyspot related problem email [[tiddlyspot support|mailto:support@tiddlyspot.com]].",
"",
"@@font-weight:bold;font-size:1.3em;color:#444; //Enjoy :)// @@ We hope you like using your tiddlyspot.com site. Please email [[feedback@tiddlyspot.com|mailto:feedback@tiddlyspot.com]] with any comments or suggestions."
].join("\n"),
'TspotControls':[
"| tiddlyspot password:|<<option pasUploadPassword>>|",
"| site management:|<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">>//(requires tiddlyspot password)//<br>[[control panel|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/controlpanel]], [[download (go offline)|http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download]]|",
"| links:|[[tiddlyspot.com|http://tiddlyspot.com/]], [[FAQs|http://faq.tiddlyspot.com/]], [[blog|http://tiddlyspot.blogspot.com/]], email [[support|mailto:support@tiddlyspot.com]] & [[feedback|mailto:feedback@tiddlyspot.com]], [[donate|http://tiddlyspot.com/?page=donate]]|"
].join("\n"),
'TspotSidebar':[
"<<upload http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/store.cgi index.html . . " + config.tiddlyspotSiteId + ">><html><a href='http://" + config.tiddlyspotSiteId + ".tiddlyspot.com/download' class='button'>download</a></html>"
].join("\n"),
'TspotOptions':[
"tiddlyspot password:",
"<<option pasUploadPassword>>",
""
].join("\n")
});
//}}}
<html><div align="center"><iframe src="http://twspot.tiddlyspot.com/index.html" frameborder="0" width="100%" height="800"></iframe></div></html>
<html><div align="center"><iframe src="http://labs.mozilla.com/projects/ubiquity/" frameborder="0" width="100%" height="600"></iframe></div></html>
Forskellige udvidelser af Firefox med stort potentiale
config.macros.unread = {};
config.macros.unread.handler = function(place,macroName,param,wikifier,paramString,tiddler) {
// check to see if tiddler has extended field "unread"
// if so, add button to click to change status to read
if (tiddler.fields["unread"]) {
var unread = tiddler.fields["unread"] == "true" ? true : false;
// SUPPORTING: tiddlers with notes - if a note is unread, reflect that in the status
if (config.macros.notes) {
// Get the notes tiddlers for this tiddler and set their unread status to that of the parent tiddler
var notes_tiddlers = store.getTaggedTiddlers("notes");
var notes = [];
var notesCount = 0;
for (var i=0;i<notes_tiddlers.length;i++) {
if (notes_tiddlers[i].title != t.title && notes_tiddlers[i].title.indexOf(t.title) != -1) {
if (notes_tiddlers[i].fields["unread"]) {
unread = notes_tiddlers[i].fields["unread"] == "true" ? true : false;
}
}
}
}
var label = (unread) ? "Mark as read" : "Mark as unread";
var caption = (!unread) ? "Click to mark as read" : "Click to mark as unread";
var theUnreadBox = createTiddlyButton(place,label,caption);
theUnreadBox.onclick = config.macros.unread.markAsRead;
theUnreadBox.status = unread;
}
};
config.macros.unread.markAsRead = function() {
var DOMTiddler = story.findContainingTiddler(this);
var t = store.fetchTiddler(DOMTiddler.getAttribute("tiddler"));
// switch unread status
t.fields["unread"] = this.status ? "false" : "true";
// SUPPORTING: tiddlers with notes, so we can mark all read at once
if (config.macros.notes) {
// Get the notes tiddlers for this tiddler and set their unread status to that of the parent tiddler
var notes_tiddlers = store.getTaggedTiddlers("notes");
var notes = [];
var notesCount = 0;
for (var i=0;i<notes_tiddlers.length;i++) {
if (notes_tiddlers[i].title != t.title && notes_tiddlers[i].title.indexOf(t.title) != -1) {
if (notes_tiddlers[i].fields["unread"]) {
notes_tiddlers[i].fields["unread"] = t.fields["unread"];
}
}
}
}
// store.saveTiddler(t.title,t.title,t.text,t.modifier,t.modified,t.tags,t.fields,false,t.created);
// story.refreshTiddler(DOMTiddler.getAttribute("tiddler"),DOMTiddler.getAttribute("template"),true);
story.refreshAllTiddlers();
// the line above seems rather heavy-handed... what's an efficient way to make another tiddler respond to a change in this one's fields?
// also, if I don't save t back to the store, does this have any consequences? Or is it happening automatically?
};
| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |
| 21/06/2009 05:52:15 | DitNavn | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 21/06/2009 05:55:50 | DitNavn | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 21/06/2009 23:37:15 | DitNavn | [[index.html|http://edb.tiddlyspot.com/index.html]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 23/06/2009 09:12:22 | DitNavn | [[index.html|http://edb.tiddlyspot.com/index.html]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 15/07/2009 11:10:41 | DitNavn | [[index.html|http://edb.tiddlyspot.com/index.html]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 15/07/2009 12:27:27 | MaMa | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 20/08/2009 00:43:34 | DitNavn | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 20/10/2009 00:29:29 | DitNavn | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . | ok |
| 20/10/2009 00:31:04 | DitNavn | [[/|http://edb.tiddlyspot.com/]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
| 21/10/2009 11:13:11 | DitNavn | [[index.html|http://edb.tiddlyspot.com/index.html#%5B%5BIt%2C%20faglig%20l%C3%A6ring%20og%20p%C3%A6dagogisk%20videnledelse%5D%5D]] | [[store.cgi|http://edb.tiddlyspot.com/store.cgi]] | . | [[index.html | http://edb.tiddlyspot.com/index.html]] | . |
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
major: 4, minor: 1, revision: 3,
date: new Date("Feb 24, 2008"),
source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
//
// Upload Macro
//
config.macros.upload = {
// default values
defaultBackupDir: '', //no backup
defaultStoreScript: "store.php",
defaultToFilename: "index.html",
defaultUploadDir: ".",
authenticateUser: true // UploadService Authenticate User
};
config.macros.upload.label = {
promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
promptParamMacro: "Save and Upload this TiddlyWiki in %0",
saveLabel: "save to web",
saveToDisk: "save to disk",
uploadLabel: "upload"
};
config.macros.upload.messages = {
noStoreUrl: "No store URL in parmeters or options",
usernameOrPasswordMissing: "Username or password missing"
};
config.macros.upload.handler = function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = this.label.saveLabel;
else
label = this.label.uploadLabel;
var prompt;
if (params[0]) {
prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0],
(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
} else {
prompt = this.label.promptOption;
}
createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};
config.macros.upload.action = function(params)
{
// for missing macro parameter set value from options
if (!params) params = {};
var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
var username = params[4] ? params[4] : config.options.txtUploadUserName;
var password = config.options.pasUploadPassword; // for security reason no password as macro parameter
// for still missing parameter set default value
if ((!storeUrl) && (document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
if (storeUrl.substr(0,4) != "http")
storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
if (!toFilename)
toFilename = bidix.basename(window.location.toString());
if (!toFilename)
toFilename = config.macros.upload.defaultToFilename;
if (!uploadDir)
uploadDir = config.macros.upload.defaultUploadDir;
if (!backupDir)
backupDir = config.macros.upload.defaultBackupDir;
// report error if still missing
if (!storeUrl) {
alert(config.macros.upload.messages.noStoreUrl);
clearMessage();
return false;
}
if (config.macros.upload.authenticateUser && (!username || !password)) {
alert(config.macros.upload.messages.usernameOrPasswordMissing);
clearMessage();
return false;
}
bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password);
return false;
};
config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir)
{
if (!storeUrl)
return null;
var dest = bidix.dirname(storeUrl);
if (uploadDir && uploadDir != '.')
dest = dest + '/' + uploadDir;
dest = dest + '/' + toFilename;
return dest;
};
//
// uploadOptions Macro
//
config.macros.uploadOptions = {
handler: function(place,macroName,params) {
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);
wizard.setValue("listWrapper",listWrapper);
this.refreshOptions(listWrapper,false);
var uploadCaption;
if (document.location.toString().substr(0,4) == "http")
uploadCaption = config.macros.upload.label.saveLabel;
else
uploadCaption = config.macros.upload.label.uploadLabel;
wizard.setButtons([
{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption,
onClick: config.macros.upload.action},
{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
]);
},
options: [
"txtUploadUserName",
"pasUploadPassword",
"txtUploadStoreUrl",
"txtUploadDir",
"txtUploadFilename",
"txtUploadBackupDir",
"chkUploadLog",
"txtUploadLogMaxLine"
],
refreshOptions: function(listWrapper) {
var opts = [];
for(i=0; i<this.options.length; i++) {
var opt = {};
opts.push();
opt.option = "";
n = this.options[i];
opt.name = n;
opt.lowlight = !config.optionsDesc[n];
opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
opts.push(opt);
}
var listview = 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,opts[n].name,"no");
}
}
},
onCancel: function(e)
{
backstage.switchTab(null);
return false;
},
wizardTitle: "Upload with options",
step1Title: "These options are saved in cookies in your browser",
step1Html: "<input type='hidden' name='markList'></input><br>",
cancelButton: "Cancel",
cancelButtonPrompt: "Cancel prompt",
listViewTemplate: {
columns: [
{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
{name: 'Option', field: 'option', title: "Option", type: 'String'},
{name: 'Name', field: 'name', title: "Name", type: 'String'}
],
rowClasses: [
{className: 'lowlight', field: 'lowlight'}
]}
};
//
// upload functions
//
if (!bidix.upload) bidix.upload = {};
if (!bidix.upload.messages) bidix.upload.messages = {
//from saving
invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
backupSaved: "Backup saved",
backupFailed: "Failed to upload backup file",
rssSaved: "RSS feed uploaded",
rssFailed: "Failed to upload RSS feed file",
emptySaved: "Empty template uploaded",
emptyFailed: "Failed to upload empty template file",
mainSaved: "Main TiddlyWiki file uploaded",
mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
//specific upload
loadOriginalHttpPostError: "Can't get original file",
aboutToSaveOnHttpPost: 'About to upload on %0 ...',
storePhpNotFound: "The store script '%0' was not found."
};
bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
var callback = function(status,uploadParams,original,url,xhr) {
if (!status) {
displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
return;
}
if (bidix.debugMode)
alert(original.substr(0,500)+"\n...");
// Locate the storeArea div's
var posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
bidix.upload.uploadRss(uploadParams,original,posDiv);
};
if(onlyIfDirty && !store.isDirty())
return;
clearMessage();
// save on localdisk ?
if (document.location.toString().substr(0,4) == "file") {
var path = document.location.toString();
var localPath = getLocalPath(path);
saveChanges();
}
// get original
var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
var originalPath = document.location.toString();
// If url is a directory : add index.html
if (originalPath.charAt(originalPath.length-1) == "/")
originalPath = originalPath + "index.html";
var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
var log = new bidix.UploadLog();
log.startUpload(storeUrl, dest, uploadDir, backupDir);
displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
if (bidix.debugMode)
alert("about to execute Http - GET on "+originalPath);
var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
bidix.upload.uploadRss = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
if(status) {
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
bidix.upload.uploadMain(params[0],params[1],params[2]);
} else {
displayMessage(bidix.upload.messages.rssFailed);
}
};
// do uploadRss
if(config.options.chkGenerateAnRssFeed) {
var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
var rssString = generateRss();
// no UnicodeToUTF8 conversion needed when location is "file" !!!
if (document.location.toString().substr(0,4) != "file")
rssString = convertUnicodeToUTF8(rssString);
bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
} else {
bidix.upload.uploadMain(uploadParams,original,posDiv);
}
};
bidix.upload.uploadMain = function(uploadParams,original,posDiv)
{
var callback = function(status,params,responseText,url,xhr) {
var log = new bidix.UploadLog();
if(status) {
// if backupDir specified
if ((params[3]) && (responseText.indexOf("backupfile:") > -1)) {
var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
}
var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
store.setDirty(false);
log.endUpload("ok");
} else {
alert(bidix.upload.messages.mainFailed);
displayMessage(bidix.upload.messages.mainFailed);
log.endUpload("failed");
}
};
// do uploadMain
var revised = bidix.upload.updateOriginal(original,posDiv);
bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};
bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
var localCallback = function(status,params,responseText,url,xhr) {
url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
if (xhr.status == 404)
alert(bidix.upload.messages.storePhpNotFound.format([url]));
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
if (responseText.charAt(0) != '0')
status = null;
callback(status,params,responseText,url,xhr);
};
// do httpUpload
var boundary = "---------------------------"+"AaB03x";
var uploadFormName = "UploadPlugin";
// compose headers data
var sheader = "";
sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
sheader += uploadFormName +"\"\r\n\r\n";
sheader += "backupDir="+uploadParams[3] +
";user=" + uploadParams[4] +
";password=" + uploadParams[5] +
";uploaddir=" + uploadParams[2];
if (bidix.debugMode)
sheader += ";debug=1";
sheader += ";;\r\n";
sheader += "\r\n" + "--" + boundary + "\r\n";
sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
sheader += "Content-Length: " + data.length + "\r\n\r\n";
// compose trailer data
var strailer = new String();
strailer = "\r\n--" + boundary + "--\r\n";
data = sheader + data + strailer;
if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
if (typeof r == "string")
displayMessage(r);
return r;
};
// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
if (!posDiv)
posDiv = locateStoreArea(original);
if((posDiv[0] == -1) || (posDiv[1] == -1)) {
alert(config.messages.invalidFileError.format([localPath]));
return;
}
var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
store.allTiddlersAsHtml() + "\n" +
original.substr(posDiv[1]);
var newSiteTitle = getPageTitle().htmlEncode();
revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
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;
};
//
// UploadLog
//
// config.options.chkUploadLog :
// false : no logging
// true : logging
// config.options.txtUploadLogMaxLine :
// -1 : no limit
// 0 : no Log lines but UploadLog is still in place
// n : the last n lines are only kept
// NaN : no limit (-1)
bidix.UploadLog = function() {
if (!config.options.chkUploadLog)
return; // this.tiddler = null
this.tiddler = store.getTiddler("UploadLog");
if (!this.tiddler) {
this.tiddler = new Tiddler();
this.tiddler.title = "UploadLog";
this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
this.tiddler.created = new Date();
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
}
return this;
};
bidix.UploadLog.prototype.addText = function(text) {
if (!this.tiddler)
return;
// retrieve maxLine when we need it
var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
if (isNaN(maxLine))
maxLine = -1;
// add text
if (maxLine != 0)
this.tiddler.text = this.tiddler.text + text;
// Trunck to maxLine
if (maxLine >= 0) {
var textArray = this.tiddler.text.split('\n');
if (textArray.length > maxLine + 1)
textArray.splice(1,textArray.length-1-maxLine);
this.tiddler.text = textArray.join('\n');
}
// update tiddler fields
this.tiddler.modifier = config.options.txtUserName;
this.tiddler.modified = new Date();
store.addTiddler(this.tiddler);
// refresh and notifiy for immediate update
story.refreshTiddler(this.tiddler.title);
store.notify(this.tiddler.title, true);
};
bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir, backupDir) {
if (!this.tiddler)
return;
var now = new Date();
var text = "\n| ";
var filename = bidix.basename(document.location.toString());
if (!filename) filename = '/';
text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
text += config.options.txtUserName + " | ";
text += "[["+filename+"|"+location + "]] |";
text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
text += uploadDir + " | ";
text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
text += backupDir + " |";
this.addText(text);
};
bidix.UploadLog.prototype.endUpload = function(status) {
if (!this.tiddler)
return;
this.addText(" "+status+" |");
};
//
// Utilities
//
bidix.checkPlugin = function(plugin, major, minor, revision) {
var ext = version.extensions[plugin];
if (!
(ext &&
((ext.major > major) ||
((ext.major == major) && (ext.minor > minor)) ||
((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
// write error in PluginManager
if (pluginInfo)
pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
}
};
bidix.dirname = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(0, lastpos);
} else {
return filePath.substring(0, filePath.lastIndexOf("\\"));
}
};
bidix.basename = function(filePath) {
if (!filePath)
return;
var lastpos;
if ((lastpos = filePath.lastIndexOf("#")) != -1)
filePath = filePath.substring(0, lastpos);
if ((lastpos = filePath.lastIndexOf("/")) != -1) {
return filePath.substring(lastpos + 1);
} else
return filePath.substring(filePath.lastIndexOf("\\")+1);
};
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
//
// Initializations
//
// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);
// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
txtUploadUserName: "Upload Username",
pasUploadPassword: "Upload Password",
chkUploadLog: "do Logging in UploadLog (default: true)",
txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});
// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');
// Backstage
merge(config.tasks,{
uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");
//}}}
/***
|''Name:''|UploadTiddlerPlugin|
|''Description:''|Upload a tiddler and Update a remote TiddlyWiki |
|''Version:''|1.2.1|
|''Date:''|2008-08-19|
|''Source:''|http://tiddlywiki.bidix.info/#UploadTiddlerPlugin|
|''Usage:''|Uses {{{uploadOptions>>}}}<br>with those UploadTiddler Options : <br>chkUploadTiddler: <<option chkUploadTiddler>><br>txtUploadTiddlerStoreUrl: <<option txtUploadTiddlerStoreUrl>>|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''CoreVersion:''|2.3.0|
***/
//{{{
version.extensions.UploadTiddlerPlugin = {
major: 1, minor: 2, revision: 1,
date: new Date("2008-08-11"),
source: 'http://tiddlywiki.bidix.info/#UploadTiddlerPlugin',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.3.0'
};
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;
bidix.uploadTiddler = {
messages: {
aboutToSaveTiddler: "About to update tiddler '%0'...",
storeTiddlerNotFound: "Script store tiddler '%0' not found",
tiddlerSaved: "Tiddler '%0' updated in '%1'"
},
upload: function(title,tiddler,oldTitle) {
var callback = function(status,params,responseText,url,xhr) {
if (xhr.status == 404) {
alert(bidix.uploadTiddler.messages.storeTiddlerNotFound.format([url]));
return;
}
if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
alert(responseText);
if (responseText.indexOf("Debug mode") >= 0 )
responseText = responseText.substring(responseText.indexOf("\n\n")+2);
} else if (responseText.charAt(0) != '0')
alert(responseText);
else
displayMessage(bidix.uploadTiddler.messages.tiddlerSaved.format([params[0], params[1]]));
store.setDirty(false);
}
if ((config.options['chkUploadTiddler']) && (document.location.toString().substr(0,4) == "http")){
displayMessage(bidix.uploadTiddler.messages.aboutToSaveTiddler.format([title]));
var ExtTiddler = null;
var html = null;
if (tiddler) {
ExtTiddler = store.getSaver().externalizeTiddler(store,tiddler);
html = wikifyStatic(tiddler.text,null,tiddler).htmlEncode();
}
var form = "title="+encodeURIComponent(title);
form = form + "&tiddler="+(ExtTiddler?encodeURIComponent(ExtTiddler):'');
form = form + "&html="+(html?encodeURIComponent(html):'');
var filename = (config.options['txtUploadFilename']?config.options['txtUploadFilename']:'index.html');
form = form +"&oldTitle="+encodeURIComponent(oldTitle);
form = form +"&fileName="+encodeURIComponent(filename);
form = form +"&backupDir="+encodeURIComponent(config.options['txtUploadBackupDir']);
form = form +"&user="+encodeURIComponent(config.options['txtUploadUserName']);
form = form +"&password="+encodeURIComponent(config.options['pasUploadPassword']);
form = form +"&uploadir="+encodeURIComponent(config.options['txtUploadDir']);
form = form +"&debug="+encodeURIComponent(0);
var storeScript = (config.options.txtUploadTiddlerStoreUrl
? config.options.txtUploadTiddlerStoreUrl : 'storeTiddler.php');
var r = doHttp("POST",storeScript,form+"\n",'application/x-www-form-urlencoded',
config.options['txtUploadUserName'],config.options['pasUploadPassword'],callback,Array(title,filename),null);
}
}
}
TiddlyWiki.prototype.saveTiddler_bidix = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(oldTitle,newTitle,newBody,modifier,modified,tags,fields,clearChangeCount,created) {
var tiddler = TiddlyWiki.prototype.saveTiddler_bidix.apply(this,arguments);
var title = (newTitle?newTitle:oldTitle);
if (oldTitle == title)
oldTitle = '';
bidix.uploadTiddler.upload(title, tiddler, oldTitle);
}
TiddlyWiki.prototype.removeTiddler_bidix =TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
TiddlyWiki.prototype.removeTiddler_bidix.apply(this,arguments);
bidix.uploadTiddler.upload(title, null);
}
//
// Initializations
//
bidix.initOption = function(name,value) {
if (!config.options[name])
config.options[name] = value;
};
// styleSheet
setStylesheet('.txtUploadTiddlerStoreUrl {width: 22em;}',"uploadTiddlerPluginStyles");
//optionsDesc
merge(config.optionsDesc,{
txtUploadTiddlerStoreUrl: "Url of the UploadTiddlerService script (default: storeTiddler.php)",
chkUploadTiddler: "Do per Tiddler upload using txtUploadTiddlerStoreUrl (default: false)"
});
// Options Initializations
bidix.initOption('txtUploadTiddlerStoreUrl','');
bidix.initOption('chkUploadTiddler','');
// add options in backstage UploadOptions
if (config.macros.uploadOptions) {
if (config.macros.uploadOptions.options) {
config.macros.uploadOptions.options.push("txtUploadTiddlerStoreUrl","chkUploadTiddler");
}
}
//}}}
/***
|''Name:''|UploadToHomeMacro|
|''Description:''|Save TiddlyWiki using HomeParameters tiddler|
|''Version:''|0.0.2|
|''Date:''|May 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#UploadToHomeMacro|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (#2125)|
|''Requires:''|UploadPlugin|
|''Usage:''|{{{<<uploadToHome [HomeParameters]>>}}}<br>{{{HomeParameters:}}} optional - Tiddler with upload parameters in slices (see HomeParameters).|
***/
//{{{
version.extensions.UploadToHomeMacro = {
major: 0, minor: 0, revision: 2,
date: new Date("May 19, 2007"),
source: 'http://tiddlywiki.bidix.info/#UploadToHomeMacro',
author: 'BidiX (BidiX (at) bidix (dot) info',
coreVersion: '2.2.0 (#3125)'
};
//
// Environment
//
if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false; // true to activate both in Plugin and UploadService
bidix.checkPlugin("UploadPlugin", 4, 1, 0);
//
// uploadUsing Macro
//
config.macros.uploadToHome = {
handler: function(place,macroName,params) {
if (readOnly)
return;
var label;
if (document.location.toString().substr(0,4) == "http")
label = config.macros.upload.label.saveLabel;
else
label = config.macros.upload.label.uploadLabel;
var prompt;
var homeParams = (params[0] ? params[0]:this.messages.homeParamsTiddler);
if (store.tiddlerExists(homeParams) || store.isShadowTiddler(homeParams)) {
prompt = this.messages.prompt.toString().format([homeParams]);
} else {
throw(this.messages.tiddlerNotFound.toString().format([homeParams]));
}
var prompt = this.messages.prompt.toString().format([homeParams]);
createTiddlyButton(place, label, prompt, function() {config.macros.uploadToHome.action(homeParams);}, null, null, this.accessKey);
},
action: function(homeParams) {
homeParams = (homeParams ? homeParams : config.macros.uploadToHome.messages.homeParamsTiddler);
if (!store.tiddlerExists(homeParams) && !store.isShadowTiddler(homeParams)) {
throw(config.macros.uploadToHome.messages.tiddlerNotFound.toString().format([homeParams]));
}
config.macros.upload.action(config.macros.uploadToHome.getParamsFromTiddler(homeParams));
},
getParamsFromTiddler: function(tiddlerTitle) {
tiddlerTitle = (tiddlerTitle ? tiddlerTitle:this.messages.homeParamsTiddler);
if (!store.tiddlerExists(tiddlerTitle) && !store.isShadowTiddler(tiddlerTitle)) {
throw(config.macros.uploadToHome.messages.tiddlerNotFound.toString().format([tiddlerTitle]));
}
var sliceNames = [
"UploadStoreUrl",
"UploadFilename",
"UploadBackupDir",
"UploadDir",
"UploadUserName"
//"UploadPassword", // no password in tiddlers
];
var sliceValues = store.getTiddlerSlices(tiddlerTitle,sliceNames);
var parameters = [];
for(var i=0; i<sliceNames.length; i++) {
parameters.push(sliceValues[sliceNames[i]]);
}
return parameters;
},
messages: {
homeParamsTiddler: "HomeParameters",
prompt: "Save and Upload this TiddlyWiki using parameters in '%0' tiddler",
tiddlerNotFound: "Tiddler %0 not found"
},
initAtLoad: function () {
// install Shadowed HomeParameters
var storeUrl;
if ((document.location.toString().substr(0,4) == "http"))
storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
else
storeUrl = config.macros.upload.defaultStoreScript;
var shadowedHomeParameters = (config.shadowTiddlers['HomeParameters']?config.shadowTiddlers['HomeParameters']:'');
shadowedHomeParameters += [
"|UploadUserName:|"+config.options['txtUploadUserName']+"|",
"|UploadStoreUrl:|"+storeUrl+"|",
"|UploadDir:|.|",
"|UploadFilename:|index.html|",
"|UploadBackupDir:||"
].join("\n");
merge(config.shadowTiddlers,{'HomeParameters': shadowedHomeParameters});
// install Backstage uploadToHome
merge(config.tasks,{
uploadToHome: {text: "uploadToHome", tooltip: "Upload using '" + this.messages.homeParamsTiddler + "' tiddler", action: this.action}
});
config.backstageTasks.push("uploadToHome");
}
};
config.macros.uploadToHome.initAtLoad();
//}}}
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'><span class='toolbar' macro='toolbar snapshotPrint'></span>
<span macro='newHere label:"ny her"'></span> </div>
<div macro="hideWhenTaggedAny noTitle">
<div class='title' macro='view title'></div>
<div class='tagged' macro='tags'></div></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<div class="tagglyTagging" macro="tagglyTagging"></div>
<!--}}}-->
<<siteMap [[Værktøj]] . sliders>>
Der findes mange måder at udvide ~TiddlyWikis funktionalitet.
En af dem er via <<tag systemConfig>>. En anden er ganske enkelt at man laver sit eget hierakiske system, med viden som er vigtig at kunne finde rundt i på en nem og overskuelig måde.
@@color(red):1/11/07 Updated!@@ Introduction and set-up instructions re-written for clarity
@@color(red):1/11/07 New!@@ [[Diagram|TiddlyChatter flow]] of how to get two people Chattering
@@color(red):22/10/07 New!@@ [[Designing TiddlyChatter from the user's point of view|http://tiddlychatter.tiddlyspot.com]]
This ~TiddlyWiki has been installed with TiddlyChatter, a shiny new collaboration feature.
!!~TiddlyChatter is for opt-in, decentralized collaboration. What this means:
''opt-in:'' avoid "collaboration noise" associated with standard wikis - only see the information from people you want to collaborate directly with;
''decentralized:'' everyone can keep their own personal ~TiddlyWiki and still become a part of a ~TiddlyChatter community; you don't need to rely on a central collaboration server.
!!Starting out
To get into the ~TiddlyChatter mood, you need to [[install|InstallTiddlyChatter]] the <<tag TiddlyChatterPackage>> tiddlers in your own ~TiddlyWiki. When you're done, take a look at these [[quick tips|After installing]] or read these guides to [[publishing|TiddlyChatterPublishing]] content and [[getting hold of|TiddlyChatterReading]] other people's content. There is also a [[diagram|TiddlyChatter flow]] of the flow two people would go through to Chatter with each other.
You are actively encouraged to help design and build TiddlyChatter. The tiddler [[Designing TiddlyChatter from the user's point of view]] leads to a lot of content that describes and documents the design process we are going through. Please contribute through the [[TiddlyWikiDev|http://groups.google.com/TiddlyWikiDev]] group or mail me at jon at osmosoft dot com.
You can read an example scenario of [[how TiddlyChatter works|How TiddlyChatter works - an example scenario]]. ~TiddlyChatter is still in [[development|TiddlyChatterDocumentation]]. Bugs are [[tracked|BUGS]], please post in the [[TiddlyWikiDev|http://groups.google.com/TiddlyWikiDev]] Google Group if you find more.
<html><div align="center"><iframe src="http://voicethread.com/#q.b67978.i350123" frameborder="0" width="100%" height="600"></iframe></div></html>
<html>
<img style="visibility:hidden;width:0px;height:0px;" border=0 width=0 height=0 src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyMzg*MDcwMTE3OTYmcHQ9MTIzODQwNzAyMzAzMSZwPTIwNjQyMSZkPWI2Nzk3OCZnPTImdD*mbz1mNzcwZWEwNGM3MzQ*MDAxYmJkMzI2YWE*OGZiZWE5ZA==.gif" /><object width="480" height="360"><param name="movie" value="http://voicethread.com/book.swf?b=67978"></param><param name="wmode" value="transparent"></param><embed src="http://voicethread.com/book.swf?b=67978" type="application/x-shockwave-flash" wmode="transparent" width="480" height="360"></embed></object>
</html>
/***
|''Name:''|WikiBar|
|''Version:''|2.0.0 beta3|
|''Source:''|[[AiddlyWiki|http://aiddlywiki.sourceforge.net]]|
|''Author:''|[[Arphen Lin|mailto:arphenlin@gmail.com]]|
|''Type:''|toolbar macro command extension|
|''Required:''|TiddlyWiki 2.0.0 beta6|
!Description
WikiBar is a toolbar that gives access to most of TiddlyWiki's formatting features with a few clicks. It's a handy tool for people who are not familiar with TiddlyWiki syntax.
Besides, with WikiBar-addons, users can extend the power of WikiBar.
!Support browser
*Firefox 1.5
!Revision history
*v2.0.0 beta3 (2005/12/30)
** remove macros (replaced by TWMacro addon)
** add wikibar command in toolbar automatically
** rename DOIT to HANDLER
** rename TIP to TOOLTIP
*v2.0.0 beta2 (2005/12/21)
** re-design Wikibar addon framework
*v2.0.0 beta1 (2005/12/14)
** Note:
*** WikiBarPlugin is renamed to WikiBar
** New Features:
*** support TiddlyWiki 2.0.0 template mechanism
*** new wikibar data structure
*** new wikibar-addon framework for developers
**** support dynamic popup menu generator
*** support most new macros added in TiddlyWiki 2.0.0
*** multi-level popup menu
*** fix wikibar tab stop
*** remove paletteSelector
** Known Bugs:
*** popup-menu and color-picker can't be closed correctly
*** some macros can't be displayed correctly in previewer
*** text in previewer will be displayed italic
*v1.2.0 (2005/11/21)
**New Features:
***User defined color palettes supported
####Get color palettes from [[ColorZilla Palettes|http://www.iosart.com/firefox/colorzilla/palettes.html]].
####Save the palette file(*.gpl) as a new tiddler and tag it with 'ColorPalettes', then you can use it in WikiBar.
***WikiBar style sheet supported
***Click on document to close current colorPicker, paletteSelector or aboutWikibar
*v1.1.1 (2005/11/03)
**Bugs fixed:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.1.0 (2005/11/01)
**Bugs fixed:
***WikiBar overruns (reported by by GeoffS <gslocock@yahoo.co.uk>)
**New features:
***Insert a color code at the cursor. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Enable gradient macro. (Thanks to RunningUtes <RunningUtes@gmail.com>)
***Insert tiddler comment tags {{{/% ... %/}}}. (new feature supported by TiddlyWiki 1.2.37)
***Insert DateFormatString for {{{<<today>>}}} macro. (new feature supported by TiddlyWiki 1.2.37)
**Enhanced:
***Allow optional parameters in syntax.
**Bugs:
***'Not enough parameters!' message is displayed when the parameter includes '%+number', ex: 'hello%20world!'
*v1.0.0 (2005/10/30)
**Initial release
!Code
***/
//{{{
config.macros.wikibar = {major: 2, minor: 0, revision: 0, beta: 3, date: new Date(2005,12,30)};
config.macros.wikibar.handler = function(place,macroName,params,wikifier,paramString,tiddler){
if(!(tiddler instanceof Tiddler)) {return;}
story.setDirty(tiddler.title,true);
place.id = 'wikibar'+tiddler.title;
place.className = 'toolbar wikibar';
};
function wikibar_install(){
config.commands.wikibar = {
text: 'wikibar',
tooltip: 'wikibar on/off',
handler: function(e,src,title) {
if(!e){ e = window.event; }
var theButton = resolveTarget(e);
theButton.id = 'wikibarButton'+title;
wikibarPopup.remove();
wikibar_installAddons(theButton, title);
wikibar_createWikibar(title);
return(false);
}
};
config.shadowTiddlers['EditTemplate'] = wikibar_addWikibarCommand(config.shadowTiddlers['EditTemplate']);
var tiddler = store.getTiddler('EditTemplate');
if(tiddler){
tiddler.text = wikibar_addWikibarCommand(tiddler.text);
}
}
function wikibar_installAddons(theButton, title){
var tiddlers = store.getTaggedTiddlers('wikibarAddons');
if(!tiddlers) { return; }
theButton.addons=[];
for(var i=0; i<tiddlers.length; i++){
try{
eval(tiddlers[i].text);
try{
wikibar_addonInstall(title);
wikibar_addonInstall = null;
theButton.addons.push({ok:true, name:tiddlers[i].title});
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}catch(ex){
theButton.addons.push({ok:false, name:tiddlers[i].title, error:ex});
}
}
}
function wikibar_addWikibarCommand(tiddlerText){
var div = document.createElement('div');
div.style.display = 'none';
div.innerHTML = tiddlerText;
for(var i=0; i<div.childNodes.length; i++){
var o=div.childNodes[i];
if(o.tagName==='DIV'){
if(o.className=='toolbar'){
var macroText = o.getAttribute('macro').trim();
if(macroText.search('wikibar')<=0){
macroText += ' wikibar';
o.setAttribute('macro', macroText);
}
break;
}
}
}
return div.innerHTML.replace(/\"/g, "\'");
}
function wikibar_processSyntaxParams(theSyntax, params){
try{
var pcr = 'AplWikibarPcr';
var rx=null;
var allParams=null;
if(params){
if(typeof(params)=='object'){
for(var i=0; i<params.length; i++){
if(params[i]){
params[i] = params[i].replace(new RegExp('%','g'), pcr).trim();
rx = '(\\[%'+(i+1)+'\\])' + '|' + '(%'+(i+1)+')';
theSyntax = theSyntax.replace(new RegExp(rx,'g'), params[i] );
}
}
allParams = params.join(' ').trim();
}else{
allParams = params.replace(new RegExp('%','g'), pcr).trim();
rx = /(\[%1{1}\])|(%1{1})/g;
theSyntax = theSyntax.replace(rx, allParams);
}
}
if(allParams){
theSyntax = theSyntax.replace(new RegExp('%N{1}','g'), allParams);
}
rx=/\[%(([1-9]{1,}[0-9]{0,})|(N{1}))\]/g;
theSyntax = theSyntax.replace(rx, '');
rx=/%(([1-9]{1,}[0-9]{0,})|(N{1}))/g;
if( theSyntax.match(rx) ){
throw 'Not enough parameters! ' + theSyntax;
}
theSyntax=theSyntax.replace(new RegExp(pcr,'g'), '%');
return theSyntax;
} catch(ex){
return null;
}
}
function wikibar_resolveEditItem(tiddlerWrapper, itemName){
if(tiddlerWrapper.hasChildNodes()){
var c=tiddlerWrapper.childNodes;
for(var i=0; i<c.length; i++){
var txt=wikibar_resolveEditItem(c[i], itemName);
if(!txt){
continue;
}else{
return txt;
}
}
}
return ((tiddlerWrapper.getAttribute && tiddlerWrapper.getAttribute('edit')==itemName)? tiddlerWrapper : null);
}
function wikibar_resolveEditItemValue(tiddlerWrapper, itemName){
var o = wikibar_resolveEditItem(tiddlerWrapper, itemName);
return (o? o.value.replace(/\r/mg,'') : null);
}
function wikibar_resolveTiddlerEditorWrapper(obj){
if(obj.id=='tiddlerDisplay'){return null;}
if((obj.getAttribute && obj.getAttribute('macro')=='edit text')){return obj;}
return wikibar_resolveTiddlerEditorWrapper(obj.parentNode);
}
function wikibar_resolveTiddlerEditor(obj){
if(obj.hasChildNodes()){
var c = obj.childNodes;
for(var i=0; i<c.length; i++){
var o=wikibar_resolveTiddlerEditor(c[i]);
if(o){ return o;}
}
}
return ((obj.getAttribute && obj.getAttribute('edit')=='text')? obj : null);
}
function wikibar_resolveTargetButton(obj){
if(obj.id && obj.id.substring(0,7)=='wikibar'){ return null; }
if(obj.tiddlerTitle){
return obj;
}else{
return wikibar_resolveTargetButton(obj.parentNode);
}
}
function wikibar_isValidMenuItem(tool){
if(!tool){ return false; }
if(tool.TYPE=='MENU' || tool.TYPE=='MAIN_MENU'){
for(var key in tool){
if(key.substring(0,8)=='DYNAITEM'){ return true; }
if(wikibar_isValidMenuItem(tool[key])){ return true; }
}
return false;
}else{
return (tool.HANDLER? true : false);
}
}
function wikibar_editFormat(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByWord(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){return;}
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
if(!( fullText.charAt(ss-1).match(/\W/gi) || fullText.charAt(ss).match(/\W/gi) )){
var m = frontText.match(/\W/gi);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/\W/gi);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
selText = fullText.substring(ss,se);
}
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByCursor(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
else if(ss===0 && (se===0 || se == fullText.length) ){
endText = fullText;
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByLine(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(se>ss && ss>=0){
if(this.byBlock){
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
else{
se = ss;
}
}
if(ss===0 && (se===0 || se == fullText.length) ){
var m=fullText.match(/(\n|\r)/g);
if(m){
se = fullText.indexOf(m[0]);
}else{
se = fullText.length;
}
selText = fullText.substring(0, se);
endText = fullText.substring(se, fullText.length);
}
else if(se==ss && ss>0){
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
m = frontText.match(/(\n|\r)/g);
if(m){
ss = frontText.lastIndexOf(m[m.length-1])+1;
}
else{
ss = 0;
}
m = endText.match(/(\n|\r)/g);
if(m){
se += endText.indexOf(m[0]);
}
else{
se = fullText.length;
}
frontText = fullText.substring(0, ss);
selText = fullText.substring(ss,se);
endText = fullText.substring(se, fullText.length);
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
if(this.byBlock){
if( (frontText.charAt(frontText.length-1)!='\n') && ss>0 ){
repText = '\n' + repText;
}
if( (endText.charAt(0)!='\n') || se==fullText.length){
repText += '\n';
}
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editFormatByTableCell(param){
var editor = param.button.editor;
var params = param.params;
clearMessage();
if(!editor){ return; }
var repText = wikibar_processSyntaxParams(this.syntax, params);
if(repText===null){ return; }
var st = editor.scrollTop;
var ss = editor.selectionStart;
var se = editor.selectionEnd;
var frontText= '';
var selText = '';
var endText = '';
var fullText = editor.value;
if(ss===0 || ss==fullText.length){
throw 'not valid cell!';
}
se=ss;
frontText = fullText.substring(0, ss);
endText = fullText.substring(se, fullText.length);
i=frontText.lastIndexOf('\n');
j=frontText.lastIndexOf('|');
if(i>j || j<0){
throw 'not valid cell!';
}
ss = j+1;
i=endText.indexOf('\n');
j=endText.indexOf('|');
if(i<j || j<0){
throw 'not valid cell!';
}
se += j;
frontText = fullText.substring(0, ss-1);
selText = fullText.substring(ss,se);
endText = fullText.substring(se+1, fullText.length);
if(this.key.substring(0,5)=='align'){
selText = selText.trim();
if( selText=='>' || selText=='~' || selText.substring(0,8)=='bgcolor(') {return; }
}
if(selText.length>0){
repText = repText.replace('user_text', selText);
}
if(repText.indexOf('user_text')>=0 && this.hint){
repText = repText.replace('user_text', this.hint);
}
editor.value = frontText + repText + endText;
editor.selectionStart = ss;
editor.selectionEnd = ss + repText.length - 2;
editor.scrollTop = st;
editor.focus();
}
function wikibar_editSelectAll(param){
var editor = param.button.editor;
editor.selectionStart = 0;
editor.selectionEnd = editor.value.length;
editor.scrollTop = 0;
editor.focus();
}
function wikibar_doPreview(param){
var theButton = param.button;
var editor = param.button.editor;
var wikibar = theButton.parentNode;
if(!wikibar) { return; }
title = theButton.tiddlerTitle;
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(editor);
var tiddlerWrapper = editorWrapper.parentNode;
var previewer = document.getElementById('previewer'+title);
if(previewer){
previewer.parentNode.removeChild(previewer);
editorWrapper.style.display = 'block';
visible=true;
}else{
previewer = document.createElement('div');
previewer.id = 'previewer'+title;
previewer.className = 'viewer previewer';
previewer.style.height = (editor.offsetHeight) + 'px';
wikify(editor.value, previewer);
tiddlerWrapper.insertBefore(previewer, editorWrapper);
editorWrapper.style.display = 'none';
visible=false;
}
var pv=null;
for(var i=0; i<wikibar.childNodes.length; i++){
try{
var btn = wikibar.childNodes[i];
if(btn.toolItem.key == 'preview'){ pv=btn; }
if(btn.toolItem.key != 'preview'){
btn.style.display = visible ? '': 'none';
}
}catch(ex){}
}
if(!pv) { return; }
if(visible){
pv.innerHTML = '<font face=\"verdana\">∞</font>';
pv.title = 'preview current tiddler';
}
else{
pv.innerHTML = '<font face=\"verdana\">←</font>';
pv.title = 'back to editor';
}
}
function wikibar_doListAddons(param){
clearMessage();
var title = param.button.tiddlerTitle;
var wikibarButton = document.getElementById('wikibarButton'+title);
var ok=0, fail=0;
for(var i=0; i<wikibarButton.addons.length; i++){
var addon=wikibarButton.addons[i];
if(addon.ok){
displayMessage('[ o ] '+addon.name);
ok++;
}
else{
displayMessage('[ x ] '+addon.name + ': ' + addon.error);
fail++;
}
}
displayMessage('---------------------------------');
displayMessage(ok + ' ok ; ' + fail + ' failed');
}
function wikibar_getColorCode(param){
var cbOnPickColor = function(colorCode, param){
param.params = colorCode;
param.button.toolItem.doMore(param);
};
wikibarColorTool.openColorPicker(param.button, cbOnPickColor, param);
}
function wikibar_getLinkUrl(param){
var url= prompt('Please enter the link target', (this.param? this.param : ''));
if (url && url.trim().length>0){
param.params = url;
this.doMore(param);
}
}
function wikibar_getTableRowCol(param){
var rc= prompt('Please enter (rows x cols) of the table', '2 x 3');
if (!rc || (rc.trim()).length<=0){ return; }
var arr = rc.toUpperCase().split('X');
if(arr.length != 2) { return; }
for(var i=0; i<arr.length; i++){
if(isNaN(arr[i].trim())) { return; }
}
var rows = parseInt(arr[0].trim(), 10);
var cols = parseInt(arr[1].trim(), 10);
var txtTable='';
for(var r=0; r<rows; r++){
for(var c=0; c<=cols; c++){
if(c===0){
txtTable += '|';
}else{
txtTable += ' |';
}
}
txtTable += '\n';
}
if(txtTable.trim().length>0){
param.params = txtTable.trim();
this.doMore(param);
}
}
function wikibar_getMacroParam(param){
var p = prompt('Please enter the parameters of macro \"' + this.key + '\":' +
'\nSyntax: ' + this.syntax +
'\n\nNote: '+
'\n%1,%2,... - parameter needed'+
'\n[%1] - optional parameter'+
'\n%N - more than one parameter(1~n)'+
'\n[%N] - any number of parameters(0~n)'+
'\n\nPS:'+
'\n1. Parameters should be seperated with space character'+
'\n2. Use \" to wrap the parameter that includes space character, ex: \"hello world\"'+
'\n3. Input the word(null) for the optional parameter ignored',
(this.param? this.param : '') );
if(!p) { return; }
p=p.readMacroParams();
for(var i=0; i<p.length; i++){
var s=p[i].trim();
if(s.indexOf(' ')>0){ p[i]="'"+s+"'"; }
if(s.toLowerCase()=='null'){ p[i]=null; }
}
param.params = p;
this.doMore(param);
}
function wikibar_getMorePalette(unused){
clearMessage();
displayMessage('Get more color palettes(*.gpl) from ColorZilla Palettes site', 'http:\/\/www.iosart.com/firefox/colorzilla/palettes.html');
displayMessage('Save it as a new tiddler with \"ColorPalettes\" tag');
}
function wikibar_createWikibar(title){
var theWikibar = document.getElementById('wikibar' + title);
if(theWikibar){
if(theWikibar.hasChildNodes()){
theWikibar.style.display = (theWikibar.style.display=='block'? 'none':'block');
return;
}
}
var tiddlerWrapper = document.getElementById('tiddler'+title);
var theTextarea = wikibar_resolveTiddlerEditor(tiddlerWrapper);
if(!theTextarea){
clearMessage();
displayMessage('WikiBar only works in tiddler edit mode now');
return;
}else{
if(!theTextarea.id){ theTextarea.id = 'editor'+title; }
if(!theTextarea.parentNode.id){ theTextarea.parentNode.id='editorWrapper'+title; }
}
if(theWikibar){
theWikibar = document.getElementById('wikibar'+title);
}else{
var editorWrapper = wikibar_resolveTiddlerEditorWrapper(theTextarea);
theWikibar = createTiddlyElement(tiddlerWrapper, 'div', 'wikibar'+title, 'toolbar');
addClass(theWikibar, 'wikibar');
var previewer = document.getElementById('previewer'+title);
if(previewer){
tiddlerWrapper.insertBefore(theWikibar, previewer);
}else{
tiddlerWrapper.insertBefore(theWikibar, editorWrapper);
}
}
wikibar_createMenu(theWikibar,wikibarStore,title,theTextarea);
if(config.options['chkWikibarSetEditorHeight'] && config.options['txtWikibarEditorRows']){
theTextarea.rows = config.options['txtWikibarEditorRows'];
}
setStylesheet(
'.wikibar{text-align:left;visibility:visible;margin:2px;padding:1px;}.previewer{overflow:auto;display:block;border:1px solid;}#colorPicker{position:absolute;display:none;z-index:10;margin:0px;padding:0px;}#colorPicker table{margin:0px;padding:0px;border:2px solid #000;border-spacing:0px;border-collapse:collapse;}#colorPicker td{margin:0px;padding:0px;border:1px solid;font-size:11px;text-align:center;cursor:auto;}#colorPicker .header{background-color:#fff;}#colorPicker .button{background-color:#fff;cursor:pointer;cursor:hand;}#colorPicker .button:hover{padding-top:3px;padding-bottom:3px;color:#fff;background-color:#136;}#colorPicker .cell{padding:4px;font-size:7px;cursor:crosshair;}#colorPicker .cell:hover{padding:10px;}.wikibarPopup{position:absolute;z-index:10;border:1px solid #014;color:#014;background-color:#cef;}.wikibarPopup table{margin:0;padding:0;border:0;border-spacing:0;border-collapse:collapse;}.wikibarPopup .button:hover{color:#eee;background-color:#014;}.wikibarPopup .disabled{color:#888;}.wikibarPopup .disabled:hover{color:#888;background-color:#cef;}.wikibarPopup tr .seperator hr{margin:0;padding:0;background-color:#cef;width:100%;border:0;border-top:1px dashed #014;}.wikibarPopup tr .icon{font-family:verdana;font-weight:bolder;}.wikibarPopup tr .marker{font-family:verdana;font-weight:bolder;}.wikibarPopup td{font-size:0.9em;padding:2px;}.wikibarPopup input{border:0;border-bottom:1px solid #014;margin:0;padding:0;font-family:arial;font-size:100%;background-color:#fff;}',
'WikiBarStyleSheet');
}
function wikibar_createMenu(place,toolset,title,editor){
if(!wikibar_isValidMenuItem(toolset)){return;}
if(!(toolset.TYPE=='MAIN_MENU' || toolset.TYPE=='MENU')){ return; }
for(var key in toolset){
if(key.substring(0,9)=='SEPERATOR'){
wikibar_createMenuSeperator(place);
continue;
}
if(key.substring(0,8)=='DYNAITEM'){
var dynaTools = toolset[key](title,editor);
if(dynaTools.TYPE && dynaTools.TYPE=='MENU'){
wikibar_createMenuItem(place,dynaTools,null,editor,title);
}else{
dynaTools.TYPE = 'MENU';
wikibar_createMenu(place, dynaTools, title, editor);
}
continue;
}
if((toolset[key].TYPE!='MENU' && toolset[key].TYPE!='MAIN_MENU') && !toolset[key].HANDLER){continue;}
wikibar_createMenuItem(place,toolset,key,editor,title);
}
}
function wikibar_createMenuItem(place,toolset,key,editor,title){
if(!key){
var tool = toolset;
}else{
tool = toolset[key];
tool.key = key;
}
if(!wikibar_isValidMenuItem(tool)){return;}
var toolIsOnMainMenu = (toolset.TYPE=='MAIN_MENU');
var toolIsMenu = (tool.TYPE=='MENU');
var theButton;
if(toolIsOnMainMenu){
theButton = createTiddlyButton(
place,
'',
(tool.TOOLTIP? tool.TOOLTIP : ''),
(toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem),
'button');
theButton.innerHTML = (tool.CAPTION? tool.CAPTION : key);
theButton.isOnMainMenu = true;
addClass(theButton, (toolIsMenu? 'menu' : 'item'));
place.appendChild( document.createTextNode('\n') );
if(!toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = function(e){ wikibarPopup.remove(); };
}
}
}else{
theButton=createTiddlyElement(place, 'tr',key,'button');
theButton.title = (tool.TOOLTIP? tool.TOOLTIP : '');
theButton.onclick = (toolIsMenu? wikibar_onClickMenuItem : wikibar_onClickItem);
var tdL = createTiddlyElement(theButton, 'td','','marker');
var td = createTiddlyElement(theButton, 'td');
var tdR = createTiddlyElement(theButton, 'td','','marker');
td.innerHTML = (tool.CAPTION? tool.CAPTION : key);
if(toolIsMenu){
tdR.innerHTML=' ›';
}
if(tool.SELECTED){
tdL.innerHTML = '√ ';
addClass(theButton, 'selected');
}
if(tool.DISABLED){
addClass(theButton, 'disabled');
}
}
theButton.tiddlerTitle = title;
theButton.toolItem = tool;
theButton.editor = editor;
theButton.tabIndex = 999;
if(toolIsMenu){
if(config.options['chkWikibarPopmenuOnMouseOver']){
theButton.onmouseover = wikibar_onClickMenuItem;
}
}
}
function wikibar_createMenuSeperator(place){
if(place.id.substring(0,7)=='wikibar') { return; }
var onclickSeperator=function(e){
if(!e){ e = window.event; }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
var theButton=createTiddlyElement(place,'tr','','seperator');
var td = createTiddlyElement(theButton, 'td','','seperator');
td.colSpan=3;
theButton.onclick=onclickSeperator;
td.innerHTML = '<hr>';
}
function wikibar_genWikibarAbout(){
var toolset={};
toolset.version = {
CAPTION: '<center>WikiBar ' +
config.macros.wikibar.major + '.' +
config.macros.wikibar.minor + '.' +
config.macros.wikibar.revision +
(config.macros.wikibar.beta? ' beta '+config.macros.wikibar.beta : '') +
'</center>',
HANDLER: function(){}
};
toolset.SEPERATOR = {};
toolset.author = {
CAPTION: '<center>Arphen Lin<br>arphenlin@gmail.com</center>',
TOOLTIP: 'send mail to the author',
HANDLER: function(){ window.open('mailto:arphenlin@gmail.com'); }
};
toolset.website = {
CAPTION: '<center>aiddlywiki.sourceforge.net</center>',
TOOLTIP: 'go to the web site of WikiBar',
HANDLER: function(){ window.open('http:\/\/aiddlywiki.sourceforge.net/'); }
};
return toolset;
}
function wikibar_genWikibarOptions(title, editor){
var toolset={};
toolset.popOnMouseOver = {
CAPTION:'popup menu on mouse over',
SELECTED: config.options['chkWikibarPopmenuOnMouseOver'],
HANDLER: function(param){
config.options['chkWikibarPopmenuOnMouseOver'] = !config.options['chkWikibarPopmenuOnMouseOver'];
saveOptionCookie('chkWikibarPopmenuOnMouseOver');
var title = param.button.tiddlerTitle;
var wikibar = document.getElementById('wikibar'+title);
if(wikibar){ wikibar.parentNode.removeChild(wikibar); }
wikibar_createWikibar(title);
}
};
toolset.setEditorSize = {
CAPTION:'set editor height: <input id=\"txtWikibarEditorRows\" type=text size=1 MAXLENGTH=3 value=\"' +
(config.options['txtWikibarEditorRows']? config.options['txtWikibarEditorRows']:editor.rows) + '\"> ok',
HANDLER: function(param){
var input = document.getElementById('txtWikibarEditorRows');
if(input){
var rows = parseInt(input.value, 10);
if(!isNaN(rows)){
var editor = param.button.editor;
editor.rows = rows;
}else{
rows=config.maxEditRows;
}
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
config.maxEditRows = rows;
}
}
};
toolset.setEditorSizeOnLoadingWikibar = {
CAPTION:'set editor height on loading wikibar',
SELECTED: config.options['chkWikibarSetEditorHeight'],
HANDLER: function(param){
config.options['chkWikibarSetEditorHeight'] = !config.options['chkWikibarSetEditorHeight'];
saveOptionCookie('chkWikibarSetEditorHeight');
if(config.options['chkWikibarSetEditorHeight']){
var rows = config.options['txtWikibarEditorRows'];
if(!isNaN(rows)){ rows = 15; }
var editor = param.button.editor;
editor.rows = rows;
config.options['txtWikibarEditorRows'] = rows;
saveOptionCookie('txtWikibarEditorRows');
}
}
};
toolset.SEPERATOR = {};
toolset.update = {
CAPTION: 'check for updates',
DISABLED: true,
HANDLER: function(){}
};
return toolset;
}
function wikibar_genPaletteSelector(){
try{
var cpTiddlers = store.getTaggedTiddlers('ColorPalettes');
if(!cpTiddlers) { return; }
var palettes=[];
palettes.push(wikibarColorTool.defaultPaletteName);
for(var i=0; i<cpTiddlers.length; i++){
palettes.push(cpTiddlers[i].title.trim());
}
var toolset={};
for(i=0; i<palettes.length; i++){
toolset[palettes[i]] = {
TOOLTIP: palettes[i],
SELECTED: (palettes[i]==wikibarColorTool.paletteName),
HANDLER: wikibar_doSelectPalette
};
}
return toolset;
}catch(ex){ return null; }
}
function wikibar_onClickItem(e){
if(!e){ e = window.event; }
var theTarget = resolveTarget(e);
if(theTarget.tagName=='INPUT'){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return;
}
var theButton = wikibar_resolveTargetButton(theTarget);
if(!theButton){ return(false); }
var o = theButton.toolItem;
if(!o) { return; }
var param = {
event: e,
button: theButton
};
if(o.HANDLER){ o.HANDLER(param); }
if(o.DISABLED){
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
}
return(false);
}
function wikibar_onClickMenuItem(e){
if(!e){ e = window.event; }
var theButton = wikibar_resolveTargetButton(resolveTarget(e));
if(!theButton){ return(false); }
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
var title = theButton.tiddlerTitle;
var editor = theButton.editor;
var tool = theButton.toolItem;
if(!tool) { return; }
var popup = wikibarPopup.create(this);
if(popup){
wikibar_createMenu(popup,tool,title,editor);
if(!popup.hasChildNodes()){
wikibarPopup.remove();
}else{
wikibarPopup.show(popup, false);
}
}
return(false);
}
var wikibarColorTool = {
defaultPaletteName : 'default',
defaultColumns : 16,
defaultPalette : [
'#FFF','#DDD','#CCC','#BBB','#AAA','#999','#666','#333','#111','#000','#FC0','#F90','#F60','#F30','#C30','#C03',
'#9C0','#9D0','#9E0','#E90','#D90','#C90','#FC3','#FC6','#F96','#F63','#600','#900','#C00','#F00','#F36','#F03',
'#CF0','#CF3','#330','#660','#990','#CC0','#FF0','#C93','#C63','#300','#933','#C33','#F33','#C36','#F69','#F06',
'#9F0','#CF6','#9C3','#663','#993','#CC3','#FF3','#960','#930','#633','#C66','#F66','#903','#C39','#F6C','#F09',
'#6F0','#9F6','#6C3','#690','#996','#CC6','#FF6','#963','#630','#966','#F99','#F39','#C06','#906','#F3C','#F0C',
'#3F0','#6F3','#390','#6C0','#9F3','#CC9','#FF9','#C96','#C60','#C99','#F9C','#C69','#936','#603','#C09','#303',
'#0C0','#3C0','#360','#693','#9C6','#CF9','#FFC','#FC9','#F93','#FCC','#C9C','#969','#939','#909','#636','#606',
'#060','#3C3','#6C6','#0F0','#3F3','#6F6','#9F9','#CFC','#9CF','#FCF','#F9F','#F6F','#F3F','#F0F','#C6C','#C3C',
'#030','#363','#090','#393','#696','#9C9','#CFF','#39F','#69C','#CCF','#C9F','#96C','#639','#306','#90C','#C0C',
'#0F3','#0C3','#063','#396','#6C9','#9FC','#9CC','#06C','#369','#99F','#99C','#93F','#60C','#609','#C3F','#C0F',
'#0F6','#3F6','#093','#0C6','#3F9','#9FF','#699','#036','#039','#66F','#66C','#669','#309','#93C','#C6F','#90F',
'#0F9','#6F9','#3C6','#096','#6FF','#6CC','#366','#069','#36C','#33F','#33C','#339','#336','#63C','#96F','#60F',
'#0FC','#6FC','#3C9','#3FF','#3CC','#399','#033','#39C','#69F','#00F','#00C','#009','#006','#003','#63F','#30F',
'#0C9','#3FC','#0FF','#0CC','#099','#066','#3CF','#6CF','#09C','#36F','#0CF','#09F','#06F','#03F','#03C','#30C'
],
colorPicker : null,
pickColorHandler: null,
userData: null
};
wikibarColorTool.paletteName = wikibarColorTool.defaultPaletteName;
wikibarColorTool.columns = wikibarColorTool.defaultColumns;
wikibarColorTool.palette = wikibarColorTool.defaultPalette;
wikibarColorTool.onPickColor = function(e){
if (!e){ e = window.event; }
var theCell = resolveTarget(e);
if(!theCell){ return(false); }
color = theCell.bgColor.toLowerCase();
if(!color) { return; }
wikibarColorTool.displayColorPicker(false);
if(wikibarColorTool.pickColorHandler){
wikibarColorTool.pickColorHandler(color, wikibarColorTool.userData);
}
return(false);
};
wikibarColorTool.onMouseOver = function(e){
if (!e){ e = window.event; }
var theButton = resolveTarget(e);
if(!theButton){ return(false); }
if(!wikibarColorTool) { return; }
color = theButton.bgColor.toUpperCase();
if(!color) { return; }
td=document.getElementById('colorPickerInfo');
if(!td) { return; }
td.bgColor = color;
td.innerHTML = '<span style=\"color:#000;\">'+color+'</span> ' +
'<span style=\"color:#fff;\">'+color+'</span>';
e.cancelBubble = true;
if (e.stopPropagation){ e.stopPropagation(); }
return(false);
};
wikibarColorTool.openColorPicker = function(theTarget, pickColorHandler, userData){
wikibarColorTool.skipClickDocumentEvent = true;
wikibarColorTool.pickColorHandler = pickColorHandler;
wikibarColorTool.userData = userData;
wikibarColorTool.moveColorPicker(theTarget);
};
wikibarColorTool.convert3to6HexColor = function(c){
c=c.trim();
var rx=/^\#(\d|[a-f])(\d|[a-f])(\d|[a-f])$/gi;
return (rx.test(c)? c.replace(rx, '#$1$1$2$2$3$3') : c);
};
wikibarColorTool.numToHexColor = function (n){
if(typeof(n)=='number' && (n>=0 && n<=255)) {
s = n.toString(16).toLowerCase();
return ((s.length==1)? '0'+s : s);
}else{
return null;
}
};
wikibarColorTool.renderColorPalette = function(){
if(wikibarColorTool.paletteName==wikibarColorTool.defaultPaletteName){
wikibarColorTool.palette=wikibarColorTool.defaultPalette;
wikibarColorTool.columns=wikibarColorTool.defaultColumns;
return;
}
tiddlerText = (store.getTiddlerText(wikibarColorTool.paletteName, '')).trim();
if(tiddlerText.length<=0) { return; }
var cpContents = tiddlerText.split('\n');
var colors=[];
columns = wikibarColorTool.defaultColumns;
var tmpArray=null;
errCount=0;
for(var i=0; i<cpContents.length; i++){
cpLine=cpContents[i].trim();
if( (!cpLine) || (cpLine.length<=0) || (cpLine.charAt(0) == '#') ){ continue; }
if(cpLine.substring(0,8).toLowerCase()=='columns:'){
tmpArray = cpLine.split(':');
try{
columns = parseInt(tmpArray[1],10);
}catch(ex){
columns = wikibarColorTool.defaultColumns;
}
}else{
tmpArray = cpLine.replace('\t', ' ').split(/[ ]{1,}/);
try{
color='';
for(var j=0; j<3; j++){
c=parseInt(tmpArray[j].trim(), 10);
if(isNaN(c)){
break;
}else{
c=wikibarColorTool.numToHexColor(c);
if(!c) {break;}
color+=c;
}
}
if(color.length==6){
colors.push('#'+color);
} else {
throw 'error';
}
}catch(ex){
}
}
}
if(colors.length>0){
wikibarColorTool.palette = colors;
wikibarColorTool.columns = columns;
}else{
throw 'renderColorPalette(): No color defined in the palette.';
}
};
wikibarColorTool.displayColorPicker = function(visible){
if(wikibarColorTool.colorPicker){
wikibarColorTool.colorPicker.style.display = (visible? 'block' : 'none');
}
};
wikibarColorTool.moveColorPicker = function(theTarget){
if(!wikibarColorTool.colorPicker){
wikibarColorTool.createColorPicker();
}
var cp = wikibarColorTool.colorPicker;
var rootLeft = findPosX(theTarget);
var rootTop = findPosY(theTarget);
var popupLeft = rootLeft;
var popupTop = rootTop;
var popupWidth = cp.offsetWidth;
var winWidth = findWindowWidth();
if(popupLeft + popupWidth > winWidth){
popupLeft = winWidth - popupWidth;
}
cp.style.left = popupLeft + 'px';
cp.style.top = popupTop + 'px';
wikibarColorTool.displayColorPicker(true);
};
wikibarColorTool.createColorPicker = function(unused, palette){
if(palette){ wikibarColorTool.paletteName=palette; }
wikibarColorTool.renderColorPalette();
wikibarColorTool.colorPicker = document.createElement('div');
wikibarColorTool.colorPicker.id = 'colorPicker';
document.body.appendChild(wikibarColorTool.colorPicker);
var theTable = document.createElement('table');
wikibarColorTool.colorPicker.appendChild(theTable);
var theTR = document.createElement('tr');
theTable.appendChild(theTR);
var theTD = document.createElement('td');
theTD.className = 'header';
theTD.colSpan = wikibarColorTool.columns;
theTD.innerHTML = wikibarColorTool.paletteName;
theTR.appendChild(theTD);
for(var i=0; i<wikibarColorTool.palette.length; i++){
if((i%wikibarColorTool.columns)===0){
theTR = document.createElement('tr');
theTable.appendChild(theTR);
}
theTD = document.createElement('td');
theTD.className = 'cell';
theTD.bgColor = wikibarColorTool.convert3to6HexColor(wikibarColorTool.palette[i]);
theTD.onclick = wikibarColorTool.onPickColor;
theTD.onmouseover = wikibarColorTool.onMouseOver;
theTR.appendChild(theTD);
}
rest = wikibarColorTool.palette.length % wikibarColorTool.columns;
if(rest>0){
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns-rest;
theTD.bgColor = '#000000';
theTR.appendChild(theTD);
}
theTR = document.createElement('tr');
theTable.appendChild(theTR);
theTD = document.createElement('td');
theTD.colSpan = wikibarColorTool.columns;
theTD.id = 'colorPickerInfo';
theTR.appendChild(theTD);
};
wikibarColorTool.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarColorTool.skipClickDocumentEvent) {
wikibarColorTool.skipClickDocumentEvent = false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarColorTool.displayColorPicker(false);
}
return true;
};
function wikibar_doSelectPalette(param){
clearMessage();
var theButton = param.button;
if(!theButton.toolItem.key) { return; }
var palette = theButton.toolItem.key;
var oldPaletteName = wikibarColorTool.paletteName;
if(oldPaletteName != palette){
try{
wikibarColorTool.createColorPicker(theButton, palette);
displayMessage('Palette \"'+palette+'\" ('+ wikibarColorTool.palette.length +' colors) is selected');
}catch(ex){
errMsg = ex;
if(errMsg.substring(0,18)=='renderColorPalette'){
displayMessage('Invalid palette \"' + palette + '\", please check it out!');
wikibarColorTool.createColorPicker(theButton, oldPaletteName);
}
}
}
}
var wikibarPopup = {
skipClickDocumentEvent: false,
stack: []
};
wikibarPopup.resolveRootPopup = function(o){
if(o.isOnMainMenu){ return null; }
if(o.className.substring(0,12)=='wikibarPopup'){ return o;}
return wikibarPopup.resolveRootPopup(o.parentNode);
};
wikibarPopup.create = function(root){
for(var i=0; i<wikibarPopup.stack.length; i++){
var p=wikibarPopup.stack[i];
if(p.root==root){
wikibarPopup.removeFrom(i+1);
return null;
}
}
var rootPopup = wikibarPopup.resolveRootPopup(root);
if(!rootPopup){
wikibarPopup.remove();
}else{
wikibarPopup.removeFromRootPopup(rootPopup);
}
var popup = createTiddlyElement(document.body,'div','wikibarPopup'+root.toolItem.key,'wikibarPopup');
var pop = createTiddlyElement(popup,'table','','');
wikibarPopup.stack.push({rootPopup: rootPopup, root: root, popup: popup});
return pop;
};
wikibarPopup.show = function(unused,slowly){
var curr = wikibarPopup.stack[wikibarPopup.stack.length-1];
var overlayWidth = 1;
var rootLeft, rootTop, rootWidth, rootHeight, popupLeft, popupTop, popupWidth;
if(curr.rootPopup){
rootLeft = findPosX(curr.rootPopup);
rootTop = findPosY(curr.root);
rootWidth = curr.rootPopup.offsetWidth;
popupLeft = rootLeft + rootWidth - overlayWidth;
popupTop = rootTop;
}else{
rootLeft = findPosX(curr.root);
rootTop = findPosY(curr.root);
rootHeight = curr.root.offsetHeight;
popupLeft = rootLeft;
popupTop = rootTop + rootHeight;
}
var winWidth = findWindowWidth();
popupWidth = curr.popup.offsetWidth;
if(popupLeft + popupWidth > winWidth){
popupLeft = rootLeft - popupWidth + overlayWidth;
}
curr.popup.style.left = popupLeft + 'px';
curr.popup.style.top = popupTop + 'px';
curr.popup.style.display = 'block';
addClass(curr.root, 'highlight');
if(config.options.chkAnimate){
anim.startAnimating(new Scroller(curr.popup,slowly));
}else{
window.scrollTo(0,ensureVisible(curr.popup));
}
};
wikibarPopup.remove = function(){
if(wikibarPopup.stack.length > 0){
wikibarPopup.removeFrom(0);
}
};
wikibarPopup.removeFrom = function(from){
for(var t=wikibarPopup.stack.length-1; t>=from; t--){
var p = wikibarPopup.stack[t];
removeClass(p.root,'highlight');
p.popup.parentNode.removeChild(p.popup);
}
wikibarPopup.stack = wikibarPopup.stack.slice(0,from);
};
wikibarPopup.removeFromRootPopup = function(from){
for(var t=0; t<wikibarPopup.stack.length; t++){
var p = wikibarPopup.stack[t];
if(p.rootPopup==from){
wikibarPopup.removeFrom(t);
break;
}
}
};
wikibarPopup.onDocumentClick = function(e){
if (!e){ e = window.event; }
if(wikibarPopup.skipClickDocumentEvent){
wikibarPopup.skipClickDocumentEvent=false;
return true;
}
if((!e.eventPhase) || e.eventPhase == Event.BUBBLING_PHASE || e.eventPhase == Event.AT_TARGET){
wikibarPopup.remove();
}
return true;
};
var wikibarStore = {
TYPE: 'MAIN_MENU',
help:{
TYPE:'MENU',
CAPTION: '<font face=\"verdana\">?</font>',
TOOLTIP: 'about WikiBar',
options:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarOptions
},
about:{
TYPE:'MENU',
DYNAITEM: wikibar_genWikibarAbout
}
},
preview:{
TOOLTIP: 'preview this tiddler',
CAPTION: '<font face=\"verdana\">∞</font>',
HANDLER: wikibar_doPreview
},
line:{
TOOLTIP: 'horizontal line',
CAPTION: '<font face=\"verdana\">—</font>',
syntax: '\n----\n',
HANDLER: wikibar_editFormatByCursor
},
crlf:{
TOOLTIP: 'new line',
CAPTION: '<font face=\"verdana\">¶</font>',
syntax: '\n',
HANDLER: wikibar_editFormatByCursor
},
selectAll:{
TOOLTIP: 'select all',
CAPTION: '<font face=\"verdana\">§</font>',
HANDLER: wikibar_editSelectAll
},
deleteSelected:{
TOOLTIP: 'delete selected',
CAPTION: '<font face=\"verdana\">×</font>',
syntax: '',
HANDLER: wikibar_editFormat
},
textFormat:{
TYPE: 'MENU',
CAPTION: 'text',
TOOLTIP: 'text formatters',
ignore:{
TOOLTIP: 'ignore wiki word',
CAPTION: 'ignore wikiWord',
syntax: '~user_text',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
bolder:{
TOOLTIP: 'bolder text',
CAPTION: '<strong>bolder</strong>',
syntax: "''user_text''",
hint: 'bold_text',
HANDLER: wikibar_editFormatByWord
},
italic:{
TOOLTIP: 'italic text',
CAPTION: '<em>italic</em>',
syntax: '\/\/user_text\/\/',
hint: 'italic_text',
HANDLER: wikibar_editFormatByWord
},
underline:{
TOOLTIP: 'underline text',
CAPTION: '<u>underline</u>',
syntax: '__user_text__',
hint: 'underline_text',
HANDLER: wikibar_editFormatByWord
},
strikethrough:{
TOOLTIP: 'strikethrough text',
CAPTION: '<strike>strikethrough</strike>',
syntax: '==user_text==',
hint: 'strikethrough_text',
HANDLER: wikibar_editFormatByWord
},
superscript:{
TOOLTIP: 'superscript text',
CAPTION: 'X<sup>superscript</sup>',
syntax: '^^user_text^^',
hint: 'superscript_text',
HANDLER: wikibar_editFormatByWord
},
subscript:{
TOOLTIP: 'subscript text',
CAPTION: 'X<sub>subscript</sub>',
syntax: '~~user_text~~',
hint: 'subscript_text',
HANDLER: wikibar_editFormatByWord
},
comment:{
TOOLTIP: 'comment text',
CAPTION: 'comment text',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByWord
},
monospaced:{
TOOLTIP: 'monospaced text',
CAPTION: '<code>monospaced</code>',
syntax: '{{{user_text}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByWord
}
},
paragraph:{
TYPE: 'MENU',
TOOLTIP: 'paragarph formatters',
list:{
TYPE: 'MENU',
TOOLTIP: 'list tools',
bullet:{
TOOLTIP: 'bullet point',
syntax: '*user_text',
hint: 'bullet_text',
HANDLER: wikibar_editFormatByLine
},
numbered:{
TOOLTIP: 'numbered list',
syntax: '#user_text',
hint: 'numbered_text',
HANDLER: wikibar_editFormatByLine
}
},
heading:{
TYPE: 'MENU',
heading1:{
CAPTION:'<h1>Heading 1</h1>',
TOOLTIP: 'Heading 1',
syntax: '!user_text',
hint: 'heading_1',
HANDLER: wikibar_editFormatByLine
},
heading2:{
CAPTION:'<h2>Heading 2<h2>',
TOOLTIP: 'Heading 2',
syntax: '!!user_text',
hint: 'heading_2',
HANDLER: wikibar_editFormatByLine
},
heading3:{
CAPTION:'<h3>Heading 3</h3>',
TOOLTIP: 'Heading 3',
syntax: '!!!user_text',
hint: 'heading_3',
HANDLER: wikibar_editFormatByLine
},
heading4:{
CAPTION:'<h4>Heading 4</h4>',
TOOLTIP: 'Heading 4',
syntax: '!!!!user_text',
hint: 'heading_4',
HANDLER: wikibar_editFormatByLine
},
heading5:{
CAPTION:'<h5>Heading 5</h5>',
TOOLTIP: 'Heading 5',
syntax: '!!!!!user_text',
hint: 'heading_5',
HANDLER: wikibar_editFormatByLine
}
},
comment:{
TYPE: 'MENU',
commentByLine:{
CAPTION:'comment by line',
TOOLTIP: 'line comment',
syntax: '/%user_text%/',
hint: 'comment_text',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION:'comment by block',
TOOLTIP: 'block comment',
syntax: '/%\nuser_text\n%/',
hint: 'comment_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
monospaced:{
TYPE: 'MENU',
monosByLine:{
CAPTION: 'monospaced by line',
TOOLTIP: 'line monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
HANDLER: wikibar_editFormatByLine
},
monosByBlock:{
CAPTION: 'monospaced by block',
TOOLTIP: 'block monospaced',
syntax: '{{{\nuser_text\n}}}',
hint: 'monospaced_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
quote:{
TYPE: 'MENU',
quoteByLine:{
CAPTION: 'quote by line',
TOOLTIP: 'line quote',
syntax: '>user_text',
hint: 'quote_text',
HANDLER: wikibar_editFormatByLine
},
quoteByBlcok:{
CAPTION: 'quote by block',
TOOLTIP: 'block quote',
syntax: '<<<\nuser_text\n<<<',
hint: 'quote_text',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
plugin:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for plugin',
syntax: '\n\/\/{{{\nuser_text\n\/\/}}}\n',
hint: 'monospaced_plugin_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '\/\/user_text',
hint: 'plugin_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '\/\***\nuser_text\n***\/',
hint: 'plugin_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
},
css:{
TYPE: 'MENU',
code:{
CAPTION: 'code area',
TOOLTIP: 'block monospaced for css',
syntax: '\n\nuser_text\n\n',
hint: 'monospaced_css_code',
byBlock: true,
HANDLER: wikibar_editFormatByLine
},
commentByLine:{
CAPTION: 'comment by line',
TOOLTIP: 'line comment',
syntax: '',
hint: 'css_comment',
HANDLER: wikibar_editFormatByLine
},
commentByBlock:{
CAPTION: 'comment by block',
TOOLTIP: 'block comment',
syntax: '',
hint: 'css_comment',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
color:{
TYPE: 'MENU',
TOOLTIP: 'color tools',
highlight:{
CAPTION:'highlight text',
TOOLTIP: 'highlight text',
syntax: '@@user_text@@',
hint: 'highlight_text',
HANDLER: wikibar_editFormatByWord
},
color:{
CAPTION:'text color',
TOOLTIP: 'text color',
hint: 'your_text',
syntax: '@@color(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
bgcolor:{
CAPTION:'background color',
TOOLTIP: 'background color',
hint: 'your_text',
syntax: '@@bgcolor(%1):user_text@@',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByWord
},
colorcode:{
CAPTION:'color code',
TOOLTIP: 'insert color code',
syntax: '%1',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByCursor
},
'color palette':{
TYPE:'MENU',
DYNAITEM: wikibar_genPaletteSelector,
SEPERATOR:{},
morePalette:{
CAPTION:'more palettes',
TOOLTIP:'get more palettes',
HANDLER: wikibar_getMorePalette
}
}
},
link:{
TYPE: 'MENU',
TOOLTIP: 'insert link',
wiki:{
CAPTION:'wiki link',
TOOLTIP: 'wiki link',
syntax: '[[user_text]]',
hint: 'wiki_word',
HANDLER: wikibar_editFormatByWord
},
pretty:{
CAPTION: 'pretty link',
TOOLTIP: 'pretty link',
syntax: '[[user_text|%1]]',
hint: 'pretty_word',
param: 'PrettyLink Target',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
url:{
TOOLTIP: 'url link',
syntax: '[[user_text|%1]]',
hint: 'your_text',
param: 'http:\/\/...',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
},
image:{
TOOLTIP: 'image link',
syntax: '[img[user_text|%1]]',
hint: 'alt_text',
param: 'image/icon.jpg',
HANDLER: wikibar_getLinkUrl,
doMore: wikibar_editFormatByWord
}
},
macro:{},
more:{
TYPE: 'MENU',
TOOLTIP: 'more tools',
table:{
TYPE: 'MENU',
TOOLTIP: 'table',
table:{
CAPTION:'create table',
TOOLTIP: 'create a new table',
syntax: '\n%1\n',
HANDLER: wikibar_getTableRowCol,
doMore: wikibar_editFormatByWord
},
header:{
TOOLTIP: 'table header text',
syntax: '|user_text|c',
hint: 'table_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TOOLTIP: 'create a tabel cell',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByWord
},
columnHeader:{
CAPTION:'column header',
TOOLTIP: 'create a column header cell',
syntax: '|!user_text|',
hint: 'column_header',
HANDLER: wikibar_editFormatByWord
},
cell:{
TYPE: 'MENU',
CAPTION: 'cell options',
bgcolor:{
CAPTION: 'background color',
TOOLTIP: 'cell bgcolor',
syntax: '|bgcolor(%1):user_text|',
hint: 'your_text',
HANDLER: wikibar_getColorCode,
doMore: wikibar_editFormatByTableCell
},
alignLeft:{
CAPTION: 'align left',
TOOLTIP: 'left align cell text',
syntax: '|user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignCenter:{
CAPTION: 'align center',
TOOLTIP: 'center align cell text',
syntax: '| user_text |',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
},
alignRight:{
CAPTION: 'align right',
TOOLTIP: 'right align cell text',
syntax: '| user_text|',
hint: 'your_text',
HANDLER: wikibar_editFormatByTableCell
}
}
},
html:{
TYPE: 'MENU',
html:{
CAPTION: '<html>',
TOOLTIP: 'html tag',
syntax: '<html>\nuser_text\n</html>',
hint: 'html_content',
byBlock: true,
HANDLER: wikibar_editFormatByLine
}
}
},
addon:{
TYPE: 'MENU',
TOOLTIP:'3rd party tools',
'about addons':{
TOOLTIP: 'list loaded addons',
HANDLER: wikibar_doListAddons
},
SEPERATOR:{}
}
};
addEvent(document, 'click', wikibarColorTool.onDocumentClick);
addEvent(document, 'click', wikibarPopup.onDocumentClick);
wikibar_install();
//}}}
[[Write4net|http://write4.net/en]]
<html><div align="center"><iframe src="http://write4.net/da" frameborder="0" width="100%" height="600"></iframe></div></html>
/***
|''Name:''|YourSearchPlugin|
|''Version:''|2.1.0 (2006-10-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#YourSearchPlugin ([[del.icio.us|http://del.icio.us/post?url=http://tiddlywiki.abego-software.de/index.html%23YourSearchPlugin]])|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|© 2005-2006 [[abego Software|http://www.abego-software.de]]|
|''~CoreVersion:''|2.1.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; ~InternetExplorer 6.0|
!About YourSearch
YourSearch gives you a bunch of new features to simplify and speed up your daily searches in TiddlyWiki. It seamlessly integrates into the standard TiddlyWiki search: just start typing into the 'search' field and explore!
For more information see [[Help|YourSearch Help]].
!Compatibility
This plugin requires TiddlyWiki 2.1.
Check the [[archive|http://tiddlywiki.abego-software.de/archive]] for ~YourSearchPlugins supporting older versions of TiddlyWiki.
!Revision history
* v2.1.0 (2006-10-12)
** Release version with TiddlyWiki 2.1 support
*** Support (Extended) Field search
*** Support parenthesis in Boolean Search
*** Support direct regular expression input
*** Support JavaScript Expressions for filtering
*** "new tiddler" feature (create tiddler based on search text)
* v2.0.2 (2006-02-13)
** Bugfix for Firefox 1.5.0.1 related to the "Show prefix" checkbox. Thanks to Ted Pavlic for reporting and to BramChen for fixing.
** Internal
*** Make "JSLint" conform
* v2.0.1 (2006-02-05)
** Support "Exact Word Match" (use '=' to prefix word)
** Support default filter settings (when no filter flags are given in search term)
** Rework on the "less than 3 chars search text" feature (thanks to EricShulman)
** Better support SinglePageMode when doing "Open all tiddlers" (thanks to EricShulman)
** Support Firefox 1.5.0.1
** Bug: Fixed a hilite bug in "classic search mode" (thanks to EricShulman)
* v2.0.0 (2006-01-16)
** Add User Interface
* v1.0.1 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.0 (2005-12-28)
** initial version
!Source Code
***/
//{{{
//============================================================================
//============================================================================
// YourSearchPlugin
//============================================================================
//============================================================================
// Ensure that the Plugin is only installed once.
//
if (!version.extensions.YourSearchPlugin) {
version.extensions.YourSearchPlugin = {
major: 2, minor: 1, revision: 0,
source: "http://tiddlywiki.abego-software.de/#YourSearchPlugin",
licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
copyright: "Copyright (c) abego Software GmbH, 2005-2006 (www.abego-software.de)"
};
if (!window.abego) window.abego = {};
// define the Array forEach when not yet defined (e.g. by Mozilla)
if (!Array.forEach) {
Array.forEach = function(obj, callback, thisObj) {
for (var i = 0,len = obj.length; i < len; i++)
callback.call(thisObj, obj[i], i, obj);
};
Array.prototype.forEach = function(callback, thisObj) {
for (var i = 0,len = this.length; i < len; i++)
callback.call(thisObj, this[i], i, this);
};
}
abego.toInt = function(s, defaultValue) {
if (!s) return defaultValue;
var n = parseInt(s);
return (n == NaN) ? defaultValue : n;
};
abego.createEllipsis = function(place) {
var e = createTiddlyElement(place,"span");
e.innerHTML = "…";
};
//#concept Object
//
abego.shallowCopy = function(object) {
if (!object)
return object;
var result = {};
for (var n in object)
result[n] = object[n];
return result;
};
// Returns a shallow copy of the options, or a new, empty object if options is null/undefined.
//
// @param options [may be null/undefined]
//
//#concept Object, Options
//#import abego.shallowCopy
//
abego.copyOptions = function(options) {
return !options ? {} : abego.shallowCopy(options);
};
//#import abego.define-namespace
// returns the number of occurances of s in the text
abego.countStrings = function(text, s) {
if (!s)
return 0;
var len = s.length;
var n = 0;
var lastIndex = 0;
while (1) {
var i = text.indexOf(s, lastIndex);
if (i < 0)
return n;
n++;
lastIndex = i+len;
}
return n;
};// Returns the content of the first "braced" text {...}
// Also takes care of nested braces
//
// Returns undefined when no braced text is found or it is not properly nested
//
// @param [optional] when defined and a braced text is found lastIndexRef.lastIndex will contain the index of the char following the (final) closing brace on return.
//
abego.getBracedText = function(text, offset,lastIndexRef) {
if (!offset) offset = 0;
var re = /\{([^\}]*)\}/gm;
re.lastIndex = offset;
var m = re.exec(text);
if (m) {
// The matching stopped at the first closing brace.
// But if the matched text contains opening braces
// this is not the final closing brace.
// Handle this case specially, find the "corresponding" closing brace
var s = m[1];
var nExtraOpenBrace = abego.countStrings(s,"{");
if (!nExtraOpenBrace) {
if (lastIndexRef)
lastIndexRef.lastIndex = re.lastIndex;
// simple case: no nested braces
return s;
}
// special case: "nested braces"
var len = text.length;
for (var i = re.lastIndex; i < len && nExtraOpenBrace; i++) {
var c = text.charAt(i);
if (c == "{")
nExtraOpenBrace++;
else if (c == "}")
nExtraOpenBrace--;
}
if (!nExtraOpenBrace) {
// found the corresponding "}".
if (lastIndexRef)
lastIndexRef.lastIndex = i-1;
return text.substring(m.index+1, i-1);
}
}
// no return means: return undefined;
};
// Returns an array with those items from the array that pass the given test
//
// @param test an one-arg boolean function that returns true when the item should be added.
// @param testObj [optional] the receiver for the test function (global if undefined or null)
// @param result [optional] an array. When define the selected items are added to this array, otherwise a new array is used.
//
//#import Array.prototype.forEach
//
abego.select = function(array,test,testObj,result) {
if (!result) result = [];
array.forEach(function(t) {
if (test.call(testObj,t))
result.push(t);
});
return result;
};
// Class abego.TiddlerFilterTerm =================================================================
//
// Used to check if a tiddler contains a given text.
//
// A list of fields (standard and/or extended) may be specified to restrict the search to certain fields.
//
// When no explicit fields are given the fields defined by defaultFields are checked, plus all extended
// fields (when options.withExtendedFields is true).
//
// @param options [may be null/undefined]
// options.fields @seeParam abego.MultiFieldRegExpTester.fields
// options.withExtendedFields @seeParam abego.MultiFieldRegExpTester.withExtendedFields
// options.caseSensitive [Default: false]
// options.fullWordMatch [Default: false]
// options.textIsRegExp [Default: false] when true the given text is already a regExp
//
//#import abego.MultiFieldRegExpTester
//
abego.TiddlerFilterTerm = function(text,options) {
if (!options) options = {};
var reText = text;
if (!options.textIsRegExp) {
reText = text.escapeRegExp();
if (options.fullWordMatch)
reText = "\\b"+reText+"\\b";
}
var regExp = new RegExp(reText, "m"+(options.caseSensitive ? "" : "i"));
this.tester = new abego.MultiFieldRegExpTester(regExp, options.fields, options.withExtendedFields);
}
abego.TiddlerFilterTerm.prototype.test = function(tiddler) {
return this.tester.test(tiddler);
}
//#import abego.define-namespace
// Recognize a string like
// "Some Title. Some content text #Tag1 #Tag2 Tag3"
// with the tags and the text being optional.
// Also the period at the end of the title is optional when no content text is specified)
//
// Returns the result in an object with properties "title" and "params",
// with "params" following the parseParams format, containing the "tag" and "text" arguments.
//
abego.parseNewTiddlerCommandLine = function(s) {
var m = /(.*?)\.(?:\s+|$)([^#]*)(#.*)?/.exec(s);
if (!m)
m = /([^#]*)()(#.*)?/.exec(s);
if (m) {
var r;
if (m[3]) {
var s2 = m[3].replace(/#/g,"");
r = s2.parseParams("tag");
} else
r = [[]];
// add the text parameter
var text = m[2]?m[2].trim():"";
r.push({name: "text", value: text});
r[0].text = [text];
return {title: m[1].trim(), params: r};
} else
return {title: s.trim(),params: [[]]};
}
// options.defaultFields [@seeOptionDefault abego.TiddlerFilterTerm.fields] fields to check when no fields are explicitly specified in queryText.
// options.withExtendedFields [@seeOptionDefault abego.TiddlerFilterTerm.withExtendedFields] when true and no fields are explicitly specified in queryText also the extended fields are considered (in addition to the ones in defaultFields).
// @seeOptions abego.TiddlerFilterTerm (-fields -fullWordMatch -withExtendedFields)
//
//#import abego.getBracedText
//#import abego.copyOptions
//#import abego.TiddlerFilterTerm
//
abego.parseTiddlerFilterTerm = function(queryText,offset,options) {
// group 1: {...} (JavaScript expression)
// group 2: '=' (full word match (optional))
// group 3: [!%#] (field selection short cuts)
// group 4: fieldName ':'
// group 5: String literal "..."
// group 6: RegExp literal /.../
// group 7: scheme '://' nonSpaceChars
// group 8: word
var re = /\s*(?:(?:\{([^\}]*)\})|(?:(=)|([#%!])|(?:(\w+)\s*\:(?!\/\/))|(?:(?:("(?:(?:\\")|[^"])+")|(?:\/((?:(?:\\\/)|[^\/])+)\/)|(\w+\:\/\/[^\s]+)|([^\s\)\-\"]+)))))/mg;
var shortCuts = {'!':'title','%':'text','#':'tags'};
var fieldNames = {};
var fullWordMatch;
re.lastIndex = offset;
while (1) {
var i = re.lastIndex;
var m = re.exec(queryText);
if (!m || m.index != i)
throw "Word or String literal expected";
if (m[1]) {
var lastIndexRef = {};
var code = abego.getBracedText(queryText,0,lastIndexRef);
if (!code)
throw "Invalid {...} syntax";
var f = Function("tiddler","return ("+code+");");
return {func: f,
lastIndex:lastIndexRef.lastIndex,
markRE: null};
}
if (m[2])
fullWordMatch = true;
else if (m[3])
fieldNames[shortCuts[m[3]]] = 1;
else if (m[4])
fieldNames[m[4]] = 1;
else {
var textIsRegExp = m[6];
var text = m[5] ? window.eval(m[5]) : m[6] ? m[6] : m[7] ? m[7] : m[8];
var options = abego.copyOptions(options);
options.fullWordMatch = fullWordMatch;
options.textIsRegExp = textIsRegExp;
var fields = [];
for (var n in fieldNames)
fields.push(n);
if (fields.length == 0) {
options.fields = options.defaultFields;
} else {
options.fields = fields;
options.withExtendedFields = false;
}
var term = new abego.TiddlerFilterTerm(text,options);
var markREText = textIsRegExp ? text : text.escapeRegExp();
if (markREText && fullWordMatch)
markREText = "\\b"+markREText+"\\b";
return {func: function(tiddler) {return term.test(tiddler);},
lastIndex:re.lastIndex,
markRE: markREText ? "(?:"+markREText+")" : null};
}
}
};
// Class abego.BoolExp =================================================================
//
// Allows the execution/evaluation of a boolean expression, according to this syntax:
//
// boolExpression : unaryExpression (("AND"|"OR"|"&&"|"||")? unaryExpression)*
// ;
//
// unaryExpression : ("not"|"-")? primaryExpression
// ;
//
// primaryExpression : "(" boolExpression ")"
// | Term
// ;
//
// For flexibility the Term syntax is defined by a separate parse function.
//
// Notice that there is no precedence between "AND" and "OR" operators, i.e. they are evaluated from left to right.
//
// To evaluate the expression in a given context use code like this:
//
// var be = new abego.BoolExp(s, termParseFunc);
// var result = be.exec(context);
//
// @param s the text defining the expression
// @param parseTermFunc a Function(text,offset,options) that parses the text starting at offset for a "Term" and returns an object with properties {func: Function(context), lastIndex: ...}. func is the function to be used to evaluate the term in the given context.
// @param options [may be null/undefined] (is also passed to the parseTermFunc)
// options.defaultOperationIs_OR [Default: false] When true the concatenation of unaryExpressions (without an operator) is interpreted as an "OR", otherwise as an "AND".
// options.caseSensitive [default: false]
//
abego.BoolExp = function(s, parseTermFunc, options) {
this.s = s;
var defaultOperationIs_OR = options && options.defaultOperationIs_OR;
var reStart = /\s*(?:(\-|not)|(\())/gi; // group 1: NOT, group2 "("
var reCloseParenthesis = /\s*\)/g; // match )
var reAndOr = /\s*(?:(and|\&\&)|(or|\|\|))/gi; // group 1: AND, group 2: OR
var reNonWhiteSpace = /\s*[^\)\s]/g;
var reNot_Parenthesis = /\s*(\-|not)?(\s*\()?/gi;
var parseUnaryExpression = function(offset) {
reNot_Parenthesis.lastIndex = offset;
var m = reNot_Parenthesis.exec(s);
var negate;
var result;
if (m && m.index == offset) {
offset = reNot_Parenthesis.lastIndex;
negate = m[1];
if (m[2]) {
// case: (...)
var e = parseBoolExpression(offset);
reCloseParenthesis.lastIndex = e.lastIndex;
if (!reCloseParenthesis.exec(s))
throw "Missing ')'";
result = {func: e.func, lastIndex: reCloseParenthesis.lastIndex};
}
}
if (!result)
result = parseTermFunc(s,offset,options);
if (negate) {
result.func = (function(f){return function(context) {return !f(context);}})(result.func);
// don't mark patterns that are negated
// (This is essential since the marking may also be used to calculate "ranks". If we
// would also count the negated matches (i.e. that should not exist) the rank may get too high)
result.markRE = null;
}
return result;
};
var parseBoolExpression = function(offset) {
var result = parseUnaryExpression(offset);
while (1) {
var l = result.lastIndex;
reAndOr.lastIndex = l;
var m = reAndOr.exec(s);
var isOrCase;
var nextExp;
if (m && m.index == l) {
isOrCase = !m[1];
nextExp = parseUnaryExpression(reAndOr.lastIndex);
} else {
// no "AND" or "OR" found.
// Maybe it is a concatenations of parseUnaryExpression without operators
try {
nextExp = parseUnaryExpression(l);
} catch (e) {
// no unary expression follows. We are done
return result;
}
isOrCase = defaultOperationIs_OR;
}
result.func = (function(func1, func2, isOrCase) {
return isOrCase
? function(context) {return func1(context) || func2(context);}
: function(context) {return func1(context) && func2(context);};
})(result.func,nextExp.func,isOrCase);
result.lastIndex = nextExp.lastIndex;
if (!result.markRE)
result.markRE = nextExp.markRE;
else if (nextExp.markRE)
result.markRE = result.markRE + "|" + nextExp.markRE;
}
};
var expr = parseBoolExpression(0);
this.evalFunc = expr.func;
if (expr.markRE)
this.markRegExp = new RegExp(expr.markRE, options.caseSensitive ? "mg" : "img");
}
abego.BoolExp.prototype.exec = function() {
return this.evalFunc.apply(this,arguments);
};
abego.BoolExp.prototype.getMarkRegExp = function() {
return this.markRegExp;
};
abego.BoolExp.prototype.toString = function() {
return this.s;
};
// Class abego.MultiFieldRegExpTester ==================================================================
//
// @param fields [optional; Default: ["title","text","tags"]] array of names of fields to be considered
// @param withExtendedFields [optional; Default: false] when true also extended fields are considered (in addition to the ones given in 'fields')
//
abego.MultiFieldRegExpTester = function(re, fields, withExtendedFields) {
this.re = re;
this.fields = fields ? fields : ["title","text","tags"];
this.withExtendedFields = withExtendedFields;
}
// Returns the name of the first field found that value succeeds the given test,
// or null when no such field is found
//
abego.MultiFieldRegExpTester.prototype.test = function(tiddler) {
var re = this.re;
// Check the fields explicitly specified
for (var i = 0; i < this.fields.length; i++) {
var s = store.getValue(tiddler, this.fields[i]);
if (typeof s == "string" && re.test(s))
return this.fields[i];
}
// Check the extended fields (if required)
if (this.withExtendedFields)
return store.forEachField(
tiddler,
function(tiddler, fieldName, value) {
return typeof value == "string" && re.test(value)?fieldName:null;
}, true);
return null;
}
// Class abego.TiddlerQuery ==================================================================
//
//#import abego.select
//#import abego.MultiFieldRegExpTester
//
abego.TiddlerQuery = function(queryText,caseSensitive,useRegExp,defaultFields,withExtendedFields) {
if (useRegExp) {
this.regExp = new RegExp(queryText, caseSensitive ? "mg" : "img");
this.tester = new abego.MultiFieldRegExpTester(this.regExp, defaultFields, withExtendedFields);
} else {
this.expr = new abego.BoolExp(
queryText,
abego.parseTiddlerFilterTerm, {
defaultFields: defaultFields,
caseSensitive: caseSensitive,
withExtendedFields: withExtendedFields});
}
this.getQueryText = function() {
return queryText;
};
this.getUseRegExp = function() {
return useRegExp;
};
this.getCaseSensitive = function() {
return caseSensitive;
};
this.getDefaultFields = function() {
return defaultFields;
};
this.getWithExtendedFields = function() {
return withExtendedFields;
};
}
// Returns true iff the query includes the given tiddler
//
// @param tiddler [may be null/undefined]
//
abego.TiddlerQuery.prototype.test = function(tiddler) {
if (!tiddler) return false;
if (this.regExp) {
return this.tester.test(tiddler);
}
return this.expr.exec(tiddler);
};
// Returns an array with those tiddlers from the tiddlers array that match the query.
//
abego.TiddlerQuery.prototype.filter = function(tiddlers) {
return abego.select(tiddlers,this.test,this);
};
abego.TiddlerQuery.prototype.getMarkRegExp = function() {
if (this.regExp) {
// Only use the regExp for marking when it does not match the empty string.
return "".search(this.regExp) >= 0 ? null : this.regExp;
}
return this.expr.getMarkRegExp();
};
abego.TiddlerQuery.prototype.toString = function() {
return (this.regExp ? this.regExp : this.expr).toString();
};
// Class abego.PageWiseRenderer ================================================
//
// Subclass or instance must implement getItemsPerPage function;
// They should also implement onPageChanged and refresh the container of the
// PageWiseRenderer on that event.
//
//#import abego.toInt
//
abego.PageWiseRenderer = function() {
this.firstIndexOnPage = 0; // The index of the first item of the lastResults list displayed on the search result page
};
merge(abego.PageWiseRenderer.prototype, {
setItems: function(items) {
this.items = items;
this.setFirstIndexOnPage(0);
},
// Maximum number of pages listed in the navigation bar (before or after the current page)
//
getMaxPagesInNavigation: function() {
return 10;
},
getItemsCount: function(items) {
return this.items ? this.items.length : 0;
},
getCurrentPageIndex: function() {
return Math.floor(this.firstIndexOnPage / this.getItemsPerPage());
},
getLastPageIndex: function() {
return Math.floor((this.getItemsCount()-1) / this.getItemsPerPage())
},
setFirstIndexOnPage: function(index) {
this.firstIndexOnPage = Math.min(Math.max(0, index), this.getItemsCount()-1);
},
getFirstIndexOnPage: function() {
// Ensure that the firstIndexOnPage is really a page start.
// This may have become violated when getItemsPerPage has changed,
// (e.g. when switching between previewText and simple mode.)
this.firstIndexOnPage = Math.floor(this.firstIndexOnPage / this.getItemsPerPage()) * this.getItemsPerPage();
return this.firstIndexOnPage;
},
getLastIndexOnPage: function() {
return Math.min(this.getFirstIndexOnPage()+this.getItemsPerPage()-1, this.getItemsCount()-1);
},
onPageChanged: function(pageIndex,oldPageIndex) {
},
renderPage: function(itemRenderer) {
if (itemRenderer.beginRendering)
itemRenderer.beginRendering(this);
try {
// When there are items found add them to the result page (pagewise)
if (this.getItemsCount()) {
// Add the items of the current page
var lastIndex = this.getLastIndexOnPage();
var iInPage = -1;
for (var i=this.getFirstIndexOnPage(); i <= lastIndex; i++) {
iInPage++;
itemRenderer.render(this,this.items[i],i,iInPage);
}
}
} finally {
if (itemRenderer.endRendering)
itemRenderer.endRendering(this);
}
},
addPageNavigation: function(place) {
if (!this.getItemsCount()) return;
var self = this;
var onNaviButtonClick = function(e) {
if (!e) var e = window.event;
var pageIndex = abego.toInt(this.getAttribute("page"),0);
var oldPageIndex = self.getCurrentPageIndex();
if (pageIndex == oldPageIndex)
return;
var index = pageIndex * self.getItemsPerPage();
self.setFirstIndexOnPage(index);
self.onPageChanged(pageIndex,oldPageIndex);
};
var button;
var currentPageIndex = this.getCurrentPageIndex();
var lastPageIndex = this.getLastPageIndex();
if (currentPageIndex > 0) {
button = createTiddlyButton(place, "Previous", "Go to previous page (Shortcut: Alt-'<')", onNaviButtonClick, "prev");
button.setAttribute("page",(currentPageIndex-1).toString());
button.setAttribute("accessKey","<");
}
for (var i = -this.getMaxPagesInNavigation(); i < this.getMaxPagesInNavigation(); i++) {
var pageIndex = currentPageIndex+i;
if (pageIndex < 0) continue;
if (pageIndex > lastPageIndex) break;
var pageNo = (i+currentPageIndex+1).toString();
var buttonClass = pageIndex == currentPageIndex ? "currentPage" : "otherPage";
button = createTiddlyButton(place, pageNo, "Go to page %0".format([pageNo]), onNaviButtonClick, buttonClass);
button.setAttribute("page",(pageIndex).toString());
}
if (currentPageIndex < lastPageIndex) {
button = createTiddlyButton(place, "Next", "Go to next page (Shortcut: Alt-'>')", onNaviButtonClick, "next");
button.setAttribute("page",(currentPageIndex+1).toString());
button.setAttribute("accessKey",">");
}
}
});
// Class abego.LimitedTextRenderer ===========================================================
//
// Renders a given text, ensuring that a given limit of number of characters
// is not exceeded.
//
// A "markRegExp" may be specified. Substring matching this regular expression
// ("matched strings") are rendered with the class "marked".
//
// if the given text is longer than the limit the matched strings are preferred
// to be included in the rendered text (with some leading and trailing "context text").
//
// Example:
// var renderer = new abego.LimitedTextRenderer();
//
// var place = ... // a DOM element that should contain the rendered (limited) text
// var s = "This is another 'Hello World' example, as saying 'Hello' is always nice. So let's say it again: >Hello!<";
// var maxLen = 50;
// var markRE = /hello/gi;
// renderer.render(place,s,maxLen,markRE);
//
//#import abego.createEllipsis
//
abego.LimitedTextRenderer = function() {
var minMatchWithContextSize = 40;
var maxMovementForWordCorrection = 4; // When a "match" context starts or end on a word the context borders may be changed to at most this amount to include or exclude the word.
//----------------------------------------------------------------------------
//
// Ranges
//
// Objects with a "start" and "end" property (not a specific class).
//
// In a corresponding "Ranges array" these objects are sorted by their start
// and no Range object intersects/touches any other in the array.
//
//----------------------------------------------------------------------------
// Adds the Range [startIndex,endIndex[ to the ranges, ensuring that the Ranges
// in the array are sorted by their start and no Range object
// intersects/touches any other in the array (i.e. possibly the new Range is
// "merged" with existing ranges)
//
// @param ranges array of Range objects
//
var addRange = function(ranges, startIndex, endIndex) {
var n = ranges.length;
// When there are no ranges in ranges, just add it.
if (n == 0) {
ranges.push({start: startIndex, end: endIndex});
return;
}
var i = 0;
for (; i < n; i++) {
var range = ranges[i];
// find the first range that intersects or "touches" [startIndex, endIndex[
if (range.start <= endIndex && startIndex <= range.end) {
// Found.
var r;
// find the first range behind the new range that does not interfere
var rIndex = i+1;
for (; rIndex < n; rIndex++) {
r = ranges[rIndex];
if (r.start > endIndex || startIndex > range.end) {
break;
}
}
// Replace the ranges i to rIndex-1 with the union of the new range with these ranges.
var unionStart = startIndex;
var unionEnd = endIndex;
for (var j = i; j < rIndex; j++) {
r = ranges[j];
unionStart = Math.min(unionStart, r.start);
unionEnd = Math.max(unionEnd, r.end);
}
ranges.splice(i, rIndex-i, {start: unionStart, end: unionEnd});
return;
}
// if we found a range R that is right of the new range there is no
// intersection and we can insert the new range before R.
if (range.start > endIndex) {
break;
}
}
// When we are here the new range does not interfere with any range in ranges and
// i is the index of the first range right to it (or ranges.length, when the new range
// becomes the right most range).
ranges.splice(i, 0, {start: startIndex, end: endIndex});
};
// Returns the total size of all Ranges in ranges
//
var getTotalRangesSize = function(ranges) {
var totalRangeSize = 0;
for (var i=0; i < ranges.length; i++) {
var range = ranges[i];
totalRangeSize += range.end-range.start;
}
return totalRangeSize;
};
//----------------------------------------------------------------------------
var isWordChar = function(c) {
return (c >= "a" && c <= "z") || (c >= "A" && c <= "Z") || c == "_";
};
// Returns the bounds of the word in s around offset as a {start: , end:} object.
//
// Returns null when the char at offset is not a word char.
//
var getWordBounds = function(s, offset) {
// Handle the "offset is not in word" case
if (!isWordChar(s[offset])) return null;
for (var i = offset-1; i >= 0 && isWordChar(s[i]); i--)
{/*empty*/}
var startIndex = i+1;
var n = s.length;
for (i = offset+1; i < n && isWordChar(s[i]); i++)
{/*empty*/}
return {start: startIndex, end: i};
};
var moveToWordBorder = function(s, offset, isStartOffset) {
var wordBounds;
if (isStartOffset) {
wordBounds = getWordBounds(s, offset);
} else {
if (offset <= 0) return offset;
wordBounds = getWordBounds(s, offset-1);
}
if (!wordBounds) return offset;
if (isStartOffset) {
if (wordBounds.start >= offset-maxMovementForWordCorrection) return wordBounds.start;
if (wordBounds.end <= offset+maxMovementForWordCorrection) return wordBounds.end;
} else {
if (wordBounds.end <= offset+maxMovementForWordCorrection) return wordBounds.end;
if (wordBounds.start >= offset-maxMovementForWordCorrection) return wordBounds.start;
}
return offset;
};
// Splits s into a sequence of "matched" and "unmatched" substrings, using the
// matchRegExp to do the matching.
//
// Returns an array of objects with a "text" property containing the substring text.
// Substrings that are "matches" also contain a boolean "isMatch" property set to true.
//
// @param matchRegExp [may be null] when null no matching is performed and the returned
// array just contains one item with s as its text
//
var getTextAndMatchArray = function(s, matchRegExp) {
var result = [];
if (matchRegExp) {
var startIndex = 0;
var n = s.length;
var currentLen = 0;
do {
matchRegExp.lastIndex = startIndex;
var match = matchRegExp.exec(s);
if (match) {
if (startIndex < match.index) {
var t = s.substring(startIndex, match.index);
result.push({text:t});
}
result.push({text:match[0], isMatch:true});
startIndex = match.index + match[0].length;
} else {
result.push({text: s.substr(startIndex)});
break;
}
} while (true);
} else {
result.push({text: s});
}
return result;
};
var getMatchedTextCount = function(textAndMatches) {
var result = 0;
for (var i=0; i < textAndMatches.length; i++) {
if (textAndMatches[i].isMatch) {
result++;
}
}
return result;
};
var getContextRangeAround = function(s, startIndex, endIndex, matchCount, maxLen) {
// Partition the available space into equal sized areas for each match and one
// for the text start.
// But the size should not go below a certain limit
var size = Math.max(Math.floor(maxLen/(matchCount+1)), minMatchWithContextSize);
// Substract the size of the range to get the size of the context.
var contextSize = Math.max(size-(endIndex-startIndex), 0);
// Two thirds of the context should be before the match, one third after.
var contextEnd = Math.min(Math.floor(endIndex+contextSize/3), s.length);
var contextStart = Math.max(contextEnd - size, 0);
// If the contextStart/End is inside a word and the end of the word is
// close move the pointers accordingly to make the text more readable.
contextStart = moveToWordBorder(s, contextStart, true);
contextEnd = moveToWordBorder(s, contextEnd, false);
return {start: contextStart, end: contextEnd};
};
// Get all ranges around matched substrings with their contexts
//
var getMatchedTextWithContextRanges = function(textAndMatches, s, maxLen) {
var ranges = [];
var matchCount = getMatchedTextCount(textAndMatches);
var pos = 0;
for (var i=0; i < textAndMatches.length; i++) {
var t = textAndMatches[i];
var text = t.text;
if (t.isMatch) {
var range = getContextRangeAround(s, pos, pos+text.length, matchCount, maxLen);
addRange(ranges, range.start, range.end);
}
pos += text.length;
}
return ranges;
};
var fillUpRanges = function(s, ranges, maxLen) {
var remainingLen = maxLen - getTotalRangesSize(ranges);
while (remainingLen > 0) {
if (ranges.length == 0) {
// No matches added yet. Make one large range.
addRange(ranges, 0, moveToWordBorder(s, maxLen, false));
return;
} else {
var range = ranges[0];
var startIndex;
var maxEndIndex;
if (range.start == 0) {
// The first range already starts at the beginning of the string.
// When there is a second range fill to the next range start or to the maxLen.
startIndex = range.end;
if (ranges.length > 1) {
maxEndIndex = ranges[1].start;
} else {
// Only one range. Add a range after that with the complete remaining len
// (corrected to "beautify" the output)
addRange(ranges, startIndex, moveToWordBorder(s, startIndex+remainingLen, false));
return;
}
} else {
// There is unused space between the start of the text and the first range.
startIndex = 0;
maxEndIndex = range.start;
}
var endIndex = Math.min(maxEndIndex, startIndex+remainingLen);
addRange(ranges, startIndex, endIndex);
remainingLen -= (endIndex-startIndex);
}
}
};
// Write the given ranges of s, using textAndMatches for marking portions of the text.
//
var writeRanges = function(place, s, textAndMatches, ranges, maxLen) {
if (ranges.length == 0) return;
// Processes the text between startIndex and endIndex of the textAndMatches
// "writes" them (as DOM elements) at the given place, possibly as "marked" text.
//
// When endIndex is not the end of the full text an ellisis is appended.
//
var writeTextAndMatchRange = function(place, s, textAndMatches, startIndex, endIndex) {
var t;
var text;
// find the first text item to write
var pos = 0;
var i = 0;
var offset = 0;
for (;i < textAndMatches.length; i++) {
t = textAndMatches[i];
text = t.text;
if (startIndex < pos+text.length) {
offset = startIndex - pos;
break;
}
pos += text.length;
}
var remainingLen = endIndex - startIndex;
for (; i < textAndMatches.length && remainingLen > 0; i++) {
t = textAndMatches[i];
text = t.text.substr(offset);
offset = 0;
if (text.length > remainingLen) text = text.substr(0,remainingLen);
if (t.isMatch) {
createTiddlyElement(place,"span",null,"marked",text);
} else {
createTiddlyText(place, text);
}
remainingLen -= text.length;
}
if (endIndex < s.length) {
abego.createEllipsis(place);
}
};
// When the first range is not at the start of the text write an ellipsis("...")
// (Ellipses between ranges are written in the writeTextAndMatchRange method)
if (ranges[0].start > 0) abego.createEllipsis(place);
var remainingLen = maxLen;
for (var i = 0; i < ranges.length && remainingLen > 0; i++) {
var range = ranges[i];
var len = Math.min(range.end - range.start, remainingLen);
writeTextAndMatchRange(place, s, textAndMatches, range.start, range.start+len);
remainingLen -= len;
}
};
this.render = function(place,s,maxLen,markRegExp) {
if (s.length < maxLen) maxLen = s.length;
var textAndMatches = getTextAndMatchArray(s, markRegExp);
var ranges = getMatchedTextWithContextRanges(textAndMatches, s, maxLen);
// When the maxLen is not yet reached add more ranges
// starting from the beginning until either maxLen or
// the end of the string is reached.
fillUpRanges(s, ranges, maxLen);
writeRanges(place, s, textAndMatches, ranges, maxLen);
};
};
(function() {
function alertAndThrow(msg) {
alert(msg);
throw msg;
};
if (version.major < 2 || (version.major == 2 && version.minor < 1))
alertAndThrow("YourSearchPlugin requires TiddlyWiki 2.1 or newer.\n\nCheck the archive for YourSearch plugins\nsupporting older versions of TiddlyWiki.\n\nArchive: http://tiddlywiki.abego-software.de/archive");
abego.YourSearch = {};
//----------------------------------------------------------------------------
// The Search Core
//----------------------------------------------------------------------------
// Model Variables
var lastResults; // Array of tiddlers that matched the last search
var lastQuery; // The last Search query (TiddlerQuery)
var setLastResults = function(array) {
lastResults = array;
};
var getLastResults = function() {
return lastResults ? lastResults : [];
};
var getLastResultsCount = function() {
return lastResults ? lastResults.length : 0;
};
// Standard Ranking Weights
var matchInTitleWeight = 4;
var precisionInTitleWeight = 10;
var matchInTagsWeight = 2;
var getMatchCount = function(s, re) {
var m = s.match(re);
return m ? m.length : 0;
};
var standardRankFunction = function(tiddler, query) {
// Count the matches in the title and the tags
var markRE = query.getMarkRegExp();
if (!markRE) return 1;
var matchesInTitle = tiddler.title.match(markRE);
var nMatchesInTitle = matchesInTitle ? matchesInTitle.length : 0;
var nMatchesInTags = getMatchCount(tiddler.getTags(), markRE);
// Calculate the "precision" of the matches in the title as the ratio of
// the length of the matches to the total length of the title.
var lengthOfMatchesInTitle = matchesInTitle ? matchesInTitle.join("").length : 0;
var precisionInTitle = tiddler.title.length > 0 ? lengthOfMatchesInTitle/tiddler.title.length : 0;
// calculate a weighted score
var rank= nMatchesInTitle * matchInTitleWeight
+ nMatchesInTags * matchInTagsWeight
+ precisionInTitle * precisionInTitleWeight
+ 1;
return rank;
};
// @return Tiddler[]
//
var findMatches = function(store, searchText,caseSensitive,useRegExp,sortField,excludeTag) {
lastQuery = null;
var candidates = store.reverseLookup("tags",excludeTag,false);
try {
var defaultFields = [];
if (config.options.chkSearchInTitle) defaultFields.push("title");
if (config.options.chkSearchInText) defaultFields.push("text");
if (config.options.chkSearchInTags) defaultFields.push("tags");
lastQuery = new abego.TiddlerQuery(
searchText,caseSensitive, useRegExp,defaultFields,config.options.chkSearchExtendedFields);
} catch (e) {
// when an invalid query is given no tiddlers are matched
return [];
}
var results = lastQuery.filter(candidates);
// Rank the results
var rankFunction = abego.YourSearch.getRankFunction();
for (var i = 0; i < results.length; i++) {
var tiddler = results[i];
var rank = rankFunction(tiddler, lastQuery);
// Add the rank information to the tiddler.
// This is used during the sorting, but it may also
// be used in the result, e.g. to display some "relevance"
// information in the result
tiddler.searchRank = rank;
}
// sort the result, taking care of the rank and the sortField
if(!sortField) {
sortField = "title";
}
var sortFunction = function (a,b) {
var searchRankDiff = a.searchRank - b.searchRank;
if (searchRankDiff == 0) {
if (a[sortField] == b[sortField]) {
return(0);
} else {
return (a[sortField] < b[sortField]) ? -1 : +1;
}
} else {
return (searchRankDiff > 0) ? -1 : +1;
}
};
results.sort(sortFunction);
return results;
};
//----------------------------------------------------------------------------
// The Search UI (Result page)
//----------------------------------------------------------------------------
// Visual appearance of the result page
var maxCharsInTitle = 80;
var maxCharsInTags = 50;
var maxCharsInText = 250;
var maxCharsInField = 50;
var itemsPerPageDefault = 25; // Default maximum number of items on one search result page
var itemsPerPageWithPreviewDefault = 10; // Default maximum number of items on one search result page when PreviewText is on
// DOM IDs
var yourSearchResultID = "yourSearchResult";
var yourSearchResultItemsID = "yourSearchResultItems";
var lastSearchText; // The last search text, as passed to findMatches
var resultElement; // The (popup) DOM element containing the search result [may be null]
var searchInputField; // The "search" input field
var searchButton; // The "search" button
var lastNewTiddlerButton;
var initStylesheet = function() {
if (version.extensions.YourSearchPlugin.styleSheetInited)
return;
version.extensions.YourSearchPlugin.styleSheetInited = true;
setStylesheet(store.getTiddlerText("YourSearchStyleSheet"),"yourSearch");
}
var isResultOpen = function() {
return resultElement != null && resultElement.parentNode == document.body;
};
var closeResult = function() {
if (isResultOpen()) {
document.body.removeChild(resultElement);
}
};
// Closes the Search Result window and displays the tiddler
// defined by the "tiddlyLink" attribute of this element
//
var closeResultAndDisplayTiddler = function(e)
{
closeResult();
var title = this.getAttribute("tiddlyLink");
if(title) {
var withHilite = this.getAttribute("withHilite");
var oldHighlightHack = highlightHack;
if (withHilite && withHilite=="true" && lastQuery) {
highlightHack = lastQuery.getMarkRegExp();
}
story.displayTiddler(this,title);
highlightHack = oldHighlightHack;
}
return(false);
};
// Adjusts the resultElement's size and position, relative to the search input field.
//
var adjustResultPositionAndSize = function() {
if (!searchInputField) return;
var root = searchInputField;
// Position the result below the root and resize it if necessary.
var rootLeft = findPosX(root);
var rootTop = findPosY(root);
var rootHeight = root.offsetHeight;
var popupLeft = rootLeft;
var popupTop = rootTop + rootHeight;
// Make sure the result is not wider than the window
var winWidth = findWindowWidth();
if (winWidth < resultElement.offsetWidth) {
resultElement.style.width = (winWidth - 100)+"px";
winWidth = findWindowWidth();
}
// Ensure that the left and right of the result are not
// clipped by the window. Move it to the left or right, if necessary.
var popupWidth = resultElement.offsetWidth;
if(popupLeft + popupWidth > winWidth)
popupLeft = winWidth - popupWidth-30;
if (popupLeft < 0) popupLeft = 0;
// Do the actual moving
resultElement.style.left = popupLeft + "px";
resultElement.style.top = popupTop + "px";
resultElement.style.display = "block";
};
var scrollVisible = function() {
// Scroll the window to make the result page (and the search Input field) visible.
if (resultElement) window.scrollTo(0,ensureVisible(resultElement));
if (searchInputField) window.scrollTo(0,ensureVisible(searchInputField));
};
// Makes sure the result page has a good size and position and visible
// (may scroll the window)
//
var ensureResultIsDisplayedNicely = function() {
adjustResultPositionAndSize();
scrollVisible();
};
var indexInPage; // The index (in the current page) of the tiddler currently rendered.
var currentTiddler; // While rendering the page the tiddler that is currently rendered.
var pager = new abego.PageWiseRenderer();
var MyItemRenderer = function(parent) {
// Load the template how to display the items that represent a found tiddler
this.itemHtml = store.getTiddlerText("YourSearchItemTemplate");
if (!this.itemHtml) alertAndThrow("YourSearchItemTemplate not found");
// Locate the node that shall contain the list of found tiddlers
this.place = document.getElementById(yourSearchResultItemsID);
if(!this.place)
this.place = createTiddlyElement(parent,"div",yourSearchResultItemsID);
};
merge(MyItemRenderer.prototype,{
render: function(pager,object,index,indexOnPage) {
// Define global variables, referenced by macros during applyHtmlMacros
indexInPage = indexOnPage;
currentTiddler = object;
var item = createTiddlyElement(this.place,"div",null, "yourSearchItem");
item.innerHTML = this.itemHtml;
applyHtmlMacros(item,null);
refreshElements(item,null);
},
endRendering: function(pager) {
// The currentTiddler must only be defined while rendering the found tiddlers
currentTiddler = null;
}
});
// Refreshes the content of the result with the current search result
// of the selected page.
//
// Assumes that the result is already open.
//
var refreshResult = function() {
if (!resultElement || !searchInputField) return;
// Load the template for the YourSearchResult
var html = store.getTiddlerText("YourSearchResultTemplate");
if (!html) html = "<b>Tiddler YourSearchResultTemplate not found</b>";
resultElement.innerHTML = html;
// Expand the template macros etc.
applyHtmlMacros(resultElement,null);
refreshElements(resultElement,null);
var itemRenderer = new MyItemRenderer(resultElement);
pager.renderPage(itemRenderer);
ensureResultIsDisplayedNicely();
};
pager.getItemsPerPage = function() {
var n = (config.options.chkPreviewText)
? abego.toInt(config.options.txtItemsPerPageWithPreview, itemsPerPageWithPreviewDefault)
: abego.toInt(config.options.txtItemsPerPage, itemsPerPageDefault);
return (n > 0) ? n : 1;
};
pager.onPageChanged = function() {
refreshResult();
};
var showResult = function() {
if (!resultElement) {
resultElement = createTiddlyElement(document.body,"div",yourSearchResultID,"yourSearchResult");
} else if (resultElement.parentNode != document.body) {
document.body.appendChild(resultElement);
}
refreshResult();
};
var reopenResultIfApplicable = function() {
if (searchInputField == null || !config.options.chkUseYourSearch) return;
if ((searchInputField.value == lastSearchText) && lastSearchText && !isResultOpen()) {
// For speedup we check re-use the previously created resultElement, if possible.
if (resultElement && (resultElement.parentNode != document.body)) {
document.body.appendChild(resultElement);
ensureResultIsDisplayedNicely();
} else {
showResult();
}
}
};
var invalidateResult = function() {
closeResult();
resultElement = null;
lastSearchText = null;
};
//-------------------------------------------------------------------------
// Close the search result page when the user clicks on the document
// (and not into the searchInputField, on the search button or in the result)
// or presses the ESC key
// Returns true if e is either self or a descendant (child, grandchild,...) of self.
//
// @param self DOM:Element
// @param e DOM:Element or null
//
var isDescendantOrSelf = function(self, e) {
while (e != null) {
if (self == e) return true;
e = e.parentNode;
}
return false;
};
var onDocumentClick = function(e) {
if (e.target == searchInputField) return;
if (e.target == searchButton) return;
if (resultElement && isDescendantOrSelf(resultElement, e.target)) return;
closeResult();
};
var onDocumentKeyup = function(e) {
// Close the search result page when the user presses "ESC"
if (e.keyCode == 27) closeResult();
};
addEvent(document,"click",onDocumentClick);
addEvent(document,"keyup",onDocumentKeyup);
// Our Search Macro Hijack Function ==========================================
// Helper
var myStorySearch = function(text,useCaseSensitive,useRegExp)
{
lastSearchText = text;
setLastResults(findMatches(store, text,useCaseSensitive,useRegExp,"title","excludeSearch"));
highlightHack = lastQuery ? lastQuery.getMarkRegExp() : null;
pager.setItems(getLastResults());
showResult();
highlightHack = null;
};
var myMacroSearchHandler = function(place,macroName,params,wikifier,paramString,tiddler)
{
initStylesheet();
lastSearchText = "";
var searchTimeout = null;
var doSearch = function(txt)
{
if (config.options.chkUseYourSearch)
myStorySearch(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
else
story.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch);
lastSearchText = txt.value;
};
var clickHandler = function(e)
{
doSearch(searchInputField);
return false;
};
var keyHandler = function(e)
{
if (!e) var e = window.event;
searchInputField = this;
switch(e.keyCode)
{
case 13:
if (e.ctrlKey && lastNewTiddlerButton && isResultOpen())
lastNewTiddlerButton.onclick.apply(lastNewTiddlerButton,[e]);
else
doSearch(this);
break;
case 27:
// When the result is open, close it,
// otherwise clear the content of the input field
if (isResultOpen()) {
closeResult();
} else {
this.value = "";
clearMessage();
}
break;
}
if (String.fromCharCode(e.keyCode) == this.accessKey || e.altKey)
{
reopenResultIfApplicable();
}
if(this.value.length<3 && searchTimeout) clearTimeout(searchTimeout);
if(this.value.length > 2)
{
if (this.value != lastSearchText)
{
if (!config.options.chkUseYourSearch || config.options.chkSearchAsYouType)
{
if(searchTimeout)
clearTimeout(searchTimeout);
var txt = this;
searchTimeout = setTimeout(function() {doSearch(txt);},500);
}
}
else
{
if(searchTimeout)
clearTimeout(searchTimeout);
}
};
if (this.value.length == 0)
{
closeResult();
}
};
var focusHandler = function(e)
{
this.select();
clearMessage();
reopenResultIfApplicable();
};
var args = paramString.parseParams("list",null,true);
var buttonAtRight = getFlag(args, "buttonAtRight");
var sizeTextbox = getParam(args, "sizeTextbox", this.sizeTextbox);
var btn;
if (!buttonAtRight)
btn = createTiddlyButton(place,this.label,this.prompt,clickHandler);
var txt = createTiddlyElement(place,"input",null,null,null);
if(params[0])
txt.value = params[0];
txt.onkeyup = keyHandler;
txt.onfocus = focusHandler;
txt.setAttribute("size",sizeTextbox);
txt.setAttribute("accessKey",this.accessKey);
txt.setAttribute("autocomplete","off");
if(config.browser.isSafari)
{
txt.setAttribute("type","search");
txt.setAttribute("results","5");
}
else
txt.setAttribute("type","text");
if (buttonAtRight)
btn = createTiddlyButton(place,this.label,this.prompt,clickHandler);
searchInputField = txt;
searchButton = btn;
};
//----------------------------------------------------------------------------
// Support for Macros
//----------------------------------------------------------------------------
var openAllFoundTiddlers = function() {
closeResult();
var results = getLastResults();
var n = results.length;
if (n) {
var titles=[];
for(var i = 0; i<n; i++)
titles.push(results[i].title);
story.displayTiddlers(null,titles);
}
};
var createOptionWithRefresh = function(place, optionParams, wikifier,tiddler) {
invokeMacro(place,"option",optionParams,wikifier,tiddler);
// The option macro appended the component at the end of the place.
var elem = place.lastChild;
var oldOnClick = elem.onclick;
elem.onclick = function(e) {
var result = oldOnClick.apply(this, arguments);
refreshResult();
return result;
};
return elem;
};
var removeTextDecoration = function(s) {
var removeThis = ["''", "{{{", "}}}", "//", "<<<", "/***", "***/"];
var reText = "";
for (var i = 0; i < removeThis.length; i++) {
if (i != 0) reText += "|";
reText += "("+removeThis[i].escapeRegExp()+")";
}
return s.replace(new RegExp(reText, "mg"), "").trim();
};
// Returns the "shortcut number" of the currentTiddler.
// I.e. When the user presses Alt-n the given tiddler is opened/display.
//
// @return 0-9 or -1 when no number is defined
//
var getShortCutNumber = function() {
var i = indexInPage;
return (i >= 0 && i <= 9)
? (i < 9 ? (i+1) : 0)
: -1;
};
var limitedTextRenderer = new abego.LimitedTextRenderer();
var renderLimitedText = function(place, s, maxLen) {
limitedTextRenderer.render(place,s,maxLen,lastQuery.getMarkRegExp())
}
// When any tiddler are changed reset the result.
//
var oldTiddlyWikiSaveTiddler = TiddlyWiki.prototype.saveTiddler;
TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags,fields) {
oldTiddlyWikiSaveTiddler.apply(this, arguments);
invalidateResult();
};
var oldTiddlyWikiRemoveTiddler = TiddlyWiki.prototype.removeTiddler;
TiddlyWiki.prototype.removeTiddler = function(title) {
oldTiddlyWikiRemoveTiddler.apply(this, arguments);
invalidateResult();
};
//----------------------------------------------------------------------------
// Macros
//----------------------------------------------------------------------------
// ====Macro yourSearch ================================================
config.macros.yourSearch = {
// Standard Properties
label: "yourSearch",
prompt: "Gives access to the current/last YourSearch result",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
if (params.length == 0) return;
var name = params[0];
var func = config.macros.yourSearch.funcs[name];
if (func) func(place,macroName,params,wikifier,paramString,tiddler);
},
tests: {
"true" : function() {return true;},
"false" : function() {return false;},
"found" : function() {return getLastResultsCount() > 0;},
"previewText" : function() {return config.options.chkPreviewText;}
},
funcs: {
itemRange: function(place) {
if (getLastResultsCount()) {
var lastIndex = pager.getLastIndexOnPage();
var s = "%0 - %1".format([pager.getFirstIndexOnPage()+1,lastIndex+1]);
createTiddlyText(place, s);
}
},
count: function(place) {
createTiddlyText(place, getLastResultsCount().toString());
},
query: function(place) {
if (lastQuery) {
createTiddlyText(place, lastQuery.toString());
}
},
version: function(place) {
var t = "YourSearch %0.%1.%2".format(
[version.extensions.YourSearchPlugin.major,
version.extensions.YourSearchPlugin.minor,
version.extensions.YourSearchPlugin.revision]);
var e = createTiddlyElement(place, "a");
e.setAttribute("href", "http://tiddlywiki.abego-software.de/#YourSearchPlugin");
e.innerHTML = '<font color="black" face="Arial, Helvetica, sans-serif">'+t+'<font>';
},
copyright: function(place) {
var e = createTiddlyElement(place, "a");
e.setAttribute("href", "http://www.abego-software.de");
e.innerHTML = '<font color="black" face="Arial, Helvetica, sans-serif">© 2005-2006 <b><font color="red">abego</font></b> Software<font>';
},
newTiddlerButton: function(place) {
if (lastQuery) {
var r = abego.parseNewTiddlerCommandLine(lastQuery.getQueryText());
var btn = config.macros.newTiddler.createNewTiddlerButton(place,r.title,r.params,"new tiddler","Create a new tiddler based on search text. (Shortcut: Ctrl-Enter; Separators: '.', '#')",null,"text");
// Close the result before the new tiddler is created.
var oldOnClick = btn.onclick;
btn.onclick = function() {
closeResult();
oldOnClick.apply(this,arguments);
}
lastNewTiddlerButton = btn;
}
},
linkButton: function(place,macroName,params,wikifier,paramString,tiddler) {
if (params < 2) return;
var tiddlyLink = params[1];
var text = params < 3 ? tiddlyLink : params[2];
var tooltip = params < 4 ? text : params[3];
var accessKey = params < 5 ? null : params[4];
var btn = createTiddlyButton(place,text,tooltip,closeResultAndDisplayTiddler,null,null, accessKey);
btn.setAttribute("tiddlyLink",tiddlyLink);
},
closeButton: function(place,macroName,params,wikifier,paramString,tiddler) {
var button = createTiddlyButton(place, "close", "Close the Search Results (Shortcut: ESC)", closeResult);
},
openAllButton: function(place,macroName,params,wikifier,paramString,tiddler) {
var n = getLastResultsCount();
if (n == 0) return;
var title = n == 1 ? "open tiddler" : "open all %0 tiddlers".format([n]);
var button = createTiddlyButton(place, title, "Open all found tiddlers (Shortcut: Alt-O)", openAllFoundTiddlers);
button.setAttribute("accessKey","O");
},
naviBar: function(place,macroName,params,wikifier,paramString,tiddler) {
pager.addPageNavigation(place);
},
"if": function(place,macroName,params,wikifier,paramString,tiddler) {
if (params.length < 2) return;
var testName = params[1];
var negate = (testName == "not");
if (negate) {
if (params.length < 3) return;
testName = params[2];
}
var test = config.macros.yourSearch.tests[testName];
var showIt = false;
try {
if (test) {
showIt = test(place,macroName,params,wikifier,paramString,tiddler) != negate;
} else {
// When no predefined test is specified try to evaluate it as a JavaScript expression.
showIt = (!eval(testName)) == negate;
}
} catch (ex) {
}
if (!showIt) {
place.style.display="none";
}
},
chkPreviewText: function(place,macroName,params,wikifier,paramString,tiddler) {
var optionParams = params.slice(1).join(" ");
var elem = createOptionWithRefresh(place, "chkPreviewText", wikifier,tiddler);
elem.setAttribute("accessKey", "P");
elem.title = "Show text preview of found tiddlers (Shortcut: Alt-P)";
return elem;
}
}
};
// ====Macro foundTiddler ================================================
config.macros.foundTiddler = {
// Standard Properties
label: "foundTiddler",
prompt: "Provides information on the tiddler currently processed on the YourSearch result page",
handler: function(place,macroName,params,wikifier,paramString,tiddler) {
var name = params[0];
var func = config.macros.foundTiddler.funcs[name];
if (func) func(place,macroName,params,wikifier,paramString,tiddler);
},
funcs: {
title: function(place,macroName,params,wikifier,paramString,tiddler) {
if (!currentTiddler) return;
var shortcutNumber = getShortCutNumber();
var tooltip = shortcutNumber >= 0
? "Open tiddler (Shortcut: Alt-%0)".format([shortcutNumber.toString()])
: "Open tiddler";
var btn = createTiddlyButton(place,null,tooltip,closeResultAndDisplayTiddler,null);
btn.setAttribute("tiddlyLink",currentTiddler.title);
btn.setAttribute("withHilite","true");
renderLimitedText(btn, currentTiddler.title, maxCharsInTitle);
if (shortcutNumber >= 0) {
btn.setAttribute("accessKey",shortcutNumber.toString());
}
},
tags: function(place,macroName,params,wikifier,paramString,tiddler) {
if (!currentTiddler) return;
renderLimitedText(place, currentTiddler.getTags(), maxCharsInTags);
},
text: function(place,macroName,params,wikifier,paramString,tiddler) {
if (!currentTiddler) return;
renderLimitedText(place, removeTextDecoration(currentTiddler.text), maxCharsInText);
},
field: function(place,macroName,params,wikifier,paramString,tiddler) {
if (!currentTiddler) return;
var name = params[1];
var len = params.length > 2 ? abego.toInt(params[2],maxCharsInField) : maxCharsInField;
var v = store.getValue(currentTiddler,name);
if (v)
renderLimitedText(place, removeTextDecoration(v), len);
},
// Renders the "shortcut number" of the current tiddler, to indicate to the user
// what number to "Alt-press" to open the tiddler.
//
number: function(place,macroName,params,wikifier,paramString,tiddler) {
var numberToDisplay = getShortCutNumber();
if (numberToDisplay >= 0) {
var text = "%0)".format([numberToDisplay.toString()]);
createTiddlyElement(place,"span",null,"shortcutNumber",text);
}
}
}
};
//----------------------------------------------------------------------------
// Configuration Stuff
//----------------------------------------------------------------------------
var opts = {chkUseYourSearch:true,
chkPreviewText:true,
chkSearchAsYouType:true,
chkSearchInTitle:true,
chkSearchInText:true,
chkSearchInTags:true,
chkSearchExtendedFields:true,
txtItemsPerPage:itemsPerPageDefault,
txtItemsPerPageWithPreview:itemsPerPageWithPreviewDefault};
for (var n in opts)
if (config.options[n] == undefined) config.options[n] = opts[n];
//----------------------------------------------------------------------------
// Shadow Tiddlers
//----------------------------------------------------------------------------
config.shadowTiddlers.AdvancedOptions += "\n<<option chkUseYourSearch>> Use 'Your Search' //([[more options|YourSearch Options]]) ([[help|YourSearch Help]])// ";
config.shadowTiddlers["YourSearch Help"] =
"!Field Search\nWith the Field Search you can restrict your search to certain fields of a tiddler, e.g"+
" only search the tags or only the titles. The general form is //fieldname//'':''//textToSearch// (e."+
"g. {{{title:intro}}}). In addition one-character shortcuts are also supported for the standard field"+
"s {{{title}}}, {{{text}}} and {{{tags}}}:\n|!What you want|!What you type|!Example|\n|Search ''titles "+
"only''|start word with ''!''|{{{!jonny}}} (shortcut for {{{title:jonny}}})|\n|Search ''contents/text "+
"only''|start word with ''%''|{{{%football}}} (shortcut for {{{text:football}}})|\n|Search ''tags only"+
"''|start word with ''#''|{{{#Plugin}}} (shortcut for {{{tags:Plugin}}})|\n\nUsing this feature you may"+
" also search the extended fields (\"Metadata\") introduced with TiddlyWiki 2.1, e.g. use {{{priority:1"+
"}}} to find all tiddlers with the priority field set to \"1\".\n\nYou may search a word in more than one"+
" field. E.g. {{{!#Plugin}}} (or {{{title:tags:Plugin}}} in the \"long form\") finds tiddlers containin"+
"g \"Plugin\" either in the title or in the tags (but does not look for \"Plugin\" in the text). \n\n!Boole"+
"an Search\nThe Boolean Search is useful when searching for multiple words.\n|!What you want|!What you "+
"type|!Example|\n|''All words'' must exist|List of words|{{{jonny jeremy}}} (or {{{jonny and jeremy}}}"+
")|\n|''At least one word'' must exist|Separate words by ''or''|{{{jonny or jeremy}}}|\n|A word ''must "+
"not exist''|Start word with ''-''|{{{-jonny}}} (or {{{not jonny}}})|\n\n''Note:'' When you specify two"+
" words, separated with a space, YourSearch finds all tiddlers that contain both words, but not neces"+
"sarily next to each other. If you want to find a sequence of word, e.g. '{{{John Brown}}}', you need"+
" to put the words into quotes. I.e. you type: {{{\"john brown\"}}}.\n\nUsing parenthesis you may change "+
"the default \"left to right\" evaluation of the boolean search. E.g. {{{not (jonny or jeremy)}}} finds"+
" all tiddlers that contain neither \"jonny\" nor \"jeremy. In contrast to this {{{not jonny or jeremy}}"+
"} (i.e. without parenthesis) finds all tiddlers that either don't contain \"jonny\" or that contain \"j"+
"eremy\".\n\n!'Exact Word' Search\nBy default a search result all matches that 'contain' the searched tex"+
"t. E.g. if you search for {{{Task}}} you will get all tiddlers containing 'Task', but also '~Complet"+
"edTask', '~TaskForce' etc.\n\nIf you only want to get the tiddlers that contain 'exactly the word' you"+
" need to prefix it with a '='. E.g. typing '=Task' will find the tiddlers that contain the word 'Tas"+
"k', ignoring words that just contain 'Task' as a substring.\n\n!~CaseSensitiveSearch and ~RegExpSearch"+
"\nThe standard search options ~CaseSensitiveSearch and ~RegExpSearch are fully supported by YourSearc"+
"h. However when ''~RegExpSearch'' is on Filtered and Boolean Search are disabled.\n\nIn addition you m"+
"ay do a \"regular expression\" search even with the ''~RegExpSearch'' set to false by directly enterin"+
"g the regular expression into the search field, framed with {{{/.../}}}. \n\nExample: {{{/m[ae][iy]er/"+
"}}} will find all tiddlers that contain either \"maier\", \"mayer\", \"meier\" or \"meyer\".\n\n!~JavaScript E"+
"xpression Filtering\nIf you are familiar with JavaScript programming and know some TiddlyWiki interna"+
"ls you may also use JavaScript expression for the search. Just enter a JavaScript boolean expression"+
" into the search field, framed with {{{ { ... } }}}. In the code refer to the variable tiddler and e"+
"valuate to {{{true}}} when the given tiddler should be included in the result. \n\nExample: {{{ { tidd"+
"ler.modified > new Date(\"Jul 4, 2005\")} }}} returns all tiddler modified after July 4th, 2005.\n\n!Com"+
"bined Search\nYou are free to combine the various search options. \n\n''Examples''\n|!What you type|!Res"+
"ult|\n|{{{!jonny !jeremy -%football}}}|all tiddlers with both {{{jonny}}} and {{{jeremy}}} in its tit"+
"les, but no {{{football}}} in content.|\n|{{{#=Task}}}|All tiddlers tagged with 'Task' (the exact wor"+
"d). Tags named '~CompletedTask', '~TaskForce' etc. are not considered.|\n\n!Access Keys\nYou are encour"+
"aged to use the access keys (also called \"shortcut\" keys) for the most frequently used operations. F"+
"or quick reference these shortcuts are also mentioned in the tooltip for the various buttons etc.\n\n|"+
"!Key|!Operation|\n|{{{Alt-F}}}|''The most important keystroke'': It moves the cursor to the search in"+
"put field so you can directly start typing your query. Pressing {{{Alt-F}}} will also display the pr"+
"evious search result. This way you can quickly display multiple tiddlers using \"Press {{{Alt-F}}}. S"+
"elect tiddler.\" sequences.|\n|{{{ESC}}}|Closes the [[YourSearch Result]]. When the [[YourSearch Resul"+
"t]] is already closed and the cursor is in the search input field the field's content is cleared so "+
"you start a new query.|\n|{{{Alt-1}}}, {{{Alt-2}}},... |Pressing these keys opens the first, second e"+
"tc. tiddler from the result list.|\n|{{{Alt-O}}}|Opens all found tiddlers.|\n|{{{Alt-P}}}|Toggles the "+
"'Preview Text' mode.|\n|{{{Alt-'<'}}}, {{{Alt-'>'}}}|Displays the previous or next page in the [[Your"+
"Search Result]].|\n|{{{Return}}}|When you have turned off the 'as you type' search mode pressing the "+
"{{{Return}}} key actually starts the search (as does pressing the 'search' button).|\n\n//If some of t"+
"hese shortcuts don't work for you check your browser if you have other extensions installed that alr"+
"eady \"use\" these shortcuts.//";
config.shadowTiddlers["YourSearch Options"] =
"|>|!YourSearch Options|\n|>|<<option chkUseYourSearch>> Use 'Your Search'|\n|!|<<option chkPreviewText"+
">> Show Text Preview|\n|!|<<option chkSearchAsYouType>> 'Search As You Type' Mode (No RETURN required"+
" to start search)|\n|!|Default Search Filter:<<option chkSearchInTitle>>Title ('!') <<option chk"+
"SearchInText>>Text ('%') <<option chkSearchInTags>>Tags ('#') <<option chkSearchExtendedFiel"+
"ds>>Extended Fields<html><br><font size=\"-2\">The fields of a tiddlers that are searched when you don"+
"'t explicitly specify a filter in the search text <br>(Explictly specify fields using one or more '!"+
"', '%', '#' or 'fieldname:' prefix before the word/text to find).</font></html>|\n|!|Number of items "+
"on search result page: <<option txtItemsPerPage>>|\n|!|Number of items on search result page with pre"+
"view text: <<option txtItemsPerPageWithPreview>>|\n";
config.shadowTiddlers["YourSearchStyleSheet"] =
"/***\n!~YourSearchResult Stylesheet\n***/\n/*{{{*/\n.yourSearchResult {\n\tposition: absolute;\n\twidth: 800"+
"px;\n\n\tpadding: 0.2em;\n\tlist-style: none;\n\tmargin: 0;\n\n\tbackground: #ffd;\n\tborder: 1px solid DarkGra"+
"y;\n}\n\n/*}}}*/\n/***\n!!Summary Section\n***/\n/*{{{*/\n.yourSearchResult .summary {\n\tborder-bottom-width:"+
" thin;\n\tborder-bottom-style: solid;\n\tborder-bottom-color: #999999;\n\tpadding-bottom: 4px;\n}\n\n.yourSea"+
"rchRange, .yourSearchCount, .yourSearchQuery {\n\tfont-weight: bold;\n}\n\n.yourSearchResult .summary ."+
"button {\n\tfont-size: 10px;\n\n\tpadding-left: 0.3em;\n\tpadding-right: 0.3em;\n}\n\n.yourSearchResult .summa"+
"ry .chkBoxLabel {\n\tfont-size: 10px;\n\n\tpadding-right: 0.3em;\n}\n\n/*}}}*/\n/***\n!!Items Area\n***/\n/*{{{*"+
"/\n.yourSearchResult .marked {\n\tbackground: none;\n\tfont-weight: bold;\n}\n\n.yourSearchItem {\n\tmargin-to"+
"p: 2px;\n}\n\n.yourSearchNumber {\n\tcolor: #808080;\n}\n\n\n.yourSearchTags {\n\tcolor: #008000;\n}\n\n.yourSearc"+
"hText {\n\tcolor: #808080;\n\tmargin-bottom: 6px;\n}\n\n/*}}}*/\n/***\n!!Footer\n***/\n/*{{{*/\n.yourSearchFoote"+
"r {\n\tmargin-top: 8px;\n\tborder-top-width: thin;\n\tborder-top-style: solid;\n\tborder-top-color: #999999;"+
"\n}\n\n.yourSearchFooter a:hover{\n\tbackground: none;\n\tcolor: none;\n}\n/*}}}*/\n/***\n!!Navigation Bar\n***/"+
"\n/*{{{*/\n.yourSearchNaviBar a {\n\tfont-size: 16px;\n\tmargin-left: 4px;\n\tmargin-right: 4px;\n\tcolor: bla"+
"ck;\n\ttext-decoration: underline;\n}\n\n.yourSearchNaviBar a:hover {\n\tbackground-color: none;\n}\n\n.yourSe"+
"archNaviBar .prev {\n\tfont-weight: bold;\n\tcolor: blue;\n}\n\n.yourSearchNaviBar .currentPage {\n\tcolor: #"+
"FF0000;\n\tfont-weight: bold;\n\ttext-decoration: none;\n}\n\n.yourSearchNaviBar .next {\n\tfont-weight: bold"+
";\n\tcolor: blue;\n}\n/*}}}*/\n";
config.shadowTiddlers["YourSearchResultTemplate"] =
"<!--\n{{{\n-->\n<span macro=\"yourSearch if found\">\n<!-- The Summary Header ============================"+
"================ -->\n<table class=\"summary\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\">"+
"<tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Result <span class=\"yourSearchRange\" macro=\"yourSearc"+
"h itemRange\"></span>\n\t\t of <span class=\"yourSearchCount\" macro=\"yourSearch count\"></span>\n"+
"\t\tfor <span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>\n\t</td>\n\t<td class=\"yourSea"+
"rchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch chkPreviewText\"></span><span class=\"chkBoxLabel"+
"\">preview text</span>\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch openAllButton\"></span>\n\t\t<span macro=\"yourSearch lin"+
"kButton 'YourSearch Options' options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkB"+
"utton 'YourSearch Help' help 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch clo"+
"seButton\"></span>\n\t</td>\n </tr>\n</tbody></table>\n\n<!-- The List of Found Tiddlers ================="+
"=========================== -->\n<div id=\"yourSearchResultItems\" itemsPerPage=\"25\" itemsPerPageWithPr"+
"eview=\"10\"></div>\n\n<!-- The Footer (with the Navigation) ==========================================="+
"= -->\n<table class=\"yourSearchFooter\" border=\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody"+
">\n <tr>\n\t<td align=\"left\">\n\t\tResult page: <span class=\"yourSearchNaviBar\" macro=\"yourSearch naviBar"+
"\"></span>\n\t</td>\n\t<td align=\"right\"><span macro=\"yourSearch version\"></span>, <span macro=\"yourSearc"+
"h copyright\"></span>\n\t</td>\n </tr>\n</tbody></table>\n<!-- end of the 'tiddlers found' case ========="+
"================================== -->\n</span>\n\n\n<!-- The \"No tiddlers found\" case ================="+
"========================== -->\n<span macro=\"yourSearch if not found\">\n<table class=\"summary\" border="+
"\"0\" width=\"100%\" cellspacing=\"0\" cellpadding=\"0\"><tbody>\n <tr>\n\t<td align=\"left\">\n\t\tYourSearch Resu"+
"lt: No tiddlers found for <span class=\"yourSearchQuery\" macro=\"yourSearch query\"></span>.\n\t</td>\n\t<t"+
"d class=\"yourSearchButtons\" align=\"right\">\n\t\t<span macro=\"yourSearch newTiddlerButton\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Options'"+
" options 'Configure YourSearch'\"></span>\n\t\t<span macro=\"yourSearch linkButton 'YourSearch Help' help"+
" 'Get help how to use YourSearch'\"></span>\n\t\t<span macro=\"yourSearch closeButton\"></span>\n\t</td>\n <"+
"/tr>\n</tbody></table>\n</span>\n\n\n<!--\n}}}\n-->\n";
config.shadowTiddlers["YourSearchItemTemplate"] =
"<!--\n{{{\n-->\n<span class='yourSearchNumber' macro='foundTiddler number'></span>\n<span class='yourSea"+
"rchTitle' macro='foundTiddler title'/></span> - \n<span class='yourSearchTags' macro='found"+
"Tiddler field tags 50'/></span>\n<span macro=\"yourSearch if previewText\"><div class='yourSearchText' macro='fo"+
"undTiddler field text 250'/></div></span>\n<!--\n}}}\n-->";
config.shadowTiddlers["YourSearch"] = "<<tiddler [[YourSearch Help]]>>";
config.shadowTiddlers["YourSearch Result"] = "The popup-like window displaying the result of a YourSearch query.";
//----------------------------------------------------------------------------
// Install YourSearch
//----------------------------------------------------------------------------
// Overwrite the TiddlyWiki search handler and verify after a while
// that nobody else has overwritten it.
config.macros.search.handler = myMacroSearchHandler;
var checkForOtherHijacker = function() {
// Check that still our search handler is installed
if (config.macros.search.handler != myMacroSearchHandler) {
alert(
"Message from YourSearchPlugin:\n\n\nAnother plugin has disabled the 'Your Search' features.\n\n\nYou may "+
"disable the other plugin or change the load order of \nthe plugins (by changing the names of the tidd"+
"lers)\nto enable the 'Your Search' features.");
}
};
setTimeout(checkForOtherHijacker, 5000);
// === Public API =================================
abego.YourSearch.getStandardRankFunction = function() {
return standardRankFunction;
};
abego.YourSearch.getRankFunction = function() {
return abego.YourSearch.getStandardRankFunction();
};
abego.YourSearch.getCurrentTiddler = function() {
return currentTiddler;
};
abego.YourSearch.closeResult = function() {
closeResult();
}
})();
} // of "install only once"
// Used Globals (for JSLint) ==============
// ... JavaScript Core
/*global alert,clearTimeout,confirm */
// ... TiddlyWiki Core
/*global Tiddler, applyHtmlMacros, clearMessage, createTiddlyElement, createTiddlyButton, createTiddlyText, ensureVisible ,findPosX, highlightHack, findPosY,findWindowWidth, invokeMacro, saveChanges, refreshElements, story */
//}}}
/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005-2006 ([[www.abego-software.de|http://www.abego-software.de]])
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 abego Software 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.
***/
<html><div align="center"><iframe src="http://www.zotero.org/" frameborder="0" width="100%" height="600"></iframe></div></html>
refreshStyles("StyleSheetTiddlyChatter");
<div class="comment">
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title'>
<span class="modifier" macro='view modifier link'></span>
<span class="created" macro='view created date'>@</span>
</div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
</div>
@@color(#0066cc):Jeg har ikke opdaget hvad Claroline IKKE kan bruges til endnu.
Clarolines store styrke ligger i at kunne administrere STORE mængder elever og kurser.
Hvis alle fag var oprettet og alle elever tilmeldte sig sine hold her - ville de få deres eget skema i Claroline - med samtlige agendas for de enkelte fag. Meget meget godt. Man kan selv læse lidt om hvad Claroline bliver brugt til her: http://www.claroline.net/@@
@@color(#ff00cc):Mange skoler vælger at elever har adgang til internet overalt - indtil et bestemt tidspunkt. Jeg kan ikke se forskellen på at ville administrere om de ser film eller spiller spil efter et bestemt tidspunkt. Problemet er det samme.
Jeg synes vi bør udvide det trådløse til at omfatte alle de fælles fællesområder og undervisningslokaler (også formning) (ikke nødvendigvis gangene). Jeg mener ikke det er nødvendigt med timere (med mindre vi også kan sætte timere på spil og videoer??)
Det egentlige problem med at have åbent længe ad gangen er elevernes mulighed for at downloade i stride strømme - og derved "lægge netværket ned". Det er det vi afværger ved at køre et bonsystem. Så er der ingen der kan sætte deres pc til at downloade store filer for længe ad gangen.@@
<html><div align="center"><iframe src="https://addons.mozilla.org/en-US/firefox/addon/3863" frameborder="0" width="100%" height="600"></iframe></div></html>
<html><div class="js-kit-comments" permalink=""></div></html>
<script src="http://js-kit.com/comments.js"></script>
config.macros.lv = {};
config.macros.lv.init = function() {
// create personal ChatterFeed with the username on the end
var newTitle = "ChatterFeed" + config.options.txtUserName;
if (!store.getTiddler(newTitle)) {
var ownFeed = document.location.href.replace(/.html$/,".xml");
var newText = "|''Type:''|RSS|\n|''URL:''|"+ownFeed+"|\n|''Workspace:''||\n|''TiddlerFilter:''|[tag[public]]|";
var newTags = "channel public published systemServer";
store.saveTiddler(newTitle,newTitle,newText,config.options.txtUserName,null,newTags,null,true);
}
};
config.macros.lv.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
var table, this_tiddler;
var subManagement, subManagementSlider;
var listTemplate = {};
listTemplate.columns = [];
listTemplate.rowClasses = [];
listTemplate.buttons = [];
// listTemplate.actions = [];
listTemplate.columns.push({
type:"String",
title:"Latest update",
field:"latest_update"
});
listTemplate.columns.push({
type:"TiddlerLink",
title:"Title (no. of updates)",
field:"link_title",
tiddlerLink:"link"
});
listTemplate.columns.push({
type:"String",
title:"Last updated by",
field:"last_updated_by"
});
/* listTemplate.columns.push({
type:"Selector",
field:"checked",
rowName:"row_name"
}); */
listTemplate.rowClasses.push({
field:"unread",
className:"tiddlyChatterIncomingRowUnread"
});
listTemplate.rowClasses.push({
field:"read",
className:"tiddlyChatterIncomingRow"
});
listTemplate.buttons.push({
name:"Get updates",
caption:"Get",
allowEmptySelection:"true"
});
listTemplate.buttons.push({
name:"Create chatter",
caption:"Create",
allowEmptySelection:"true"
});
listTemplate.buttons.push({
name:"Manage subscriptions",
caption:"Manage",
allowEmptySelection:"true"
});
/* listTemplate.actions.push({
name:"bark",
caption:"woof woof"
});
listTemplate.actions.push({
name:"laugh",
caption:"ha ha"
}); */
// callback has to deal with all the different functions, so select them by 'name'
var callback = function(view,name,tiddlers) {
switch(name) {
case "Get updates":
// when filterTiddlers supports excluding tiddlers, it will make sense to
// exclude systemServer tiddlers so we don't collect other people's subscriptions
config.macros.importWorkspaceMulti.importAll("[tag["+config.options.txtImportTag+"]]");
break;
case "Manage subscriptions":
subManagement.style.display = subManagement.style.display == "none" ? "block" : "none";
break;
case "Create chatter":
// mimicing the newTiddler button
this.setAttribute("newTitle","NewChatter");
this.setAttribute("isJournal","false");
this.setAttribute("params","public");
this.setAttribute("newFocus","title");
this.setAttribute("newTemplate","2");
this.setAttribute("customFields","unread:true");
this.setAttribute("newText","Type some text and then press DONE");
config.macros.newTiddler.onClickNewTiddler.call(this,null);
break;
default:
// don't do anything
break;
}
};
/* START: routine to fill content into our listObject */
var tagFilter;
if (params) {
tagFilter = params[0];
}
// content_and_notes holds our content and associated notes in the form:
// [{content:content1,notes:[note1a,note1b]},{content:content2,notes[note2a,note2b]},...]
var content_and_notes = [];
var notes = [];
var filteredContent = store.filterTiddlers(tagFilter);
// process: collect the content first and set up the content_and_notes array
// collect the notes at the same time and store them
// sort notes by modify date
// run through cotent, adding its notes to content_and_notes
// sort content_and_notes by modify date of most recent note belonging to content
for (var i=0;i<filteredContent.length;i++) {
var t = filteredContent[i];
if (t.isTagged("public") && !t.isTagged("systemServer")) {
if (!t.isTagged("notes")) {
// it's parent content
content_and_notes.push({content:t,notes:[]});
} else {
// it's a note
notes.push(t);
}
}
}
notes.sort(function(a,b){
return a.modified > b.modified ? -1 : (a.modified == b.modified ? 0 : 1);
});
for (var i=0;i<content_and_notes.length;i++) {
var content_object = content_and_notes[i];
for (var j=0;j<notes.length;j++) {
if (notes[j].title.indexOf(content_object["content"].title) != -1) {
// matched a note with a title containing a piece of content's title
content_object["notes"].push(notes[j]);
}
}
}
content_and_notes.sort(function(a,b){
var a_most_recent, b_most_recent;
// a["notes"][0] is the most recent note for a piece of content, if it exists
// if it doesn't exist, use the content itself
if (a["notes"][0]) {
a_most_recent = a["notes"][0];
} else {
a_most_recent = a["content"];
}
if (b["notes"][0]) {
b_most_recent = b["notes"][0];
} else {
b_most_recent = b["content"];
}
return a_most_recent.modified > b_most_recent.modified ? -1 : (a_most_recent.modified == b_most_recent.modified ? 0 : 1);
});
// map content_and_notes onto listObject
var listObject = [];
for (var i=0;i<content_and_notes.length;i++) {
var content_object = content_and_notes[i];
// noteCount is the number of notes in content_object["notes"];
var noteCount = content_object["notes"] ? content_object["notes"].length : 0;
// newestNote is the first note in content_object["notes"] or the content itself if there are no notes
var newestNote = noteCount !== 0 ? content_object["notes"][0] : content_object["content"];
// display "new" next to the title if noteCount is 0
var newContent = noteCount === 0 ? true : false;
// we want to know how many days since the last update
var daysSince = newestNote.modified.relativeDays();
// display today or yesterday if daysSince is 0 or 1, respectively
if (daysSince === 0) {
daysSince = "today";
} else if (daysSince == 1) {
daysSince = "yesterday";
} else {
daysSince = daysSince + " days ago";
}
var contentTitle = content_object["content"].title;
var contentTitleSuffix = newContent ? " (new)" : " (" + noteCount + ")";
listObject[i] = {
latest_update:daysSince,
link_title:contentTitle + contentTitleSuffix,
link:contentTitle,
last_updated_by:newestNote.modifier,
checked:newestNote.fields["unread"] ? true : false,
row_name:contentTitle
};
if (newestNote.fields["unread"] == "true") {
listObject[i]["unread"] = "yes";
} else {
listObject[i]["read"] = "yes";
}
}
/* END */
// Create a listview
table = ListView.create(place,listObject,listTemplate,callback);
this_tiddler = story.findContainingTiddler(table);
this_tiddler.setAttribute("refresh","tiddler");
this_tiddler.setAttribute("force","true");
subManagement = config.macros.tiddlyChatterSetup.handler(place,"tiddlyChatterSetup",params,wikifier,paramString,tiddler);
subManagement.style.display = "none";
};
<!--{{{-->
<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='publishing' macro='publishing'></div>
<div class='unread' macro='unread'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='viewer' macro='notes tags:"notes public"'></div>
<div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|StickyOptionsPlugin|
|''Description:''||
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#StickyOptionsPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0 pre-release|
|''Date:''||
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2|
!!Usage:
* Sticky options are saved in the file rather than in cookies.
* To make an option sticky, check the 'sticky' checkbox for it in AdvancedOptions
* To force all options to be sticky, check the 'Options always sticky' checkbox at the bottom of the AdvancedOptions screen.
* Please remember that the file needs to be saved after each option is saved, for the setting to be remembered.
* Enable the 'autosave' option below, to trigger an autosave when an option is saved
Trigger autosave when an option is saved: <<option chkStickyOptionsAutoSave>>
***/
// /%
//!BEGIN-PLUGIN-CODE
if(config.options.chkStickyOptionsAutoSave == undefined)
config.options.chkStickyOptionsAutoSave = false;
config.optionsDesc.chkStickyOptionsAutoSave = "Trigger autosave when an option is saved";
StickyOptions = {
container : tiddler,
alwaysSticky : !! store.getValue(this.container,"stickyoptions.alwayssticky"),
toggleAlwaysSticky : function(stat){
this.alwaysSticky = stat;
store.setValue(this.container,"stickyoptions.alwayssticky",stat? stat : undefined);
if(stat)
this.saveAllOptions();
},
toggleOption : function(optName,toggle,stat,nosave){
if(this.isOption(optName)){
var optVal = toggle ? (stat? config.options[optName]:undefined):config.options[optName];
if(toggle)
this.updateDir(optName,stat);
store.setValue(this.container,"sticky."+optName.toLowerCase(),optVal);
if(!nosave && config.options.chkStickyOptionsAutoSave)
autoSaveChanges();
}
},
saveAllOptions : function(){
store.suspendNotifications();
for(var n in config.options){
this.toggleOption(n,true,true,true);
}
store.resumeNotifications;
store.notify(this.container.title,true);
if (config.options.chkStickyOptionsAutoSave)
autoSaveChanges();
},
updateDir : function(optName,stat){
this.options.setItem(optName,stat? +1 : -1);
store.setValue(this.container,"stickyoptions.dir",this.options);
},
getOption : function(optName){
return store.getValue(this.container,"sticky."+optName.toLowerCase());
},
isOption : function(optName){
var optType = optName.substr(0,3);
return (config.optionHandlers[optType] && config.optionHandlers[optType].get);
},
isSticky : function(optName){
return this.options.contains(optName);
},
loadAllOptions : function(){
if(safeMode)
return;
var savedOpts = store.getValue(this.container,"stickyoptions.dir");
this.options = savedOpts? savedOpts.split(",") : [];
for (var i=0; i<this.options.length; i++){
var optType = this.options[i].substr(0,3);
if(config.optionHandlers[optType] && config.optionHandlers[optType].set)
config.optionHandlers[optType].set(this.options[i],this.getOption(this.options[i]));
}
},
oldSaveOptionCookie : window.saveOptionCookie
};
StickyOptions.loadAllOptions();
saveOptionCookie = function(name){
if (StickyOptions.alwaysSticky || StickyOptions.isSticky(name)){
StickyOptions.toggleOption(name,StickyOptions.alwaysSticky ? true:false ,true);
}
else{
StickyOptions.oldSaveOptionCookie(name);
}
};
config.macros.options.step1Title += " unless they are sticky. Sticky options are saved in this file.";
config.macros.options.old_step1Html = config.macros.options.step1Html;
config.macros.options.updateStep1Html = function(){
this.step1Html = this.old_step1Html + "<br><input type='checkbox' " + (StickyOptions.alwaysSticky? "checked":"") + " onclick='config.macros.options.toggleAlwaysSticky(this);'>Options always sticky</input>";
};
config.macros.options.listViewTemplate.columns.splice(1,0,{name: 'Sticky', field: 'name', title: "Sticky", type: 'StickyOption'});
config.macros.options.old_handler = config.macros.options.handler;
config.macros.options.handler = function(place,macroName,params,wikifier,paramString,tiddler){
this.updateStep1Html();
this.old_handler.apply(this,arguments);
};
config.macros.options.toggleAlwaysSticky = function(e)
{
StickyOptions.toggleAlwaysSticky(e.checked);
var wizard = new Wizard(e);
var listWrapper = wizard.getValue("listWrapper");
var chkUnknown = wizard.getElement("chkUnknown").checked;
removeChildren(listWrapper);
config.macros.options.refreshOptions(listWrapper,chkUnknown);
return false;
};
ListView.columnTypes.StickyOption = {
createHeader: ListView.columnTypes.String.createHeader,
createItem: function(place,listObject,field,columnTemplate,col,row)
{
var opt = listObject[field];
var e = createTiddlyCheckbox(place,null,StickyOptions.isSticky(opt),this.onChange);
e.disabled = StickyOptions.alwaysSticky;
e.name = opt;
},
onChange : function(e){
StickyOptions.toggleOption(this.name,true,this.checked);
}
};
//!END-PLUGIN-CODE
// %/
<<tagCloud admin authorbook Bøger Dansk [[Eksempel emne]] [[Eksempel underemne]] Emner excludeList excludeLists excludeSearch Note Ondskaben Resume script settings systemConfig systemServer TiddlyHomeSystem Upload TiddlySnip IFramePackage MediaPackage [[Live Media GPS eksempel]] TiddlyChatterPackage>>
/* Update on 09/10/07: SIMPLIFICATION
* No longer offering a choice of feeds by default
* ID for feed tiddlers now supplied as a parameter */
config.macros.publishing = {};
config.macros.publishing.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
// publishing puts a box on a tiddler that shows:
// if the tiddler is not 'published', a 'publish' button -
// - hitting 'publish' drops a menu of available streams to choose from;
// if the tiddler is published, a 'published' label -
// - hitting 'published' drops a menu of streams the tiddler is published in
// - plus the list of streams that you can also publish it in
// being published is defined as being tagged with a channel name
var published = false;
var publications = {};
// collect a list of streams and label them as being streams this tiddler is published in or not
params = paramString.parseParams("anon",null,true,false,false);
// stream_id defines what a stream tiddler is tagged with
// if we haven't supplied that parameter, we just look at whether this tiddler is tagged published or not
var stream_id = getParam(params,"stream_id",null);
if (stream_id) {
var streams = store.getTaggedTiddlers(stream_id);
publications = {'yes':[], 'no':[]};
for (var i=0;i<streams.length;i++) {
if (tiddler.isTagged(streams[i].title)) {
publications.yes.push(streams[i]);
} else {
publications.no.push(streams[i]);
}
}
if (publications.yes.length !== 0) {
published = true;
}
} else {
if (tiddler.isTagged("published")) {
published = true;
}
}
if (published) {
// add a published box
var thePublishedBox = createTiddlyButton(place,"Published","Click to unpublish");
// is there is no stream_id, we are not working with streams, so clicking Published unpublishes the content, which means updates will no longer appear in the stream
if (stream_id) {
thePublishedBox.onclick = this.reveal;
// create the published list
var thePublishedList = createTiddlyElement(place,"ul");
thePublishedList.style.display = "none";
for (var i=0;i<publications.yes.length;i++) {
// for the published list just present a simple list
var streamItem = createTiddlyElement(thePublishedList,"li",null,null,publications.yes[i].title);
}
} else {
thePublishedBox.onclick = function() {
config.macros.publishing.unsubscribe.call(this,"published");
};
}
} else {
// add a publish box
var thePublishBox = createTiddlyButton(place,"Publish","Click to publish");
// if there is no stream_id, we are not working with streams, so clicking publish just adds "published" to the tiddler's tags
if (stream_id) {
thePublishBox.onclick = this.reveal;
// create the publish list
var thePublishListBox = createTiddlyElement(place,"div");
thePublishListBox.style.display = "none";
var thePublishList = createTiddlyElement(thePublishListBox,"ul");
for (var i=0;i<publications.no.length;i++) {
// for the publish list present a list of buttons
var streamItem = createTiddlyElement(thePublishList,"li");
createTiddlyButton(streamItem,publications.no[i].title,publications.no[i].title,this.subscribe);
}
// CROSS-PLUGIN DEPENDENCY!
if (config.macros.tiddlyChatterSetup) {
var newStream = createTiddlyButton(thePublishListBox,"new stream...","Create a new stream",this.reveal);
var newStreamBox = createTiddlyElement(thePublishListBox,"div");
newStreamBox.style.display = "none";
// next line to give input box and go button same depth as list items above
// so the subscribe function points to the parent tiddler properly in both cases
var newStreamList = createTiddlyElement(newStreamBox,"div");
var newStreamInput = createTiddlyElement(newStreamList,"input",null,null);
newStreamInput.setAttribute("size","5");
createTiddlyButton(newStreamList,"go","go",config.macros.publishing.onClickNewChannel);
}
} else {
thePublishBox.onclick = function() {
config.macros.publishing.subscribe.call(this,"published");
};
}
}
};
config.macros.publishing.onClickNewChannel = function() {
// call the onclick for the stream creator, setting 'this' to the current value of 'this'
config.macros.tiddlyChatterSetup.onClickNewChannel.call(this);
// now subscribe to this channel
var created = false;
if (store.fetchTiddler(this.previousSibling.value)) {
created = true;
}
// subscribe, setting 'this' to be the input with the new stream name in
this.previousSibling.textContent = this.previousSibling.value;
config.macros.publishing.subscribe.call(this.previousSibling);
};
// onclick for channel names; 'this' refers to the link
config.macros.publishing.subscribe = function(tag) {
var DOMTiddler = story.findContainingTiddler(this);
var tiddler = store.fetchTiddler(DOMTiddler.attributes.tiddler.textContent);
if (!tag) {
tag = this.textContent;
}
tiddler.tags.push(tag);
tiddler.set(tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.created,tiddler.fields);
story.refreshTiddler(DOMTiddler.getAttribute("tiddler"),DOMTiddler.getAttribute("template"),true);
};
// onclick for channel names when published; 'this' refers to the link
config.macros.publishing.unsubscribe = function(tag) {
var DOMTiddler = story.findContainingTiddler(this);
var tiddler = store.fetchTiddler(DOMTiddler.attributes.tiddler.textContent);
if (!tag) {
tag = this.textContent;
}
tiddler.tags.splice(tiddler.tags.indexOf(tag),1);
tiddler.set(tiddler.title,tiddler.text,tiddler.modifier,tiddler.modified,tiddler.tags,tiddler.created,tiddler.fields);
story.refreshTiddler(DOMTiddler.getAttribute("tiddler"),DOMTiddler.getAttribute("template"),true);
};
// onclick for "publish" buttons; 'this' refers to the span
config.macros.publishing.reveal = function() {
// create an interface to give your channel an id
var slideBox = this.nextSibling;
var isOpen = slideBox.style.display != "none";
if(anim && typeof Slider == "function")
anim.startAnimating(new Slider(slideBox,!isOpen,null,"none"));
else
slideBox.style.display = isOpen ? "none" : "block";
};
//{{{
/* Update on 09/10/07: SIMPLIFICATION
* No longer offering a choice of streams by default
* Boolean parameter provided to specify whether we are working with streams */
config.macros.tiddlyChatterSetup = {};
config.macros.tiddlyChatterSetup.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
params = paramString.parseParams("anon",null,true,false,false);
// using_streams defines whether we are working with multiple streams
var using_streams = getParam(params,"using_streams",null);
var streamManagementWrapper = createTiddlyElement(place,"div","streamManagementWrapper");
var channelBox;
if(using_streams) {
// create an interface for handling streams
// a streams is a feed you publish
// add a button to create new streams
var channelWrapper = createTiddlyElement(streamManagementWrapper,"div","channelWrapper");
channelBox = createTiddlyElement(channelWrapper,"div","channelBox");
var newChannelButton = createTiddlyButton(channelBox,"New stream","New stream",this.reveal);
createTiddlyElement(channelBox,"br");
// set up the new channel UI to reveal when 'new channel' is clicked
var newChannelBox = createTiddlyElement(channelWrapper,"div","newChannelBox");
newChannelBox.style.display = "none";
createTiddlyElement(newChannelBox,"span",null,null,"Please provide a name for your stream");
createTiddlyElement(newChannelBox,"br");
createTiddlyElement(newChannelBox,"span",null,null,"Stream:");
var channelName = createTiddlyElement(newChannelBox,"input","newChannelName");
createTiddlyButton(newChannelBox,"create","Create stream",this.onClickNewChannel);
createTiddlyElement(newChannelBox,"br");
}
// create an interface for handling subscriptions
// we do this whether or not using_streams is true
// a subscription is to someone else's stream
// add a button to create new subscriptions
var subscriptionWrapper = createTiddlyElement(streamManagementWrapper,"div","subscriptionWrapper");
var subscriptionBox = createTiddlyElement(subscriptionWrapper,"div","subscriptionBox");
var newSubscriptionButton = createTiddlyButton(subscriptionBox,"New subscription","New subscription",this.reveal);
createTiddlyElement(subscriptionBox,"br");
// set up the new subscription UI to reveal when 'new subscription' is clicked
var newSubscriptionBox = createTiddlyElement(subscriptionWrapper,"div","newSubscriptionBox");
newSubscriptionBox.style.display = "none";
createTiddlyElement(newSubscriptionBox,"span",null,null,"Please point to the stream list you want to subscribe to");
createTiddlyElement(newSubscriptionBox,"br");
createTiddlyElement(newSubscriptionBox,"span",null,null,"URL:");
var subscriptionURL = createTiddlyElement(newSubscriptionBox,"input","newSubscriptionURL");
createTiddlyButton(newSubscriptionBox,"go","View stream list",this.onClickNewSubscription);
createTiddlyElement(newSubscriptionBox,"br");
// a stream is defined as a tiddler tagged with systemServer, channel and the id of the channel
// the id is what you tag your tiddler with to put it in that channel
// a subscription is defined as a tiddler tagged with systemServer, channel, subscription and the id of the channel
// a subscription is also a channel, in that you can subscribe to it
var channels = [];
var subscriptions = [];
if (using_streams) {
store.forEachTiddler(function(title,tiddler) {
if (tiddler.isTagged("systemServer") && tiddler.isTagged("channel")) {
channels.push(tiddler);
if (tiddler.isTagged("subscription")) {
subscriptions.push(tiddler);
}
}
});
// the channels array now has all the channel tiddlers in it, so we add them to the channelBox
for (var i=0;i<channels.length;i++) {
createTiddlyLink(channelBox,channels[i].title,true);
// if the channel is a subscription too, flag this to the user
if (channels[i].isTagged("subscription")) {
wikify("// - one of your own subscriptions//",channelBox);
}
createTiddlyElement(channelBox,"br");
}
} else {
store.forEachTiddler(function(title,tiddler) {
if (tiddler.isTagged("systemServer") && tiddler.isTagged("published")) {
subscriptions.push(tiddler);
}
});
}
// the subscriptions array now has all the subscriptions tiddlers in it, so we add them to the subscriptionBox
// we do this whether or not using_streams is true
var ownPath = document.location.href.replace(/.html$/,"");
for (var i=0;i<subscriptions.length;i++) {
createTiddlyLink(subscriptionBox,subscriptions[i].title,true);
// if the url of a subscription is the same as the page (minus the file extension)
// flag that to the user
var feedPath = store.getTiddlerSlice(subscriptions[i].title,"URL").replace(/.xml$/,"");
if (ownPath == feedPath) {
wikify("// - this is your own ~ChatterFeed//",subscriptionBox);
} else {
wikify("// - <html>" + store.getTiddlerSlice(subscriptions[i].title,"URL") + "</html>//",subscriptionBox);
}
createTiddlyElement(subscriptionBox,"br");
}
return streamManagementWrapper;
};
// onclick for creating a new channel; 'this' refers to the button
config.macros.tiddlyChatterSetup.onClickNewChannel = function() {
var channelName = this.previousSibling.value;
// create a new tiddler tagged with channel, systemServer and whatever id the user specified
// a channel's filter is of the form [tag[public id]], where id is the same as above
// we leave the URL field blank and let that be created by the subscription mechanism
var tags = "channel systemServer";
tags += " " +channelName;
var tiddlerBody = "|''Type:''|RSS|\n|''URL:''||\n|''Workspace:''||\n|''TiddlerFilter:''|[tag[public "+channelName+"]]|";
store.saveTiddler(channelName,channelName,tiddlerBody,config.options.txtUserName,null,tags);
var this_tiddler = story.findContainingTiddler(this);
story.refreshTiddler(this_tiddler.getAttribute("tiddler"),this_tiddler.getAttribute("template"),true);
};
// onclick after clicking the new subscription button; 'this' refers to the button
config.macros.tiddlyChatterSetup.onClickNewSubscription = function() {
var subscriptionURL = document.getElementById("newSubscriptionURL").value;
var place = document.getElementById("newSubscriptionBox");
// load up the url provided and show a list of channels to subscribe to
// assume we are pointing at a TiddlyWiki
var adaptor = new FileAdaptor();
var context = {};
context.place = place;
adaptor.openHost(subscriptionURL,context,null,config.macros.tiddlyChatterSetup.onOpenHost);
};
config.macros.tiddlyChatterSetup.onOpenHost = function(context,userParams) {
if(context.status !== true) {
displayMessage("error opening host: " + context.statusText);
} else {
var filter = "[tag[channel systemServer]]";
context.adaptor.getTiddlerList(context,userParams,config.macros.tiddlyChatterSetup.onGetTiddlerList,filter);
}
};
config.macros.tiddlyChatterSetup.onGetTiddlerList = function(context,userParams) {
// collect a list of existing channels to check against
var channels = [];
store.forEachTiddler(function(title,tiddler) {
if (tiddler.isTagged("systemServer") && tiddler.isTagged("channel")) {
channels.push(tiddler);
}
});
// offer a list of channels to subscribe to
for (var i=0; i<context.tiddlers.length; i++) {
createTiddlyElement(context.place,"span",null,null,context.tiddlers[i].title);
var box = createTiddlyCheckbox(context.place,"tick me",false,function(){
var subscribeButton = document.getElementById("subscribeButton");
if(this.checked==true) {
subscribeButton.tiddler_title = this.previousSibling.textContent;
} else {
subscribeButton.tiddler_title = "";
}
});
// if the name of a potential subscription is the same as one of your own channels,
// flag that to the user
for (var t in channels) {
if (channels[t].title == context.tiddlers[i].title) {
wikify("// - this could be your own content - learn more [[here|ReciprocalSubscriptions]]//",context.place);
}
}
createTiddlyElement(context.place,"br");
}
var subscribeButton = createTiddlyButton(context.place,"subscribe","Subscribe",config.macros.tiddlyChatterSetup.onClickSubscribe,null,"subscribeButton");
subscribeButton.context = context;
};
// onclick for clicking the subscribe button; 'this' refers to the button
config.macros.tiddlyChatterSetup.onClickSubscribe = function() {
var tiddler = {};
var tiddler_title = this.tiddler_title;
for (var t in this.context.tiddlers) {
if (this.context.tiddlers[t].title == this.tiddler_title) {
tiddler = this.context.tiddlers[t];
}
}
if (tiddler) {
// now copy the tiddler across, adding in the 'subscription' tag and rebuilding the body with the URL
var adaptor_store = this.context.adaptor.store;
var type_field = adaptor_store.getTiddlerSlice(tiddler.title,"Type");
var url_field = adaptor_store.getTiddlerSlice(tiddler.title,"URL");
var workspace_field = adaptor_store.getTiddlerSlice(tiddler.title,"Workspace");
var filter_field = adaptor_store.getTiddlerSlice(tiddler.title,"TiddlerFilter");
var subscriptionTemplate = "|''Type:''|%0|\n|''URL:''|%1|\n|''Workspace:''|%2|\n|''TiddlerFilter:''|%3|";
var text = subscriptionTemplate.format([type_field,url_field,workspace_field,filter_field]);
tiddler.tags.push("subscription");
store.saveTiddler(tiddler.title, tiddler.title, text, tiddler.modifier, tiddler.modified, tiddler.tags, tiddler.fields, true, tiddler.created);
var this_tiddler = story.findContainingTiddler(this);
story.refreshTiddler(this_tiddler.getAttribute("tiddler"),this_tiddler.getAttribute("template"),true);
} else {
displayMessage("problem with matching: " + tiddler_title);
}
};
// onclick for "new" buttons; 'this' refers to the button
config.macros.tiddlyChatterSetup.reveal = function() {
var slideBox = this.parentNode.nextSibling;
var isOpen = slideBox.style.display != "none";
if(anim && typeof Slider == "function")
anim.startAnimating(new Slider(slideBox,!isOpen,null,"none"));
else
slideBox.style.display = isOpen ? "none" : "block";
};
// Extension to TiddlyWiki.js
// Filter a list of tiddlers
TiddlyWiki.prototype.filterTiddlers = function(filter)
{
var results = [];
if(filter) {
var re = /(\w+)|(?:\[([ \w]+)\[([ \w]+)\]\])|(?:\[\[([ \w]+)\]\])/mg;
var match = re.exec(filter);
while(match) {
if(match[1]) {
var tiddler = this.fetchTiddler(match[1])
if(tiddler)
results.push(tiddler);
} else if(match[2]) {
if(match[2]=="tag") {
this.forEachTiddler(function(title,tiddler) {
if(tiddler.isTaggedAllOf(match[3].split(" "))) {
results.push(tiddler);
}
});
}
} else if(match[4]) {
var tiddler = this.fetchTiddler(match[4])
if(tiddler)
results.push(tiddler);
}
match = re.exec(filter);
}
} else {
this.forEachTiddler(function(title,tiddler) {results.push(tiddler);});
}
return results;
};
//}}}
//{{{
config.options.chkHttpReadOnly = false;
config.options.chkAutoSave = false;
config.options.chkSaveBackups = true;
config.options.chkAnimate = true;
config.options.chkShowRightSidebar= false;
config.options.chkSinglePageMode= true;
config.options.chkSinglePagePermalink= false;
if (window.location.protocol!="file:") showBackstage=false;
config.options.chkSearchTitles=true;
config.options.chkSearchText=true;
config.options.chkSearchTags=true;
config.options.chkSearchFields=true;
config.options.chkSearchTitlesFirst=false;
config.options.chkSearchList=true;
config.options.chkSearchByDate=false;
config.options.chkSearchIncremental=true;
config.options.chkSearchShadows=false;
config.options.chkShowQuickEdit=true;
//}}}
Hentning af materiale fra edb.tiddlyspot.com