tiddlywiki 5.3.1 → 5.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (372) hide show
  1. package/.github/workflows/ci.yml +9 -2
  2. package/bin/build-site.sh +25 -5
  3. package/bin/ci-test.sh +16 -0
  4. package/boot/boot.js +12 -0
  5. package/core/language/en-GB/Exporters.multids +1 -1
  6. package/core/language/en-GB/Help/commands.tid +1 -1
  7. package/core/language/en-GB/Help/savewikifolder.tid +2 -2
  8. package/core/language/en-GB/Help/server.tid +1 -1
  9. package/core/language/en-GB/Types/image_svg_xml.tid +1 -1
  10. package/core/language/en-GB/Types/image_x-icon.tid +1 -1
  11. package/core/modules/commands/savetiddlers.js +1 -1
  12. package/core/modules/editor/engines/framed.js +1 -1
  13. package/core/modules/editor/engines/simple.js +1 -1
  14. package/core/modules/filters/all.js +5 -5
  15. package/core/modules/filters/encodings.js +6 -2
  16. package/core/modules/filters/json-ops.js +95 -1
  17. package/core/modules/filters/listops.js +1 -0
  18. package/core/modules/parsers/textparser.js +5 -4
  19. package/core/modules/parsers/wikiparser/rules/conditional.js +120 -0
  20. package/core/modules/parsers/wikiparser/wikiparser.js +33 -8
  21. package/core/modules/savers/github.js +1 -1
  22. package/core/modules/startup/windows.js +2 -1
  23. package/core/modules/syncer.js +160 -122
  24. package/core/modules/utils/dom/dom.js +3 -3
  25. package/core/modules/utils/dom/http.js +1 -1
  26. package/core/modules/utils/fakedom.js +5 -1
  27. package/core/modules/utils/utils.js +27 -4
  28. package/core/modules/widgets/browse.js +10 -0
  29. package/core/modules/widgets/button.js +15 -3
  30. package/core/modules/widgets/checkbox.js +11 -0
  31. package/core/modules/widgets/draggable.js +16 -5
  32. package/core/modules/widgets/droppable.js +14 -2
  33. package/core/modules/widgets/image.js +19 -14
  34. package/core/modules/widgets/link.js +12 -2
  35. package/core/modules/widgets/list.js +179 -19
  36. package/core/modules/widgets/radio.js +4 -0
  37. package/core/modules/widgets/range.js +4 -0
  38. package/core/modules/widgets/scrollable.js +66 -1
  39. package/core/modules/widgets/select.js +34 -26
  40. package/core/modules/widgets/transclude.js +19 -6
  41. package/core/modules/widgets/widget.js +35 -19
  42. package/core/modules/wiki.js +2 -2
  43. package/core/templates/html-json-skinny-tiddler.tid +1 -2
  44. package/core/templates/html-json-tiddler.tid +1 -1
  45. package/core/templates/store.area.template.html.tid +6 -8
  46. package/core/ui/ControlPanel/Basics.tid +2 -2
  47. package/core/ui/EditTemplate/body/default.tid +9 -8
  48. package/core/ui/EditTemplate/fields.tid +2 -2
  49. package/core/ui/EditTemplate/type.tid +1 -1
  50. package/core/ui/EditorToolbar/preview.tid +5 -8
  51. package/core/ui/PageTemplate.tid +1 -1
  52. package/core/ui/ViewTemplate/subtitle.tid +2 -5
  53. package/core/wiki/config/OfficialPluginLibrary.tid +1 -1
  54. package/core/wiki/macros/colour-picker.tid +6 -6
  55. package/core/wiki/macros/image-picker.tid +5 -5
  56. package/core/wiki/macros/list.tid +95 -78
  57. package/core/wiki/macros/tabs.tid +9 -1
  58. package/core/wiki/macros/tag-picker.tid +2 -2
  59. package/core/wiki/macros/tag.tid +2 -1
  60. package/core/wiki/macros/toc.tid +2 -2
  61. package/editions/de-AT/tiddlers/HelloThere.tid +2 -2
  62. package/editions/de-AT/tiddlers/community/Fur_Entwickler.tid +1 -1
  63. package/editions/de-AT-server/tiddlers/system/favicon.png +0 -0
  64. package/editions/{es-ES-server/tiddlers/system/favicon.ico.meta → de-AT-server/tiddlers/system/favicon.png.meta} +1 -1
  65. package/editions/dev/tiddlers/images/favicon.png +0 -0
  66. package/editions/{de-AT-server/tiddlers/system/favicon.ico.meta → dev/tiddlers/images/favicon.png.meta} +1 -1
  67. package/editions/dev/tiddlers/new/HookMechanism.tid +28 -3
  68. package/editions/empty/tiddlywiki.info +5 -2
  69. package/editions/es-ES/tiddlers/Forums.tid +4 -5
  70. package/editions/es-ES/tiddlers/HelloThere.tid +2 -2
  71. package/editions/es-ES/tiddlers/Typography.tid +1 -1
  72. package/editions/es-ES/tiddlers/images/favicon.png +0 -0
  73. package/editions/{dev/tiddlers/images/favicon.ico.meta → es-ES/tiddlers/images/favicon.png.meta} +1 -1
  74. package/editions/es-ES/tiddlers/images/green_favicon.png +0 -0
  75. package/editions/es-ES/tiddlers/images/{green_favicon.ico.meta → green_favicon.png.meta} +1 -1
  76. package/editions/es-ES-server/tiddlers/system/favicon.png +0 -0
  77. package/editions/{es-ES/tiddlers/images/favicon.ico.meta → es-ES-server/tiddlers/system/favicon.png.meta} +1 -1
  78. package/editions/fr-FR/tiddlers/images/favicon.png +0 -0
  79. package/editions/fr-FR/tiddlers/images/favicon.png.meta +2 -0
  80. package/editions/fr-FR/tiddlers/images/green_favicon.png +0 -0
  81. package/editions/fr-FR/tiddlers/images/{green_favicon.ico.meta → green_favicon.png.meta} +1 -1
  82. package/editions/fr-FR-server/tiddlers/system/favicon.png +0 -0
  83. package/editions/fr-FR-server/tiddlers/system/favicon.png.meta +2 -0
  84. package/editions/highlightdemo/tiddlywiki.info +1 -1
  85. package/editions/ja-JP/tiddlers/images/favicon.png +0 -0
  86. package/editions/ja-JP/tiddlers/images/favicon.png.meta +2 -0
  87. package/editions/ja-JP/tiddlers/images/green_favicon.png +0 -0
  88. package/editions/ja-JP/tiddlers/images/{green_favicon.ico.meta → green_favicon.png.meta} +1 -1
  89. package/editions/katexdemo/tiddlywiki.info +1 -1
  90. package/editions/ko-KR/tiddlers/images/favicon.png +0 -0
  91. package/editions/ko-KR/tiddlers/images/favicon.png.meta +2 -0
  92. package/editions/ko-KR/tiddlers/images/green_favicon.png +0 -0
  93. package/editions/ko-KR/tiddlers/images/{green_favicon.ico.meta → green_favicon.png.meta} +1 -1
  94. package/editions/ko-KR-server/tiddlers/system/favicon.png +0 -0
  95. package/editions/ko-KR-server/tiddlers/system/favicon.png.meta +2 -0
  96. package/editions/pluginlibrary/tiddlywiki.info +2 -2
  97. package/editions/prerelease/tiddlers/{Release 5.3.2.tid → Release 5.3.4.tid } +26 -25
  98. package/editions/prerelease/tiddlers/system/PrereleaseLocalPluginLibrary.tid +1 -1
  99. package/editions/prerelease/tiddlers/system/PrereleaseOfficialPluginLibrary.tid +1 -1
  100. package/editions/prerelease/tiddlers/system/favicon.png +0 -0
  101. package/editions/prerelease/tiddlers/system/favicon.png.meta +2 -0
  102. package/editions/prerelease/tiddlers/system/temp-my-scroll-position.tid +3 -0
  103. package/editions/resumebuilder/tiddlywiki.info +1 -1
  104. package/editions/server/tiddlywiki.info +1 -1
  105. package/editions/server-external-js/tiddlywiki.info +1 -1
  106. package/editions/test/playwright.spec.js +25 -0
  107. package/editions/test/tiddlers/tests/data/conditionals/Basic.tid +26 -0
  108. package/editions/test/tiddlers/tests/data/conditionals/BlockMode.tid +37 -0
  109. package/editions/test/tiddlers/tests/data/conditionals/Else.tid +26 -0
  110. package/editions/test/tiddlers/tests/data/conditionals/Elseif.tid +32 -0
  111. package/editions/test/tiddlers/tests/data/conditionals/MissingEndIf.tid +26 -0
  112. package/editions/test/tiddlers/tests/data/conditionals/MultipleResults.tid +12 -0
  113. package/editions/test/tiddlers/tests/data/conditionals/Nested.tid +38 -0
  114. package/editions/test/tiddlers/tests/data/conditionals/NestedElseif.tid +60 -0
  115. package/editions/test/tiddlers/tests/data/list-widget/WithEmptyParagraphTemplate.tid +13 -0
  116. package/editions/test/tiddlers/tests/data/list-widget/WithExplicitTemplates.tid +29 -0
  117. package/editions/test/tiddlers/tests/data/list-widget/WithExplicitTemplatesInBlockMode.tid +32 -0
  118. package/editions/test/tiddlers/tests/data/list-widget/WithExplicitTemplatesOverriddenByAttributes.tid +33 -0
  119. package/editions/test/tiddlers/tests/data/list-widget/WithJoinTemplate.tid +30 -0
  120. package/editions/test/tiddlers/tests/data/list-widget/WithJoinTemplateInBlockMode.tid +32 -0
  121. package/editions/test/tiddlers/tests/data/list-widget/WithLimit.tid +25 -0
  122. package/editions/test/tiddlers/tests/data/list-widget/WithMissingTemplate.tid +26 -0
  123. package/editions/test/tiddlers/tests/data/pragmas/WhitespaceAfterPragma.tid +64 -0
  124. package/editions/test/tiddlers/tests/data/pragmas/WhitespaceNoPragma.tid +32 -0
  125. package/editions/test/tiddlers/tests/data/transclude/CustomWidget-CodeblockOverride-TextParser.tid +20 -0
  126. package/editions/test/tiddlers/tests/data/transclude/Variable-Refreshing.tid +27 -0
  127. package/editions/test/tiddlers/tests/data/transclude/Variable-Static.tid +15 -0
  128. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/ButtonWidget-DataAttributes.tid +27 -0
  129. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/CheckboxWidget-DataAttributes.tid +22 -0
  130. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/DraggableWidget-DataAttributes.tid +27 -0
  131. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/DroppableWidget-DataAttributes.tid +27 -0
  132. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/LinkWidget-DataAttributes.tid +27 -0
  133. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/OrderedStyleAttributes.tid +15 -0
  134. package/editions/test/tiddlers/tests/data/widgets/DataAttributes/SelectWidget-DataAttributes.tid +27 -0
  135. package/editions/test/tiddlers/tests/data/widgets/ElementWidgetEventAttributes.tid +15 -0
  136. package/editions/test/tiddlers/tests/data/widgets/ElementWidgetStyleAttributes.tid +15 -0
  137. package/editions/test/tiddlers/tests/test-filters.js +1 -0
  138. package/editions/test/tiddlers/tests/test-json-filters.js +40 -0
  139. package/editions/test/tiddlers/tests/test-utils.js +23 -0
  140. package/editions/test/tiddlers/tests/test-widget.js +62 -0
  141. package/editions/tw.org/tiddlers/$__favicon.ico.png +0 -0
  142. package/editions/tw.org/tiddlywiki.info +1 -1
  143. package/editions/tw5.com/tiddlers/_tw_shared/favicons/classic.tiddlywiki.com.png +0 -0
  144. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{classic.tiddlywiki.com.ico.meta → classic.tiddlywiki.com.png.meta} +1 -1
  145. package/editions/tw5.com/tiddlers/_tw_shared/favicons/links.tiddlywiki.org.png +0 -0
  146. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{links.tiddlywiki.org.ico.meta → links.tiddlywiki.org.png.meta} +1 -1
  147. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.dev.png +0 -0
  148. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{tiddlywiki.com.dev.ico.meta → tiddlywiki.com.dev.png.meta} +1 -1
  149. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.png +0 -0
  150. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{tiddlywiki.com.ico.meta → tiddlywiki.com.png.meta} +1 -1
  151. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.prerelease.png +0 -0
  152. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{tiddlywiki.com.prerelease.ico.meta → tiddlywiki.com.prerelease.png.meta} +1 -1
  153. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.upgrade.png +0 -0
  154. package/editions/tw5.com/tiddlers/_tw_shared/favicons/{tiddlywiki.com.upgrade.ico.meta → tiddlywiki.com.upgrade.png.meta} +1 -1
  155. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.org.png +0 -0
  156. package/editions/tw5.com/tiddlers/about/Archive.tid +82 -0
  157. package/editions/tw5.com/tiddlers/community/Chinese Community.tid +20 -0
  158. package/editions/tw5.com/tiddlers/community/editions/Tidme by oflg.tid +16 -0
  159. package/editions/tw5.com/tiddlers/community/plugins/FSRS4TW by oflg.tid +10 -0
  160. package/editions/tw5.com/tiddlers/community/resources/_Timimi_ Extension and executable by Riz.tid +3 -1
  161. package/editions/tw5.com/tiddlers/concepts/Macros.tid +7 -3
  162. package/editions/tw5.com/tiddlers/concepts/Title List.tid +5 -1
  163. package/editions/tw5.com/tiddlers/filters/decodebase64 Operator.tid +6 -1
  164. package/editions/tw5.com/tiddlers/filters/encodebase64 Operator.tid +6 -1
  165. package/editions/tw5.com/tiddlers/filters/examples/jsonset.tid +59 -0
  166. package/editions/tw5.com/tiddlers/filters/examples/jsonstringify Operator (Examples).tid +7 -5
  167. package/editions/tw5.com/tiddlers/filters/examples/stringify_Operator_(Examples).tid +5 -3
  168. package/editions/tw5.com/tiddlers/filters/jsonextract.tid +8 -0
  169. package/editions/tw5.com/tiddlers/filters/jsonget.tid +8 -0
  170. package/editions/tw5.com/tiddlers/filters/jsonset.tid +64 -0
  171. package/editions/tw5.com/tiddlers/filters/jsonstringify Operator.tid +14 -15
  172. package/editions/tw5.com/tiddlers/filters/jsontype.tid +8 -0
  173. package/editions/tw5.com/tiddlers/filters/stringify_Operator.tid +12 -15
  174. package/editions/tw5.com/tiddlers/filters/syntax/Filter Expression.tid +1 -1
  175. package/editions/tw5.com/tiddlers/hellothere/HelloThere.tid +6 -1
  176. package/editions/tw5.com/tiddlers/howtos/Constructing JSON tiddlers.tid +3 -3
  177. package/editions/tw5.com/tiddlers/images/Favicon template.svg +296 -0
  178. package/editions/tw5.com/tiddlers/images/Favicon template.svg.meta +3 -0
  179. package/editions/tw5.com/tiddlers/images/New Release Banner.png +0 -0
  180. package/editions/tw5.com/tiddlers/images/favicon.png +0 -0
  181. package/editions/tw5.com/tiddlers/images/favicon.png.meta +2 -0
  182. package/editions/tw5.com/tiddlers/images/green_favicon.png +0 -0
  183. package/editions/tw5.com/tiddlers/images/green_favicon.png.meta +2 -0
  184. package/editions/tw5.com/tiddlers/macros/CoreMacros.tid +1 -1
  185. package/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-delete-tiddler.tid +3 -1
  186. package/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-open-window.tid +12 -5
  187. package/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-permalink.tid +1 -1
  188. package/editions/tw5.com/tiddlers/pragmas/Pragma_ _define.tid +3 -1
  189. package/editions/tw5.com/tiddlers/pragmas/Pragma_ _whitespace.tid +7 -3
  190. package/editions/tw5.com/tiddlers/procedures/Procedure Definitions.tid +3 -1
  191. package/editions/tw5.com/tiddlers/releasenotes/BetaReleases.tid +2 -2
  192. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.0.tid +1 -0
  193. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.1.tid +1 -0
  194. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.10.tid +1 -0
  195. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.11.tid +1 -0
  196. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.12.tid +1 -0
  197. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.13.tid +1 -0
  198. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.14.tid +1 -0
  199. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.15.tid +1 -0
  200. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.16.tid +1 -0
  201. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.17.tid +1 -0
  202. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.18.tid +1 -0
  203. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.19.tid +1 -0
  204. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.2.tid +1 -0
  205. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.20.tid +1 -0
  206. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.21.tid +1 -0
  207. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.22.tid +1 -0
  208. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.23.tid +1 -0
  209. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.3.tid +1 -0
  210. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.4.tid +1 -0
  211. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.5.tid +1 -0
  212. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.6.tid +1 -0
  213. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.7.tid +1 -0
  214. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.8.tid +1 -0
  215. package/editions/tw5.com/tiddlers/releasenotes/Release 5.1.9.tid +1 -0
  216. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.0.tid +1 -0
  217. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.1.tid +1 -0
  218. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.2.tid +1 -0
  219. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.3.tid +1 -0
  220. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.4.tid +1 -0
  221. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.5.tid +1 -0
  222. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.6.tid +1 -0
  223. package/editions/tw5.com/tiddlers/releasenotes/Release 5.2.7.tid +1 -0
  224. package/editions/tw5.com/tiddlers/releasenotes/Release 5.3.0.tid +1 -0
  225. package/editions/tw5.com/tiddlers/releasenotes/Release 5.3.1.tid +8 -1
  226. package/editions/tw5.com/tiddlers/releasenotes/Release 5.3.2.tid +184 -0
  227. package/editions/tw5.com/tiddlers/releasenotes/Release 5.3.3.tid +30 -0
  228. package/editions/tw5.com/tiddlers/releasenotes/Releases.tid +3 -1
  229. package/editions/tw5.com/tiddlers/releasenotes/alpha/AlphaReleases.tid +2 -2
  230. package/editions/tw5.com/tiddlers/system/tw5.com-styles.tid +5 -0
  231. package/editions/tw5.com/tiddlers/widgets/BrowseWidget.tid +3 -1
  232. package/editions/tw5.com/tiddlers/widgets/ButtonWidget.tid +3 -1
  233. package/editions/tw5.com/tiddlers/widgets/CheckboxWidget.tid +3 -1
  234. package/editions/tw5.com/tiddlers/widgets/Custom Widgets.tid +3 -1
  235. package/editions/tw5.com/tiddlers/widgets/DraggableWidget.tid +3 -2
  236. package/editions/tw5.com/tiddlers/widgets/DroppableWidget.tid +3 -1
  237. package/editions/tw5.com/tiddlers/widgets/GenesisWidget.tid +3 -2
  238. package/editions/tw5.com/tiddlers/widgets/ImageWidget.tid +2 -1
  239. package/editions/tw5.com/tiddlers/widgets/LinkWidget.tid +3 -1
  240. package/editions/tw5.com/tiddlers/widgets/ListWidget.tid +25 -2
  241. package/editions/tw5.com/tiddlers/widgets/RadioWidget.tid +3 -1
  242. package/editions/tw5.com/tiddlers/widgets/RangeWidget.tid +3 -1
  243. package/editions/tw5.com/tiddlers/widgets/ScrollableWidget.tid +27 -2
  244. package/editions/tw5.com/tiddlers/widgets/SelectWidget.tid +4 -1
  245. package/editions/tw5.com/tiddlers/widgets/SetWidget.tid +17 -1
  246. package/editions/tw5.com/tiddlers/widgets/TranscludeWidget.tid +2 -2
  247. package/editions/tw5.com/tiddlers/wikitext/Conditional Shortcut Syntax.tid +62 -0
  248. package/editions/tw5.com/tiddlers/wikitext/Transclusion and Substitution.tid +3 -3
  249. package/editions/tw5.com/tiddlywiki.info +9 -3
  250. package/editions/tw5.com-server/tiddlers/system/tiddlywiki.com.server.png +0 -0
  251. package/editions/tw5.com-server/tiddlers/system/tiddlywiki.com.server.png.meta +2 -0
  252. package/editions/zh-Hans/tiddlers/images/favicon.png +0 -0
  253. package/editions/zh-Hans/tiddlers/images/favicon.png.meta +2 -0
  254. package/editions/zh-Hans/tiddlers/images/green_favicon.png +0 -0
  255. package/editions/zh-Hans/tiddlers/images/green_favicon.png.meta +2 -0
  256. package/editions/zh-Hant/tiddlers/images/favicon.png +0 -0
  257. package/editions/zh-Hant/tiddlers/images/favicon.png.meta +2 -0
  258. package/editions/zh-Hant/tiddlers/images/green_favicon.png +0 -0
  259. package/editions/zh-Hant/tiddlers/images/green_favicon.png.meta +2 -0
  260. package/languages/de-DE/Exporters.multids +1 -1
  261. package/languages/de-DE/Help/commands.tid +2 -2
  262. package/languages/de-DE/Help/server.tid +1 -1
  263. package/languages/de-DE/Types/image_x-icon.tid +1 -1
  264. package/languages/es-ES/Buttons.multids +2 -0
  265. package/languages/es-ES/Fields.multids +4 -0
  266. package/languages/es-ES/Help/listen.tid +1 -1
  267. package/languages/es-ES/Help/savewikifolder.tid +16 -1
  268. package/languages/es-ES/Help/server.tid +1 -1
  269. package/languages/es-ES/Misc.multids +3 -0
  270. package/languages/es-ES/SiteTitle.tid +1 -1
  271. package/languages/pl-PL/Exporters.multids +1 -1
  272. package/languages/pl-PL/Help/commands.tid +1 -1
  273. package/languages/pl-PL/Help/savewikifolder.tid +3 -1
  274. package/languages/pl-PL/Help/server.tid +1 -1
  275. package/languages/zh-Hans/Exporters.multids +1 -1
  276. package/languages/zh-Hans/Help/commands.tid +1 -1
  277. package/languages/zh-Hans/Help/server.tid +1 -1
  278. package/languages/zh-Hans/Types/image_svg_xml.tid +1 -1
  279. package/languages/zh-Hans/Types/image_x-icon.tid +1 -1
  280. package/languages/zh-Hant/Exporters.multids +1 -1
  281. package/languages/zh-Hant/Help/commands.tid +1 -1
  282. package/languages/zh-Hant/Help/server.tid +1 -1
  283. package/languages/zh-Hant/Types/image_svg_xml.tid +1 -1
  284. package/languages/zh-Hant/Types/image_x-icon.tid +1 -1
  285. package/licenses/cla-individual.md +12 -0
  286. package/package.json +4 -1
  287. package/playwright.config.js +46 -0
  288. package/plugins/tiddlywiki/codemirror/styles.tid +5 -0
  289. package/plugins/tiddlywiki/comments/styles.tid +8 -8
  290. package/plugins/tiddlywiki/dynannotate/docs/readme.tid +1 -0
  291. package/plugins/tiddlywiki/dynannotate/modules/dynannotate.js +28 -27
  292. package/plugins/tiddlywiki/evernote/modules/enex-deserializer.js +82 -23
  293. package/plugins/tiddlywiki/evernote/readme.tid +1 -0
  294. package/plugins/tiddlywiki/evernote/samples/sample-enex-with-image.xml.enex +2 -2
  295. package/plugins/tiddlywiki/jasmine/run-wiki-based-tests.js +1 -1
  296. package/plugins/tiddlywiki/qrcode/barcodereader.js +90 -0
  297. package/plugins/tiddlywiki/qrcode/docs/barcodereader.tid +44 -0
  298. package/plugins/tiddlywiki/qrcode/{doc/usage.tid → docs/makeqr.tid} +4 -4
  299. package/plugins/tiddlywiki/qrcode/docs.tid +3 -0
  300. package/plugins/tiddlywiki/qrcode/{MakeContactQR.tid → examples/make/MakeContactQR.tid} +1 -1
  301. package/plugins/tiddlywiki/qrcode/{MakeGenericQR.tid → examples/make/MakeGenericQR.tid} +1 -1
  302. package/plugins/tiddlywiki/qrcode/{MakeWifiQR.tid → examples/make/MakeWifiQR.tid} +1 -1
  303. package/plugins/tiddlywiki/qrcode/examples/make/make.tid +5 -0
  304. package/plugins/tiddlywiki/qrcode/examples/read/BarCodeReader.tid +17 -0
  305. package/plugins/tiddlywiki/qrcode/examples/read/read.tid +5 -0
  306. package/plugins/tiddlywiki/qrcode/examples.tid +3 -0
  307. package/plugins/tiddlywiki/qrcode/files/html5-qrcode/LICENSE +201 -0
  308. package/plugins/tiddlywiki/qrcode/files/html5-qrcode/README.md +398 -0
  309. package/plugins/tiddlywiki/qrcode/files/html5-qrcode/html5-qrcode.min.js +1 -0
  310. package/plugins/tiddlywiki/qrcode/files/tiddlywiki.files +20 -4
  311. package/plugins/tiddlywiki/qrcode/makeqr.js +1 -1
  312. package/plugins/tiddlywiki/qrcode/plugin.info +1 -1
  313. package/plugins/tiddlywiki/qrcode/readme.tid +15 -0
  314. package/plugins/tiddlywiki/tiddlyweb/html-json-skinny-tiddler.tid +1 -2
  315. package/plugins/tiddlywiki/tiddlyweb/html-json-tiddler.tid +1 -2
  316. package/plugins/tiddlywiki/upgrade/UpgradeWizard.tid +2 -2
  317. package/plugins/tiddlywiki/upgrade/favicon.png +0 -0
  318. package/plugins/tiddlywiki/upgrade/favicon.png.meta +2 -0
  319. package/readme.md +1 -1
  320. package/themes/tiddlywiki/vanilla/base.tid +37 -7
  321. package/themes/tiddlywiki/vanilla/settings.multids +1 -1
  322. package/editions/de-AT-server/tiddlers/system/favicon.ico +0 -0
  323. package/editions/dev/tiddlers/images/favicon.ico +0 -0
  324. package/editions/es-ES/tiddlers/images/favicon.ico +0 -0
  325. package/editions/es-ES/tiddlers/images/green_favicon.ico +0 -0
  326. package/editions/es-ES-server/tiddlers/system/favicon.ico +0 -0
  327. package/editions/fr-FR/tiddlers/images/favicon.ico +0 -0
  328. package/editions/fr-FR/tiddlers/images/favicon.ico.meta +0 -2
  329. package/editions/fr-FR/tiddlers/images/green_favicon.ico +0 -0
  330. package/editions/fr-FR-server/tiddlers/system/favicon.ico +0 -0
  331. package/editions/fr-FR-server/tiddlers/system/favicon.ico.meta +0 -2
  332. package/editions/ja-JP/tiddlers/images/favicon.ico +0 -0
  333. package/editions/ja-JP/tiddlers/images/favicon.ico.meta +0 -2
  334. package/editions/ja-JP/tiddlers/images/green_favicon.ico +0 -0
  335. package/editions/ko-KR/tiddlers/images/favicon.ico +0 -0
  336. package/editions/ko-KR/tiddlers/images/favicon.ico.meta +0 -2
  337. package/editions/ko-KR/tiddlers/images/green_favicon.ico +0 -0
  338. package/editions/ko-KR-server/tiddlers/system/favicon.ico +0 -0
  339. package/editions/ko-KR-server/tiddlers/system/favicon.ico.meta +0 -2
  340. package/editions/prerelease/tiddlers/system/favicon.ico +0 -0
  341. package/editions/prerelease/tiddlers/system/favicon.ico.meta +0 -2
  342. package/editions/tw5.com/tiddlers/_tw_shared/favicons/classic.tiddlywiki.com.ico +0 -0
  343. package/editions/tw5.com/tiddlers/_tw_shared/favicons/links.tiddlywiki.org.ico +0 -0
  344. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.dev.ico +0 -0
  345. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.ico +0 -0
  346. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.prerelease.ico +0 -0
  347. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.com.upgrade.ico +0 -0
  348. package/editions/tw5.com/tiddlers/_tw_shared/favicons/tiddlywiki.org.ico +0 -0
  349. package/editions/tw5.com/tiddlers/community/editions/TiddlyMemo by oflg.tid +0 -16
  350. package/editions/tw5.com/tiddlers/community/tutorials/Install and run TiddlyWiki on a CentOS 6 VPS using Nginx.tid +0 -16
  351. package/editions/tw5.com/tiddlers/images/favicon.ico +0 -0
  352. package/editions/tw5.com/tiddlers/images/favicon.ico.meta +0 -2
  353. package/editions/tw5.com/tiddlers/images/green_favicon.ico +0 -0
  354. package/editions/tw5.com/tiddlers/images/green_favicon.ico.meta +0 -2
  355. package/editions/tw5.com-server/tiddlers/system/favicon.ico +0 -0
  356. package/editions/tw5.com-server/tiddlers/system/favicon.ico.meta +0 -2
  357. package/editions/zh-Hans/tiddlers/images/favicon.ico +0 -0
  358. package/editions/zh-Hans/tiddlers/images/favicon.ico.meta +0 -2
  359. package/editions/zh-Hans/tiddlers/images/green_favicon.ico +0 -0
  360. package/editions/zh-Hans/tiddlers/images/green_favicon.ico.meta +0 -2
  361. package/editions/zh-Hant/tiddlers/images/favicon.ico +0 -0
  362. package/editions/zh-Hant/tiddlers/images/favicon.ico.meta +0 -2
  363. package/editions/zh-Hant/tiddlers/images/green_favicon.ico +0 -0
  364. package/editions/zh-Hant/tiddlers/images/green_favicon.ico.meta +0 -2
  365. package/plugins/tiddlywiki/qrcode/doc/examples.tid +0 -3
  366. package/plugins/tiddlywiki/qrcode/doc/readme.tid +0 -13
  367. package/plugins/tiddlywiki/upgrade/favicon.ico +0 -0
  368. package/plugins/tiddlywiki/upgrade/favicon.ico.meta +0 -2
  369. /package/editions/tw5.com/tiddlers/_tw_shared/favicons/{tiddlywiki.org.ico.meta → tiddlywiki.org.png.meta} +0 -0
  370. /package/plugins/tiddlywiki/qrcode/files/{LICENSE → qrcode/LICENSE} +0 -0
  371. /package/plugins/tiddlywiki/qrcode/files/{README.md → qrcode/README.md} +0 -0
  372. /package/plugins/tiddlywiki/qrcode/files/{qrcode.js → qrcode/qrcode.js} +0 -0
