Merge branch 'TiddlyWiki:master' into toc-v5.3.x-rewrite

This commit is contained in:
Mario Pietsch 2025-10-08 18:44:04 +02:00 committed by GitHub
commit ded8248a38
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
284 changed files with 1694 additions and 26584 deletions

40
.github/workflows/eslint.yml vendored Normal file
View file

@ -0,0 +1,40 @@
name: ESLint
on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
concurrency:
group: lint-${{ github.event.pull_request.number || github.ref_name }}
cancel-in-progress: true
permissions:
contents: read
# Needed for GitHub Checks API
checks: write
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install --include=dev
- name: Run ESLint with reviewdog (GitHub Checks)
uses: reviewdog/action-eslint@v1
with:
eslint_flags: '.'
reporter: github-pr-check
fail_level: error
level: error
tool_name: ESLint PR code

View file

@ -799,12 +799,13 @@ the password, and to encrypt/decrypt a block of text
$tw.utils.Crypto = function() {
var sjcl = $tw.node ? (global.sjcl || require("./sjcl.js")) : window.sjcl,
currentPassword = null,
callSjcl = function(method,inputText,password) {
callSjcl = function(method,inputText,password,options) {
options = options || {};
password = password || currentPassword;
var outputText;
try {
if(password) {
outputText = sjcl[method](password,inputText);
outputText = sjcl[method](password,inputText,options);
}
} catch(ex) {
console.log("Crypto error:" + ex);
@ -830,7 +831,8 @@ $tw.utils.Crypto = function() {
return !!currentPassword;
}
this.encrypt = function(text,password) {
return callSjcl("encrypt",text,password);
// set default ks:256 -- see: http://bitwiseshiftleft.github.io/sjcl/doc/convenience.js.html
return callSjcl("encrypt",text,password,{v:1,iter:10000,ks:256,ts:64,mode:"ccm",adata:"",cipher:"aes"});
};
this.decrypt = function(text,password) {
return callSjcl("decrypt",text,password);
@ -1433,7 +1435,7 @@ $tw.Wiki = function(options) {
checkTiddler = function(tiddler,title) {
if(tiddler && tiddler.fields.type === "application/json" && tiddler.fields["plugin-type"] && (!pluginType || tiddler.fields["plugin-type"] === pluginType)) {
var disablingTiddler = self.getTiddler("$:/config/Plugins/Disabled/" + title);
if(title === "$:/core" || !disablingTiddler || (disablingTiddler.fields.text || "").trim() !== "yes") {
if(title === "$:/core" || title === "$:/core-server" || !disablingTiddler || (disablingTiddler.fields.text || "").trim() !== "yes") {
self.unregisterPluginTiddlers(null,[title]); // Unregister the plugin if it's already registered
pluginTiddlers.push(tiddler);
registeredTitles.push(tiddler.fields.title);
@ -1530,7 +1532,8 @@ Define all modules stored in ordinary tiddlers
*/
$tw.Wiki.prototype.defineTiddlerModules = function() {
this.each(function(tiddler,title) {
if(tiddler.hasField("module-type")) {
// Modules in draft tiddlers are disabled
if(tiddler.hasField("module-type") && (!tiddler.hasField("draft.of"))) {
switch(tiddler.fields.type) {
case "application/javascript":
// We only define modules that haven't already been defined, because in the browser modules in system tiddlers are defined in inline script
@ -1557,6 +1560,11 @@ $tw.Wiki.prototype.defineShadowModules = function() {
this.eachShadow(function(tiddler,title) {
// Don't define the module if it is overidden by an ordinary tiddler
if(!self.tiddlerExists(title) && tiddler.hasField("module-type")) {
if(tiddler.hasField("draft.of")) {
// Report a fundamental problem
console.warn(`TiddlyWiki: Plugins should not contain tiddlers with a 'draft.of' field: ${tiddler.fields.title}`);
return;
}
// Define the module
$tw.modules.define(tiddler.fields.title,tiddler.fields["module-type"],tiddler.fields.text);
}
@ -2350,6 +2358,7 @@ $tw.loadTiddlersNode = function() {
});
// Load the core tiddlers
$tw.wiki.addTiddler($tw.loadPluginFolder($tw.boot.corePath));
$tw.wiki.addTiddler($tw.loadPluginFolder($tw.boot.coreServerPath));
// Load any extra plugins
$tw.utils.each($tw.boot.extraPlugins,function(name) {
if(name.charAt(0) === "+") { // Relative path to plugin
@ -2423,6 +2432,7 @@ $tw.boot.initStartup = function(options) {
// System paths and filenames
$tw.boot.bootPath = options.bootPath || path.dirname(module.filename);
$tw.boot.corePath = path.resolve($tw.boot.bootPath,"../core");
$tw.boot.coreServerPath = path.resolve($tw.boot.bootPath,"../core-server");
// If there's no arguments then default to `--help`
if($tw.boot.argv.length === 0) {
$tw.boot.argv = ["--help"];

View file

@ -0,0 +1,5 @@
title: Community Cards Caveats
created: 20250909171928024
modified: 20250909171928024
''Please note that [[Community Cards]] are a new initiative started in September 2025. There is further work required to complete the team and people information.''

View file

@ -0,0 +1,11 @@
title: Community Cards
tags: Community
modified: 20250909171928024
created: 20250909171928024
The purpose of Community Cards is to allow project plans and other community activities to be linked to the people who are involved in them. They also allow people to share their interests and activities in the TiddlyWiki community, and to help people in the TiddlyWiki community get to know each other better.
{{Community Cards Caveats}}
* [[Submitting a Community Card]]
* [[Displaying Community Cards]]

View file

@ -0,0 +1,26 @@
title: Displaying Community Cards
tags: [[Community Cards]]
modified: 20250909171928024
created: 20250909171928024
!! Cards for people
This is an inline card for <<community-card-pill-person title:"@Jermolene">> and <<community-card-pill-person title:"@ericshulman">> which can be used in the middle of a sentence.
This is a stack of inline cards:
<<community-card-pill-stack-person>>
Here is a full format card:
<<community-card-person title:"@Jermolene">>
This is how the card looks when there is no such person:
<<community-card-person title:"@MissingPerson">>
!! Cards for teams
This is a card for a project team:
<<community-card-team title:"Project Team">>

View file

@ -0,0 +1,36 @@
title: Submitting a Community Card
tags: [[Community Cards]]
modified: 20250909171928024
created: 20250909171928024
Anyone associated with the TiddlyWiki community can submit a Community Card. The submission process currently involves making a GitHub pull request but we intend to provide a more user-friendly submission process in the future.
Pull requests to add or update a community card should be made against the `tiddlywiki-com` branch of the [[TiddlyWiki repository|https://github.com/TiddlyWiki/TiddlyWiki5]] in the directory `community/people`.
The card should be a TiddlyWiki tiddler with the following fields:
|!Field |!Required|!Description |
|`title`|Yes |The username of the person represented by the card, starting with `@` (e.g. `@Jermolene`). This is the title of the card and should be unique |
|`tags`|Yes |The tags for the card, including `Community/Person` |
|`fullname`|Yes |The full name of the person or group represented by the card |
|`avatar`|Yes |The base64 representation of the 32x32 avatar image for the person represented by the card |
|`first-sighting`|No |The date of the first sighting in the community of the person represented by the card. This should be in ISO 8601 format (YYYY-MM-DD) |
|`talk.tiddlywiki.org`|Yes |The username of the person or group on the TiddlyWiki Talk forum |
|`github`|No |The username of the person or group on GitHub |
|`linkedin`|No |The URL of the LinkedIn profile for the person or group represented by the card |
|`flickr`|No |The URL of the Flickr profile for the person or group represented by the card |
|`homepage`|No |The URL of the homepage for the person or group represented by the card |
|`email`|No |The email address of the person or group represented by the card |
|`text`|Yes |The text of the card. This should include a brief description of the person or group represented by the card, and any other relevant information |
! Rules for Community Cards
Community cards must observe the following rules. It is intended to enforce them with an automated script, but for the moment they will be manually checked.
* `title` must be unique and start with `@`
* `tags` must include `Community/Person`
* `fullname` must be provided
* `avatar` must be a base64 representation of a 32x32 image, with a limit of 1KB. [[Squoosh|https://squoosh.app/]] is recommended for resizing and compressing images
* `first-sighting` should be in ISO 8601 format (YYYY-MM-DD)
* `talk.tiddlywiki.org` must be provided
* `text` total size must not exceed 2KB

View file

@ -0,0 +1,10 @@
title: @Arlen22
tags: Community/Person
fullname: Arlen Beiler
first-sighting: 2011-06-20
talk.tiddlywiki.org: arlen22
github: Arlen22
homepage: arlen22.github.io
avatar: /9j/4AAQSkZJRgABAQAAAQABAAD/2wEEEAAVABUAFQAVABYAFQAYABoAGgAYACEAIwAfACMAIQAwAC0AKQApAC0AMABJADQAOAA0ADgANABJAG8ARQBRAEUARQBRAEUAbwBiAHcAYQBaAGEAdwBiALEAiwB7AHsAiwCxAMwArACiAKwAzAD4AN0A3QD4ATgBKAE4AZcBlwIkEQAVABUAFQAVABYAFQAYABoAGgAYACEAIwAfACMAIQAwAC0AKQApAC0AMABJADQAOAA0ADgANABJAG8ARQBRAEUARQBRAEUAbwBiAHcAYQBaAGEAdwBiALEAiwB7AHsAiwCxAMwArACiAKwAzAD4AN0A3QD4ATgBKAE4AZcBlwIk/8IAEQgAQABAAwEiAAIRAQMRAf/EADAAAAIDAQEAAAAAAAAAAAAAAAMFAQQGAgABAQEBAQEAAAAAAAAAAAAAAAIDAQAE/9oADAMBAAIQAxAAAADIRMd3XctQlXtCTTmB6RFvANDouy4DYwEEar6YVM7ocz57mcqnZys+V2azZU4XZSoiZqhQt9TKOlnO+GOl1HyoUPXLn//EACYQAAICAQQCAgEFAAAAAAAAAAECABEDBBIhMUFRECITFCMycZH/2gAIAQEAAT8AI4Bv4ryAeBAnANHuNidWogEwYHNRsdfA8iruVMOIu6iYtK4c714vgTDpXyOfrQHdifoArEXxM2mR0NeOhUzI+LJzYbuHszCm5hYseZh0gXYWFIai4cWJgFJuFKYvtr2sJRuB9fUzgDHlGMHia2757uYsYc0TNHpsSmzzMONjl9iu74iK6PbWT7gv/RMiZDk+qcA3NXkAVl3gE+ADU1PDVdiaDCGJZjQEyowKANS1ZMwK+HJ+3a0KUDqYnYINxJ3eItDk81M2cZD+NVIrmanU/wAl2gCZiGNiaFziJ3LYIHcXMrLvDABe17EN1vCgqR2TNPnGTBSBbDTeV3c2amdlxPuD2C3H9epqmV628xqsUYmdiuwkVVTSZ0Q/dxwYdScrgBRsqONi2KQX7mo1G4WCK20B6j6p/VpcfMXPVQ9mbhx9eLgZrFGDUZB1DqMrCma4xN8mDcR5qK5Rgw7Hx//EABwRAQEBAQACAwAAAAAAAAAAAAECABEDIhIxQf/aAAgBAgEBPwDVQYpfzd66qDeOSn7yEmH23ffDAi66mug6DM9N8HTAY3//xAAcEQEBAQEAAgMAAAAAAAAAAAABAAIREBIiQVH/2gAIAQMBAT8AglC+rJbdCT1vVC33l83tj2OPLS+AJ3+Tf//Z
I make random software.

View file

@ -0,0 +1,29 @@
title: @ericshulman
tags: Community/Person Community/Team/Contributors
fullname: Eric Shulman
first-sighting: 2005-06-21
talk.tiddlywiki.org: ericshulman
github: ericshulman
homepage: tiddlytools.com
email: elsdesign@gmail.com
avatar: iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAD/ElEQVR42o2Tf2iUdRzH37e7rOa222233bab3mqKU9QihCAi+isKwX/sh5UQhGYQhNAvQowRUoghQWDOIJtQmOY0M92ZmVGm0WbTyZI1Nnft99S1jc3dPT9efffg/bHdLn19Hp4HPjzv9/fz+fL5aE58PwUkjzzFVC4P/G/k6E445Pc+uceeaqnv7Ogd6Rq68PPhrc+vkiERWOLT/+Ib8uQHNiXax3BIM0mC+CEtl2G7X9mIeCV+9Ejrr2MAtgkH14SNBRZXrYYPNF86nsXCkx/8dATAsp0JhknQTYJrTHg5SNI0qMekb+aw8Hr74WCKpNNu/0Kck5ymkRMcZz/1Jv5g2CUFbZYelrbMvlBMonHvJK3JuPsdTQxwExc8XG7SxF7OcxGScP6wRGCG/Asjf39VPydTzbQyRBrXBKToBCP/nQQ9VpIDO6SumU3EjUFLzX766HMG0mIvoJnXEbU47GGXc4TGBs3zWp5Jh7F47omdf56hy9lLIz3gyYfZSQMJztFEH3KEDg+bf1dkzkO9Savks7H9NLqnuEw3MEU314nTwABj/MV2R6y8JL+0wKdM8MtX23aFy04dF5mg08QI6XYsemmzRfiMDP5Mg1emK4ienZxi0p0gBfRwhSHAxgXGGeS6tYUdu6TPA3Ofr3Mfj9Bv4zHMDaCTMcBlnG4cJqx64sagN9Ngw3RJoa5R+MftI8k1Wm7NcSsH6KKPFGBbG1n1srQ+06DWpJ59cRhsGKGbo0wBFpDgNGcBcHGsl9BuSZmjfCRHWnv0BtgOcJVWwAZG2cw+3uErAKacZ6hq32PkGWuNSaxsHgIHxqjje5I4/Ms2dCt+BHpcUT4ai0j5sw22TCea2sCBbz3BOjaRFj+JeAE46IoHxlUmlfrmWuZT+8Ae935fjljDe3zpLdEJxGriLHdFtL8mKC2cbbAgIOXVBemwBhHibZq4xN/0YgPrESsRsiMs+C1zEwwFxqBqs4hY2yhlKeIUab5GLEM8SLlVRslu77jZhEwL/ofKKZ4uknxiiLO0cYFGFpJPMTGiRO0iQqtNrX7NxueTcahqv4/FTpgwFYinOcoxtiLKWEwF+U6Mqv5FuVlWSQHzvBWmKmUqIEg1YiMfIu6lhjKCRK0YkXelwoDmIjztWrCot5KQs5R5zKccIVZQwl3cTaVdQVGnfOkrzFbDuvuJWTVuBcXcQ5iFlFFAmBynlBKKH/f6z06pX6r6pJoSQlaeW2gsighi3na1E6HwNSkUUHbS45FXG7ajhIi68+1cO98qtqqJEHzTW6LbEfUstER1ef2llBKhiGqKW7VGUk6lT7dnmS/gnZMf1KPaoI16VWsrA1KhX3dObo5m9VqQpff/AFTcI4hMzFV+AAAAAElFTkSuQmCC
\define wiki(text,topic) [[$text$|https://en.wikipedia.org/wiki/$topic$]]
''Hello! My name is Eric Shulman''. I am the author of ''[[www.TiddlyTools.com|http://www.TiddlyTools.com]] (Small Tools for Big Ideas! &trade;)'', a popular collection of original plugins, macros, widgets, templates and stylesheets for TiddlyWiki that I have created and shared with the TiddlyWiki community.
<<<
Think of TiddlyTools as a ''virtual hardware store and "demonstration showroom"'', offering tools, parts and techniques that provide a rich variety of new functionality and feature enhancements to help you ''turn a general-purpose TiddlyWiki "info-house" into a comfortable, custom-built "info-home"''.
The TiddlyWiki core system provides the basic structure and utilities: the foundation, framing, walls, roof, windows/doors, plumbing, heating, and electrical systems. Then, TiddlyTools helps you with all the "finish work": the appliances, fixtures, lighting, cabinets, furniture, paint, wallpaper, carpeting, etc. ''to best suit your specific needs and personal style''.
<<<
Since the early days of TiddlyWiki (April 2005), I have worked closely with its inventor, [[Jeremy Ruston|https://jermolene.com/]], to help develop and improve TiddlyWiki's core functions. I am also a key contributor and administrator of the online TiddlyWiki [[Discourse|https://talk.TiddlyWiki.org]] and [[GoogleGroups|https://groups.google.com/forum/#!forum/tiddlywiki]] discussion forums, providing ongoing assistance to the worldwide TiddlyWiki community. I have written over 15,000 detailed responses to individual questions posted online. For several years I was also the lead developer and maintainer of the [[TiddlyWiki Classic|https://classic.tiddlywiki.com/]] codebase.
I was born and raised in suburban Long Island, NY, and attended [[Carnegie Mellon University (CMU)|https://www.cmu.edu/]] in Pittsburgh, PA, where I studied ''Computer Science, Cognitive Psychology, Sociology, Human Factors Design, and Artificial Intelligence''. As an undergraduate at CMU, I was privileged to work with some of the major luminaries in early software research and design, including <<wiki "Herbert Simon" "Herbert_A._Simon">>, <<wiki "Allen Newell" "Allen_Newell">>, <<wiki "James Gosling" "James_Gosling">>, and <<wiki "Raj Reddy" "Raj_Reddy">>. I was also employed in several Computer Science Department research projects, including the development of speech recognition technologies, graphical interface systems, and interactive applications for instruction in physics, art and music. I received a ''Bachelor of Science in "Interactive Systems Design"'' from CMU in 1985.
During my early post-graduate years, I worked for several notable software development companies, including
<<wiki "Honeywell Information Systems" "Honeywell#Honeywell_Information_Systems">> and <<wiki "Lotus Software" "Lotus_Software">>. I was an integral member of the <<wiki "1-2-3 spreadsheet"
"Lotus_1-2-3">> development team where I helped create the first GUI-based application interfaces for Microsoft Windows and IBM OS/2.
Since 1998, I have been an ''independent design consultant'', living and working in Silicon Valley, where I apply more than 40 years of experience to provide ''analysis, design and software development services'' for commercial companies and not-for-profit organizations, with emphasis on ''information architecture'' and ''interaction/visual design standards'' to improve ease-of-use for new and existing software products and online environments.

View file

@ -0,0 +1,21 @@
title: @Jermolene
tags: Community/Person
fullname: Jeremy Ruston
first-sighting: 2004-09-20
talk.tiddlywiki.org: jeremyruston
github: Jermolene
linkedin: www.linkedin.com/in/jermy
flickr: www.flickr.com/photos/jermy/
bluesky: https://bsky.app/profile/jermolene.bsky.social
homepage: jermolene.com
email: jeremy@jermolene.com
avatar: /9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAgICAgJCAkKCgkNDgwODRMREBARExwUFhQWFBwrGx8bGx8bKyYuJSMlLiZENS8vNUROQj5CTl9VVV93cXecnNEBCAgICAkICQoKCQ0ODA4NExEQEBETHBQWFBYUHCsbHxsbHxsrJi4lIyUuJkQ1Ly81RE5CPkJOX1VVX3dxd5yc0f/CABEIACAAIAMBIgACEQEDEQH/xAAtAAEBAAMAAAAAAAAAAAAAAAAHBgIEBQEBAQEBAAAAAAAAAAAAAAAAAgQBBf/aAAwDAQACEAMQAAAANF4uTuPRhD2nBLnUiJvKM0DtMKy//8QAKxAAAgIBAwMDAQkAAAAAAAAAAQIDBBEABRITITEiMkFxFEJRUmFicoGR/9oACAEBAAE/AInTA6gUGP4ZOQbW1bPsmyUq1q+gmvFPUzZPDkPamtwqU75ks04JakroVcg5RwRjg66NUx25KbzqJYyMngfqSuq0M3NZYIebJIvZozIvI/iNPcp/aalSdJXsS4VcKeIzlvU3jVTcYLNiaGISrjkhWQYDfQ63pYAzCDBsOiu7Dsx4EHH6r2w2ttimjd2IsNErhhJHKI04/uzqxuCxpBYVVWKSHqwMyMSQ33SB7dUJFmlkMYRgnqZgCMf7rf8AeEt3A9YOhjXAb2k8u7dtT1RZeOtXmYxiOPj4ZWY/lb51skqUNnNW/wBNzC7IpB6gQeeB/jq/fqGOaLbowuYn5MAQOw8LjW5Vmeo0qIsqYLLKjHIZmwv9fB1//8QAHxEAAQMEAwEAAAAAAAAAAAAAEQABAgMSIWExMkFR/9oACAECAQE/AD9iTy2lJmHUB8BVKM4SNSOj46a29saX/8QAHREAAgICAwEAAAAAAAAAAAAAAQIAAwQRITGBkf/aAAgBAwEBPwDHpFpJZtamVSiBWT2Yt7hmCDsb+TKtsKqpGg3M/9k=
I'm the original inventor of TiddlyWiki. You can hire me through my consultancy company [[Intertwingled Innovations|https://intertwingledinnovations.com]] or contact me directly.
Further information:
* A recording of the [[keynote I gave at QCon London in April 2024|https://www.infoq.com/presentations/bbc-micro/]], and the [[discussion on talk.tiddlywiki.org|https://talk.tiddlywiki.org/t/recording-of-jeremys-keynote-at-qcon-london-april-2024/10505]]. The talk mixes some nostalgia about my teenage activities with the BBC Micro with thoughts on the development of the software industry and insights gained from working with TiddlyWiki
* An [[interview with me in The Inquirer|https://web.archive.org/web/20111103225832/http://www.theinquirer.net/inquirer/feature/2105529/bt-software-engineer-tells-telco-source]] by Wendy Grossman
* A [[hilarious interview with me|https://www.youtube.com/watch?v=auyIhw8MTmQ]] from British television in 1983
* Here's a video of a presentation I did in 2007 called [["How to Start an Open Source Project"|http://vimeo.com/856110]].

View file

@ -0,0 +1,11 @@
title: @MotovunJack
tags: Community/Person Community/Robot
fullname: Motovun Jack
first-sighting: 2012-01-12
github: MotovunJack
homepage: tiddlywiki.com
avatar: /9j/4AAQSkZJRgABAQAAAQABAAD/2wEEEAAYABgAGAAYABkAGAAaAB0AHQAaACUAKAAjACgAJQA2ADIALgAuADIANgBSADsAPwA7AD8AOwBSAH0ATgBbAE4ATgBbAE4AfQBuAIYAbQBlAG0AhgBuAMYAnACKAIoAnADGAOUAwQC2AMEA5QEWAPgA+AEWAV4BTAFeAckByQJmEQAYABgAGAAYABkAGAAaAB0AHQAaACUAKAAjACgAJQA2ADIALgAuADIANgBSADsAPwA7AD8AOwBSAH0ATgBbAE4ATgBbAE4AfQBuAIYAbQBlAG0AhgBuAMYAnACKAIoAnADGAOUAwQC2AMEA5QEWAPgA+AEWAV4BTAFeAckByQJm/8IAEQgAQABAAwEiAAIRAQMRAf/EADAAAAIDAQEAAAAAAAAAAAAAAAMEAQIFBgABAQEBAQEAAAAAAAAAAAAAAAIDAQAE/9oADAMBAAIQAxAAAADZCfn5vZJz+rnODGtpbpm6O8xzG9lCiszXtikQhtkTBputBxURJuVVYlEdBaQ284mPDj6GmkNUblMxRmi7dKw//8QAKxAAAgIBAgUCBgMBAAAAAAAAAQIAAxESIQQTIkFRFGEjMUJxgaEyNGLR/9oACAEBAAE/AMmX3ilMkjPaV3ragZDtNRmoxpvA2sEqQcHEwJxlwa98nYbCU8TymDfSTvPVKMbZHkQcTU4yDH46tTiE8RxjLXnQp7Dx5MACgKuyqMAS1xXU7kjYTiEbWp3y0IucYbGx6e05hDAqMH/k59o3DfxAE5hss1MNzODdVraxu50ieppH1Tivi8O6eYQ1j4B6guAftChDMNjBqycHcCYJqdj2s3idRBHfpi/1Kie7PDo95w/EMxYM22n9yy5AzBc/iLe7dIqx7kyy2ypyOWoYTofhCyDAZtx4MOmpK9sncyx1NdSq2kBBt3EKf6mgIzDUPIiByuqk7faMLbOyEjuuxEAyo56AgeTA3KL1AYRm1CcvmkgAs2wHjEvPxGIMJPmHUQCQNothr32A0ggeYluplcAK2PlLbTytZUkdwI7V3lAQMgbAfP8AMoCV1AKMOR+pdsc5yD595mMmNIGD4h0vsfupHyBlTKW9znMd+TQnljPWqHYIqhwD1zKsqtjBzCAVAyBicnqG6jbOe0//xAAbEQEBAAMBAQEAAAAAAAAAAAABAAIRIRASQf/aAAgBAgEBPwBYbZDuXvnLE5OrkWJzxI4g33ift//EABsRAAMBAQADAAAAAAAAAAAAAAABEQIhEBJB/9oACAEDAQE/AMqjzHwjGoZXPHTb6Zp1/TRp1khYjW01xHqz/9k=
Motovun Jack is a robot that helps maintain the TiddlyWiki project infrastructure. It is not a person, but rather a set of automated scripts and tools that assist in managing the various services and resources used by the TiddlyWiki community.
The origin of the name "Motovun Jack" is a lovable and playful kitten encountered by [[@Jermolene]] in the beautiful medieval hill town of Motovun in Croatia. Jack was [[first adopted|https://github.com/TiddlyWiki/TiddlyWiki5/commit/ecfbaaa5641f14e1766ef17ef6416bf9aa992863]] as the TiddlyWiki 5 mascot in 2012.

View file

@ -0,0 +1,10 @@
title: TiddlyWiki People
modified: 20250909171928024
created: 20250909171928024
tags: Community About
Members of the TiddlyWiki community who are involved in the development of TiddlyWiki and the running of the project are invited to [[create a Community Card|Submitting a Community Card]] so that they can be included in project plans and organisation charts. Community Cards can also showcase their interests and activities in the TiddlyWiki community.
{{Community Cards Caveats}}
<<community-card-pill-stack-person personFilter:"[tag[Community/Person]sort[title]]">>

View file

@ -0,0 +1,10 @@
title: TiddlyWiki Project
modified: 20250909171928024
created: 20250909171928024
tags: Community About
The TiddlyWiki Project is the coordinated, ongoing effort to maintain and improve TiddlyWiki, and to support the TiddlyWiki community.
{{Community Cards Caveats}}
<$list filter="[tag[Community/Team]]" template="$:/tiddlywiki/community/cards/ViewTemplateBodyTemplateTeam"/>

View file

@ -0,0 +1,4 @@
title: Vacant Positions
tags: [[TiddlyWiki Project]]
If you are interested in volunteering to help the project please get in touch with <<community-card-pill-person title:"@Jermolene">>.

View file

@ -0,0 +1,8 @@
title: Core Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
leader: @Jermolene
team: @saqimtiaz
The core team is responsible for the maintenance and development of the TiddlyWiki core and official plugins.

View file

@ -0,0 +1,14 @@
title: Infrastructure Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
team: @MotovunJack
The Infrastructure Team is responsible for maintaining and improving the infrastructure that supports the TiddlyWiki project. This includes the hosting, deployment, and management of the TiddlyWiki websites and services, as well as the tools and systems used by the TiddlyWiki community.
The infrastructure includes:
* talk.tiddlywiki.org
* github.com/TiddlyWiki
* tiddlywiki.com DNS
* Netlify account for PR previews

View file

@ -0,0 +1,8 @@
title: MultiWikiServer Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
leader: @Arlen22
team:
The MultiWikiServer development repository is at https://github.com/TiddlyWiki/MultiWikiServer

View file

@ -0,0 +1,6 @@
title: Newsletter Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
The Newsletter Team is responsible for producing the TiddlyWiki Newsletter, a monthly email newsletter that highlights news, updates, and community contributions related to TiddlyWiki.

View file

@ -0,0 +1,15 @@
title: Project Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
icon: $:/tiddlywiki/community/icons/project-team
leader: @Jermolene
team: @saqimtiaz @ericshulman
The project team is responsible for the overall TiddlyWiki project, its vision, mission and values, and ensuring that it meets the needs of the community.
Areas of responsibility include:
* Communicating and demonstrating the vision, mission and values of the project
* Continuously improve the development process and practices of the project
* more to come...

View file

@ -0,0 +1,13 @@
title: Succession Team
tags: Community/Team
modified: 20250909171928024
created: 20250909171928024
leader: @Jermolene
team: @saqimtiaz @ericshulman
The Succession Team is responsible for ensuring that personnel changes do not impact access to the external infrastructure used by the project.
* Work with the other teams to ensure that the project has a succession plan for key personnel
* Work with the other teams to ensure that they are using the appropriate, community-owned infrastructure
* Ensure that the members of the succession team share ownership of the key project resources (eg passwords and user accounts). The Succession Team is not expected to use their access rights apart from managing access in the event of personnel changes

View file

@ -0,0 +1,5 @@
title: Community/Team
modified: 20250909171928024
created: 20250909171928024
list: [[Project Team]] [[Core Team]] [[Documentation Team]] [[MultiWikiServer Team]] [[Newsletter Team]] [[Infrastructure Team]] [[Succession Team]]

3
community/readme.md Normal file
View file

@ -0,0 +1,3 @@
# Community Records and Resources
These raw tiddlers comprise the community records and resources for the TiddlyWiki project. They are packaged as a root directory outside of the usual "editions" folder so that they can be shared with other wikis.

View file

@ -0,0 +1,15 @@
title: $:/config/DefaultColourMappings/
community-card-background: #ffffee
community-card-foreground: #441111
community-card-dark-shadow: rgba(188, 189, 189, 0.5)
community-card-shadow: rgba(212, 212, 213, 0.5)
community-card-header-background: #9e3060
community-card-header-foreground: #ddddee
community-card-team-header-background: #306090
community-card-team-header-foreground: #ddeedd
community-card-vacancy-header-background: #609030
community-card-vacancy-header-foreground: #eedddd
community-card-info-background: #f3f38b
community-card-info-foreground: #444411
community-card-field-name-foreground: #888844

View file

@ -0,0 +1,168 @@
title: $:/tiddlywiki/community/cards/Procedures
tags: $:/tags/Global
\procedure community-card-display-jpeg-field(fieldName,mode:"block",default)
<$genesis $type={{{ [<mode>match[block]then[div]else[span]] }}} class={{{ tc-community-card-field-image [[tc-community-card-field-image-]addsuffix<fieldName>] +[join[ ]] }}}>
<%if [<currentTiddler>has<fieldName>] %>
<img src={{{ [<currentTiddler>get<fieldName>addprefix[data:image/jpeg;base64,]] }}} width="32"/>
<%else%>
<$transclude $tiddler=<<default>> $mode=<<mode>>/>
<%endif%>
</$genesis>
\end community-card-display-jpeg-field
\procedure community-card-display-transclusion(fieldName,mode:"inline",default)
<$genesis $type={{{ [<mode>match[block]then[div]else[span]] }}} class={{{ tc-community-card-field-image [[tc-community-card-field-image-]addsuffix<fieldName>] +[join[ ]] }}}>
<%if [<currentTiddler>has<fieldName>] %>
<$transclude $tiddler={{{ [<currentTiddler>get<fieldName>] }}} $mode=<<mode>>/>
<%else%>
<$transclude $tiddler=<<default>> $mode=<<mode>>/>
<%endif%>
</$genesis>
\end community-card-display-transclusion
\procedure community-card-display-text-field(fieldName,showLabel:"yes",linkPrefix,displayPrefix,mode:"block")
<%if [<currentTiddler>has<fieldName>] :or[<fieldName>match[title]] %>
<$genesis $type={{{ [<mode>match[block]then[div]else[span]] }}} class={{{ tc-community-card-field-text [[tc-community-card-field-text-]addsuffix<fieldName>] +[join[ ]] }}}>
<%if [<showLabel>match[yes]] %>
<span class="tc-community-card-field-text-name"><$text text=<<fieldName>>/></span>
<%endif%>
<%if [<linkPrefix>!match[]] %>
<a
href={{{ [<currentTiddler>get<fieldName>addprefix<linkPrefix>] }}}
class="tc-community-card-field-text-value"
rel="noopener noreferrer"
target="_blank"
>
<$text text={{{ [<currentTiddler>get<fieldName>] :else[<fieldName>match[title]then<currentTiddler>] +[addprefix<displayPrefix>] }}}/>
</a>
<%else%>
<span class="tc-community-card-field-text-value">
<$text text={{{ [<currentTiddler>get<fieldName>] :else[<fieldName>match[title]then<currentTiddler>] +[addprefix<displayPrefix>] }}}/>
</span>
<%endif%>
</$genesis>
<%endif%>
\end community-card-display-text-field
\procedure community-card-person(title)
<$let currentTiddler=<<title>>>
<div class="tc-community-card">
<$link to=<<currentTiddler>> class="tc-community-card-header-link">
<div class="tc-community-card-header">
<<community-card-display-jpeg-field "avatar" default:"$:/tiddlywiki/community/icons/person">>
<<community-card-display-text-field "title" showLabel:"no">>
</div>
</$link>
<div class="tc-community-card-info">
<<community-card-display-text-field "fullname">>
<<community-card-display-text-field "first-sighting">>
<<community-card-display-text-field "talk.tiddlywiki.org" linkPrefix:"https://talk.tiddlywiki.org/u/" displayPrefix:"@">>
<<community-card-display-text-field "github" linkPrefix:"https://github.com/" displayPrefix:"@">>
<<community-card-display-text-field "linkedin" linkPrefix:"https://">>
<<community-card-display-text-field "flickr" linkPrefix:"https://">>
<<community-card-display-text-field "homepage" linkPrefix:"https://">>
<<community-card-display-text-field "email" linkPrefix:"mailto:">>
<%if [all[tiddlers+shadows]tag[Community/Team]sort[title]] :filter[{!!leader}match<..currentTiddler>] +[count[]compare:number:gt[0]] %>
<div class="tc-community-card-field-text">
<span class="tc-community-card-field-text-name">leader</span>
<span class="tc-community-card-field-text-value">
<$list filter="[all[tiddlers+shadows]tag[Community/Team]sort[title]] :filter[{!!leader}match<..currentTiddler>]">
<$transclude $variable="community-card-pill-team" title=<<currentTiddler>>/>
</$list>
</span>
</div>
<%endif%>
<%if [all[tiddlers+shadows]tag[Community/Team]sort[title]] :filter[enlist{!!team}match<..currentTiddler>] +[count[]compare:number:gt[0]] %>
<div class="tc-community-card-field-text">
<span class="tc-community-card-field-text-name">member</span>
<span class="tc-community-card-field-text-value">
<$list filter="[all[tiddlers+shadows]tag[Community/Team]sort[title]] :filter[enlist{!!team}match<..currentTiddler>]">
<$transclude $variable="community-card-pill-team" title=<<currentTiddler>>/>
</$list>
</span>
</div>
<%endif%>
</div>
<div class="tc-community-card-body">
<$transclude $tiddler=<<currentTiddler>> $field="text" $mode="block"/>
</div>
</div>
</$let>
\end community-card-person
\procedure community-card-team(title)
<$let currentTiddler=<<title>>>
<div class="tc-community-card tc-community-card-team">
<$link to=<<currentTiddler>> class="tc-community-card-header-link">
<div class="tc-community-card-header">
<<community-card-display-transclusion fieldName:"icon" default:"$:/tiddlywiki/community/icons/team">>
<<community-card-display-text-field "title" showLabel:"no">>
</div>
</$link>
<div class="tc-community-card-info">
<div class="tc-community-card-field-text">
<span class="tc-community-card-field-text-name">leader</span>
<span class="tc-community-card-field-text-value">
<%if [<currentTiddler>has[leader]] %>
<$transclude $variable="community-card-pill-person" title={{!!leader}}/>
<%else%>
<$transclude $variable="community-card-vacancy"/>
<%endif%>
</span>
</div>
<div class="tc-community-card-field-text">
<span class="tc-community-card-field-text-name">team</span>
<span class="tc-community-card-field-text-value"><$transclude $variable="community-card-pill-stack-person" personFilter={{!!team}}/></span>
</div>
</div>
<div class="tc-community-card-body">
<$transclude $tiddler=<<currentTiddler>> $field="text" $mode="block"/>
</div>
</div>
</$let>
\end community-card-team
\procedure community-card-pill-person(title)
<$let currentTiddler=<<title>>>
<$link to=<<currentTiddler>> class="tc-community-card-pill">
<<community-card-display-jpeg-field "avatar" default:"$:/tiddlywiki/community/icons/person" mode="inline">>
<<community-card-display-text-field "title" showLabel:"no" mode:"inline">>
</$link>
</$let>
\end community-card-pill-person
\procedure community-card-pill-stack-person(personFilter:"[tag[Community/Person]]")
<div class="tc-community-card-pill-stack">
<$list filter=<<personFilter>>>
<$list-template>
<$transclude $variable="community-card-pill-person" title=<<currentTiddler>> mode="block"/>
</$list-template>
<$list-empty>
<$transclude $variable="community-card-vacancy"/>
</$list-empty>
</$list>
</div>
\end community-card-pill-stack-person
\procedure community-card-pill-team(title)
<$let currentTiddler=<<title>>>
<$link to=<<currentTiddler>> class="tc-community-card-pill">
<<community-card-display-transclusion fieldName:"icon" default:"$:/tiddlywiki/community/icons/team">>
<<community-card-display-text-field "title" showLabel:"no" mode:"inline">>
</$link>
</$let>
\end community-card-pill-team
\procedure community-card-vacancy()
<$link to="Vacant Positions" class="tc-community-card-pill tc-community-card-pill-vacancy">
<span class="tc-community-card-field-image tc-community-card-field-image-avatar">
{{$:/core/images/help}}
</span>
<span class="tc-community-card-field-text tc-community-card-field-text-title">
<span class="tc-community-card-field-text-value">
Vacant
</span>
</span>
</$link>
\end community-card-vacancy

View file

@ -0,0 +1,158 @@
title: $:/tiddlywiki/community/cards/Styles
tags: $:/tags/Stylesheet
.tc-community-card {
display: flex;
flex-direction: column;
flex-wrap: wrap;
justify-content: center;
border-radius: 8px;
width: 100%;
margin-bottom: 8px;
background: <<colour community-card-background>>;
color: <<colour community-card-foreground>>;
fill: <<colour community-card-foreground>>;
box-shadow: 0 1px 3px 0 <<colour community-card-shadow>>, 0 0 0 1px <<colour community-card-shadow>>;
transition: box-shadow 0.3s ease,transform .3s ease;
}
.tc-community-card:hover {
box-shadow: 0 1px 6px 0 <<colour community-card-dark-shadow>>, 0 0 0 1px <<colour community-card-shadow>>;
transform: translateY(-2px);
}
.tc-community-card .tc-community-card-header-link {
background-color: <<colour community-card-header-background>>;
color: <<colour community-card-header-foreground>>;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
}
.tc-community-card.tc-community-card-team .tc-community-card-header-link {
background: <<colour community-card-team-header-background>>;
color: <<colour community-card-team-header-foreground>>;
fill: <<colour community-card-team-header-foreground>>;
}
.tc-community-card .tc-community-card-header-link:hover {
text-decoration: none;
background-color: <<colour community-card-header-foreground>>;
color: <<colour community-card-header-background>>;
}
.tc-community-card-header {
margin: 0;
padding: 0.5em;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
justify-content: flex-start;
align-items: center;
line-height: 0;
}
.tc-community-card-header .tc-community-card-field-text-title {
font-size: 1.5em;
font-weight: bold;
}
.tc-community-card-header .tc-community-card-field-image {
display: table-row;
width: auto;
max-width: 100%;
margin-right: 12px;
}
.tc-community-card-info {
display: table;
width: auto;
max-width: 100%;
padding: 8px;
margin: 0;
background-color: <<colour community-card-info-background>>;
color: <<colour community-card-info-foreground>>;
}
.tc-community-card-body {
padding: 0 8px;
}
.tc-community-card .tc-community-card-field-text {
display: table-row;
}
.tc-community-card .tc-community-card-field-text-name,
.tc-community-card .tc-community-card-field-text-value {
display: table-cell;
padding: 2px 6px 2px 0;
vertical-align: top;
}
.tc-community-card .tc-community-card-field-text-name {
color: <<colour community-card-field-name-foreground>>;
white-space: nowrap;
text-align: right;
padding-right: 8px;
}
.tc-community-card .tc-community-card-field-text-value {
word-break: break-word;
font-weight: bold;
width: 100%;
}
a.tc-community-card-pill {
display: inline-flex;
align-items: center;
gap: 4px;
width: auto;
min-width:0;
max-width: none;
align-self: auto;
font-size: 0.9em;
line-height: 1;
vertical-align: middle;
padding: 4px;
border-radius: 4px;
background: <<colour community-card-header-background>>;
color: <<colour community-card-header-foreground>>;
fill: <<colour community-card-header-foreground>>;
box-shadow: 0 1px 3px 0 <<colour community-card-shadow>>, 0 0 0 1px <<colour community-card-shadow>>;
transition: box-shadow 0.3s ease,transform .3s ease;
}
a.tc-community-card-pill.tc-community-card-pill-vacancy {
background: <<colour community-card-vacancy-header-background>>;
color: <<colour community-card-vacancy-header-foreground>>;
fill: <<colour community-card-vacancy-header-foreground>>;
}
a.tc-community-card-pill:hover {
text-decoration: none;
box-shadow: 0 1px 6px 0 <<colour community-card-dark-shadow>>, 0 0 0 1px <<colour community-card-shadow>>;
transform: translateY(-2px);
background: <<colour community-card-header-foreground>>;
color: <<colour community-card-header-background>>;
fill: <<colour community-card-header-background>>;
}
a.tc-community-card-pill .tc-community-card-field-image img,
a.tc-community-card-pill .tc-community-card-field-image svg {
width: 16px;
height: 16px;
vertical-align: middle;
display: inline-block;
}
a.tc-community-card-pill .tc-community-card-field-text {
display: inline;
}
.tc-community-card-pill-stack {
display: inline-flex;
flex-direction: column;
align-items: stretch;
gap: 4px;
margin: 0;
padding: 0;
}

View file

@ -0,0 +1,6 @@
title: $:/tiddlywiki/community/cards/ViewTemplateBodyCascade
tags: $:/tags/ViewTemplateBodyFilter
list-before:
[tag[Community/Person]then[$:/tiddlywiki/community/cards/ViewTemplateBodyTemplatePerson]]
[tag[Community/Team]then[$:/tiddlywiki/community/cards/ViewTemplateBodyTemplateTeam]]

View file

@ -0,0 +1,3 @@
title: $:/tiddlywiki/community/cards/ViewTemplateBodyTemplatePerson
<$transclude $variable="community-card-person" title=<<currentTiddler>>/>

View file

@ -0,0 +1,3 @@
title: $:/tiddlywiki/community/cards/ViewTemplateBodyTemplateTeam
<$transclude $variable="community-card-team" title=<<currentTiddler>>/>

View file

@ -0,0 +1,7 @@
title: $:/tiddlywiki/community/icons/person
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> viewBox="0 0 64 64">
<path d="M43.127,29.612c-0.879,-0.378 -1.452,-1.25 -1.452,-2.207c-0.006,-0.678 0.27,-1.33 0.761,-1.797c0.147,-0.141 0.29,-0.28 0.397,-0.393c0.753,-0.791 1.416,-1.663 1.978,-2.6c1.392,-2.318 2.126,-4.974 2.126,-7.677c0,-8.196 -6.744,-14.938 -14.938,-14.938c-0.945,0 -1.886,0.088 -2.813,0.266c-5.891,1.031 -10.578,5.586 -11.781,11.446c-1.105,5.016 0.454,10.264 4.118,13.865c0.495,0.469 0.78,1.118 0.792,1.799l0,0.012c0.008,0.966 -0.567,1.848 -1.453,2.23c-5.949,2.466 -10.698,7.172 -13.217,13.099c-1.772,4.059 -2.66,8.45 -2.607,12.88l0,3.192c0,2.858 2.351,5.211 5.212,5.211l43.5,0c2.859,0 5.212,-2.353 5.212,-5.211l-0,-3.225c0.053,-4.427 -0.837,-8.816 -2.611,-12.873c-2.523,-5.922 -7.274,-10.621 -13.224,-13.079Z" style="fill-rule:nonzero;"/>
</svg>

View file

@ -0,0 +1,7 @@
title: $:/tiddlywiki/community/icons/project-team
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> viewBox="0 0 64 64">
<path d="M24.891,49.399l-3.521,0c-1.398,0 -2.547,-1.15 -2.547,-2.547l0,-1.56c-0.026,-2.165 0.408,-4.311 1.274,-6.295c1.231,-2.897 3.552,-5.197 6.46,-6.402c0.433,-0.187 0.714,-0.618 0.71,-1.09l0,-0.006c-0.006,-0.333 -0.145,-0.65 -0.387,-0.879c-1.791,-1.76 -2.553,-4.325 -2.013,-6.777c0.588,-2.864 2.879,-5.09 5.758,-5.594c0.453,-0.087 0.913,-0.13 1.375,-0.13c4.005,0 7.301,3.295 7.301,7.301c0,1.321 -0.359,2.619 -1.039,3.752c-0.275,0.458 -0.599,0.884 -0.967,1.271c-0.052,0.055 -0.122,0.123 -0.194,0.192c-0.24,0.228 -0.375,0.547 -0.372,0.878c0,0.468 0.28,0.894 0.71,1.079c2.908,1.201 5.23,3.498 6.463,6.392c0.815,1.865 1.248,3.872 1.276,5.904c-0.179,0.006 -0.351,0.007 -0.514,0.003c-0.556,-0.016 -1.375,-0.294 -2.288,-0.512c-1.295,-0.308 -2.719,-0.543 -4.01,-0.396l-0.013,0.001c-1.056,0.128 -2.116,0.325 -3.097,0.76c-0.385,0.171 -1.216,0.753 -1.446,0.916c-1.157,0.297 -2.564,0.475 -3.797,0.312c-0.713,-0.094 -1.402,-0.225 -1.703,-0.778c-0.207,-0.382 -0.181,-0.896 -0.031,-1.565c0.068,-0.3 0.11,-0.593 0.118,-0.842l-0.106,-0.887l-0.212,-0.491l-0.258,-0.36l-0.669,-0.514l-0.832,-0.231l-0.491,0.017l-0.459,0.12l-0.417,0.211l-0.415,0.342l-0.546,0.802l-0.033,0.067c-1.174,2.499 -0.945,4.643 0.013,6.317c0.251,0.437 0.56,0.845 0.919,1.219Zm22.984,-4.722c-0.052,-2.344 -0.566,-4.656 -1.514,-6.805c-1.232,-2.86 -3.339,-5.257 -6.018,-6.845c0.955,-0.816 2.033,-1.473 3.195,-1.949c0.434,-0.187 0.715,-0.618 0.71,-1.09l-0,-0.006c-0.005,-0.333 -0.144,-0.651 -0.386,-0.88c-1.791,-1.76 -2.553,-4.324 -2.013,-6.776c0.587,-2.864 2.878,-5.09 5.758,-5.594c0.453,-0.087 0.913,-0.131 1.375,-0.131c4.005,0 7.3,3.296 7.3,7.301c-0,1.322 -0.359,2.619 -1.038,3.753c-0.276,0.457 -0.6,0.883 -0.968,1.27c-0.052,0.055 -0.121,0.123 -0.194,0.192c-0.24,0.229 -0.375,0.547 -0.372,0.878c-0,0.468 0.28,0.894 0.71,1.079c2.908,1.201 5.229,3.498 6.462,6.392c0.756,1.728 1.184,3.578 1.264,5.458c-0.577,-0.341 -1.293,-0.373 -1.904,-0.07c-0.961,0.475 -1.861,1.117 -2.911,1.371c-0.49,-0.133 -0.983,-0.245 -1.485,-0.308c-0.253,-0.326 -0.536,-0.66 -0.84,-0.911l-0.813,-0.51l-0.752,-0.225c-0.327,-0.051 -0.662,-0.021 -0.974,0.089l-0.67,0.321l-0.569,0.448c-0.403,0.393 -0.733,0.911 -0.979,1.569c-0.202,0.54 -0.344,1.222 -0.492,2.014c-0.244,-0.027 -0.49,-0.047 -0.737,-0.058c-0.333,-0.02 -0.725,-0.006 -1.145,0.023Zm-24.215,-13.651c-2.683,1.591 -4.793,3.994 -6.024,6.861c-1.026,2.332 -1.542,4.857 -1.513,7.405l0,0.59l-11.735,0c-1.397,0 -2.547,-1.15 -2.547,-2.547l0,-1.561c-0.026,-2.165 0.409,-4.31 1.274,-6.295c1.231,-2.897 3.553,-5.197 6.46,-6.401c0.434,-0.187 0.715,-0.618 0.71,-1.09l0,-0.006c-0.005,-0.333 -0.144,-0.651 -0.386,-0.88c-1.791,-1.76 -2.553,-4.324 -2.013,-6.776c0.588,-2.864 2.879,-5.09 5.758,-5.594c0.453,-0.087 0.914,-0.131 1.375,-0.131c4.005,0 7.301,3.296 7.301,7.301c0,1.322 -0.359,2.619 -1.039,3.753c-0.275,0.457 -0.6,0.883 -0.967,1.27c-0.052,0.055 -0.122,0.123 -0.194,0.192c-0.24,0.228 -0.375,0.547 -0.372,0.878c0,0.468 0.28,0.894 0.71,1.079c1.164,0.476 2.246,1.135 3.202,1.952Zm29.027,33.111c-1.417,-0.04 -2.04,-0.037 -2.761,-1.223l-0.563,0.016c-0.654,-0.029 -0.381,-0.016 -0.818,-0.038c-0.73,-0.028 -0.613,-0.722 -0.742,-1.089c-0.205,-1.244 0.272,-2.494 0.257,-3.739c-0.005,-0.442 -0.63,-2.005 -0.854,-2.564c-0.7,0.131 -1.404,0.157 -2.114,0.192c-1.637,-0.004 -3.263,-0.205 -4.878,-0.459c-0.314,1.299 -1.249,3.118 -0.476,4.439c0.938,1.366 1.596,1.745 2.617,1.827c1.02,0.082 1.251,1.234 1.004,1.646c-0.219,0.284 -0.603,0.336 -0.929,0.405l-0.653,0.03c-0.513,-0.017 -0.973,-0.155 -1.43,-0.369c-0.765,-0.427 -1.554,-1.314 -2.141,-1.951c0.137,0.254 0.218,0.751 0.095,0.982c-0.347,0.491 -1.847,0.488 -2.534,0.183c-0.78,-0.347 -2.665,-2.781 -2.957,-4.604c0.776,-1.467 1.905,-2.744 2.477,-4.341c-1.246,-0.795 -1.913,-2.089 -1.827,-3.555l0.032,-0.17c-1.226,0.23 -0.59,0.144 -1.909,0.244c-4.2,-0.013 -7.893,-2.86 -5.813,-7.286c0.135,-0.262 0.263,-0.5 0.493,-0.386c0.184,0.091 0.157,0.457 0.065,0.863c-1.189,5.288 4.621,5.329 8.192,4.35c0.355,-0.097 1.06,-0.751 1.548,-0.968c0.798,-0.354 1.665,-0.498 2.524,-0.602c2.139,-0.244 4.709,0.883 6.015,0.92c1.306,0.037 3.164,-0.313 4.305,-0.239c0.827,0.037 1.64,0.187 2.438,0.4c0.517,-2.519 0.554,-4.374 1.779,-4.804c0.719,0.113 1.273,1.093 1.683,1.617l0.002,-0c0.835,-0.033 1.63,0.178 2.42,0.414c1.431,-0.203 2.631,-1.007 3.895,-1.632c-0.004,0.02 -0.025,0.027 -0.037,0.04c-1.244,1.005 -1.417,2.706 -1.271,4.278c0.054,0.816 -0.176,1.702 -0.461,2.538c-0.534,1.361 -1.564,2.796 -2.759,2.722c-0.452,-0.014 -0.715,-0.27 -1.051,-0.543c-0.065,0.553 -0.321,1.047 -0.568,1.536c-0.57,1.086 -2.06,1.564 -3.44,2.723c-1.379,1.159 0.442,5.297 0.883,6.052c0.442,0.754 1.674,1.03 1.196,1.71c-0.147,0.225 -0.37,0.305 -0.609,0.393l-0.325,0.042Zm-15.735,-3.096l0.206,0.06c0.258,-0.115 0.778,0.064 1.054,0.151c-0.508,-0.563 -1.273,-1.389 -1.824,-1.91c-0.181,-0.631 -0.103,-1.266 -0.065,-1.91l0.008,-0.053c-0.217,0.515 -0.493,1.016 -0.641,1.559c-0.173,0.732 0.771,1.522 1.137,1.975l0.125,0.128Z"/>
</svg>

View file

@ -0,0 +1,9 @@
title: $:/tiddlywiki/community/icons/team
tags: $:/tags/Image
\parameters (size:"22pt")
<svg width=<<size>> height=<<size>> viewBox="0 0 64 64">
<path d="M37.439,32.592c-0.43,-0.185 -0.71,-0.611 -0.71,-1.079c-0.003,-0.331 0.132,-0.65 0.372,-0.878c0.072,-0.069 0.142,-0.137 0.194,-0.192c0.368,-0.387 0.692,-0.813 0.967,-1.271c0.68,-1.133 1.039,-2.431 1.039,-3.752c-0,-4.006 -3.296,-7.301 -7.301,-7.301c-0.462,-0 -0.922,0.043 -1.375,0.13c-2.879,0.504 -5.17,2.73 -5.758,5.594c-0.54,2.452 0.222,5.017 2.013,6.777c0.242,0.229 0.381,0.546 0.387,0.879l-0,0.006c0.004,0.472 -0.277,0.903 -0.71,1.09c-2.908,1.205 -5.229,3.505 -6.46,6.402c-0.866,1.984 -1.3,4.13 -1.274,6.295l-0,1.56c-0,1.397 1.149,2.547 2.547,2.547c-0,-0 0,-0 0,-0l21.261,-0c1.397,-0 2.547,-1.15 2.547,-2.547l-0,-1.576c0.026,-2.164 -0.409,-4.309 -1.276,-6.292c-1.233,-2.894 -3.555,-5.191 -6.463,-6.392Z" style="fill-rule:nonzero;"/>
<path d="M60.882,35.466c-1.233,-2.894 -3.554,-5.191 -6.462,-6.392c-0.43,-0.185 -0.71,-0.611 -0.71,-1.079c-0.003,-0.331 0.132,-0.649 0.372,-0.878c0.073,-0.069 0.142,-0.137 0.194,-0.192c0.368,-0.387 0.692,-0.813 0.968,-1.27c0.679,-1.134 1.038,-2.431 1.038,-3.753c0,-4.005 -3.295,-7.301 -7.3,-7.301c-0.462,0 -0.922,0.044 -1.375,0.131c-2.88,0.504 -5.171,2.73 -5.758,5.594c-0.54,2.452 0.222,5.016 2.013,6.776c0.242,0.229 0.381,0.547 0.386,0.88l-0,0.006c0.005,0.472 -0.276,0.903 -0.71,1.09c-1.162,0.476 -2.24,1.133 -3.195,1.949c2.679,1.588 4.786,3.985 6.018,6.845c1.029,2.332 1.546,4.857 1.517,7.405l-0,0.605l11.734,-0c1.397,-0 2.547,-1.15 2.547,-2.547l-0,-1.576c0.026,-2.165 -0.409,-4.31 -1.277,-6.293Z" style="fill-rule:nonzero;"/>
<path d="M23.66,31.026c-0.956,-0.817 -2.038,-1.476 -3.202,-1.952c-0.43,-0.185 -0.71,-0.611 -0.71,-1.079c-0.003,-0.331 0.132,-0.65 0.372,-0.878c0.072,-0.069 0.142,-0.137 0.194,-0.192c0.367,-0.387 0.692,-0.813 0.967,-1.27c0.68,-1.134 1.039,-2.431 1.039,-3.753c-0,-4.005 -3.296,-7.301 -7.301,-7.301c-0.461,0 -0.922,0.044 -1.375,0.131c-2.879,0.504 -5.17,2.73 -5.758,5.594c-0.54,2.452 0.222,5.016 2.013,6.776c0.242,0.229 0.381,0.547 0.386,0.88l0,0.006c0.005,0.472 -0.276,0.903 -0.71,1.09c-2.907,1.204 -5.229,3.504 -6.46,6.401c-0.865,1.985 -1.3,4.13 -1.274,6.295c0,0 0,1.561 0,1.561c0,1.397 1.15,2.547 2.547,2.547c-0,-0 11.735,-0 11.735,-0l0,-0.59c-0.029,-2.548 0.487,-5.073 1.513,-7.405c1.231,-2.867 3.341,-5.27 6.024,-6.861Z" style="fill-rule:nonzero;"/>
</svg>

View file

@ -76,6 +76,7 @@ WikiFolderMaker.prototype.tiddlersToIgnore = [
"$:/boot/boot.js",
"$:/boot/bootprefix.js",
"$:/core",
"$:/core-server",
"$:/library/sjcl.js",
"$:/temp/info-plugin"
];

11
core-server/plugin.info Normal file
View file

@ -0,0 +1,11 @@
{
"title": "$:/core-server",
"name": "Core Server Components",
"description": "TiddlyWiki5 core server components",
"author": "JeremyRuston",
"core-version": ">=5.0.0",
"platform": "server",
"plugin-priority": "0",
"list": "readme",
"stability": "STABILITY_2_STABLE"
}

7
core-server/readme.tid Normal file
View file

@ -0,0 +1,7 @@
title: $:/core-server/readme
This plugin contains TiddlyWiki's core components that are only needed on the server, comprising:
* Commands
* HTTP server code
* Utility functions for server

View file

@ -0,0 +1,86 @@
/*\
title: $:/core/modules/info/windowdimensions.js
type: application/javascript
module-type: info
\*/
exports.getInfoTiddlerFields = function(updateInfoTiddlersCallback) {
if(!$tw.browser) {
return [];
}
class WindowDimensionsTracker {
constructor(updateCallback) {
this.updateCallback = updateCallback;
this.resizeHandlers = new Map();
this.dimensionsInfo = [
["outer/width", win => win.outerWidth],
["outer/height", win => win.outerHeight],
["inner/width", win => win.innerWidth],
["inner/height", win => win.innerHeight],
["client/width", win => win.document.documentElement.clientWidth],
["client/height", win => win.document.documentElement.clientHeight]
];
}
buildTiddlers(win,windowId) {
const prefix = `$:/info/browser/window/${windowId}/`;
return this.dimensionsInfo.map(([suffix, getter]) => ({
title: prefix + suffix,
text: String(getter(win))
}));
}
clearTiddlers(windowId) {
const prefix = `$:/info/browser/window/${windowId}/`,
deletions = this.dimensionsInfo.map(([suffix]) => prefix + suffix);
this.updateCallback([], deletions);
}
getUpdateHandler(win,windowId) {
let scheduled = false;
return () => {
if(!scheduled) {
scheduled = true;
requestAnimationFrame(() => {
this.updateCallback(this.buildTiddlers(win,windowId), []);
scheduled = false;
});
}
};
}
trackWindow(win,windowId) {
const handler = this.getUpdateHandler(win, windowId);
handler(); // initial update
win.addEventListener("resize",handler,{passive:true});
this.resizeHandlers.set(windowId,{win, handler});
}
untrackWindow(windowId) {
const entry = this.resizeHandlers.get(windowId);
if(entry) {
entry.win.removeEventListener("resize", entry.handler);
this.resizeHandlers.delete(windowId);
}
this.clearTiddlers(windowId);
}
}
const tracker = new WindowDimensionsTracker(updateInfoTiddlersCallback);
// Track main window
tracker.trackWindow(window,"system/main");
// Hook into event bus for user windows
if($tw.eventBus) {
$tw.eventBus.on("window:opened", ({window: win, windowID}) => {
tracker.trackWindow(win, "user/" + windowID);
});
$tw.eventBus.on("window:closed", ({windowID}) => {
tracker.untrackWindow("user/" + windowID);
});
}
return [];
};

View file

@ -82,6 +82,7 @@ exports.parseTokenString = function(source,pos,token) {
/*
Look for a token matching a regex. Returns null if not found, otherwise returns {type: "regexp", match:, start:, end:,}
Use the "Y" (sticky) flag to avoid searching the entire rest of the string
*/
exports.parseTokenRegExp = function(source,pos,reToken) {
var node = {
@ -172,7 +173,7 @@ exports.parseMacroParameter = function(source,pos) {
start: pos
};
// Define our regexp
var reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/g;
const reMacroParameter = /(?:([A-Za-z0-9\-_]+)\s*:)?(?:\s*(?:"""([\s\S]*?)"""|"([^"]*)"|'([^']*)'|\[\[([^\]]*)\]\]|((?:(?:>(?!>))|[^\s>"'])+)))/y;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for the parameter
@ -240,7 +241,7 @@ exports.parseMacroInvocation = function(source,pos) {
params: []
};
// Define our regexps
var reMacroName = /([^\s>"'=]+)/g;
const reMacroName = /([^\s>"'=]+)/y;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a double less than sign
@ -277,7 +278,7 @@ exports.parseFilterVariable = function(source) {
params: [],
},
pos = 0,
reName = /([^\s"']+)/g;
reName = /([^\s"']+)/y;
// If there is no whitespace or it is an empty string then there are no macro parameters
if(/^\S*$/.test(source)) {
node.name = source;
@ -302,11 +303,11 @@ exports.parseAttribute = function(source,pos) {
start: pos
};
// Define our regexps
var reAttributeName = /([^\/\s>"'`=]+)/g,
reUnquotedAttribute = /([^\/\s<>"'`=]+)/g,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/g,
reIndirectValue = /\{\{([^\}]+)\}\}/g,
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/g;
const reAttributeName = /([^\/\s>"'`=]+)/y,
reUnquotedAttribute = /([^\/\s<>"'`=]+)/y,
reFilteredValue = /\{\{\{([\S\s]+?)\}\}\}/y,
reIndirectValue = /\{\{([^\}]+)\}\}/y,
reSubstitutedValue = /(?:```([\s\S]*?)```|`([^`]|[\S\s]*?)`)/y;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Get the attribute name

View file

@ -39,7 +39,7 @@ exports.parse = function() {
// Return the classed span
return [{
type: "element",
tag: "strike",
tag: "s",
children: tree
}];
};

View file

@ -49,7 +49,7 @@ exports.parse = function() {
// Advance the parser position to past the tag
this.parser.pos = tag.end;
// Check for an immediately following double linebreak
var hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
var hasLineBreak = !tag.isSelfClosing && !!$tw.utils.parseTokenRegExp(this.parser.source,this.parser.pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/y);
// Set whether we're in block mode
tag.isBlock = this.is.block || hasLineBreak;
// Parse the body if we need to
@ -100,7 +100,7 @@ exports.parseTag = function(source,pos,options) {
orderedAttributes: []
};
// Define our regexps
var reTagName = /([a-zA-Z0-9\-\$\.]+)/g;
const reTagName = /([a-zA-Z0-9\-\$\.]+)/y;
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Look for a less than sign
@ -148,7 +148,7 @@ exports.parseTag = function(source,pos,options) {
pos = token.end;
// Check for a required line break
if(options.requireLineBreak) {
token = $tw.utils.parseTokenRegExp(source,pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/g);
token = $tw.utils.parseTokenRegExp(source,pos,/([^\S\n\r]*\r?\n(?:[^\S\n\r]*\r?\n|$))/y);
if(!token) {
return null;
}

View file

@ -113,7 +113,7 @@ exports.parseImage = function(source,pos) {
// Skip whitespace
pos = $tw.utils.skipWhiteSpace(source,pos);
// Get the source up to the terminating `]]`
token = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\]]*?)\|)?([^\]]+?)\]\]/g);
token = $tw.utils.parseTokenRegExp(source,pos,/(?:([^|\]]*?)\|)?([^\]]+?)\]\]/y);
if(!token) {
return null;
}

View file

@ -0,0 +1,46 @@
/*\
title: $:/core/modules/startup/eventbus.js
type: application/javascript
module-type: startup
Event bus for cross module communication
\*/
exports.name = "eventbus";
exports.platforms = ["browser"];
exports.before = ["windows"];
exports.synchronous = true;
$tw.eventBus = {
listenersMap: new Map(),
on(event,handler) {
if(!this.listenersMap.has(event)) {
this.listenersMap.set(event,new Set());
}
const listeners = this.listenersMap.get(event);
listeners.add(handler);
},
off(event,handler) {
const listeners = this.listenersMap.get(event);
if(listeners) {
listeners.delete(handler);
}
},
once(event,handler) {
const wrapper = (...args) => {
handler(...args);
this.off(event, wrapper);
};
this.on(event, wrapper);
},
emit(event,data) {
const listeners = this.listenersMap.get(event);
if(listeners) {
listeners.forEach(fn => fn(data));
}
}
};

View file

@ -19,11 +19,17 @@ var TITLE_INFO_PLUGIN = "$:/temp/info-plugin";
exports.startup = function() {
// Function to bake the info plugin with new tiddlers
var updateInfoPlugin = function(tiddlerFieldsArray) {
// additions: array of tiddler field objects
// removals: array of titles to remove
var updateInfoPlugin = function(additions = [], removals = []) {
// Get the existing tiddlers
var json = $tw.wiki.getTiddlerData(TITLE_INFO_PLUGIN,{tiddlers: {}});
// Add the new ones
$tw.utils.each(tiddlerFieldsArray,function(fields) {
$tw.utils.each(removals,function(title) {
if(json.tiddlers[title]) {
delete json.tiddlers[title];
}
});
$tw.utils.each(additions,function(fields) {
if(fields && fields.title) {
json.tiddlers[fields.title] = fields;
}
@ -47,7 +53,7 @@ exports.startup = function() {
}
});
updateInfoPlugin(tiddlerFieldsArray);
var changes = $tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
$tw.wiki.readPluginInfo([TITLE_INFO_PLUGIN]);
$tw.wiki.registerPluginTiddlers("info",[TITLE_INFO_PLUGIN]);
$tw.wiki.unpackPluginTiddlers();
};

View file

@ -31,5 +31,7 @@ exports.startup = function() {
$tw.modules.applyMethods("tiddlerdeserializer",$tw.Wiki.tiddlerDeserializerModules);
$tw.macros = $tw.modules.getModulesByTypeAsHashmap("macro");
$tw.wiki.initParsers();
$tw.Commander.initCommands();
if($tw.node) {
$tw.Commander.initCommands();
}
};

View file

@ -56,9 +56,11 @@ exports.startup = function() {
srcDocument.write("<!DOCTYPE html><head></head><body class='tc-body tc-single-tiddler-window'></body></html>");
srcDocument.close();
srcDocument.title = windowTitle;
$tw.eventBus.emit("window:opened",{windowID, window: srcWindow});
srcWindow.addEventListener("beforeunload",function(event) {
delete $tw.windows[windowID];
$tw.wiki.removeEventListener("change",refreshHandler);
$tw.eventBus.emit("window:closed",{windowID});
},false);
// Set up the styles
var styleWidgetNode = $tw.wiki.makeTranscludeWidget("$:/core/ui/PageStylesheet",{

View file

@ -1,142 +0,0 @@
// From https://gist.github.com/Nijikokun/5192472
//
// UTF8 Module
//
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
(function (name, definition, context, dependencies) {
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
else { context[name] = definition.apply(context); }
})('utf8', function () {
return {
encode: function (string) {
if (typeof string !== 'string') return string;
else string = string.replace(/\r\n/g, "\n");
var output = "", i = 0, charCode;
for (i; i < string.length; i++) {
charCode = string.charCodeAt(i);
if (charCode < 128) {
output += String.fromCharCode(charCode);
} else if ((charCode > 127) && (charCode < 2048)) {
output += String.fromCharCode((charCode >> 6) | 192);
output += String.fromCharCode((charCode & 63) | 128);
} else if ((charCode > 55295) && (charCode < 57344) && string.length > i+1) {
// Surrogate pair
var hiSurrogate = charCode;
var loSurrogate = string.charCodeAt(i+1);
i++; // Skip the low surrogate on the next loop pass
var codePoint = (((hiSurrogate - 55296) << 10) | (loSurrogate - 56320)) + 65536;
output += String.fromCharCode((codePoint >> 18) | 240);
output += String.fromCharCode(((codePoint >> 12) & 63) | 128);
output += String.fromCharCode(((codePoint >> 6) & 63) | 128);
output += String.fromCharCode((codePoint & 63) | 128);
} else {
// Not a surrogate pair, or a dangling surrogate without its partner that we'll just encode as-is
output += String.fromCharCode((charCode >> 12) | 224);
output += String.fromCharCode(((charCode >> 6) & 63) | 128);
output += String.fromCharCode((charCode & 63) | 128);
}
}
return output;
},
decode: function (string) {
if (typeof string !== 'string') return string;
var output = "", i = 0, charCode = 0;
while (i < string.length) {
charCode = string.charCodeAt(i);
if (charCode < 128) {
output += String.fromCharCode(charCode),
i++;
} else if ((charCode > 191) && (charCode < 224)) {
output += String.fromCharCode(((charCode & 31) << 6) | (string.charCodeAt(i + 1) & 63));
i += 2;
} else if ((charCode > 223) && (charCode < 240)) {
output += String.fromCharCode(((charCode & 15) << 12) | ((string.charCodeAt(i + 1) & 63) << 6) | (string.charCodeAt(i + 2) & 63));
i += 3;
} else {
var codePoint = ((charCode & 7) << 18) | ((string.charCodeAt(i + 1) & 63) << 12) | ((string.charCodeAt(i + 2) & 63) << 6) | (string.charCodeAt(i + 3) & 63);
// output += String.fromCodePoint(codePoint); // Can't do this because Internet Explorer doesn't have String.fromCodePoint
output += String.fromCharCode(((codePoint - 65536) >> 10) + 55296) + String.fromCharCode(((codePoint - 65536) & 1023) + 56320); // So we do this instead
i += 4;
}
}
return output;
}
};
}, this);
// Base64 Module
//
// Cleaner, modularized and properly scoped base64 encoding and decoding module for strings.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
(function (name, definition, context, dependencies) {
if (typeof context['module'] !== 'undefined' && context['module']['exports']) { if (dependencies && context['require']) { for (var i = 0; i < dependencies.length; i++) context[dependencies[i]] = context['require'](dependencies[i]); } context['module']['exports'] = definition.apply(context); }
else if (typeof context['define'] !== 'undefined' && context['define'] === 'function' && context['define']['amd']) { define(name, (dependencies || []), definition); }
else { context[name] = definition.apply(context); }
})('base64', function (utf8) {
var $this = this;
var $utf8 = utf8 || this.utf8;
var map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
return {
encode: function (input) {
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
if (typeof input !== 'string') return input;
else input = $utf8.encode(input);
var output = "", a, b, c, d, e, f, g, i = 0;
while (i < input.length) {
a = input.charCodeAt(i++);
b = input.charCodeAt(i++);
c = input.charCodeAt(i++);
d = a >> 2;
e = ((a & 3) << 4) | (b >> 4);
f = ((b & 15) << 2) | (c >> 6);
g = c & 63;
if (isNaN(b)) f = g = 64;
else if (isNaN(c)) g = 64;
output += map.charAt(d) + map.charAt(e) + map.charAt(f) + map.charAt(g);
}
return output;
},
decode: function (input) {
if (typeof $utf8 === 'undefined') throw { error: "MissingMethod", message: "UTF8 Module is missing." };
if (typeof input !== 'string') return input;
else input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
var output = "", a, b, c, d, e, f, g, i = 0;
while (i < input.length) {
d = map.indexOf(input.charAt(i++));
e = map.indexOf(input.charAt(i++));
f = map.indexOf(input.charAt(i++));
g = map.indexOf(input.charAt(i++));
a = (d << 2) | (e >> 4);
b = ((e & 15) << 4) | (f >> 2);
c = ((f & 3) << 6) | g;
output += String.fromCharCode(a);
if (f != 64) output += String.fromCharCode(b);
if (g != 64) output += String.fromCharCode(c);
}
return $utf8.decode(output);
}
}
}, this, [ "utf8" ]);

View file

@ -1,9 +0,0 @@
// From https://gist.github.com/Nijikokun/5192472
//
// UTF8 Module
//
// Cleaner and modularized utf-8 encoding and decoding library for javascript.
//
// copyright: MIT
// author: Nijiko Yonskai, @nijikokun, nijikokun@gmail.com
!function(r,e,o,t){void 0!==o.module&&o.module.exports?o.module.exports=e.apply(o):void 0!==o.define&&"function"===o.define&&o.define.amd?define("utf8",[],e):o.utf8=e.apply(o)}(0,function(){return{encode:function(r){if("string"!=typeof r)return r;r=r.replace(/\r\n/g,"\n");for(var e,o="",t=0;t<r.length;t++)if((e=r.charCodeAt(t))<128)o+=String.fromCharCode(e);else if(e>127&&e<2048)o+=String.fromCharCode(e>>6|192),o+=String.fromCharCode(63&e|128);else if(e>55295&&e<57344&&r.length>t+1){var i=e,n=r.charCodeAt(t+1);t++;var d=65536+(i-55296<<10|n-56320);o+=String.fromCharCode(d>>18|240),o+=String.fromCharCode(d>>12&63|128),o+=String.fromCharCode(d>>6&63|128),o+=String.fromCharCode(63&d|128)}else o+=String.fromCharCode(e>>12|224),o+=String.fromCharCode(e>>6&63|128),o+=String.fromCharCode(63&e|128);return o},decode:function(r){if("string"!=typeof r)return r;for(var e="",o=0,t=0;o<r.length;)if((t=r.charCodeAt(o))<128)e+=String.fromCharCode(t),o++;else if(t>191&&t<224)e+=String.fromCharCode((31&t)<<6|63&r.charCodeAt(o+1)),o+=2;else if(t>223&&t<240)e+=String.fromCharCode((15&t)<<12|(63&r.charCodeAt(o+1))<<6|63&r.charCodeAt(o+2)),o+=3;else{var i=(7&t)<<18|(63&r.charCodeAt(o+1))<<12|(63&r.charCodeAt(o+2))<<6|63&r.charCodeAt(o+3);e+=String.fromCharCode(55296+(i-65536>>10))+String.fromCharCode(56320+(i-65536&1023)),o+=4}return e}}},this),function(r,e,o,t){if(void 0!==o.module&&o.module.exports){if(t&&o.require)for(var i=0;i<t.length;i++)o[t[i]]=o.require(t[i]);o.module.exports=e.apply(o)}else void 0!==o.define&&"function"===o.define&&o.define.amd?define("base64",t||[],e):o.base64=e.apply(o)}(0,function(r){var e=r||this.utf8,o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";return{encode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=e.encode(r);for(var t,i,n,d,f,a,h,C="",c=0;c<r.length;)d=(t=r.charCodeAt(c++))>>2,f=(3&t)<<4|(i=r.charCodeAt(c++))>>4,a=(15&i)<<2|(n=r.charCodeAt(c++))>>6,h=63&n,isNaN(i)?a=h=64:isNaN(n)&&(h=64),C+=o.charAt(d)+o.charAt(f)+o.charAt(a)+o.charAt(h);return C},decode:function(r){if(void 0===e)throw{error:"MissingMethod",message:"UTF8 Module is missing."};if("string"!=typeof r)return r;r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");for(var t,i,n,d,f,a,h="",C=0;C<r.length;)t=o.indexOf(r.charAt(C++))<<2|(d=o.indexOf(r.charAt(C++)))>>4,i=(15&d)<<4|(f=o.indexOf(r.charAt(C++)))>>2,n=(3&f)<<6|(a=o.indexOf(r.charAt(C++))),h+=String.fromCharCode(t),64!=f&&(h+=String.fromCharCode(i)),64!=a&&(h+=String.fromCharCode(n));return e.decode(h)}}},this,["utf8"]);

View file

@ -1,14 +0,0 @@
{
"tiddlers": [
{
"file": "base64-utf8.module.min.js",
"fields": {
"type": "application/javascript",
"title": "$:/core/modules/utils/base64-utf8/base64-utf8.module.js",
"module-type": "library"
},
"prefix": "(function(){",
"suffix": "}).call(exports);"
}
]
}

View file

@ -210,7 +210,7 @@ Modal.prototype.display = function(title,options) {
bodyWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
footerWidgetNode.addEventListener("tm-close-tiddler",closeHandler,false);
// Whether to close the modal dialog when the mask (area outside the modal) is clicked
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true")) {
if(tiddler.fields && (tiddler.fields["mask-closable"] === "yes" || tiddler.fields["mask-closable"] === "true" || tiddler.fields["mask-closable"] === "" || "mask-closable" in tiddler.fields === false)) {
modalBackdrop.addEventListener("click",closeHandler,false);
}
// Set the initial styles for the message

View file

@ -9,8 +9,6 @@ Various static utility functions.
"use strict";
var base64utf8 = require("$:/core/modules/utils/base64-utf8/base64-utf8.module.js");
/*
Display a message, in colour if we're on a terminal
*/
@ -842,22 +840,50 @@ if(typeof window !== 'undefined') {
}
}
exports.base64ToBytes = function(base64) {
const binString = exports.atob(base64);
return Uint8Array.from(binString, (m) => m.codePointAt(0));
};
exports.bytesToBase64 = function(bytes) {
const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
return exports.btoa(binString);
};
exports.base64EncodeUtf8 = function(str) {
if ($tw.browser) {
return exports.bytesToBase64(new TextEncoder().encode(str));
} else {
const buff = Buffer.from(str, "utf-8");
return buff.toString("base64");
}
};
exports.base64DecodeUtf8 = function(str) {
if ($tw.browser) {
return new TextDecoder().decode(exports.base64ToBytes(str));
} else {
const buff = Buffer.from(str, "base64");
return buff.toString("utf-8");
}
};
/*
Decode a base64 string
*/
exports.base64Decode = function(string64,binary,urlsafe) {
var encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;
const encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;
if(binary) return exports.atob(encoded)
else return base64utf8.base64.decode.call(base64utf8,encoded);
else return exports.base64DecodeUtf8(encoded);
};
/*
Encode a string to base64
*/
exports.base64Encode = function(string64,binary,urlsafe) {
var encoded;
let encoded;
if(binary) encoded = exports.btoa(string64);
else encoded = base64utf8.base64.encode.call(base64utf8,string64);
else encoded = exports.base64EncodeUtf8(string64);
if(urlsafe) {
encoded = encoded.replace(/\+/g,'-').replace(/\//g,'_');
}

View file

@ -61,6 +61,10 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
sourcePrefix: "data-",
destPrefix: "data-"
});
this.assignAttributes(domNode,{
sourcePrefix: "aria-",
destPrefix: "aria-"
});
// Assign other attributes
if(this.style) {
domNode.setAttribute("style",this.style);
@ -68,9 +72,6 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
if(this.tooltip) {
domNode.setAttribute("title",this.tooltip);
}
if(this["aria-label"]) {
domNode.setAttribute("aria-label",this["aria-label"]);
}
if (this.role) {
domNode.setAttribute("role", this.role);
}
@ -215,7 +216,6 @@ ButtonWidget.prototype.execute = function() {
this.setTo = this.getAttribute("setTo");
this.popup = this.getAttribute("popup");
this.hover = this.getAttribute("hover");
this["aria-label"] = this.getAttribute("aria-label");
this.role = this.getAttribute("role");
this.tooltip = this.getAttribute("tooltip");
this.style = this.getAttribute("style");
@ -271,6 +271,10 @@ ButtonWidget.prototype.refresh = function(changedTiddlers) {
sourcePrefix: "data-",
destPrefix: "data-"
});
this.assignAttributes(this.domNodes[0],{
sourcePrefix: "aria-",
destPrefix: "aria-"
});
}
return this.refreshChildren(changedTiddlers);
};

View file

@ -74,6 +74,8 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
// Create the DOM node and render children
var domNode = this.document.createElementNS(this.namespace,this.tag);
this.assignAttributes(domNode,{excludeEventAttributes: true});
// Allow hooks to manipulate the DOM node. Eg: Add debug info
$tw.hooks.invokeHook("th-dom-rendering-element", domNode, this);
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);

View file

@ -44,7 +44,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
domNode.addEventListener(type,function(event) {
var selector = self.getAttribute("selector"),
matchSelector = self.getAttribute("matchSelector"),
actions = self.getAttribute("$"+type) || self.getAttribute("actions-"+type),
actions = self.getAttribute("$"+type),
stopPropagation = self.getAttribute("stopPropagation","onaction"),
selectedNode = event.target,
selectedNodeRect,
@ -122,9 +122,6 @@ EventWidget.prototype.execute = function() {
self.types.push(key.slice(1));
}
});
if(!this.types.length) {
this.types = this.getAttribute("events","").split(" ");
}
this.elementTag = this.getAttribute("tag");
// Make child widgets
this.makeChildWidgets();

View file

@ -45,6 +45,10 @@ LinkWidget.prototype.render = function(parent,nextSibling) {
sourcePrefix: "data-",
destPrefix: "data-"
});
this.assignAttributes(domNode,{
sourcePrefix: "aria-",
destPrefix: "aria-"
});
parent.insertBefore(domNode,nextSibling);
this.renderChildren(domNode,null);
this.domNodes.push(domNode);
@ -125,9 +129,13 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
});
domNode.setAttribute("title",tooltipText);
}
if(this["aria-label"]) {
domNode.setAttribute("aria-label",this["aria-label"]);
if(this.role) {
domNode.setAttribute("role",this.role);
}
this.assignAttributes(domNode,{
sourcePrefix: "aria-",
destPrefix: "aria-"
})
// Add a click event handler
$tw.utils.addEventListeners(domNode,[
{name: "click", handlerObject: this, handlerMethod: "handleClickEvent"},
@ -188,7 +196,7 @@ LinkWidget.prototype.execute = function() {
// Pick up our attributes
this.to = this.getAttribute("to",this.getVariable("currentTiddler"));
this.tooltip = this.getAttribute("tooltip");
this["aria-label"] = this.getAttribute("aria-label");
this.role = this.getAttribute("role");
this.linkClasses = this.getAttribute("class");
this.overrideClasses = this.getAttribute("overrideClass");
this.tabIndex = this.getAttribute("tabindex");

View file

@ -94,8 +94,6 @@ RangeWidget.prototype.getActionVariables = function(options) {
// actionsStart
RangeWidget.prototype.handleMouseDownEvent = function(event) {
this.mouseDown = true; // TODO remove once IE is gone.
this.startValue = this.inputDomNode.value; // TODO remove this line once IE is gone!
this.handleEvent(event);
// Trigger actions
if(this.actionsMouseDown) {
@ -106,26 +104,16 @@ RangeWidget.prototype.handleMouseDownEvent = function(event) {
// actionsStop
RangeWidget.prototype.handleMouseUpEvent = function(event) {
this.mouseDown = false; // TODO remove once IE is gone.
this.handleEvent(event);
// Trigger actions
if(this.actionsMouseUp) {
var variables = this.getActionVariables()
this.invokeActionString(this.actionsMouseUp,this,event,variables);
}
// TODO remove the following if() once IE is gone!
if ($tw.browser.isIE) {
if (this.startValue !== this.inputDomNode.value) {
this.handleChangeEvent(event);
this.startValue = this.inputDomNode.value;
}
}
}
RangeWidget.prototype.handleChangeEvent = function(event) {
if (this.mouseDown) { // TODO refactor this function once IE is gone.
this.handleInputEvent(event);
}
this.handleInputEvent(event);
};
RangeWidget.prototype.handleInputEvent = function(event) {
@ -152,8 +140,6 @@ RangeWidget.prototype.handleEvent = function(event) {
Compute the internal state of the widget
*/
RangeWidget.prototype.execute = function() {
// TODO remove the next 1 lines once IE is gone!
this.mouseUp = true; // Needed for IE10
// Get the parameters from the attributes
this.tiddlerTitle = this.getAttribute("tiddler",this.getVariable("currentTiddler"));
this.tiddlerField = this.getAttribute("field","text");

View file

@ -181,7 +181,7 @@ ScrollableWidget.prototype.render = function(parent,nextSibling) {
};
ScrollableWidget.prototype.listenerFunction = function(event) {
self = this;
var self = this;
clearTimeout(this.timeout);
this.timeout = setTimeout(function() {
var existingTiddler = self.wiki.getTiddler(self.scrollableBind),

View file

@ -3,7 +3,7 @@ title: $:/core/save/all-external-js
\whitespace trim
\import [subfilter{$:/core/config/GlobalImportFilter}]
\define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[has[plugin-type]field:platform[server]] +[sort[title]] $(publishFilter)$
\end
<!-- Important: core library is provided by serving URI encoded $:/core/templates/tiddlywiki5.js -->

View file

@ -3,7 +3,7 @@ title: $:/core/save/offline-external-js
\whitespace trim
\import [subfilter{$:/core/config/GlobalImportFilter}]
\define saveTiddlerFilter()
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] +[sort[title]] $(publishFilter)$
[is[tiddler]] -[prefix[$:/state/popup/]] -[prefix[$:/temp/]] -[prefix[$:/HistoryList]] -[status[pending]plugin-type[import]] -[[$:/core]] -[[$:/plugins/tiddlywiki/filesystem]] -[[$:/plugins/tiddlywiki/tiddlyweb]] -[[$:/boot/boot.css]] -[is[system]type[application/javascript]library[yes]] -[[$:/boot/boot.js]] -[[$:/boot/bootprefix.js]] -[has[plugin-type]field:platform[server]] +[sort[title]] $(publishFilter)$
\end
\define defaultCoreURL() tiddlywikicore-$(version)$.js
<$let coreURL={{{ [[coreURL]is[variable]then<coreURL>else<defaultCoreURL>] }}}>

View file

@ -1,12 +1,13 @@
title: $:/core/templates/tiddlywiki5-external-js.html
<$set name="saveTiddlerAndShadowsFilter" filter="[subfilter<saveTiddlerFilter>] [subfilter<saveTiddlerFilter>plugintiddlers[]]">
<$set name="rawMarkupFilter" filter="[enlist<saveTiddlerAndShadowsFilter>] +[[$:/core]plugintiddlers[]]">
`<!doctype html>
`{{$:/core/templates/MOTW.html}}`<html lang="`<$text text={{{ [{$:/language}get[name]] }}}/>`">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<!--~~ Raw markup for the top of the head section ~~-->
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/TopHead]] ||$:/core/templates/raw-static-tiddler}}}`
<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
<meta name="application-name" content="TiddlyWiki" />
<meta name="generator" content="TiddlyWiki" />
@ -22,13 +23,13 @@ title: $:/core/templates/tiddlywiki5-external-js.html
<!--~~ This is a Tiddlywiki file. The points of interest in the file are marked with this pattern ~~-->
<!--~~ Raw markup ~~-->
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/core/wiki/rawmarkup]] ||$:/core/templates/plain-text-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkup]] ||$:/core/templates/plain-text-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified]] ||$:/core/templates/raw-static-tiddler}}}`
</head>
<body class="tc-body">
<!--~~ Raw markup for the top of the body section ~~-->
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/TopBody]] ||$:/core/templates/raw-static-tiddler}}}`
<!--~~ Static styles ~~-->
<div id="styleArea">
`{{$:/boot/boot.css||$:/core/templates/css-tiddler}}`
@ -42,9 +43,10 @@ title: $:/core/templates/tiddlywiki5-external-js.html
<!--~~ Ordinary tiddlers ~~-->
`{{$:/core/templates/store.area.template.html}}`
<!--~~ Raw markup for the bottom of the body section ~~-->
`{{{ [enlist<saveTiddlerAndShadowsFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`
`{{{ [enlist<rawMarkupFilter>tag[$:/tags/RawMarkupWikified/BottomBody]] ||$:/core/templates/raw-static-tiddler}}}`
<!--~~ Load external JavaScripts ~~-->
<script src="`{{{ [<coreURL>] }}}`" onerror="alert('Error: Cannot load `{{{ [<coreURL>] }}}`');"></script>
</body>
</html>`
</$set>
</$set>

Some files were not shown because too many files have changed in this diff Show more