{"tiddlers":{"$:/plugins/linonetwo/preview-glass/changelog":{"title":"$:/plugins/linonetwo/preview-glass/changelog","created":"20260120000000000","modified":"20260428010000000","type":"text/vnd.tiddlywiki","text":"!!! v1.0.3 (2026-04-28)\n\n* Fixed lazy-loading support for skinny tiddlers by triggering core lazy loading on hover\n* Preview popups now also show for metadata-only tiddlers without a `text` field\n* Removed the `exclude-empty` option because empty tiddlers should still preview their metadata\n\n---\n\n!!! v1.0.2 (2026-04-28)\n\n* Migrated the startup module from JavaScript to TypeScript\n* Kept the hover preview event delegation behavior unchanged\n\n---\n\n!!! v1.0.0 (2026-01-20)\n\nComplete rewrite of the preview plugin.\n\nBreaking changes:\n\n* Removed dependencies on `tobibeer/appear` and `ooktech/dynamic-tables`\n* Requires TiddlyWiki 5.2.0 or later\n* Simplified configuration options\n\nTechnical improvements:\n\n* Replaced widget hijacking with lightweight startup module\n* Uses standard Reveal widget and PageTemplate\n* Integrated with TiddlyWiki palette system for theme compatibility\n* Modern CSS with backdrop-filter glass effect and smooth animations\n* Document-level event delegation for better performance\n* 150ms hover delay to avoid accidental triggers\n\nFile changes:\n\n* Added: `startup.js`, `page-template.tid`, `palette-styles.tid`\n* Modified: all style and template files\n* Removed: `link.js`, `keyboard.js`, `popups.tid`\n\nMigration:\n\nUpgrading from 0.6.0 should work automatically. Custom templates remain compatible.\n\n---\n\n!!! v0.6.0 (2020-04-14)\n\n* Fork of tobibeer/preview plugin\n* Added auto-close on mouse leave\n* Added glass effect styling"},"$:/plugins/linonetwo/preview-glass/config":{"title":"$:/plugins/linonetwo/preview-glass/config","caption":"Preview Glass Configuration","text":"\\define config-option()\n<div class=\"tc-config-row\">\n  <div class=\"tc-config-label\">\n    <$transclude tiddler=\"$:/plugins/linonetwo/preview-glass/lingo/$(option)$\" mode=\"inline\"/>\n  </div>\n  <div class=\"tc-config-control\">\n    <$list filter=\"[[$(option)$]prefix[exclude-]]\" variable=\"null\">\n      <$checkbox \n        tiddler=\"$:/plugins/linonetwo/preview-glass/defaults/$(option)$\" \n        field=\"text\" \n        checked=\"yes\" \n        unchecked=\"no\" \n        default=\"yes\"\n      >\n        Enable\n      </$checkbox>\n    </$list>\n    <$list filter=\"[[$(option)$]prefix[template]]\" variable=\"null\">\n      <$edit-text \n        tag=\"input\" \n        tiddler=\"$:/plugins/linonetwo/preview-glass/defaults/$(option)$\"\n        default=\"$:/plugins/linonetwo/preview-glass/template\"\n        class=\"tc-edit-texteditor\"\n      />\n    </$list>\n  </div>\n</div>\n\\end\n\n<div class=\"tc-preview-glass-config\">\n  <h2>Preview Glass Settings</h2>\n  \n  <$vars defaults=\"$:/plugins/linonetwo/preview-glass/defaults/\">\n    <$list filter=\"[all[tiddlers+shadows]removeprefix<defaults>sort[title]]\" variable=\"option\">\n      <<config-option>>\n    </$list>\n  </$vars>\n</div>\n\n<style>\n.tc-preview-glass-config {\n  max-width: 600px;\n}\n\n.tc-config-row {\n  display: flex;\n  align-items: center;\n  padding: 12px 0;\n  border-bottom: 1px solid rgba(0, 0, 0, 0.1);\n}\n\n.tc-config-label {\n  flex: 1;\n  font-weight: 500;\n}\n\n.tc-config-control {\n  flex: 0 0 auto;\n}\n\n.tc-config-control input[type=\"text\"] {\n  width: 300px;\n  padding: 4px 8px;\n}\n</style>\n"},"$:/plugins/linonetwo/preview-glass/lingo/template":{"title":"$:/plugins/linonetwo/preview-glass/lingo/template","text":"the preview template"},"$:/plugins/linonetwo/preview-glass/defaults/template":{"title":"$:/plugins/linonetwo/preview-glass/defaults/template","text":"$:/plugins/linonetwo/preview-glass/template"},"$:/plugins/linonetwo/preview-glass/lingo/exclude-system":{"title":"$:/plugins/linonetwo/preview-glass/lingo/exclude-system","text":"exclude system tiddlers from preview"},"$:/plugins/linonetwo/preview-glass/defaults/exclude-system":{"title":"$:/plugins/linonetwo/preview-glass/defaults/exclude-system","text":"yes"},"$:/plugins/linonetwo/preview-glass/lingo/exclude-shadows":{"title":"$:/plugins/linonetwo/preview-glass/lingo/exclude-shadows","text":"exclude shadow tiddlers from preview"},"$:/plugins/linonetwo/preview-glass/defaults/exclude-shadows":{"title":"$:/plugins/linonetwo/preview-glass/defaults/exclude-shadows","text":"yes"},"$:/plugins/linonetwo/preview-glass/page-template":{"title":"$:/plugins/linonetwo/preview-glass/page-template","tags":"$:/tags/PageTemplate","text":"\\define preview-state() $:/state/preview-glass/popup\n\n\\define handle-close()\n<$action-deletetiddler $tiddler=<<preview-state>> />\n\\end\n\n<!-- The preview popup - shown when state tiddler exists -->\n<$reveal type=\"nomatch\" state=<<preview-state>> text=\"\">\n  <$let previewTiddler={{{ [<preview-state>get[text]] }}}>\n    <$list filter=\"[<previewTiddler>!is[blank]]\" variable=\"null\">\n      <$tiddler tiddler=<<previewTiddler>>>\n        <div \n          class=\"tc-preview-popup tc-preview-glass\"\n          style={{{ [<preview-state>get[x]addprefix[left:]addsuffix[px;]] [<preview-state>get[y]addprefix[top:]addsuffix[px;]] +[join[ ]] }}}\n        >\n          <div class=\"tc-preview-popup-inner\">\n            <div class=\"tc-preview-header\">\n              <span class=\"tc-preview-title\">{{!!title}}</span>\n              <$button class=\"tc-btn-invisible tc-preview-close\" tooltip=\"Close preview\">\n                <<handle-close>>\n                {{$:/core/images/close-button}}\n              </$button>\n            </div>\n            \n            <div class=\"tc-preview-content\">\n              <!-- Transclude the custom template -->\n              <$transclude \n                tiddler={{{ [[$:/plugins/linonetwo/preview-glass/defaults/template]get[text]else[$:/plugins/linonetwo/preview-glass/template]] }}}\n                mode=\"block\"\n              />\n            </div>\n          </div>\n        </div>\n      </$tiddler>\n    </$list>\n  </$let>\n</$reveal>\n"},"$:/plugins/linonetwo/preview-glass/palette-styles":{"title":"$:/plugins/linonetwo/preview-glass/palette-styles","tags":"$:/tags/Stylesheet","type":"text/css","text":".tc-preview-popup{color:<<colour foreground>>;border:1px solid;box-shadow:0 10px 40px <<colour dropdown-tab-background-selected>>}.tc-preview-header{border-bottom:1px solid}.tc-preview-title{color:<<colour tiddler-title-foreground>>}.tc-preview-content{color:<<colour foreground>>}.tc-preview-excerpt{border-left:3px solid}.tc-preview-text::after{background:linear-gradient(to bottom,transparent,<<colour page-background>>)}.tc-preview-plugin-info{color:<<colour muted-foreground>>}.tc-preview-fields tr{border-bottom:1px solid}.tc-preview-field-name{color:<<colour muted-foreground>>}.tc-preview-field-value{color:<<colour foreground>>}"},"$:/plugins/linonetwo/preview-glass/preview-template.css":{"title":"$:/plugins/linonetwo/preview-glass/preview-template.css","text":".tc-preview-popup{position:fixed;pointer-events:auto;z-index:1000;max-width:500px;min-width:300px;max-height:600px;overflow:hidden;border-radius:12px;animation:.2s ease-out preview-fade-in;backdrop-filter:blur(20px) saturate(180%);-webkit-backdrop-filter:blur(20px) saturate(180%)}@keyframes preview-fade-in{from{opacity:0;transform:translateY(-10px) scale(.95)}to{opacity:1;transform:translateY(0) scale(1)}}.tc-preview-popup-inner{padding:16px;overflow-y:auto;max-height:600px}.tc-preview-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding-bottom:8px}.tc-preview-title{font-weight:600;font-size:1.1em;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tc-preview-close{flex-shrink:0;padding:4px;width:24px;height:24px;opacity:.6;transition:opacity .2s}.tc-preview-close:hover{opacity:1}.tc-preview-close svg{width:16px;height:16px}.tc-preview-content{line-height:1.5}.tc-preview-excerpt{margin-bottom:12px;padding:8px;border-radius:6px}.tc-preview-text{font-size:.95em;max-height:200px;overflow:hidden;position:relative}.tc-preview-text::after{content:\"\";position:absolute;bottom:0;left:0;right:0;height:40px}.tc-preview-info{margin:12px 0;font-size:.9em}.tc-preview-backlinks{padding:8px;border-radius:6px}.tc-preview-plugin-info{padding:8px;font-style:italic}.tc-preview-metadata{margin-top:12px;font-size:.85em}.tc-preview-fields{width:100%;border-collapse:collapse}.tc-preview-field-name{padding:4px 8px;font-weight:500;white-space:nowrap;width:80px}.tc-preview-field-value{padding:4px 8px}.tc-preview-popup-inner::-webkit-scrollbar{width:6px}.tc-preview-popup-inner::-webkit-scrollbar-track{border-radius:3px}.tc-preview-popup-inner::-webkit-scrollbar-thumb{border-radius:3px}","created":"20200415090452849","modified":"20200530033507747","tags":"$:/tags/Stylesheet","type":"text/css"},"$:/plugins/linonetwo/preview-glass/readme":{"title":"$:/plugins/linonetwo/preview-glass/readme","created":"20200414135748497","modified":"20260120000000000","type":"text/vnd.tiddlywiki","text":"!! About\n\nLink hover preview plugin with glass effect. Complete rewrite of [[tobibeer/preview|https://tobibeer.github.io/tw5-plugins/#preview]].\n\nShows popup on link hover with:\n\n* Content excerpt (first few lines)\n* Backlinks (requires inverse-link-and-folder plugin)\n* Metadata (modified, created, tags)\n\n!! Features\n\n* Glass effect with backdrop-filter\n* Adapts to all themes via TiddlyWiki palette system\n* Lightweight implementation using document-level event listeners\n* Positioned near cursor\n* Configurable exclusions for system/shadow tiddlers\n* 150ms hover delay to avoid accidental triggers\n* Supports lazy-loaded and metadata-only tiddlers\n\n!! Optional Dependencies\n\n* [[$:/plugins/linonetwo/inverse-link-and-folder]] - for displaying backlinks\n\n!! Configuration\n\nVisit the [[config panel|$:/plugins/linonetwo/preview-glass/config]] to customize:\n\n* Preview content template\n* Exclusion rules (system/shadow tiddlers)\n\n!! Implementation\n\n|!Component |!Description |\n|`startup.ts` |Document-level event listener |\n|`page-template.tid` |Popup display using Reveal widget |\n|`template.tid` |Customizable preview content template |\n|`palette-styles.tid` |Palette-based color styles |\n|`preview-template.css` |Structural CSS |\n\n!! Comparison\n\n|!Aspect |!v0.6.0 |!v1.0.0 |\n|Implementation |Hijacks link widget |startup module + PageTemplate |\n|Dependencies |tobibeer/appear, dynamic-tables |None (inverse-link optional) |\n|Performance |Hijacks every link render |Event delegation |\n|Styling |Hardcoded colors |Palette system |\n|Maintainability |Complex JS |Clean TS + standard APIs |\n\n!! Changelog\n\nSee [[changelog|$:/plugins/linonetwo/preview-glass/changelog]] for version history.\n\n!! Source\n\nhttps://github.com/linonetwo/tiddlywiki-plugins\n"},"$:/plugins/linonetwo/preview-glass/template":{"title":"$:/plugins/linonetwo/preview-glass/template","created":"20200413014112868","modified":"20260119000000000","type":"text/vnd.tiddlywiki","text":"\\define preview-excerpt()\n<$transclude mode=\"block\" />\n\\end\n\n<!-- Preview content structure -->\n<div class=\"tc-preview-excerpt\">\n  <$list filter=\"[<currentTiddler>has[text]]\" variable=\"null\">\n    <$wikify name=\"excerpt\" text={{{ [<currentTiddler>get[text]splitregexp[\\n]first[5]join[\\n]] }}} output=\"text\">\n      <div class=\"tc-preview-text\">\n        <<excerpt>>\n      </div>\n    </$wikify>\n  </$list>\n  <$list filter=\"[<currentTiddler>has:field[_is_skinny]]\" variable=\"null\">\n    <div class=\"tc-preview-text\">\n      Loading preview...\n    </div>\n  </$list>\n</div>\n\n<!-- Info bar with reverse links -->\n<div class=\"tc-preview-info\">\n  <$list filter=\"[<currentTiddler>plugintiddlers[]limit[1]]\" variable=\"null\" emptyMessage=\"\"\"\n    <div class=\"tc-preview-backlinks\">\n      {{||$:/plugins/linonetwo/inverse-link-and-folder/infobar}}\n    </div>\n  \"\"\">\n    <div class=\"tc-preview-plugin-info\">\n      <em>This is a plugin tiddler</em>\n    </div>\n  </$list>\n</div>\n\n<!-- Metadata table -->\n<div class=\"tc-preview-metadata\">\n  <table class=\"tc-preview-fields\">\n    <$list filter=\"modified created tags\" variable=\"fieldName\">\n      <tr>\n        <td class=\"tc-preview-field-name\"><<fieldName>></td>\n        <td class=\"tc-preview-field-value\">\n          <$transclude tiddler=<<currentTiddler>> field=<<fieldName>> mode=\"inline\" />\n        </td>\n      </tr>\n    </$list>\n  </table>\n</div>"},"$:/plugins/linonetwo/preview-glass/tree":{"title":"$:/plugins/linonetwo/preview-glass/tree","type":"text/vnd.tiddlywiki","text":"<<tree prefix:\"$:/plugins/linonetwo/preview-glass/\">>"},"$:/plugins/linonetwo/preview-glass/startup.js":{"title":"$:/plugins/linonetwo/preview-glass/startup.js","type":"application/javascript","module-type":"startup","Modern.TiddlyDev#Origin":"startup.ts","text":"\"use strict\";var hoverTimeout,currentPreviewTiddler,__defProp=Object.defineProperty,__getOwnPropDesc=Object.getOwnPropertyDescriptor,__getOwnPropNames=Object.getOwnPropertyNames,__hasOwnProp=Object.prototype.hasOwnProperty,__export=(e,t)=>{for(var r in t)__defProp(e,r,{get:t[r],enumerable:!0})},__copyProps=(t,r,o,i)=>{if(r&&\"object\"==typeof r||\"function\"==typeof r)for(let e of __getOwnPropNames(r))__hasOwnProp.call(t,e)||e===o||__defProp(t,e,{get:()=>r[e],enumerable:!(i=__getOwnPropDesc(r,e))||i.enumerable});return t},__toCommonJS=e=>__copyProps(__defProp({},\"__esModule\",{value:!0}),e),startup_exports={},name=(__export(startup_exports,{after:()=>after,name:()=>name,platforms:()=>platforms,startup:()=>startup,synchronous:()=>synchronous}),module.exports=__toCommonJS(startup_exports),\"preview-glass\"),platforms=[\"browser\"],after=[\"render\"],synchronous=!0,PREVIEW_STATE=\"$:/state/preview-glass/popup\",DEFAULTS_PREFIX=\"$:/plugins/linonetwo/preview-glass/defaults/\",SHOW_DELAY=150,HIDE_DELAY=100,getConfig=(e,t)=>$tw.wiki.getTiddler(\"\"+DEFAULTS_PREFIX+e)?.fields.text??t,isSkinnyTiddler=e=>$tw.wiki.getTiddler(e)?.hasField(\"_is_skinny\")??!1,shouldExclude=e=>void 0===e||\"\"===e||!(\"yes\"!==getConfig(\"exclude-system\",\"yes\")||!$tw.wiki.isSystemTiddler(e))||!(\"yes\"!==getConfig(\"exclude-shadows\",\"yes\")||!$tw.wiki.isShadowTiddler(e)),getTiddlerFromHref=e=>{if(null!==e&&\"\"!==e){var t=e.split(\"#\")[1];if(void 0!==t&&\"\"!==t)try{return decodeURIComponent(t)}catch{return t}}},clearHoverTimeout=()=>{void 0!==hoverTimeout&&(window.clearTimeout(hoverTimeout),hoverTimeout=void 0)},showPreview=(e,t,r)=>{shouldExclude(e)||(currentPreviewTiddler=e,$tw.wiki.setText(PREVIEW_STATE,\"text\",void 0,e),$tw.wiki.setText(PREVIEW_STATE,\"x\",void 0,String(t)),$tw.wiki.setText(PREVIEW_STATE,\"y\",void 0,String(r)),isSkinnyTiddler(e)&&$tw.wiki.getTiddlerText(e))},hidePreview=()=>{currentPreviewTiddler=void 0,$tw.wiki.deleteTiddler(PREVIEW_STATE)},getClosestElement=(e,t)=>{var r;return e instanceof Element?e.matches(t)&&e instanceof HTMLElement?e:(r=e.closest(t))instanceof HTMLElement?r:null:null},getClosestLink=e=>getClosestElement(e,\".tc-tiddlylink\"),getClosestPopup=e=>getClosestElement(e,\".tc-preview-popup\"),startup=()=>{$tw.browser&&(document.addEventListener(\"mouseover\",e=>{var t=getClosestLink(e.target);if(null!==t){clearHoverTimeout();const r=getTiddlerFromHref(t.getAttribute(\"href\"));if(void 0!==r&&!shouldExclude(r)){const o=t.getBoundingClientRect();hoverTimeout=window.setTimeout(()=>{showPreview(r,o.left,o.bottom+5)},SHOW_DELAY)}}},!0),document.addEventListener(\"mouseout\",e=>{null!==getClosestLink(e.target)&&null===getClosestPopup(e.relatedTarget)&&(clearHoverTimeout(),hoverTimeout=window.setTimeout(()=>{hidePreview()},HIDE_DELAY))},!0),document.addEventListener(\"mouseleave\",e=>{var t=getClosestPopup(e.target);if(null!==t){t=getClosestLink(e.relatedTarget);if(null!==t){t=getTiddlerFromHref(t.getAttribute(\"href\"));if(void 0!==t&&t===currentPreviewTiddler)return}hidePreview()}},!0))};"}}}