Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .changeset/spotty-pins-cover-fields.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
---
---

`scripts/__tests__/plugin-published-stylesheet.test.ts` now runs its per-package
assertions over `@object-ui/fields` as well as the two plugin sheets. Test-only:
no published package's source changes, so this declares "no release" explicitly
rather than bumping anything.

Fields is the package whose stylesheet has actually been shipping to consumers
since objectui#4059 — the defect the test's own header cites as the reason the
shape exists — and it was the one supplement sheet the suite did not cover. Its
`dist/index.css` was guarded only by the four write-time assertions inside the
shared builder, which run during a build; CI runs this suite on an unbuilt
worktree, so nothing in the test run inspected it. It could not be a subject
before objectui#6405 re-pointed it at the shared
`createPluginStylesheetBuilder`, because it ran its own copy and exported no
module surface.

The `CARD_THEMED` entry for fields is derived from the sheet the build actually
emits — the surviving classes whose declarations resolve a `--color-*` token
from components' unpublished `@theme` block — rather than read back off fields'
own `MUST_SURVIVE`, which would have pinned nothing.
66 changes: 63 additions & 3 deletions scripts/__tests__/plugin-published-stylesheet.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,13 +5,32 @@ import { fileURLToPath } from 'node:url';

import * as gridStylesheet from '../../packages/plugin-grid/scripts/build-css.mjs';
import * as kanbanStylesheet from '../../packages/plugin-kanban/scripts/build-css.mjs';
import * as fieldsStylesheet from '../../packages/fields/scripts/build-css.mjs';
import { classesOf, COMPONENTS_ENTRY, REPO_ROOT } from '../build-plugin-stylesheet.mjs';

/**
* objectui#4929: `@object-ui/plugin-grid` and `@object-ui/plugin-kanban` now
* publish a stylesheet, built in the subtraction shape `@object-ui/fields`
* established (objectui#4059).
*
* objectui#6438: `@object-ui/fields` is a subject here too. It is the package
* whose sheet has actually been shipping to consumers since objectui#4059 — the
* defect this file's shape exists to prevent — and until now it was pinned by
* nothing in the suite: the builder's four write-time assertions run only during
* a build, and CI runs this suite on an unbuilt worktree. It could not be a
* subject earlier because it ran its own copy of the builder and exported no
* module surface; objectui#6405 re-pointed it at the shared
* `createPluginStylesheetBuilder`, so it now exports the same shape the two
* plugins do and the five per-package assertions apply to it unchanged.
*
* One asymmetry is deliberate and load-bearing: fields passes a per-package
* `header` through `buildOptions` (its published banner bytes predate the shared
* module, and objectui#6405's acceptance gate was that re-pointing it changed
* `dist/index.css` by not one byte), while the plugins inherit the shared
* default. Nothing below reads the emitted banner; anything added later that
* does must take it from `mod.buildOptions`, never from the shared default,
* or it will judge fields wrongly.
*
* ## What has to be pinned, and why a naive test would pass while broken
*
* Two properties, and only both together mean anything:
Expand DownExpand Up@@ -80,17 +99,58 @@ const CARD_THEMED = {
'text-muted-foreground/60',
'text-primary/90',
],
/**
* Derived for objectui#6438 from the sheet this build actually emits, NOT read
* back off fields' own `MUST_SURVIVE` — the note above applies with more force
* here, because three of these are in that list and copying it would have
* looked identical while pinning nothing.
*
* Method: build fields' sheet through the shared builder, then keep every
* surviving class whose own declarations resolve a `--color-*` token declared
* in `packages/components/src/index.css`'s `@theme` block (35 tokens) — the
* file that package does not publish, which is exactly what makes a build
* inside this monorepo the only possible producer of these utilities.
*
* That yields 17, and 17 is independently what
* `packages/fields/scripts/build-css.mjs` records having measured at
* objectui#4059 ("17 of those depend on the ObjectUI `@theme` block").
* `bg-primary/20`, `hover:bg-accent/30` and `ring-destructive/50` — the three
* that card names — are 3 of the 17, i.e. its starting corpus rather than its
* answer; the other 14 are ones its literal-grep method could not see.
*/
fields: [
'bg-background/60',
'bg-destructive/5',
'bg-muted/60',
'bg-primary/20',
'border-background',
'border-border/40',
'border-muted-foreground/25',
'border-muted-foreground/30',
'focus-visible:ring-ring/60',
'focus:ring-ring/60',
'hover:bg-accent/30',
'hover:bg-muted/80',
'hover:bg-primary/10',
'hover:bg-primary/50',
'hover:border-primary/50',
'ring-border/60',
'ring-destructive/50',
],
} as const;

/**
* Utilities `@object-ui/components`' sheet carries. Each is also used by both
* plugins, so "absent from the plugin sheet" can only mean the subtraction ran.
* Utilities `@object-ui/components`' sheet carries. Each is also compiled by all
* three subjects — asserted below against each one's own pre-subtraction
* compile — so "absent from the emitted sheet" can only mean the subtraction
* ran, and never that the package simply does not use the class.
*/
const ALREADY_SHIPPED = ['flex', 'text-sm', 'rounded-md', 'bg-background', 'sr-only'];

const SUBJECTS = [
{ name: 'plugin-grid', mod: gridStylesheet },
{ name: 'plugin-kanban', mod: kanbanStylesheet },
{ name: 'fields', mod: fieldsStylesheet },
] as const;

type Built = {
Expand DownExpand Up@@ -125,7 +185,7 @@ beforeAll(async () => {
}
}, 120_000);

describe('published plugin stylesheets (objectui#4929)', () => {
describe('published supplement stylesheets (objectui#4929, objectui#6438)', () => {
it('gives every themed utility the card measured a producer', () => {
const everything = new Set(
SUBJECTS.flatMap(({ name }) => [...(built.get(name) as Built).classes]),
Expand Down
Loading