diff --git a/core/images/info-button.svg b/core/images/info-button.svg new file mode 100644 index 000000000..4aeac24c7 --- /dev/null +++ b/core/images/info-button.svg @@ -0,0 +1,3 @@ + + + diff --git a/core/images/info-button.svg.meta b/core/images/info-button.svg.meta new file mode 100644 index 000000000..ea7c07ab5 --- /dev/null +++ b/core/images/info-button.svg.meta @@ -0,0 +1,2 @@ +title: $:/core/images/info-button.svg +type: image/svg+xml diff --git a/core/modules/filters.js b/core/modules/filters.js index a5fbef221..01af4bb6f 100644 --- a/core/modules/filters.js +++ b/core/modules/filters.js @@ -174,6 +174,22 @@ exports.operators = { return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {$tw.utils.pushTop(subResults,this.getTiddlersWithTag(subResultsTemp[t]));}"; } }, + "links": { // Return outgoing links on selected tiddlers + selector: function(operator) { + return "for(title in source) {r = this.getTiddlerLinks(title); $tw.utils.pushTop(subResults,r);}"; + }, + filter: function(operator) { + return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerLinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}"; + } + }, + "backlinks": { // Return incoming links on selected tiddlers + selector: function(operator) { + return "for(title in source) {r = this.getTiddlerBacklinks(title); $tw.utils.pushTop(subResults,r);}"; + }, + filter: function(operator) { + return "subResultsTemp = subResults;\nsubResults = [];for(t=subResultsTemp.length-1; t>=0; t--) {r = this.getTiddlerBacklinks(subResultsTemp[t]); $tw.utils.pushTop(subResults,r);}"; + } + }, "has": { // Filter by presence of a particular field selector: function(operator) { var op = operator.prefix === "!" ? "=" : "!"; diff --git a/core/modules/widgets/button.js b/core/modules/widgets/button.js index f24ea6f59..f2ac5ca31 100644 --- a/core/modules/widgets/button.js +++ b/core/modules/widgets/button.js @@ -90,17 +90,22 @@ ButtonWidget.prototype.setTiddler = function() { }; ButtonWidget.prototype.handleClickEvent = function(event) { + var handled = false; if(this.message) { this.dispatchMessage(event); + handled = true; } if(this.popup) { this.triggerPopup(event); + handled = true; } if(this.set && this.setTo) { this.setTiddler(); + handled = true; } + event.stopPropagation(); event.preventDefault(); - return false; + return handled; }; ButtonWidget.prototype.handleMouseOverOrOutEvent = function(event) { diff --git a/core/modules/wiki.js b/core/modules/wiki.js index cf7d1aa56..b2b35eab1 100644 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -288,6 +288,21 @@ exports.getTiddlerLinks = function(title) { }); }; +/* +Return an array of tiddler titles that link to the specified tiddler +*/ +exports.getTiddlerBacklinks = function(targetTitle) { + var self = this, + backlinks = []; + this.forEachTiddler(function(title,tiddler) { + var links = self.getTiddlerLinks(title); + if(links.indexOf(targetTitle) !== -1) { + backlinks.push(title); + } + }); + return backlinks; +}; + /* Return a hashmap of tiddler titles that are referenced but not defined. Each value is the number of times the missing tiddler is referenced */ diff --git a/core/styles/base.tid b/core/styles/base.tid index f208ace9a..dff72e323 100644 --- a/core/styles/base.tid +++ b/core/styles/base.tid @@ -130,6 +130,7 @@ a.tw-tiddlylink-missing { } .tw-tiddler-frame { + position: relative; padding: 3em; margin-bottom: 2em; background-color: {{$:/core/styles/colourmappings##tiddlerbackground}}; @@ -235,7 +236,7 @@ a.tw-tiddlylink-missing { } .tw-tab-buttons { - font-size: 0.7em; + font-size: 0.85em; line-height: 100%; margin-bottom: -1px; } @@ -261,19 +262,13 @@ a.tw-tiddlylink-missing { padding: 1em; } -.config-area { - max-width: 50em; - padding: 1em 3em 3em 3em; - border: 1px solid #aaa; - background: #ddd; - <> - <> +.tw-drop-down .tw-tab-buttons button { + background-color: #ececec; } -.config-area h1 { - font-size: 1.2em; - text-align: center; - color: #888; +.tw-drop-down .tw-tab-buttons button.tw-tab-selected { + background-color: #fff; + border-bottom: 1px solid #fff; } .tw-edit-texteditor input, .tw-edit-texteditor textarea { diff --git a/core/templates/MoreSideBar.tid b/core/templates/MoreSideBar.tid index b27a80d88..bc6b8355e 100644 --- a/core/templates/MoreSideBar.tid +++ b/core/templates/MoreSideBar.tid @@ -1,8 +1,11 @@ title: $:/templates/MoreSideBar
-
<$button type="set" set="$:/state/moreSideBarTabSet" setTo="missingTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Missing<$button type="set" set="$:/state/moreSideBarTabSet" setTo="orphanTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Orphans<$button type="set" set="$:/state/moreSideBarTabSet" setTo="systemTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">System
+
<$button type="set" set="$:/state/moreSideBarTabSet" setTo="tagsTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Tags<$button type="set" set="$:/state/moreSideBarTabSet" setTo="missingTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Missing<$button type="set" set="$:/state/moreSideBarTabSet" setTo="orphanTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Orphans<$button type="set" set="$:/state/moreSideBarTabSet" setTo="systemTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">System
+<$reveal type="match" state="$:/state/moreSideBarTabSet" text="tagsTab" qualifyTiddlerTitles="yes"> +<$list filter="[tags[]sort[title]]" itemClass="tw-menu-list-item"/> + <$reveal type="match" state="$:/state/moreSideBarTabSet" text="missingTab" qualifyTiddlerTitles="yes"> <$list filter="[is[missing]sort[title]]" itemClass="tw-menu-list-item"/> diff --git a/core/templates/TiddlerDropdown.tid b/core/templates/TiddlerDropdown.tid new file mode 100644 index 000000000..54abfab6f --- /dev/null +++ b/core/templates/TiddlerDropdown.tid @@ -0,0 +1,16 @@ +title: $:/templates/TiddlerDropdown + +
<$button type="set" set="$:/state/moreSideBarTabSet" setTo="refTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">References<$button type="set" set="$:/state/moreSideBarTabSet" setTo="taggingTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Tagging<$button type="set" set="$:/state/moreSideBarTabSet" setTo="fieldsTab" qualifyTiddlerTitles="yes" selectedClass="tw-tab-selected">Fields
+
+<$reveal type="match" state="$:/state/moreSideBarTabSet" text="refTab" qualifyTiddlerTitles="yes"> +<$list filter="[is[current]backlinks[]sort[title]]" emptyMessage="No tiddlers link to this one"> + + +<$reveal type="match" state="$:/state/moreSideBarTabSet" text="taggingTab" qualifyTiddlerTitles="yes"> +<$list filter="[is[current]tagging[]sort[title]]" itemClass="tw-menu-list-item" emptyMessage="No tiddlers are tagged with this one"/> + +<$reveal type="match" state="$:/state/moreSideBarTabSet" text="fieldsTab" qualifyTiddlerTitles="yes"> +Fields... + +
+
\ No newline at end of file diff --git a/core/templates/ViewTemplate.tid b/core/templates/ViewTemplate.tid index d6a2c5b36..cf54b7d88 100644 --- a/core/templates/ViewTemplate.tid +++ b/core/templates/ViewTemplate.tid @@ -2,12 +2,15 @@ title: $:/templates/ViewTemplate modifier: JeremyRuston +<$button popup="tiddlerDropdown" qualifyTiddlerTitles="yes" class="btn-invisible">{{$:/core/images/info-button.svg}} <$button message="tw-edit-tiddler" class="btn-invisible">{{$:/core/images/edit-button.svg}} <$button message="tw-close-tiddler" class="btn-invisible">{{$:/core/images/close-button.svg}} - -<$view field="title"/> - +<$view field="title"/> + +<$reveal type="popup" state="tiddlerDropdown" qualifyTiddlerTitles="yes"> +
<$transclude template="$:/templates/TiddlerDropdown">
+
<$view field="modifier" format="link"/> <$view field="modified" format="date"/>
diff --git a/core/wiki/moreSideBarTabSet.tid b/core/wiki/moreSideBarTabSet.tid index 9e19a5931..90b97dd75 100644 --- a/core/wiki/moreSideBarTabSet.tid +++ b/core/wiki/moreSideBarTabSet.tid @@ -1,3 +1,3 @@ title: $:/state/moreSideBarTabSet-tiddlerTitle:$:/templates/MoreSideBar;templateTitle:$:/templates/MoreSideBar;-tiddlerTitle:$:/templates/SideBar;templateTitle:$:/templates/SideBar;-tiddlerTitle:$:/templates/PageTemplate;- -missingTab \ No newline at end of file +tagsTab \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid b/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid index fbdc87886..6a9c7098c 100644 --- a/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid +++ b/editions/tw5.com/tiddlers/concepts/TiddlerFilters.tid @@ -40,6 +40,8 @@ A filter string consists of one or more runs of filter operators that each look * ''{field}'': tests whether a tiddler field has a specified value (`[modifier[Jeremy]]`) or not (`[!modifier[Jeremy]]`) * ''tags'': selects the tags on the currently selected tiddlers * ''tagging'': selects the tiddlers tagged with the currently selected tiddlers +* ''links'': selects the outgoing links on the currently selected tiddlers +* ''backlinks'': selects the tiddlers that link to the currently selected tiddlers * ''list'': selects the tiddlers listed in a specified tiddler (newline delimited) An operator can be negated with by preceding it with `!`, for example `[!tag[Tommy]]` selects the tiddlers that are not tagged with `Tommy`. @@ -50,6 +52,8 @@ The operands available with the `is` operator are: * ''system'': selects all system tiddlers * ''current'': selects the current ContextTiddler +* ''missing'': selects all missing tiddlers +* ''orphan'': selects all orphan tiddlers ! Runs