mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
c0f78df48d
4
core/images/home-button.tid
Normal file
4
core/images/home-button.tid
Normal file
@ -0,0 +1,4 @@
|
||||
title: $:/core/images/home-button
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tw-image-home-button tw-image-button" viewBox="81 513 64 54" width="22pt" height="22pt"><g><path d="M 97.04536 522.62083 L 81.364685 531.49067 L 87.85863 531.49067 L 87.85863 566.9699 L 107.49902 566.9699 L 107.49902 552.99265 L 117.95268 552.99265 L 117.95268 566.9699 L 137.59307 566.9699 L 137.59307 531.49067 L 144.086885 531.49067 L 112.72591 513.751 L 107.49902 516.70758 L 107.49902 513.751 L 97.04536 513.751 Z M 94.669443 534.17844 L 103.222493 534.17844 L 103.222493 545.19854 L 94.669443 545.19854 Z M 108.449266 534.17844 L 117.002435 534.17844 L 117.002435 545.19854 L 108.449266 545.19854 Z M 122.387575 534.17844 L 130.9405 534.17844 L 130.9405 545.19854 L 122.387575 545.19854 Z"/></g></svg>
|
4
core/images/menu-button.tid
Normal file
4
core/images/menu-button.tid
Normal file
@ -0,0 +1,4 @@
|
||||
title: $:/core/images/menu-button
|
||||
tags: $:/tags/Image
|
||||
|
||||
<svg class="tw-image-menu-button tw-image-button" viewBox="216 585 63 45" width="22pt" height="22pt"><g><path d="M 274.5 585 L 229.5 585 C 227.01472 585 225 587.01472 225 589.5 L 225 589.5 C 225 591.98528 227.01472 594 229.5 594 L 274.5 594 C 276.98528 594 279 591.98528 279 589.5 L 279 589.5 C 279 587.01472 276.98528 585 274.5 585 Z"/><path d="M 274.5 603 L 229.5 603 C 227.01472 603 225 605.01472 225 607.5 L 225 607.5 C 225 609.98528 227.01472 612 229.5 612 L 274.5 612 C 276.98528 612 279 609.98528 279 607.5 L 279 607.5 C 279 605.01472 276.98528 603 274.5 603 Z"/><path d="M 274.5 621 L 229.5 621 C 227.01472 621 225 623.01472 225 625.5 L 225 625.5 C 225 627.9853 227.01472 630 229.5 630 L 274.5 630 C 276.98528 630 279 627.9853 279 625.5 L 279 625.5 C 279 623.01472 276.98528 621 274.5 621 Z"/></g></svg>
|
@ -5,6 +5,7 @@ ClassicWarning/Upgrade/Caption: upgrade
|
||||
CloseAll/Button: close all
|
||||
ConfirmDeleteTiddler: Do you wish to delete the tiddler "<$text text=<<title>>/>"?
|
||||
ConfirmOverwriteTiddler: Do you wish to overwrite the tiddler "<$text text=<<title>>/>"?
|
||||
InvalidFieldName: Illegal characters in field name "<$text text=<<fieldName>>/>". Fields can only contain lowercase letters and the characters underscore (`_`), hyphen (`-`) and period (`.`)
|
||||
MissingTiddler/Hint: Missing tiddler "<$text text=<<currentTiddler>>/>" - click {{$:/core/images/edit-button}} to create
|
||||
RecentChanges/DateFormat: DDth MMM YYYY
|
||||
RelativeDate/Future/Days: <<period>> days from now
|
||||
|
@ -25,7 +25,7 @@ var ZoominListView = function(listWidget) {
|
||||
}
|
||||
domNode.style.position = "absolute";
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
ZoominListView.prototype.navigateTo = function(historyInfo) {
|
||||
var duration = $tw.utils.getAnimationDuration(),
|
||||
|
@ -55,25 +55,20 @@ Handle a scroll event hitting the page document
|
||||
*/
|
||||
PageScroller.prototype.scrollIntoView = function(element) {
|
||||
var duration = $tw.utils.getAnimationDuration();
|
||||
// Get the offset bounds of the element
|
||||
var bounds = {
|
||||
left: element.offsetLeft,
|
||||
top: element.offsetTop,
|
||||
width: element.offsetWidth,
|
||||
height: element.offsetHeight
|
||||
};
|
||||
// Walk up the tree adjusting the offset bounds by each offsetParent
|
||||
while(element.offsetParent) {
|
||||
element = element.offsetParent;
|
||||
bounds.left += element.offsetLeft;
|
||||
bounds.top += element.offsetTop;
|
||||
}
|
||||
// Now get ready to scroll the body
|
||||
this.cancelScroll();
|
||||
this.startTime = new Date();
|
||||
var scrollPosition = $tw.utils.getScrollPosition(),
|
||||
// We'll consider the horizontal and vertical scroll directions separately via this function
|
||||
getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
|
||||
var scrollPosition = $tw.utils.getScrollPosition();
|
||||
// Get the client bounds of the element and adjust by the scroll position
|
||||
var clientBounds = element.getBoundingClientRect(),
|
||||
bounds = {
|
||||
left: clientBounds.left + scrollPosition.x,
|
||||
top: clientBounds.top + scrollPosition.y,
|
||||
width: clientBounds.width,
|
||||
height: clientBounds.height
|
||||
};
|
||||
// We'll consider the horizontal and vertical scroll directions separately via this function
|
||||
var getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
|
||||
// If the target is above/left of the current view, then scroll to it's top/left
|
||||
if(targetPos <= currentPos) {
|
||||
return targetPos;
|
||||
|
@ -71,10 +71,20 @@ FieldManglerWidget.prototype.handleRemoveFieldEvent = function(event) {
|
||||
};
|
||||
|
||||
FieldManglerWidget.prototype.handleAddFieldEvent = function(event) {
|
||||
var tiddler = this.wiki.getTiddler(this.mangleTitle);
|
||||
var tiddler = this.wiki.getTiddler(this.mangleTitle),
|
||||
fieldValidatorRegEx = /^[a-z\-\._]+$/mg;
|
||||
if(tiddler && typeof event.param === "string") {
|
||||
var name = event.param.toLowerCase();
|
||||
if(name !== "" && !$tw.utils.hop(tiddler.fields,name)) {
|
||||
if(!fieldValidatorRegEx.test(name)) {
|
||||
alert($tw.language.getString(
|
||||
"InvalidFieldName",
|
||||
{variables:
|
||||
{fieldName: name}
|
||||
}
|
||||
));
|
||||
return true;
|
||||
}
|
||||
var addition = this.wiki.getModificationFields();
|
||||
addition[name] = "";
|
||||
this.wiki.addTiddler(new $tw.Tiddler(tiddler,addition));
|
||||
|
184
core/modules/widgets/scrollable.js
Normal file
184
core/modules/widgets/scrollable.js
Normal file
@ -0,0 +1,184 @@
|
||||
/*\
|
||||
title: $:/core/modules/widgets/scrollable.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Scrollable widget
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var ScrollableWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
this.scaleFactor = 1;
|
||||
this.addEventListeners([
|
||||
{type: "tw-scroll", handler: "handleScrollEvent"}
|
||||
]);
|
||||
if($tw.browser) {
|
||||
this.requestAnimationFrame = window.requestAnimationFrame ||
|
||||
window.webkitRequestAnimationFrame ||
|
||||
window.mozRequestAnimationFrame ||
|
||||
function(callback) {
|
||||
return window.setTimeout(callback, 1000/60);
|
||||
};
|
||||
this.cancelAnimationFrame = window.cancelAnimationFrame ||
|
||||
window.webkitCancelAnimationFrame ||
|
||||
window.webkitCancelRequestAnimationFrame ||
|
||||
window.mozCancelAnimationFrame ||
|
||||
window.mozCancelRequestAnimationFrame ||
|
||||
function(id) {
|
||||
window.clearTimeout(id);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
ScrollableWidget.prototype = new Widget();
|
||||
|
||||
ScrollableWidget.prototype.cancelScroll = function() {
|
||||
if(this.idRequestFrame) {
|
||||
this.cancelAnimationFrame.call(window,this.idRequestFrame);
|
||||
this.idRequestFrame = null;
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Handle a scroll event
|
||||
*/
|
||||
ScrollableWidget.prototype.handleScrollEvent = function(event) {
|
||||
// Pass the scroll event through if our offsetsize is larger than our scrollsize
|
||||
if(this.outerDomNode.scrollWidth <= this.outerDomNode.offsetWidth && this.outerDomNode.scrollHeight <= this.outerDomNode.offsetHeight && this.fallthrough === "yes") {
|
||||
return true;
|
||||
}
|
||||
this.scrollIntoView(event.target);
|
||||
return false; // Handled event
|
||||
};
|
||||
|
||||
/*
|
||||
Scroll an element into view
|
||||
*/
|
||||
ScrollableWidget.prototype.scrollIntoView = function(element) {
|
||||
var duration = $tw.utils.getAnimationDuration();
|
||||
this.cancelScroll();
|
||||
this.startTime = new Date();
|
||||
var scrollPosition = {
|
||||
x: this.outerDomNode.scrollLeft,
|
||||
y: this.outerDomNode.scrollTop
|
||||
};
|
||||
// Get the client bounds of the element and adjust by the scroll position
|
||||
var scrollableBounds = this.outerDomNode.getBoundingClientRect(),
|
||||
clientTargetBounds = element.getBoundingClientRect(),
|
||||
bounds = {
|
||||
left: clientTargetBounds.left + scrollPosition.x - scrollableBounds.left,
|
||||
top: clientTargetBounds.top + scrollPosition.y - scrollableBounds.top,
|
||||
width: clientTargetBounds.width,
|
||||
height: clientTargetBounds.height
|
||||
};
|
||||
// We'll consider the horizontal and vertical scroll directions separately via this function
|
||||
var getEndPos = function(targetPos,targetSize,currentPos,currentSize) {
|
||||
// If the target is already visible then stay where we are
|
||||
if(targetPos >= currentPos && (targetPos + targetSize) <= (currentPos + currentSize)) {
|
||||
return currentPos;
|
||||
// If the target is above/left of the current view, then scroll to its top/left
|
||||
} else if(targetPos <= currentPos) {
|
||||
return targetPos;
|
||||
// If the target is smaller than the window and the scroll position is too far up, then scroll till the target is at the bottom of the window
|
||||
} else if(targetSize < currentSize && currentPos < (targetPos + targetSize - currentSize)) {
|
||||
return targetPos + targetSize - currentSize;
|
||||
// If the target is big, then just scroll to the top
|
||||
} else if(currentPos < targetPos) {
|
||||
return targetPos;
|
||||
// Otherwise, stay where we are
|
||||
} else {
|
||||
return currentPos;
|
||||
}
|
||||
},
|
||||
endX = getEndPos(bounds.left,bounds.width,scrollPosition.x,this.outerDomNode.offsetWidth),
|
||||
endY = getEndPos(bounds.top,bounds.height,scrollPosition.y,this.outerDomNode.offsetHeight);
|
||||
// Only scroll if necessary
|
||||
if(endX !== scrollPosition.x || endY !== scrollPosition.y) {
|
||||
var self = this,
|
||||
drawFrame;
|
||||
drawFrame = function () {
|
||||
var t;
|
||||
if(duration <= 0) {
|
||||
t = 1;
|
||||
} else {
|
||||
t = ((new Date()) - self.startTime) / duration;
|
||||
}
|
||||
if(t >= 1) {
|
||||
self.cancelScroll();
|
||||
t = 1;
|
||||
}
|
||||
t = $tw.utils.slowInSlowOut(t);
|
||||
self.outerDomNode.scrollLeft = scrollPosition.x + (endX - scrollPosition.x) * t;
|
||||
self.outerDomNode.scrollTop = scrollPosition.y + (endY - scrollPosition.y) * t;
|
||||
if(t < 1) {
|
||||
self.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame);
|
||||
}
|
||||
};
|
||||
drawFrame();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
ScrollableWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
// Remember parent
|
||||
this.parentDomNode = parent;
|
||||
// Compute attributes and execute state
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Create elements
|
||||
this.outerDomNode = this.document.createElement("div");
|
||||
$tw.utils.setStyle(this.outerDomNode,[
|
||||
{overflowY: "auto"},
|
||||
{overflowX: "auto"},
|
||||
{webkitOverflowScrolling: "touch"}
|
||||
]);
|
||||
this.innerDomNode = this.document.createElement("div");
|
||||
this.outerDomNode.appendChild(this.innerDomNode);
|
||||
// Assign classes
|
||||
this.outerDomNode.className = this["class"] || "";
|
||||
// Insert element
|
||||
parent.insertBefore(this.outerDomNode,nextSibling);
|
||||
this.renderChildren(this.innerDomNode,null);
|
||||
this.domNodes.push(this.outerDomNode);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
ScrollableWidget.prototype.execute = function() {
|
||||
// Get attributes
|
||||
this.fallthrough = this.getAttribute("fallthrough","yes");
|
||||
this["class"] = this.getAttribute("class");
|
||||
// Make child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
ScrollableWidget.prototype.refresh = function(changedTiddlers) {
|
||||
var changedAttributes = this.computeAttributes();
|
||||
if(changedAttributes["class"]) {
|
||||
this.refreshSelf();
|
||||
return true;
|
||||
}
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
exports.scrollable = ScrollableWidget;
|
||||
|
||||
})();
|
29
core/modules/widgets/storyviews.js
Normal file
29
core/modules/widgets/storyviews.js
Normal file
@ -0,0 +1,29 @@
|
||||
/*\
|
||||
title: $:/core/modules/filters/storyviews.js
|
||||
type: application/javascript
|
||||
module-type: filteroperator
|
||||
|
||||
Filter operator for returning the names of the story views in this wiki
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
Export our filter function
|
||||
*/
|
||||
exports.storyviews = function(source,operator,options) {
|
||||
var results = [],
|
||||
storyviews = {};
|
||||
$tw.modules.applyMethods("storyview",storyviews);
|
||||
$tw.utils.each(storyviews,function(info,name) {
|
||||
results.push(name);
|
||||
});
|
||||
results.sort();
|
||||
return results;
|
||||
};
|
||||
|
||||
})();
|
@ -5,10 +5,19 @@ tags: $:/tags/EditTemplate
|
||||
\define tag-styles()
|
||||
background-color:$(backgroundColor)$;
|
||||
\end
|
||||
<div class="tw-edit-tags"><$fieldmangler><$list filter="[is[current]tags[]sort[title]]" storyview="pop"><$set name="backgroundColor" value={{!!color}}><span style=<<tag-styles>> class="tw-tag-label"><$view field="title" format="text" /><$button message="tw-remove-tag" param={{!!title}} class="btn-invisible tw-remove-tag-button">×</$button></span></$set>
|
||||
</$list>
|
||||
<div class="tw-edit-tags">
|
||||
<$fieldmangler>
|
||||
<$list filter="[is[current]tags[]sort[title]]" storyview="pop" template="$:/core/ui/TagEditTemplate"/>
|
||||
|
||||
<div class="tw-edit-add-tag"><span class="tw-add-tag-name"><$edit-text tiddler="$:/temp/NewTagName" tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/tagsAutoComplete">> class="tw-edit-texteditor"/></span> <$button popup=<<qualify "$:/state/tagsAutoComplete">> class="btn-invisible btn-dropdown">{{$:/core/images/down-arrow}}</$button> <span class="tw-add-tag-button"><$button message="tw-add-tag" param={{$:/temp/NewTagName}} set="$:/temp/NewTagName" setTo="" class=""><<lingo Tags/Add/Button>></$button></span></div>
|
||||
<div class="tw-edit-add-tag">
|
||||
<span class="tw-add-tag-name">
|
||||
<$edit-text tiddler="$:/temp/NewTagName" tag="input" default="" placeholder={{$:/language/EditTemplate/Tags/Add/Placeholder}} focusPopup=<<qualify "$:/state/tagsAutoComplete">> class="tw-edit-texteditor"/>
|
||||
</span> <$button popup=<<qualify "$:/state/tagsAutoComplete">> class="btn-invisible btn-dropdown">{{$:/core/images/down-arrow}}</$button> <span class="tw-add-tag-button">
|
||||
<$button message="tw-add-tag" param={{$:/temp/NewTagName}} set="$:/temp/NewTagName" setTo="" class="">
|
||||
<<lingo Tags/Add/Button>>
|
||||
</$button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="tw-block-dropdown-wrapper">
|
||||
|
||||
@ -18,7 +27,13 @@ background-color:$(backgroundColor)$;
|
||||
|
||||
<$linkcatcher set="$:/temp/NewTagName" setTo="" message="tw-add-tag">
|
||||
<$list filter="[!is[shadow]tags[]search{$:/temp/NewTagName}sort[title]]">
|
||||
<$link><$set name="backgroundColor" value={{!!color}}><span style=<<tag-styles>> class="tw-tag-label"><$view field="title" format="text"/></span></$set></$link>
|
||||
<$link>
|
||||
<$set name="backgroundColor" value={{!!color}}>
|
||||
<span style=<<tag-styles>> class="tw-tag-label">
|
||||
<$view field="title" format="text"/>
|
||||
</span>
|
||||
</$set>
|
||||
</$link>
|
||||
</$list>
|
||||
</$linkcatcher>
|
||||
|
||||
|
@ -42,6 +42,16 @@ $$$text/vnd.tiddlywiki>text/html
|
||||
$src$
|
||||
$$$
|
||||
|
||||
\end
|
||||
\define wikitext-example-without-html(src)
|
||||
```
|
||||
$src$
|
||||
```
|
||||
|
||||
Renders as:
|
||||
|
||||
$src$
|
||||
|
||||
\end
|
||||
\define lingo-base()
|
||||
$:/lingo/
|
||||
|
8
core/ui/PageTemplate/alerts.tid
Normal file
8
core/ui/PageTemplate/alerts.tid
Normal file
@ -0,0 +1,8 @@
|
||||
title: $:/core/ui/PageTemplate/alerts
|
||||
tags: $:/tags/PageTemplate
|
||||
|
||||
<div class="tw-alerts">
|
||||
|
||||
<$list filter="[is[shadow]!has[draft.of]tag[$:/tags/Alert]] [!is[shadow]!has[draft.of]tag[$:/tags/Alert]] +[sort[modified]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
|
||||
|
||||
</div>
|
@ -1,7 +1,11 @@
|
||||
title: $:/core/ui/PageTemplate/sidebar
|
||||
tags: $:/tags/PageTemplate
|
||||
|
||||
<header class="sidebar-header">
|
||||
<$scrollable fallthrough="no" class="tw-sidebar-scrollable">
|
||||
|
||||
<div class="sidebar-header">
|
||||
|
||||
<$reveal state="$:/state/sidebar" type="match" text="yes" default="yes" retain="yes">
|
||||
|
||||
<div class="titlebar">{{$:/SiteTitle}}</div>
|
||||
<div class="tw-subtitle">{{$:/SiteSubtitle}}</div>
|
||||
@ -14,4 +18,8 @@ tags: $:/tags/PageTemplate
|
||||
|
||||
{{$:/core/ui/SideBarLists}}
|
||||
|
||||
</header>
|
||||
</$reveal>
|
||||
|
||||
</div>
|
||||
|
||||
</$scrollable>
|
||||
|
@ -3,15 +3,6 @@ tags: $:/tags/PageTemplate
|
||||
|
||||
<section class="story-river">
|
||||
|
||||
<!-- Alerts -->
|
||||
<div class="tw-alerts">
|
||||
|
||||
<$list filter="[is[shadow]!has[draft.of]tag[$:/tags/Alert]] [!is[shadow]!has[draft.of]tag[$:/tags/Alert]] +[sort[modified]]" template="$:/core/ui/AlertTemplate" storyview="pop"/>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- The main story -->
|
||||
<$list filter="[list[$:/StoryList]]" history="$:/HistoryList" template="$:/core/ui/ViewTemplate" editTemplate="$:/core/ui/EditTemplate" storyview={{$:/view}} />
|
||||
|
||||
<!-- End of story river -->
|
||||
</section>
|
||||
|
6
core/ui/PageTemplate/topleftbar.tid
Normal file
6
core/ui/PageTemplate/topleftbar.tid
Normal file
@ -0,0 +1,6 @@
|
||||
title: $:/core/ui/PageTemplate/topleftbar
|
||||
tags: $:/tags/PageTemplate
|
||||
|
||||
<span class="tw-topbar tw-topbar-left">
|
||||
<$list filter="[is[shadow]!has[draft.of]tag[$:/tags/TopLeftBar]] [!is[shadow]!has[draft.of]tag[$:/tags/TopLeftBar]] +[tag[$:/tags/TopLeftBar]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
|
||||
</span>
|
6
core/ui/PageTemplate/toprightbar.tid
Normal file
6
core/ui/PageTemplate/toprightbar.tid
Normal file
@ -0,0 +1,6 @@
|
||||
title: $:/core/ui/PageTemplate/toprightbar
|
||||
tags: $:/tags/PageTemplate
|
||||
|
||||
<span class="tw-topbar tw-topbar-right">
|
||||
<$list filter="[is[shadow]!has[draft.of]tag[$:/tags/TopRightBar]] [!is[shadow]!has[draft.of]tag[$:/tags/TopRightBar]] +[tag[$:/tags/TopRightBar]]" variable="listItem"><$transclude tiddler=<<listItem>>/></$list>
|
||||
</span>
|
16
core/ui/TagEditTemplate.tid
Normal file
16
core/ui/TagEditTemplate.tid
Normal file
@ -0,0 +1,16 @@
|
||||
title: $:/core/ui/TagEditTemplate
|
||||
|
||||
\define tag-styles()
|
||||
background-color:$(backgroundColor)$;
|
||||
\end
|
||||
<$set name="backgroundColor" value={{!!color}}>
|
||||
<$button popup=<<qualify "$:/state/tagpopup">> class="btn-invisible tw-tag-label" style=<<tag-styles>>>
|
||||
<$view field="title" format="text" />
|
||||
<$button message="tw-remove-tag" param={{!!title}} class="btn-invisible tw-remove-tag-button">×</$button>
|
||||
</$button>
|
||||
</$set>
|
||||
<$reveal state=<<qualify "$:/state/tagpopup">> type="popup" position="below" animate="yes"><div class="tw-drop-down"><$transclude tiddler="$:/core/ui/ListItemTemplate"/>
|
||||
<hr>
|
||||
<$list filter="[is[current]tagging[]]" template="$:/core/ui/ListItemTemplate"/>
|
||||
</div>
|
||||
</$reveal>
|
4
core/ui/TopLeftBar/home.tid
Normal file
4
core/ui/TopLeftBar/home.tid
Normal file
@ -0,0 +1,4 @@
|
||||
title: $:/core/ui/TopBar/home
|
||||
tags: $:/tags/TopLeftBar
|
||||
|
||||
<$button message="tw-home" class="btn-invisible">{{$:/core/images/home-button}}</$button>
|
9
core/ui/TopRightBar/menu.tid
Normal file
9
core/ui/TopRightBar/menu.tid
Normal file
@ -0,0 +1,9 @@
|
||||
title: $:/core/ui/TopBar/menu
|
||||
tags: $:/tags/TopRightBar
|
||||
|
||||
<$reveal state="$:/state/sidebar" type="nomatch" text="no">
|
||||
<$button set="$:/state/sidebar" setTo="no" class="btn-invisible">{{$:/core/images/menu-button}}</$button>
|
||||
</$reveal>
|
||||
<$reveal state="$:/state/sidebar" type="match" text="no">
|
||||
<$button set="$:/state/sidebar" setTo="yes" class="btn-invisible">{{$:/core/images/menu-button}}</$button>
|
||||
</$reveal>
|
@ -1,3 +1,3 @@
|
||||
title: $:/tags/PageTemplate
|
||||
list: [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]]
|
||||
list: [[$:/core/ui/PageTemplate/sidebar]] [[$:/core/ui/PageTemplate/story]] [[$:/core/ui/PageTemplate/alerts]] [[$:/core/ui/PageTemplate/topleftbar]] [[$:/core/ui/PageTemplate/toprightbar]]
|
||||
|
||||
|
@ -3,7 +3,7 @@ title: $:/snippets/viewswitcher
|
||||
\define lingo-base() $:/language/ControlPanel/Appearance/StoryView/
|
||||
<<lingo Prompt>> {{$:/view}}
|
||||
|
||||
<$linkcatcher to="$:/view"><$list filter="classic zoomin pop"><div><$reveal state="$:/view" type="match" text={{!!title}}>•</$reveal><$reveal state="$:/view" type="nomatch" text={{!!title}}> </$reveal> <$link to={{!!title}}><$view field="title"/></$link>
|
||||
<$linkcatcher to="$:/view"><$list filter="[storyviews[]]"><div><$reveal state="$:/view" type="match" text={{!!title}}>•</$reveal><$reveal state="$:/view" type="nomatch" text={{!!title}}> </$reveal> <$link to={{!!title}}><$view field="title"/></$link>
|
||||
</div>
|
||||
</$list>
|
||||
</$linkcatcher>
|
||||
|
@ -14,10 +14,10 @@ We have an email discussion list, too: https://groups.google.com/forum/#!members
|
||||
|
||||
The second OXTWIG meeting was held on Thursday 16th January 2014:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube.com/embed/WOK_nVBf_6U" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" height="315" src="http://www.youtube.com/embed/WOK_nVBf_6U" frameborder="0" allowfullscreen></iframe>
|
||||
|
||||
! OXTWIG #1
|
||||
|
||||
The first OXTWIG meeting was held on Thursday 21st November 2013:
|
||||
|
||||
<iframe width="560" height="315" src="//www.youtube.com/embed/tpNf_Dms_TE" frameborder="0" allowfullscreen></iframe>
|
||||
<iframe width="560" height="315" src="http://www.youtube.com/embed/tpNf_Dms_TE" frameborder="0" allowfullscreen></iframe>
|
||||
|
@ -1,6 +1,7 @@
|
||||
title: FilterOperators
|
||||
created: 20140303091312363
|
||||
modified: 20140303091312363
|
||||
modified: 20140324221721972
|
||||
title: FilterOperators
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
The available filter operators are listed here. See TiddlerFilters for an introduction to tiddler filters and how they are used.
|
||||
|
||||
@ -39,6 +40,8 @@ The available filter operators are listed here. See TiddlerFilters for an introd
|
||||
* ''bl'': another synonym for ''butlast''
|
||||
* ''nth'': selects the n-th tiddler of the list. Defaults to n = 1
|
||||
* ''indexes'': selects the names of the indexes within a [[DataTiddler|DataTiddlers]]
|
||||
* ''moduletypes'': selects the list of types of all the loaded modules
|
||||
* ''storyviews'': selects the list of names of loaded storyviews
|
||||
|
||||
The operands available with the `is` operator are:
|
||||
|
||||
|
3
editions/tw5.com/tiddlers/howtos/CurvedText.tid
Normal file
3
editions/tw5.com/tiddlers/howtos/CurvedText.tid
Normal file
@ -0,0 +1,3 @@
|
||||
title: $:/CurvedText
|
||||
|
||||
Everything in federation
|
@ -0,0 +1,26 @@
|
||||
created: 20140324223413403
|
||||
modified: 20140324223524945
|
||||
tags: howto
|
||||
title: Making curved text with SVG
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
\define textOnPath(text)
|
||||
$$$.svg
|
||||
<svg width="100%" height="100%" viewBox="0 0 1000 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<defs>
|
||||
<path id="MyPath" d="M 100 200 C 200 100 300 0 400 100 C 500 200 600 300 700 200 C 800 100 900 100 900 100"/>
|
||||
</defs>
|
||||
<use xlink:href="#MyPath" fill="none" stroke="#ddd"/>
|
||||
<text font-family="'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif" font-size="42.5">
|
||||
<textPath xlink:href="#MyPath">
|
||||
$text$
|
||||
</textPath>
|
||||
</text>
|
||||
</svg>
|
||||
$$$
|
||||
\end
|
||||
This demo shows how to use SVG to render transcluded text along a path. Enter some text in the textbox below to try it out; view the source to see how it is done.
|
||||
|
||||
<$edit-text tiddler="$:/CurvedText" tag="input" placeholder="Type text here" default=""/>
|
||||
|
||||
<$macrocall $name="textOnPath" text={{$:/CurvedText}}/>
|
@ -1,5 +1,8 @@
|
||||
title: $:/editions/tw5.com/github-fork-ribbon
|
||||
tags: $:/tags/PageTemplate
|
||||
tags: $:/tags/PageControls
|
||||
|
||||
<div class="github-fork-ribbon-wrapper right" style>
|
||||
|
||||
<div class="github-fork-ribbon" style="background-color:#A3D53A;"><$link to="ReleaseHistory"><<version>></$link></div>
|
||||
|
||||
<div class="github-fork-ribbon-wrapper right" style><div class="github-fork-ribbon" style="background-color:#A3D53A;"><$link to="ReleaseHistory"><<version>></$link></div>
|
||||
</div>
|
@ -32,3 +32,10 @@ tags: $:/tags/stylesheet
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.tw-scrollable-demo {
|
||||
border: 1px solid <<colour message-border>>;
|
||||
background-color: <<colour message-background>>;
|
||||
padding: 1em;
|
||||
height: 400px;
|
||||
}
|
||||
|
46
editions/tw5.com/tiddlers/widgets/ScrollableWidget.tid
Normal file
46
editions/tw5.com/tiddlers/widgets/ScrollableWidget.tid
Normal file
@ -0,0 +1,46 @@
|
||||
created: 20140324223413403
|
||||
modified: 20140324223524945
|
||||
tags: widget
|
||||
title: ScrollableWidget
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
! Introduction
|
||||
|
||||
The scrollable widget wraps its content in a scrollable frame. The user can scroll the contents with the mouse or with touch gestures. Code can use the [[WidgetMessage: tw-scroll]] to programmatically scroll specific DOM nodes into view.
|
||||
|
||||
! Content and Attributes
|
||||
|
||||
The content of the `<$scrollable>` widget is displayed within a pair of wrapper DIVs. If the inner DIV is larger then it scrolls within the outer one. CSS is used to specify the size of the outer wrapper.
|
||||
|
||||
|!Attribute |!Description |
|
||||
|class |The CSS class(es) to be applied to the outer DIV |
|
||||
|fallthrough |See below |
|
||||
|
||||
If a scrollable widget can't handle the `tw-scroll` message because the inner DIV fits within the outer DIV, then by default the message falls through to the parent widget. Setting the ''fallthrough'' attribute to `no` prevents this behaviour.
|
||||
|
||||
! Examples
|
||||
|
||||
This example requires the following CSS definitions from [[$:/_tw5.com-styles]]:
|
||||
|
||||
```
|
||||
.tw-scrollable-demo {
|
||||
border: 1px solid <<colour message-border>>;
|
||||
background-color: <<colour message-background>>;
|
||||
padding: 1em;
|
||||
height: 400px;
|
||||
}
|
||||
```
|
||||
|
||||
This wiki text shows how to display a list within the scrollable widget:
|
||||
|
||||
<<wikitext-example-without-html "<$scrollable class='tw-scrollable-demo'>
|
||||
<$list filter='[!is[system]]'>
|
||||
|
||||
<$view field='title'/>: <$list filter='[is[current]links[]sort[title]]' storyview='pop'>
|
||||
<$link><$view field='title'/></$link>
|
||||
</$list>
|
||||
|
||||
</$list>
|
||||
</$scrollable>
|
||||
">>
|
||||
|
@ -1,5 +1,6 @@
|
||||
{
|
||||
"plugins": [
|
||||
"tiddlywiki/cecily",
|
||||
"tiddlywiki/fullscreen",
|
||||
"tiddlywiki/googleanalytics",
|
||||
"tiddlywiki/nodewebkitsaver",
|
||||
|
143
plugins/tiddlywiki/cecily/cecily.js
Normal file
143
plugins/tiddlywiki/cecily/cecily.js
Normal file
@ -0,0 +1,143 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/cecily/cecily.js
|
||||
type: application/javascript
|
||||
module-type: storyview
|
||||
|
||||
Positions tiddlers on a 2D map
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var CecilyStoryView = function(listWidget) {
|
||||
var self = this;
|
||||
this.listWidget = listWidget;
|
||||
// Load the map
|
||||
this.loadMap();
|
||||
// Position the existing tiddlers
|
||||
$tw.utils.each(this.listWidget.children,function(itemWidget,index) {
|
||||
var domNode = itemWidget.findFirstDomNode();
|
||||
domNode.style.position = "absolute";
|
||||
var title = itemWidget.parseTreeNode.itemTitle;
|
||||
self.positionTiddler(title,domNode);
|
||||
});
|
||||
};
|
||||
|
||||
CecilyStoryView.prototype.navigateTo = function(historyInfo) {
|
||||
var listElementIndex = this.listWidget.findListItem(0,historyInfo.title);
|
||||
if(listElementIndex === undefined) {
|
||||
return;
|
||||
}
|
||||
var listItemWidget = this.listWidget.children[listElementIndex],
|
||||
targetElement = listItemWidget.findFirstDomNode();
|
||||
// Scroll the node into view
|
||||
this.listWidget.dispatchEvent({type: "tw-scroll", target: targetElement});
|
||||
};
|
||||
|
||||
CecilyStoryView.prototype.insert = function(widget) {
|
||||
var domNode = widget.findFirstDomNode(),
|
||||
duration = $tw.utils.getAnimationDuration();
|
||||
// Make the newly inserted node position absolute
|
||||
$tw.utils.setStyle(domNode,[
|
||||
{position: "absolute"},
|
||||
{transition: ""},
|
||||
{opacity: "0.0"}
|
||||
]);
|
||||
// Position it
|
||||
var title = widget.parseTreeNode.itemTitle;
|
||||
this.positionTiddler(title,domNode);
|
||||
$tw.utils.forceLayout(domNode);
|
||||
// Animate it in
|
||||
$tw.utils.setStyle(domNode,[
|
||||
{transition: "opacity " + duration + "ms ease-out"},
|
||||
{opacity: "1.0"}
|
||||
]);
|
||||
};
|
||||
|
||||
CecilyStoryView.prototype.remove = function(widget) {
|
||||
var targetElement = widget.findFirstDomNode(),
|
||||
duration = $tw.utils.getAnimationDuration();
|
||||
// Remove the widget at the end of the transition
|
||||
setTimeout(function() {
|
||||
widget.removeChildDomNodes();
|
||||
},duration);
|
||||
// Animate the closure
|
||||
$tw.utils.setStyle(targetElement,[
|
||||
{transition: "none"},
|
||||
{opacity: "1.0"}
|
||||
]);
|
||||
$tw.utils.forceLayout(targetElement);
|
||||
$tw.utils.setStyle(targetElement,[
|
||||
{transition: $tw.utils.roundTripPropertyName("transform") + " " + duration + "ms ease-in-out, " +
|
||||
"opacity " + duration + "ms ease-in-out"},
|
||||
{transform: "scale(0.01)"},
|
||||
{opacity: "0.0"}
|
||||
]);
|
||||
};
|
||||
|
||||
/*
|
||||
Load the current map
|
||||
*/
|
||||
CecilyStoryView.prototype.loadMap = function() {
|
||||
this.map = this.listWidget.wiki.getTiddlerData(this.getMapTiddlerTitle(),{
|
||||
positions: {},
|
||||
newTiddlerPosition: {x: 0, y: 0}
|
||||
});
|
||||
};
|
||||
|
||||
CecilyStoryView.prototype.getMapTiddlerTitle = function() {
|
||||
return this.listWidget.getAttribute("map","$:/TiddlerMap");
|
||||
};
|
||||
|
||||
/*
|
||||
Position a tiddler according to the map
|
||||
*/
|
||||
CecilyStoryView.prototype.positionTiddler = function(title,domNode) {
|
||||
var pos = this.lookupTiddlerInMap(title,domNode),
|
||||
scale = pos.w/domNode.offsetWidth;
|
||||
$tw.utils.setStyle(domNode,[
|
||||
{transformOrigin: "0% 0%"},
|
||||
{transform: "translateX(" + pos.x + "px) translateY(" + pos.y + "px) scale(" + scale + ")"}
|
||||
]);
|
||||
};
|
||||
|
||||
// Get the position of a particular tiddler
|
||||
CecilyStoryView.prototype.lookupTiddlerInMap = function(title,domNode) {
|
||||
// If this is a draft tiddler then look for the position of the original tiddler
|
||||
var tiddler = this.listWidget.wiki.getTiddler(title);
|
||||
if(tiddler) {
|
||||
var draftOf = tiddler.fields["draft.of"];
|
||||
if(draftOf && this.map.positions[draftOf]) {
|
||||
return this.map.positions[draftOf]
|
||||
}
|
||||
}
|
||||
// Try looking the target tiddler up in the map
|
||||
if(this.map.positions[title]) {
|
||||
return this.map.positions[title];
|
||||
}
|
||||
// If the tiddler wasn't in the map we'll have to compute it
|
||||
var newPosition;
|
||||
switch(this.map.positionNew) {
|
||||
default: // "right"
|
||||
newPosition = {
|
||||
x: this.map.newTiddlerPosition.x,
|
||||
y: this.map.newTiddlerPosition.y,
|
||||
w: 200,
|
||||
h: 200
|
||||
};
|
||||
this.map.newTiddlerPosition.x += newPosition.w * 1.1;
|
||||
break;
|
||||
}
|
||||
// A default position
|
||||
newPosition = newPosition || {x: 0,y: 0,w: 100,h: 100};
|
||||
// Save the position back to the map
|
||||
this.map.positions[title] = newPosition;
|
||||
return newPosition;
|
||||
};
|
||||
|
||||
exports.cecily = CecilyStoryView;
|
||||
|
||||
})();
|
6
plugins/tiddlywiki/cecily/plugin.info
Normal file
6
plugins/tiddlywiki/cecily/plugin.info
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "$:/plugins/tiddlywiki/cecily",
|
||||
"description": "Zoomable User Interface for TiddlyWiki",
|
||||
"author": "JeremyRuston",
|
||||
"core-version": ">=5.0.0"
|
||||
}
|
@ -17,10 +17,10 @@ tags: [[$:/tags/stylesheet]]
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
html .sidebar-header {
|
||||
html .tw-sidebar-scrollable {
|
||||
text-align: left;
|
||||
left: 50%;
|
||||
right: 0;
|
||||
padding-left: 413px;
|
||||
margin-left: 343px;
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
title: $:/themes/tiddlywiki/nighttime/base
|
||||
tags: [[$:/tags/stylesheet]]
|
||||
|
||||
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline
|
||||
|
||||
html body.tw-body {
|
||||
background-color: #5C5D8E;
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"title": "$:/themes/tiddlywiki/nighttime",
|
||||
"name": "Night-time",
|
||||
"author": "JeremyRuston",
|
||||
"core-version": ">=5.0.0",
|
||||
"plugin-type": "theme",
|
||||
"description": "A darker theme",
|
||||
"dependents": ["$:/themes/tiddlywiki/vanilla"]
|
||||
}
|
@ -7,10 +7,6 @@ tags: [[$:/tags/stylesheet]]
|
||||
text-shadow: 0 1px 0 <<colour sidebar-foreground-shadow>>;
|
||||
}
|
||||
|
||||
.tw-page-controls svg {
|
||||
<<transition "fill 150ms ease-in-out">>
|
||||
}
|
||||
|
||||
.tw-tiddler-info {
|
||||
<<box-shadow "inset 1px 2px 3px rgba(0,0,0,0.1)">>
|
||||
}
|
||||
@ -27,7 +23,7 @@ tags: [[$:/tags/stylesheet]]
|
||||
}
|
||||
}
|
||||
|
||||
.tw-tiddler-controls button svg {
|
||||
.tw-page-controls button svg, .tw-tiddler-controls button svg, .tw-topbar button svg {
|
||||
<<transition "fill 150ms ease-in-out">>
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@ Placeholder for a more thorough refinement of Snow White
|
||||
src: local("Arvo"), url(<<datauri "$:/themes/tiddlywiki/starlight/arvo.woff">>) format("woff");
|
||||
}
|
||||
|
||||
html body {
|
||||
html body, .tw-sidebar-scrollable-backdrop {
|
||||
font-family: "Arvo", "Times";
|
||||
background: url(<<datauri "$:/themes/tiddlywiki/starlight/ltbg.jpg">>);
|
||||
}
|
||||
|
@ -245,6 +245,10 @@ a.tw-tiddlylink-external:hover {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.tw-sidebar-lists input {
|
||||
color: <<colour foreground>>;
|
||||
}
|
||||
|
||||
.tw-sidebar-lists button {
|
||||
color: <<colour sidebar-button-foreground>>;
|
||||
}
|
||||
@ -253,7 +257,7 @@ a.tw-tiddlylink-external:hover {
|
||||
color: <<colour sidebar-muted-foreground>>;
|
||||
}
|
||||
|
||||
.btn-mini:hover {
|
||||
.tw-sidebar-lists button.btn-mini:hover {
|
||||
color: <<colour sidebar-muted-foreground-hover>>;
|
||||
}
|
||||
|
||||
@ -312,6 +316,33 @@ a.tw-tiddlylink-external:hover {
|
||||
** Page layout
|
||||
*/
|
||||
|
||||
.tw-topbar {
|
||||
position: fixed;
|
||||
z-index: 1200;
|
||||
}
|
||||
|
||||
.tw-topbar-left {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.tw-topbar-right {
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.tw-topbar button {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.tw-topbar svg {
|
||||
fill: <<colour muted-foreground>>;
|
||||
}
|
||||
|
||||
.tw-topbar svg:hover {
|
||||
fill: <<colour foreground>>;
|
||||
}
|
||||
|
||||
.sidebar-header {
|
||||
color: <<colour sidebar-foreground>>;
|
||||
}
|
||||
@ -386,8 +417,10 @@ a.tw-tiddlylink-external:hover {
|
||||
}
|
||||
|
||||
@media (max-width: {{$:/themes/tiddlywiki/vanilla/metrics##storywidth}}) {
|
||||
|
||||
.sidebar-header {
|
||||
padding: 14px;
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.story-river {
|
||||
@ -397,7 +430,12 @@ a.tw-tiddlylink-external:hover {
|
||||
}
|
||||
|
||||
@media (min-width: {{$:/themes/tiddlywiki/vanilla/metrics##storywidth}}) {
|
||||
.sidebar-header {
|
||||
|
||||
.tw-message-box {
|
||||
margin: 21px -21px 21px -21px;
|
||||
}
|
||||
|
||||
.tw-sidebar-scrollable {
|
||||
position: fixed;
|
||||
top: {{$:/themes/tiddlywiki/vanilla/metrics##storytop}};
|
||||
left: {{$:/themes/tiddlywiki/vanilla/metrics##storyright}};
|
||||
@ -1067,7 +1105,6 @@ canvas.tw-edit-bitmapeditor {
|
||||
border: 1px solid <<colour message-border>>;
|
||||
background: <<colour message-background>>;
|
||||
padding: 0px 21px 0px 21px;
|
||||
margin: 21px -21px 21px -21px;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
color: <<colour message-foreground>>;
|
||||
@ -1122,3 +1159,5 @@ canvas.tw-edit-bitmapeditor {
|
||||
margin: 4px;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user