Skip to content

Commit 6ef4605

Browse files
committed
release: bump to v0.8.9
1 parent 4b73934 commit 6ef4605

6 files changed

Lines changed: 2270 additions & 282 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "weavero",
3-
"version": "0.8.8",
3+
"version": "0.8.9",
44
"private": true,
55
"description": "A Zotero plugin to make clickable links and filter your library.",
66
"homepage": "https://github.com/mjthoraval/Weavero",

src/index.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1846,10 +1846,22 @@ class WeaveroPlugin {
18461846
// 'add' early-return below, otherwise the items-list
18471847
// filter never recomputes after item creation.
18481848
if (event === "add" && ids && ids.length) {
1849-
if (!this._wvRecentlyAddedItemIDs) {
1850-
this._wvRecentlyAddedItemIDs = new Set();
1849+
// Switched from `Set<id>` to `Map<id, timestamp>`
1850+
// so the apply loop can expire entries. The
1851+
// original `Set` was session-lifetime — items
1852+
// created during a session stayed force-included
1853+
// forever, defeating the filter for the user's
1854+
// own test items. With a timestamp the force-
1855+
// include window only covers the brief moment
1856+
// after creation where Zotero's auto-select +
1857+
// itemBox lookup would otherwise fail.
1858+
if (!this._wvRecentlyAddedItemIDs
1859+
|| typeof (this._wvRecentlyAddedItemIDs as any).set !== "function") {
1860+
// Migrate any pre-fix Set instance.
1861+
this._wvRecentlyAddedItemIDs = new Map();
18511862
}
1852-
for (const id of ids) this._wvRecentlyAddedItemIDs.add(id);
1863+
const now = Date.now();
1864+
for (const id of ids) (this._wvRecentlyAddedItemIDs as any).set(id, now);
18531865
}
18541866
if (event === "add" || event === "modify"
18551867
|| event === "delete" || event === "trash") {

src/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"manifest_version": 2,
33
"name": "Weavero",
4-
"version": "0.8.8",
4+
"version": "0.8.9",
55
"description": "A Zotero plugin to make clickable links and filter your library.",
66
"author": "mjthoraval",
77
"homepage_url": "https://github.com/mjthoraval/Weavero",

src/modules/constants.ts

Lines changed: 174 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -644,13 +644,48 @@ export const PLUGIN_CSS = [
644644
"}",
645645
".wv-filter-color-row:hover { background: rgba(127,127,127,0.12); }",
646646
// Wide unified-panel layout (one section per filter type).
647+
// Top padding kept to 0 so the popup's top edge sits flush
648+
// against the (visually-framed) quick-search box above —
649+
// making the "Restrict to:" row read as the search's own
650+
// settings. Other sides retain a small gutter.
647651
".wv-filter-panel-inner {",
648652
" display: flex; flex-direction: column;",
649-
" gap: 3px; padding: 4px 6px;",
653+
" gap: 3px; padding: 0 6px 4px;",
650654
// Anchor for absolutely-positioned children — currently used
651655
// by the per-cross-level-filter scope popup.
652656
" position: relative;",
657+
// XUL `<panel>` chrome inherits `-moz-user-select: none` by
658+
// default, so the user can't drag-select or copy any text
659+
// inside the popup (filter labels, the Alt+Click hint, the
660+
// search text they just typed). Re-enable text selection at
661+
// the panel root; interactive bits (chips, buttons, the
662+
// display-option labels) keep their per-element
663+
// `user-select: none` from their own rules, which is more
664+
// specific and wins.
665+
" user-select: text;",
666+
" -moz-user-select: text;",
667+
"}",
668+
// Bottom row — just the Alt+Click hint, centered. The Clear /
669+
// × buttons moved up to the right end of the cross-level row,
670+
// so the hint can be alone here without competing controls.
671+
".wv-filter-bottom-controls {",
672+
" display: flex; justify-content: center; align-items: center;",
673+
" margin-top: 4px;",
674+
"}",
675+
".wv-filter-bottom-controls .wv-filter-bottom-hint {",
676+
" text-align: center; padding: 0;",
677+
"}",
678+
// Display-option checkbox row (e.g. "Show non-matching
679+
// annotations of matched files") at the very bottom of the
680+
// popup. Small font + dimmed text so it reads as an option,
681+
// not a primary control.
682+
".wv-filter-display-opt {",
683+
" display: flex; align-items: center; gap: 4px;",
684+
" font-size: 11px; opacity: 0.85;",
685+
" padding: 4px 4px 0;",
686+
" cursor: pointer; user-select: none;",
653687
"}",
688+
".wv-filter-display-opt input { margin: 0; }",
654689
".wv-filter-section {",
655690
" display: flex; flex-direction: row; align-items: center; gap: 4px;",
656691
"}",
@@ -673,6 +708,96 @@ export const PLUGIN_CSS = [
673708
" border-bottom: 1px solid rgba(127,127,127,0.35);",
674709
" margin-bottom: 4px;",
675710
"}",
711+
// Quick Search scope variant — sits just under the (toolbar)
712+
// quick search visually, so we drop the bottom padding /
713+
// margin / border to remove the perceived gap between the
714+
// search input above and the rest of the popup below.
715+
".wv-filter-qs-scope-bar {",
716+
" padding: 0;",
717+
" margin: 0;",
718+
" border-bottom: none;",
719+
"}",
720+
// ── Quick-search "framed" appearance when the filter popup is
721+
// open. The popup itself drops its top edge + top-corner
722+
// radius (rules below), so the search box's borders read as
723+
// the popup's first row even though the two elements stay in
724+
// their original DOM positions. Class is added on
725+
// popupshown and removed on popuphidden.
726+
//
727+
// `padding-bottom: 3px` extends the framed area down by the
728+
// same amount the popup is shifted (`#wv-filter-popup`
729+
// transform), so the left/right borders bridge the small gap
730+
// between the search box and the popup — when the search
731+
// takes focus, Zotero's blue underline draws inside this gap
732+
// and remains visible.
733+
"#zotero-tb-search.wv-filter-search-framed {",
734+
" border-top: 1px solid var(--wv-popup-frame-color, rgba(127,127,127,0.55));",
735+
" border-left: 1px solid var(--wv-popup-frame-color, rgba(127,127,127,0.55));",
736+
" border-right: 1px solid var(--wv-popup-frame-color, rgba(127,127,127,0.55));",
737+
" border-top-left-radius: 6px;",
738+
" border-top-right-radius: 6px;",
739+
" border-bottom-left-radius: 0;",
740+
" border-bottom-right-radius: 0;",
741+
" padding-bottom: 3px;",
742+
"}",
743+
// Injected scope dropdown inside the framed quick-search box.
744+
// Lives as a sibling of `<search-textbox>` in
745+
// `#zotero-tb-search > #search-wrapper`. Sits to the right of
746+
// the × clear button; visible only when the search has text.
747+
// Compact glyph-only button styled to match the cross-level
748+
// filter scope arrows (`.wv-filter-cross-scope-arrow`) — same
749+
// font size / opacity / padding / border-radius / hover and
750+
// modified states so it reads as part of the same family.
751+
// `align-self: stretch` makes it match the search-textbox's
752+
// height so the button doesn't read as a smaller floating
753+
// chip inside a taller box.
754+
".wv-qs-scope-btn {",
755+
" display: inline-flex; align-items: center; justify-content: center;",
756+
" align-self: stretch;",
757+
" font: inherit; font-size: 9px; line-height: 1;",
758+
" color: inherit; cursor: pointer;",
759+
// Left margin is 3 px larger than right so the button sits a
760+
// bit further away from the × clear icon on its left.
761+
" padding: 0 4px; margin: 0 4px 0 7px;",
762+
" border: 1px solid rgba(127,127,127,0.4);",
763+
" border-radius: 4px;",
764+
" background: transparent;",
765+
" opacity: 0.7;",
766+
" -moz-window-dragging: no-drag;",
767+
"}",
768+
".wv-qs-scope-btn:hover {",
769+
" opacity: 1; background: rgba(127,127,127,0.12);",
770+
"}",
771+
// Same accent treatment the other cross-level scope arrows
772+
// use when the scope is narrowed below the all-on default.
773+
".wv-qs-scope-btn[data-modified=\"true\"] {",
774+
" color: var(--accent-orange, #cc8400);",
775+
" border-color: var(--accent-orange, rgba(204,132,0,0.6));",
776+
" opacity: 1;",
777+
"}",
778+
".wv-qs-scope-btn-arrow { font-size: inherit; line-height: 1; }",
779+
// Strip the popup's top edge so it visually connects to the
780+
// framed quick-search above. Bottom corners keep their normal
781+
// rounding; top corners go square. The frame color is shared
782+
// (via `--wv-popup-frame-color`) so the search frame and the
783+
// popup border match.
784+
//
785+
// `transform: translateY(3px)` shifts the popup down by a few
786+
// pixels so Zotero's focus underline on the quick-search box
787+
// (drawn at the very bottom of the search element when it
788+
// takes focus) remains visible instead of being covered.
789+
// Mozilla's panel positioning runs first; the CSS transform
790+
// applies after, so the popup ends up just below the
791+
// underline. Search-frame side borders are extended downward
792+
// by the matching `wv-filter-search-framed` padding-bottom
793+
// so they bridge the gap visually.
794+
"#wv-filter-popup {",
795+
" --wv-popup-frame-color: rgba(127,127,127,0.55);",
796+
" border-top: none;",
797+
" border-top-left-radius: 0;",
798+
" border-top-right-radius: 0;",
799+
" transform: translateY(3px);",
800+
"}",
676801
".wv-filter-scope-bar-label {",
677802
" flex: 0 0 var(--wv-title-col, 150px);",
678803
" font-size: 12px; opacity: 0.75;",
@@ -699,6 +824,16 @@ export const PLUGIN_CSS = [
699824
".wv-not-target:not(.selected) {",
700825
" color: var(--fill-secondary) !important;",
701826
"}",
827+
// Un-grey Weavero-primary rows that Zotero's quick-search has
828+
// tagged as `.context-row` (parent-promoted into the result
829+
// set). When OUR filter considers them real matches
830+
// (e.g. a Web Link attachment under a parent whose title
831+
// matched the search), they should read as primary, not as
832+
// greyed context. Targets only rows we marked `.wv-primary`
833+
// and are NOT also `.wv-not-target` (those still dim).
834+
".row.context-row.wv-primary:not(.wv-not-target) {",
835+
" color: inherit !important;",
836+
"}",
702837
// Divider between kind-specific (top) and scope-applicable
703838
// (bottom) filter groups in the panel. Visual marker that the
704839
// scope-handling work for these filters is still TBD.
@@ -1131,6 +1266,23 @@ export const PLUGIN_CSS = [
11311266
".wv-filter-selected-pill-x:hover {",
11321267
" opacity: 1; background: rgba(127,127,127,0.18);",
11331268
"}",
1269+
// "Apply to" scope arrow that sits on each tag pill (between
1270+
// the label and the ×). Opens a row-kind picker scoped to the
1271+
// active group's `tagScope`. Same modified-state cue as the
1272+
// cross-level filter arrows.
1273+
".wv-filter-selected-pill-scope {",
1274+
" cursor: pointer; opacity: 0.65;",
1275+
" font: inherit; font-size: 9px; line-height: 1;",
1276+
" background: transparent; border: none;",
1277+
" padding: 0 3px; margin: 0 1px; border-radius: 2px;",
1278+
" color: inherit;",
1279+
"}",
1280+
".wv-filter-selected-pill-scope:hover {",
1281+
" opacity: 1; background: rgba(127,127,127,0.18);",
1282+
"}",
1283+
".wv-filter-selected-pill-scope[data-modified=\"true\"] {",
1284+
" opacity: 1; color: var(--accent-orange, #cc8400);",
1285+
"}",
11341286
// Cross-level filter slot — the main icon button + a small ▾
11351287
// scope arrow share the same border-rounding so they read as
11361288
// one widget. The arrow opens a per-filter row-kind scope
@@ -1176,7 +1328,10 @@ export const PLUGIN_CSS = [
11761328
" padding: 4px 6px;",
11771329
" box-shadow: 0 2px 6px rgba(0,0,0,0.25);",
11781330
" font-size: 12px;",
1179-
" min-width: 160px;",
1331+
// No min-width — size to content. The 160-px floor that used
1332+
// to live here made every scope popup oversized for short
1333+
// labels (Parent / Attachment / Annotation); longer labels
1334+
// (Annotation Comment etc.) still grow the popup naturally.
11801335
"}",
11811336
".wv-filter-scope-popup-head {",
11821337
" font-size: 10px; opacity: 0.6;",
@@ -1188,6 +1343,17 @@ export const PLUGIN_CSS = [
11881343
" padding: 2px 0; cursor: pointer;",
11891344
"}",
11901345
".wv-filter-scope-popup-row input { margin: 0; }",
1346+
// QS scope-panel chrome reset — the panel hosts our own
1347+
// styled HTML, so suppress Mozilla's default panel
1348+
// background/padding (we paint our own via
1349+
// `.wv-filter-scope-popup`).
1350+
"panel.wv-qs-scope-panel {",
1351+
" --panel-padding: 0;",
1352+
" --panel-background: transparent;",
1353+
" --panel-border-color: transparent;",
1354+
" --panel-shadow: none;",
1355+
" background: transparent;",
1356+
"}",
11911357
// Subtle text-button used for "Clear all" both in the chip bar
11921358
// and in the panel footer.
11931359
".wv-filter-clear {",
@@ -1221,6 +1387,12 @@ export const PLUGIN_CSS = [
12211387
".wv-filter-top-hint {",
12221388
" font-size: 10px; opacity: 0.5;",
12231389
"}",
1390+
// Same visual weight as the old top hint, just docked to the
1391+
// bottom of the popup. Centered so it reads as a footer.
1392+
".wv-filter-bottom-hint {",
1393+
" font-size: 10px; opacity: 0.5;",
1394+
" text-align: center; padding: 4px 0 2px;",
1395+
"}",
12241396
// Text-style "Clear" button — sits between the hint and the
12251397
// red × in the top bar. Margin-auto pushes it (and the × that
12261398
// follows) to the right edge so the hint stays on the left.

0 commit comments

Comments
 (0)