@@ -40,7 +40,7 @@ exports.startup = function() {
40
40
  variables = $tw.utils.extend({},paramObject,{currentTiddler: title, "tv-window-id": windowID});
41
41
  // Open the window
42
42
  var srcWindow,
43
- srcDocument;
43
+ srcDocument;
44
44
  // In case that popup blockers deny opening a new window
45
45
  try {
46
46
  srcWindow = window.open("","external-" + windowID,"scrollbars,width=" + width + ",height=" + height + (top ? ",top=" + top : "" ) + (left ? ",left=" + left : "" )),
@@ -52,6 +52,7 @@ exports.startup = function() {
52
52
  $tw.windows[windowID] = srcWindow;
53
53
  // Check for reopening the same window
54
54
  if(srcWindow.haveInitialisedWindow) {
55
+ srcWindow.focus();
55
56
  return;
56
57
  }
57
58
  // Initialise the document
@@ -24,7 +24,7 @@ Syncer.prototype.titleSyncPollingInterval = "$:/config/SyncPollingInterval";
24
24
  Syncer.prototype.titleSyncDisableLazyLoading = "$:/config/SyncDisableLazyLoading";
25
25
  Syncer.prototype.titleSavedNotification = "$:/language/Notifications/Save/Done";
26
26
  Syncer.prototype.titleSyncThrottleInterval = "$:/config/SyncThrottleInterval";
27
- Syncer.prototype.taskTimerInterval = 1 * 1000; // Interval for sync timer
27
+ Syncer.prototype.taskTimerInterval = 0.25 * 1000; // Interval for sync timer
28
28
  Syncer.prototype.throttleInterval = 1 * 1000; // Defer saving tiddlers if they've changed in the last 1s...
29
29
  Syncer.prototype.errorRetryInterval = 5 * 1000; // Interval to retry after an error
30
30
  Syncer.prototype.fallbackInterval = 10 * 1000; // Unless the task is older than 10s
@@ -74,9 +74,11 @@ function Syncer(options) {
74
74
  this.titlesHaveBeenLazyLoaded = {}; // Hashmap of titles of tiddlers that have already been lazily loaded from the server
75
75
  // Timers
76
76
  this.taskTimerId = null; // Timer for task dispatch
77
- this.pollTimerId = null; // Timer for polling server
78
77
  // Number of outstanding requests
79
78
  this.numTasksInProgress = 0;
79
+ // True when we want to force an immediate sync from the server
80
+ this.forceSyncFromServer = false;
81
+ this.timestampLastSyncFromServer = new Date();
80
82
  // Listen out for changes to tiddlers
81
83
  this.wiki.addEventListener("change",function(changes) {
82
84
  // Filter the changes to just include ones that are being synced
@@ -203,33 +205,37 @@ Syncer.prototype.readTiddlerInfo = function() {
203
205
  Checks whether the wiki is dirty (ie the window shouldn't be closed)
204
206
  */
205
207
  Syncer.prototype.isDirty = function() {
206
- this.logger.log("Checking dirty status");
207
- // Check tiddlers that are in the store and included in the filter function
208
- var titles = this.getSyncedTiddlers();
209
- for(var index=0; index<titles.length; index++) {
210
- var title = titles[index],
211
- tiddlerInfo = this.tiddlerInfo[title];
212
- if(this.wiki.tiddlerExists(title)) {
213
- if(tiddlerInfo) {
214
- // If the tiddler is known on the server and has been modified locally then it needs to be saved to the server
215
- if(this.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
208
+ var self = this;
209
+ function checkIsDirty() {
210
+ // Check tiddlers that are in the store and included in the filter function
211
+ var titles = self.getSyncedTiddlers();
212
+ for(var index=0; index<titles.length; index++) {
213
+ var title = titles[index],
214
+ tiddlerInfo = self.tiddlerInfo[title];
215
+ if(self.wiki.tiddlerExists(title)) {
216
+ if(tiddlerInfo) {
217
+ // If the tiddler is known on the server and has been modified locally then it needs to be saved to the server
218
+ if(self.wiki.getChangeCount(title) > tiddlerInfo.changeCount) {
219
+ return true;
220
+ }
221
+ } else {
222
+ // If the tiddler isn't known on the server then it needs to be saved to the server
216
223
  return true;
217
224
  }
218
- } else {
219
- // If the tiddler isn't known on the server then it needs to be saved to the server
220
- return true;
221
225
  }
222
226
  }
223
- }
224
- // Check tiddlers that are known from the server but not currently in the store
225
- titles = Object.keys(this.tiddlerInfo);
226
- for(index=0; index<titles.length; index++) {
227
- if(!this.wiki.tiddlerExists(titles[index])) {
228
- // There must be a pending delete
229
- return true;
227
+ // Check tiddlers that are known from the server but not currently in the store
228
+ titles = Object.keys(self.tiddlerInfo);
229
+ for(index=0; index<titles.length; index++) {
230
+ if(!self.wiki.tiddlerExists(titles[index])) {
231
+ // There must be a pending delete
232
+ return true;
233
+ }
230
234
  }
235
+ return false;
231
236
  }
232
- return false;
237
+ var dirtyStatus = checkIsDirty();
238
+ return dirtyStatus;
233
239
  };
234
240
 
235
241
  /*
@@ -293,92 +299,16 @@ Syncer.prototype.getStatus = function(callback) {
293
299
  Synchronise from the server by reading the skinny tiddler list and queuing up loads for any tiddlers that we don't already have up to date
294
300
  */
295
301
  Syncer.prototype.syncFromServer = function() {
296
- var self = this,
297
- cancelNextSync = function() {
298
- if(self.pollTimerId) {
299
- clearTimeout(self.pollTimerId);
300
- self.pollTimerId = null;
301
- }
302
- },
303
- triggerNextSync = function() {
304
- self.pollTimerId = setTimeout(function() {
305
- self.pollTimerId = null;
306
- self.syncFromServer.call(self);
307
- },self.pollTimerInterval);
308
- },
309
- syncSystemFromServer = (self.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
310
- if(this.syncadaptor && this.syncadaptor.getUpdatedTiddlers) {
311
- this.logger.log("Retrieving updated tiddler list");
312
- cancelNextSync();
313
- this.syncadaptor.getUpdatedTiddlers(self,function(err,updates) {
314
- triggerNextSync();
315
- if(err) {
316
- self.displayError($tw.language.getString("Error/RetrievingSkinny"),err);
317
- return;
318
- }
319
- if(updates) {
320
- $tw.utils.each(updates.modifications,function(title) {
321
- self.titlesToBeLoaded[title] = true;
322
- });
323
- $tw.utils.each(updates.deletions,function(title) {
324
- if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
325
- delete self.tiddlerInfo[title];
326
- self.logger.log("Deleting tiddler missing from server:",title);
327
- self.wiki.deleteTiddler(title);
328
- }
329
- });
330
- if(updates.modifications.length > 0 || updates.deletions.length > 0) {
331
- self.processTaskQueue();
332
- }
333
- }
334
- });
335
- } else if(this.syncadaptor && this.syncadaptor.getSkinnyTiddlers) {
336
- this.logger.log("Retrieving skinny tiddler list");
337
- cancelNextSync();
338
- this.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {
339
- triggerNextSync();
340
- // Check for errors
341
- if(err) {
342
- self.displayError($tw.language.getString("Error/RetrievingSkinny"),err);
343
- return;
344
- }
345
- // Keep track of which tiddlers we already know about have been reported this time
346
- var previousTitles = Object.keys(self.tiddlerInfo);
347
- // Process each incoming tiddler
348
- for(var t=0; t<tiddlers.length; t++) {
349
- // Get the incoming tiddler fields, and the existing tiddler
350
- var tiddlerFields = tiddlers[t],
351
- incomingRevision = tiddlerFields.revision + "",
352
- tiddler = self.wiki.tiddlerExists(tiddlerFields.title) && self.wiki.getTiddler(tiddlerFields.title),
353
- tiddlerInfo = self.tiddlerInfo[tiddlerFields.title],
354
- currRevision = tiddlerInfo ? tiddlerInfo.revision : null,
355
- indexInPreviousTitles = previousTitles.indexOf(tiddlerFields.title);
356
- if(indexInPreviousTitles !== -1) {
357
- previousTitles.splice(indexInPreviousTitles,1);
358
- }
359
- // Ignore the incoming tiddler if it's the same as the revision we've already got
360
- if(currRevision !== incomingRevision) {
361
- // Only load the skinny version if we don't already have a fat version of the tiddler
362
- if(!tiddler || tiddler.fields.text === undefined) {
363
- self.storeTiddler(tiddlerFields);
364
- }
365
- // Do a full load of this tiddler
366
- self.titlesToBeLoaded[tiddlerFields.title] = true;
367
- }
368
- }
369
- // Delete any tiddlers that were previously reported but missing this time
370
- $tw.utils.each(previousTitles,function(title) {
371
- if(syncSystemFromServer || !self.wiki.isSystemTiddler(title)) {
372
- delete self.tiddlerInfo[title];
373
- self.logger.log("Deleting tiddler missing from server:",title);
374
- self.wiki.deleteTiddler(title);
375
- }
376
- });
377
- self.processTaskQueue();
378
- });
302
+ if(this.canSyncFromServer()) {
303
+ this.forceSyncFromServer = true;
304
+ this.processTaskQueue();
379
305
  }
380
306
  };
381
307
 
308
+ Syncer.prototype.canSyncFromServer = function() {
309
+ return !!this.syncadaptor.getUpdatedTiddlers || !!this.syncadaptor.getSkinnyTiddlers;
310
+ }
311
+
382
312
  /*
383
313
  Force load a tiddler from the server
384
314
  */
@@ -510,7 +440,7 @@ Syncer.prototype.processTaskQueue = function() {
510
440
  } else {
511
441
  self.updateDirtyStatus();
512
442
  // Process the next task
513
- self.processTaskQueue.call(self);
443
+ self.processTaskQueue.call(self);
514
444
  }
515
445
  });
516
446
  } else {
@@ -518,31 +448,39 @@ Syncer.prototype.processTaskQueue = function() {
518
448
  this.updateDirtyStatus();
519
449
  // And trigger a timeout if there is a pending task
520
450
  if(task === true) {
521
- this.triggerTimeout();
451
+ this.triggerTimeout(this.taskTimerInterval);
452
+ } else if(this.canSyncFromServer()) {
453
+ this.triggerTimeout(this.pollTimerInterval);
522
454
  }
523
455
  }
524
456
  } else {
525
- this.updateDirtyStatus();
457
+ this.updateDirtyStatus();
458
+ this.triggerTimeout(this.taskTimerInterval);
526
459
  }
527
460
  };
528
461
 
529
462
  Syncer.prototype.triggerTimeout = function(interval) {
530
463
  var self = this;
531
- if(!this.taskTimerId) {
532
- this.taskTimerId = setTimeout(function() {
533
- self.taskTimerId = null;
534
- self.processTaskQueue.call(self);
535
- },interval || self.taskTimerInterval);
464
+ if(this.taskTimerId) {
465
+ clearTimeout(this.taskTimerId);
536
466
  }
467
+ this.taskTimerId = setTimeout(function() {
468
+ self.taskTimerId = null;
469
+ self.processTaskQueue.call(self);
470
+ },interval || self.taskTimerInterval);
537
471
  };
538
472
 
539
473
  /*
540
- Choose the next sync task. We prioritise saves, then deletes, then loads from the server
474
+ Choose the next sync task. We prioritise saves to the server, then getting updates from the server, then deletes to the server, then loads from the server
541
475
 
542
- Returns either a task object, null if there's no upcoming tasks, or the boolean true if there are pending tasks that aren't yet due
476
+ Returns either:
477
+ * a task object
478
+ * the boolean true if there are pending sync tasks that aren't yet due
479
+ * null if there's no pending sync tasks (just the next poll)
543
480
  */
544
481
  Syncer.prototype.chooseNextTask = function() {
545
- var thresholdLastSaved = (new Date()) - this.throttleInterval,
482
+ var now = new Date(),
483
+ thresholdLastSaved = now - this.throttleInterval,
546
484
  havePending = null;
547
485
  // First we look for tiddlers that have been modified locally and need saving back to the server
548
486
  var titles = this.getSyncedTiddlers();
@@ -556,14 +494,18 @@ Syncer.prototype.chooseNextTask = function() {
556
494
  isReadyToSave = !tiddlerInfo || !tiddlerInfo.timestampLastSaved || tiddlerInfo.timestampLastSaved < thresholdLastSaved;
557
495
  if(hasChanged) {
558
496
  if(isReadyToSave) {
559
- return new SaveTiddlerTask(this,title);
497
+ return new SaveTiddlerTask(this,title);
560
498
  } else {
561
499
  havePending = true;
562
500
  }
563
501
  }
564
502
  }
565
503
  }
566
- // Second, we check tiddlers that are known from the server but not currently in the store, and so need deleting on the server
504
+ // Second we check for an outstanding sync from server
505
+ if(this.forceSyncFromServer || (this.timestampLastSyncFromServer && (now.valueOf() >= (this.timestampLastSyncFromServer.valueOf() + this.pollTimerInterval)))) {
506
+ return new SyncFromServerTask(this);
507
+ }
508
+ // Third, we check tiddlers that are known from the server but not currently in the store, and so need deleting on the server
567
509
  titles = Object.keys(this.tiddlerInfo);
568
510
  for(index=0; index<titles.length; index++) {
569
511
  title = titles[index];
@@ -573,13 +515,13 @@ Syncer.prototype.chooseNextTask = function() {
573
515
  return new DeleteTiddlerTask(this,title);
574
516
  }
575
517
  }
576
- // Check for tiddlers that need loading
518
+ // Finally, check for tiddlers that need loading
577
519
  title = Object.keys(this.titlesToBeLoaded)[0];
578
520
  if(title) {
579
521
  delete this.titlesToBeLoaded[title];
580
522
  return new LoadTiddlerTask(this,title);
581
523
  }
582
- // No tasks are ready
524
+ // No tasks are ready now, but might be in the future
583
525
  return havePending;
584
526
  };
585
527
 
@@ -589,6 +531,10 @@ function SaveTiddlerTask(syncer,title) {
589
531
  this.type = "save";
590
532
  }
591
533
 
534
+ SaveTiddlerTask.prototype.toString = function() {
535
+ return "SAVE " + this.title;
536
+ }
537
+
592
538
  SaveTiddlerTask.prototype.run = function(callback) {
593
539
  var self = this,
594
540
  changeCount = this.syncer.wiki.getChangeCount(this.title),
@@ -613,7 +559,6 @@ SaveTiddlerTask.prototype.run = function(callback) {
613
559
  tiddlerInfo: self.syncer.tiddlerInfo[self.title]
614
560
  });
615
561
  } else {
616
- this.syncer.logger.log(" Not Dispatching 'save' task:",this.title,"tiddler does not exist");
617
562
  $tw.utils.nextTick(callback(null));
618
563
  }
619
564
  };
@@ -624,6 +569,10 @@ function DeleteTiddlerTask(syncer,title) {
624
569
  this.type = "delete";
625
570
  }
626
571
 
572
+ DeleteTiddlerTask.prototype.toString = function() {
573
+ return "DELETE " + this.title;
574
+ }
575
+
627
576
  DeleteTiddlerTask.prototype.run = function(callback) {
628
577
  var self = this;
629
578
  this.syncer.logger.log("Dispatching 'delete' task:",this.title);
@@ -647,6 +596,10 @@ function LoadTiddlerTask(syncer,title) {
647
596
  this.type = "load";
648
597
  }
649
598
 
599
+ LoadTiddlerTask.prototype.toString = function() {
600
+ return "LOAD " + this.title;
601
+ }
602
+
650
603
  LoadTiddlerTask.prototype.run = function(callback) {
651
604
  var self = this;
652
605
  this.syncer.logger.log("Dispatching 'load' task:",this.title);
@@ -664,6 +617,91 @@ LoadTiddlerTask.prototype.run = function(callback) {
664
617
  });
665
618
  };
666
619
 
620
+ function SyncFromServerTask(syncer) {
621
+ this.syncer = syncer;
622
+ this.type = "syncfromserver";
623
+ }
624
+
625
+ SyncFromServerTask.prototype.toString = function() {
626
+ return "SYNCFROMSERVER";
627
+ }
628
+
629
+ SyncFromServerTask.prototype.run = function(callback) {
630
+ var self = this;
631
+ var syncSystemFromServer = (self.syncer.wiki.getTiddlerText("$:/config/SyncSystemTiddlersFromServer") === "yes" ? true : false);
632
+ var successCallback = function() {
633
+ self.syncer.forceSyncFromServer = false;
634
+ self.syncer.timestampLastSyncFromServer = new Date();
635
+ callback(null);
636
+ };
637
+ if(this.syncer.syncadaptor.getUpdatedTiddlers) {
638
+ this.syncer.syncadaptor.getUpdatedTiddlers(self.syncer,function(err,updates) {
639
+ if(err) {
640
+ self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err);
641
+ return callback(err);
642
+ }
643
+ if(updates) {
644
+ $tw.utils.each(updates.modifications,function(title) {
645
+ self.syncer.titlesToBeLoaded[title] = true;
646
+ });
647
+ $tw.utils.each(updates.deletions,function(title) {
648
+ if(syncSystemFromServer || !self.syncer.wiki.isSystemTiddler(title)) {
649
+ delete self.syncer.tiddlerInfo[title];
650
+ self.syncer.logger.log("Deleting tiddler missing from server:",title);
651
+ self.syncer.wiki.deleteTiddler(title);
652
+ }
653
+ });
654
+ }
655
+ return successCallback();
656
+ });
657
+ } else if(this.syncer.syncadaptor.getSkinnyTiddlers) {
658
+ this.syncer.syncadaptor.getSkinnyTiddlers(function(err,tiddlers) {
659
+ // Check for errors
660
+ if(err) {
661
+ self.syncer.displayError($tw.language.getString("Error/RetrievingSkinny"),err);
662
+ return callback(err);
663
+ }
664
+ // Keep track of which tiddlers we already know about have been reported this time
665
+ var previousTitles = Object.keys(self.syncer.tiddlerInfo);
666
+ // Process each incoming tiddler
667
+ for(var t=0; t<tiddlers.length; t++) {
668
+ // Get the incoming tiddler fields, and the existing tiddler
669
+ var tiddlerFields = tiddlers[t],
670
+ incomingRevision = tiddlerFields.revision + "",
671
+ tiddler = self.syncer.wiki.tiddlerExists(tiddlerFields.title) && self.syncer.wiki.getTiddler(tiddlerFields.title),
672
+ tiddlerInfo = self.syncer.tiddlerInfo[tiddlerFields.title],
673
+ currRevision = tiddlerInfo ? tiddlerInfo.revision : null,
674
+ indexInPreviousTitles = previousTitles.indexOf(tiddlerFields.title);
675
+ if(indexInPreviousTitles !== -1) {
676
+ previousTitles.splice(indexInPreviousTitles,1);
677
+ }
678
+ // Ignore the incoming tiddler if it's the same as the revision we've already got
679
+ if(currRevision !== incomingRevision) {
680
+ // Only load the skinny version if we don't already have a fat version of the tiddler
681
+ if(!tiddler || tiddler.fields.text === undefined) {
682
+ self.syncer.storeTiddler(tiddlerFields);
683
+ }
684
+ // Do a full load of this tiddler
685
+ self.syncer.titlesToBeLoaded[tiddlerFields.title] = true;
686
+ }
687
+ }
688
+ // Delete any tiddlers that were previously reported but missing this time
689
+ $tw.utils.each(previousTitles,function(title) {
690
+ if(syncSystemFromServer || !self.syncer.wiki.isSystemTiddler(title)) {
691
+ delete self.syncer.tiddlerInfo[title];
692
+ self.syncer.logger.log("Deleting tiddler missing from server:",title);
693
+ self.syncer.wiki.deleteTiddler(title);
694
+ }
695
+ });
696
+ self.syncer.forceSyncFromServer = false;
697
+ self.syncer.timestampLastSyncFromServer = new Date();
698
+ return successCallback();
699
+ });
700
+ } else {
701
+ return successCallback();
702
+ }
703
+ };
704
+
667
705
  exports.Syncer = Syncer;
668
706
 
669
707
  })();
@@ -313,7 +313,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
313
313
  variables["dom-" + attribute.name] = attribute.value.toString();
314
314
  });
315
315
 
316
- if(selectedNode.offsetLeft) {
316
+ if("offsetLeft" in selectedNode) {
317
317
  // Add variables with a (relative and absolute) popup coordinate string for the selected node
318
318
  var nodeRect = {
319
319
  left: selectedNode.offsetLeft,
@@ -338,12 +338,12 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
338
338
  }
339
339
  }
340
340
 
341
- if(domNode && domNode.offsetWidth) {
341
+ if(domNode && ("offsetWidth" in domNode)) {
342
342
  variables["tv-widgetnode-width"] = domNode.offsetWidth.toString();
343
343
  variables["tv-widgetnode-height"] = domNode.offsetHeight.toString();
344
344
  }
345
345
 
346
- if(event && event.clientX && event.clientY) {
346
+ if(event && ("clientX" in event) && ("clientY" in event)) {
347
347
  if(selectedNode) {
348
348
  // Add variables for event X and Y position relative to selected node
349
349
  selectedNodeRect = selectedNode.getBoundingClientRect();
@@ -187,7 +187,7 @@ HttpClientRequest.prototype.send = function(callback) {
187
187
  for (var i=0; i<len; i++) {
188
188
  binary += String.fromCharCode(bytes[i]);
189
189
  }
190
- resultVariables.data = window.btoa(binary);
190
+ resultVariables.data = $tw.utils.base64Encode(binary,true);
191
191
  }
192
192
  self.wiki.addTiddler(new $tw.Tiddler(self.wiki.getTiddler(requestTrackerTitle),{
193
193
  status: completionCode,
@@ -104,7 +104,11 @@ TW_Element.prototype.setAttribute = function(name,value) {
104
104
  if(this.isRaw) {
105
105
  throw "Cannot setAttribute on a raw TW_Element";
106
106
  }
107
- this.attributes[name] = value + "";
107
+ if(name === "style") {
108
+ this.style = value;
109
+ } else {
110
+ this.attributes[name] = value + "";
111
+ }
108
112
  };
109
113
 
110
114
  TW_Element.prototype.setAttributeNS = function(namespace,name,value) {
@@ -819,18 +819,41 @@ exports.hashString = function(str) {
819
819
  },0);
820
820
  };
821
821
 
822
+ /*
823
+ Base64 utility functions that work in either browser or Node.js
824
+ */
825
+ if(typeof window !== 'undefined') {
826
+ exports.btoa = function(binstr) { return window.btoa(binstr); }
827
+ exports.atob = function(b64) { return window.atob(b64); }
828
+ } else {
829
+ exports.btoa = function(binstr) {
830
+ return Buffer.from(binstr, 'binary').toString('base64');
831
+ }
832
+ exports.atob = function(b64) {
833
+ return Buffer.from(b64, 'base64').toString('binary');
834
+ }
835
+ }
836
+
822
837
  /*
823
838
  Decode a base64 string
824
839
  */
825
- exports.base64Decode = function(string64) {
826
- return base64utf8.base64.decode.call(base64utf8,string64);
840
+ exports.base64Decode = function(string64,binary,urlsafe) {
841
+ var encoded = urlsafe ? string64.replace(/_/g,'/').replace(/-/g,'+') : string64;
842
+ if(binary) return exports.atob(encoded)
843
+ else return base64utf8.base64.decode.call(base64utf8,encoded);
827
844
  };
828
845
 
829
846
  /*
830
847
  Encode a string to base64
831
848
  */
832
- exports.base64Encode = function(string64) {
833
- return base64utf8.base64.encode.call(base64utf8,string64);
849
+ exports.base64Encode = function(string64,binary,urlsafe) {
850
+ var encoded;
851
+ if(binary) encoded = exports.btoa(string64);
852
+ else encoded = base64utf8.base64.encode.call(base64utf8,string64);
853
+ if(urlsafe) {
854
+ encoded = encoded.replace(/\+/g,'-').replace(/\//g,'_');
855
+ }
856
+ return encoded;
834
857
  };
835
858
 
836
859
  /*
@@ -70,6 +70,11 @@ BrowseWidget.prototype.render = function(parent,nextSibling) {
70
70
  }
71
71
  return false;
72
72
  },false);
73
+ // Assign data- attributes
74
+ this.assignAttributes(domNode,{
75
+ sourcePrefix: "data-",
76
+ destPrefix: "data-"
77
+ });
73
78
  // Insert element
74
79
  parent.insertBefore(domNode,nextSibling);
75
80
  this.renderChildren(domNode,null);
@@ -95,6 +100,11 @@ BrowseWidget.prototype.execute = function() {
95
100
  Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
96
101
  */
97
102
  BrowseWidget.prototype.refresh = function(changedTiddlers) {
103
+ var changedAttributes = this.computeAttributes();
104
+ if($tw.utils.count(changedAttributes) > 0) {
105
+ this.refreshSelf();
106
+ return true;
107
+ }
98
108
  return false;
99
109
  };
100
110
 
@@ -59,6 +59,11 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
59
59
  $tw.utils.pushTop(classes,"tc-popup-handle");
60
60
  }
61
61
  domNode.className = classes.join(" ");
62
+ // Assign data- attributes
63
+ this.assignAttributes(domNode,{
64
+ sourcePrefix: "data-",
65
+ destPrefix: "data-"
66
+ });
62
67
  // Assign other attributes
63
68
  if(this.style) {
64
69
  domNode.setAttribute("style",this.style);
@@ -250,7 +255,7 @@ ButtonWidget.prototype.updateDomNodeClasses = function() {
250
255
  //Add new classes from updated class attribute.
251
256
  $tw.utils.pushTop(domNodeClasses,newClasses);
252
257
  this.domNode.className = domNodeClasses.join(" ");
253
- }
258
+ };
254
259
 
255
260
  /*
256
261
  Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
@@ -260,8 +265,15 @@ ButtonWidget.prototype.refresh = function(changedTiddlers) {
260
265
  if(changedAttributes.actions || changedAttributes.to || changedAttributes.message || changedAttributes.param || changedAttributes.set || changedAttributes.setTo || changedAttributes.popup || changedAttributes.hover || changedAttributes.selectedClass || changedAttributes.style || changedAttributes.dragFilter || changedAttributes.dragTiddler || (this.set && changedTiddlers[this.set]) || (this.popup && changedTiddlers[this.popup]) || (this.popupTitle && changedTiddlers[this.popupTitle]) || changedAttributes.popupAbsCoords || changedAttributes.setTitle || changedAttributes.setField || changedAttributes.setIndex || changedAttributes.popupTitle || changedAttributes.disabled || changedAttributes["default"]) {
261
266
  this.refreshSelf();
262
267
  return true;
263
- } else if(changedAttributes["class"]) {
264
- this.updateDomNodeClasses();
268
+ } else {
269
+ if(changedAttributes["class"]) {
270
+ this.updateDomNodeClasses();
271
+ }
272
+ this.assignAttributes(this.domNodes[0],{
273
+ changedAttributes: changedAttributes,
274
+ sourcePrefix: "data-",
275
+ destPrefix: "data-"
276
+ });
265
277
  }
266
278
  return this.refreshChildren(changedTiddlers);
267
279
  };
@@ -53,6 +53,11 @@ CheckboxWidget.prototype.render = function(parent,nextSibling) {
53
53
  this.labelDomNode.appendChild(this.inputDomNode);
54
54
  this.spanDomNode = this.document.createElement("span");
55
55
  this.labelDomNode.appendChild(this.spanDomNode);
56
+ // Assign data- attributes
57
+ this.assignAttributes(this.inputDomNode,{
58
+ sourcePrefix: "data-",
59
+ destPrefix: "data-"
60
+ });
56
61
  // Add a click event handler
57
62
  $tw.utils.addEventListeners(this.inputDomNode,[
58
63
  {name: "change", handlerObject: this, handlerMethod: "handleChangeEvent"}
@@ -325,6 +330,11 @@ CheckboxWidget.prototype.refresh = function(changedTiddlers) {
325
330
  $tw.utils.removeClass(this.labelDomNode,"tc-checkbox-checked");
326
331
  }
327
332
  }
333
+ this.assignAttributes(this.inputDomNode,{
334
+ changedAttributes: changedAttributes,
335
+ sourcePrefix: "data-",
336
+ destPrefix: "data-"
337
+ });
328
338
  return this.refreshChildren(changedTiddlers) || refreshed;
329
339
  }
330
340
  };
@@ -332,3 +342,4 @@ CheckboxWidget.prototype.refresh = function(changedTiddlers) {
332
342
  exports.checkbox = CheckboxWidget;
333
343
 
334
344
  })();
345
+
@@ -52,6 +52,11 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
52
52
  classes.push("tc-draggable");
53
53
  }
54
54
  domNode.setAttribute("class",classes.join(" "));
55
+ // Assign data- attributes and style. attributes
56
+ this.assignAttributes(domNode,{
57
+ sourcePrefix: "data-",
58
+ destPrefix: "data-"
59
+ });
55
60
  // Insert the node into the DOM and render any children
56
61
  parent.insertBefore(domNode,nextSibling);
57
62
  this.renderChildren(domNode,null);
@@ -108,13 +113,19 @@ DraggableWidget.prototype.updateDomNodeClasses = function() {
108
113
  Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
109
114
  */
110
115
  DraggableWidget.prototype.refresh = function(changedTiddlers) {
111
- var changedAttributes = this.computeAttributes(),
112
- changedAttributesCount = $tw.utils.count(changedAttributes);
113
- if(changedAttributesCount === 1 && changedAttributes["class"]) {
114
- this.updateDomNodeClasses();
115
- } else if(changedAttributesCount > 0) {
116
+ var changedAttributes = this.computeAttributes();
117
+ if(changedAttributes.tag || changedAttributes.selector || changedAttributes.dragimagetype || changedAttributes.enable || changedAttributes.startactions || changedAttributes.endactions) {
116
118
  this.refreshSelf();
117
119
  return true;
120
+ } else {
121
+ if(changedAttributes["class"]) {
122
+ this.assignDomNodeClasses();
123
+ }
124
+ this.assignAttributes(this.domNodes[0],{
125
+ changedAttributes: changedAttributes,
126
+ sourcePrefix: "data-",
127
+ destPrefix: "data-"
128
+ });
118
129
  }
119
130
  return this.refreshChildren(changedTiddlers);
120
131
  };
@@ -42,6 +42,11 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
42
42
  domNode = this.document.createElement(tag);
43
43
  this.domNode = domNode;
44
44
  this.assignDomNodeClasses();
45
+ // Assign data- attributes and style. attributes
46
+ this.assignAttributes(domNode,{
47
+ sourcePrefix: "data-",
48
+ destPrefix: "data-"
49
+ });
45
50
  // Add event handlers
46
51
  if(this.droppableEnable) {
47
52
  $tw.utils.addEventListeners(domNode,[
@@ -166,8 +171,15 @@ DroppableWidget.prototype.refresh = function(changedTiddlers) {
166
171
  if(changedAttributes.tag || changedAttributes.enable || changedAttributes.disabledClass || changedAttributes.actions || changedAttributes.effect) {
167
172
  this.refreshSelf();
168
173
  return true;
169
- } else if(changedAttributes["class"]) {
170
- this.assignDomNodeClasses();
174
+ } else {
175
+ if(changedAttributes["class"]) {
176
+ this.assignDomNodeClasses();
177
+ }
178
+ this.assignAttributes(this.domNodes[0],{
179
+ changedAttributes: changedAttributes,
180
+ sourcePrefix: "data-",
181
+ destPrefix: "data-"
182
+ });
171
183
  }
172
184
  return this.refreshChildren(changedTiddlers);
173
185
  };