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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ A few extras follow naturally from sitting at the browser level instead of insid

## Status

**v0.10.xpre-1.0, in production use.** A dedicated v0.11.x phase will handle store-readiness work (permissions audit, bundle identifier, store listing assets, publisher account decisions) before the v1.0 milestone of initial official directory releases on the **Chrome Web Store** and **Safari / Mac App Store** under the WordPress publisher account. Firefox and Edge follow post-1.0. See [`ROADMAP.md`](ROADMAP.md) for what's locked, what's open, and what's next.
**v1.0.0-rc1release candidate, in production use.** The v0.11.x store-readiness phase is complete: permissions audited against least-privilege with per-entry rationale in [`SECURITY.md`](SECURITY.md), the packaged Chrome build dropping the redundant `activeTab` ([#61](https://github.com/WordPress/browser-extension/issues/61)), a published privacy policy, and correctness linting gating CI. The v1.0 milestone is the initial official directory releases on the **Chrome Web Store** and **Safari / Mac App Store** under the WordPress publisher account; Safari store-readiness is the remaining gate. Firefox and Edge follow post-1.0. See [`ROADMAP.md`](ROADMAP.md) for what's locked, what's open, and what's next.

## Privacy

Expand Down
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ A milestone-level view of where this project is heading. Day-to-day work is trac
| **v0.8.x** | Public scaffold under the WordPress org. React popup architecture, Site Information panel, Block Inspector, host detection, developer tools. | shipped |
| **v0.9.x** | **Features:** account menu in the popup header (display name, role, profile / Gravatar); extension options page with browser-wide preferences (admin bar default, Site Information opt-in, clear-data); toolbar icon redesigned for contrast on any browser chrome; admin bar attribution comment when the extension is hiding it. **Build:** popup bundle migrated from `10up-toolkit` to `@wordpress/scripts`. **Security:** REST root and profile URL validated against same-origin so a hostile page can't redirect the extension's authenticated calls. (The Xcode project / display-name rename to "WordPress Browser Extension" shipped in v0.8.3.) | shipped |
| **v0.10.x** | **Features:** "My Sites" launcher, a global popup section listing the WordPress sites you are signed in to, with site icons, rename, and remove ([#43](https://github.com/WordPress/browser-extension/pull/43)); Edit button for template-backed pages on block themes, such as the blog index and archives, deep-linked into the site editor ([#22](https://github.com/WordPress/browser-extension/issues/22)); Chrome i18n localization scaffold via `_locales` ([#28](https://github.com/WordPress/browser-extension/issues/28)); toolbar icon redesigned into a solid three-state mark shared by Chrome and Safari, improving contrast on any browser chrome ([#15](https://github.com/WordPress/browser-extension/issues/15), [#31](https://github.com/WordPress/browser-extension/issues/31)); Edit and WordPress Admin actions gated by the signed-in user's capabilities ([#34](https://github.com/WordPress/browser-extension/issues/34)); modifier-click and middle-click open links in a new tab ([#29](https://github.com/WordPress/browser-extension/issues/29)). **Fixes:** admin and login links on subdirectory installs ([#33](https://github.com/WordPress/browser-extension/issues/33)); service-worker `runtime.lastError` noise that lit the extension Errors badge ([#37](https://github.com/WordPress/browser-extension/issues/37)). **Hardening:** a packaging integrity check, stricter admin-bar URL validation, and a degradation / security / accessibility pass ([#45](https://github.com/WordPress/browser-extension/pull/45), [#46](https://github.com/WordPress/browser-extension/pull/46)). | shipped |
| **v0.11.x** | **Chrome store-readiness phase. No new features.** Permissions audit with per-permission rationale in `SECURITY.md`; the packaged Chrome build drops the redundant `activeTab` permission ([#61](https://github.com/WordPress/browser-extension/issues/61)). Privacy policy published via GitHub Pages. Chrome Web Store listing copy and promotional images. Chrome publisher account resolved (WordPress Foundation). Correctness linting wired into CI. Ships as the unlisted Chrome Web Store release-candidate submission. | shipping |
| **v0.11.x** | **Chrome store-readiness phase. No new features.** Permissions audit with per-permission rationale in `SECURITY.md`; the packaged Chrome build drops the redundant `activeTab` permission ([#61](https://github.com/WordPress/browser-extension/issues/61)). Privacy policy published via GitHub Pages. Chrome Web Store listing copy and promotional images. Chrome publisher account resolved (WordPress Foundation). Correctness linting wired into CI. Ships as the unlisted Chrome Web Store release-candidate submission. | shipped |
| **Safari store readiness** | Safari / Mac App Store submission prep, decoupled from the Chrome track so neither gates the other. Done: bundle identifiers moved to `org.wordpress.browserextension` under the WordPress Foundation Apple Developer account. Remaining: App Store Connect app record and submission; re-evaluation of the `activeTab` removal on Safari ([#61](https://github.com/WordPress/browser-extension/issues/61)); per-store listing assets. Safari mobile preview window sizing in fullscreen Spaces ([#13](https://github.com/WordPress/browser-extension/issues/13)) remains tracked. | in progress |
| **v1.0** | Initial official directory releases under the WordPress publisher account: **Chrome Web Store** and **Safari / Mac App Store** (the two surfaces this codebase already ships). API and permissions surface frozen; deprecation policy locked. | gated by both store-readiness phases |
| **v1.0** | Initial official directory releases under the WordPress publisher account: **Chrome Web Store** and **Safari / Mac App Store** (the two surfaces this codebase already ships). API and permissions surface frozen; deprecation policy locked. | release candidate ([v1.0.0-rc1](https://github.com/WordPress/browser-extension/releases/tag/v1.0.0-rc1)) — gated on Safari store-readiness |
| **post-1.0** | Expansion to additional browser directories — **Firefox Add-ons (AMO)** (requires a manifest v2/v3 compatibility audit; Firefox's WebExtension surface diverges from Chromium in a few places) and **Edge Add-ons** (typically rides the Chrome Web Store submission, but the WordPress publisher-account question may differ). Ongoing host-detection additions as managed-WordPress platforms ship new signatures. | gated by 1.0 launch signal |

## v0.11.x checklist (Chrome)
Expand Down
12 changes: 10 additions & 2 deletions content.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,16 @@
const blockInspectorSupported = !isWpAdmin;

async function loadBlockInspectorPref() {
const prefs = (await loadPrefsRoot())[location.origin];
return !!(prefs && prefs.blockInspectorEnabled);
const prefsRoot = await loadPrefsRoot();
const prefs = prefsRoot[location.origin];
const globalPrefs = prefsRoot._global || {};
// Same per-origin-then-_global precedence as loadAdminBarPref. The popup's
// usePrefs merges `_global` for every key, so reading only the per-origin
// namespace here would let its toggle read on while the page never outlines.
if (prefs && typeof prefs.blockInspectorEnabled === 'boolean') {
return prefs.blockInspectorEnabled === true;
}
return globalPrefs.blockInspectorEnabled === true;
}

function applyBlockInspector(enabled) {
Expand Down
2 changes: 1 addition & 1 deletion dist/popup.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/popup.js

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,16 @@
const blockInspectorSupported = !isWpAdmin;

async function loadBlockInspectorPref() {
const prefs = (await loadPrefsRoot())[location.origin];
return !!(prefs && prefs.blockInspectorEnabled);
const prefsRoot = await loadPrefsRoot();
const prefs = prefsRoot[location.origin];
const globalPrefs = prefsRoot._global || {};
// Same per-origin-then-_global precedence as loadAdminBarPref. The popup's
// usePrefs merges `_global` for every key, so reading only the per-origin
// namespace here would let its toggle read on while the page never outlines.
if (prefs && typeof prefs.blockInspectorEnabled === 'boolean') {
return prefs.blockInspectorEnabled === true;
}
return globalPrefs.blockInspectorEnabled === true;
}

function applyBlockInspector(enabled) {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

35 changes: 27 additions & 8 deletions src/popup/components/DetectedView.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,23 +167,42 @@ function WpAdminActions({ ctx, origin, baseUrl, url, user }) {
);
}

const IS_MAC = typeof navigator !== 'undefined' && navigator.platform?.startsWith('Mac');

const MAC_GLYPHS = {
command: '⌘', cmd: '⌘',
alt: '⌥', option: '⌥',
ctrl: '⌃', control: '⌃', macctrl: '⌃',
shift: '⇧',
};

// Safari reports the raw "Alt+Shift+E" spelling on macOS, which reads as a
// Windows binding there. Splitting on "+" rather than substring-replacing keeps
// "MacCtrl" from being mangled into "Mac⌃", and leaves a value that is already
// glyphs (Chrome's) untouched, since it has no "+" to split on.
function toMacGlyphs(shortcut) {
return shortcut
.split('+')
.map((part) => MAC_GLYPHS[part.trim().toLowerCase()] ?? part.trim())
.join('');
}

// Live binding for the edit-this-page command. Users can rebind or clear it
// at chrome://extensions/shortcuts, and commands.getAll() returns the current
// binding already formatted for the platform (native ⌥⇧ glyphs on Mac, where
// the manifest's "Alt" means the Option key). The static suggested-key hint
// is only the fallback for when the API is unavailable (dev preview); a
// binding the user cleared shows no hint rather than a false one.
// at chrome://extensions/shortcuts. The static suggested-key hint is only the
// fallback for when the API is unavailable (dev preview); a binding the user
// cleared shows no hint rather than a false one.
function useEditShortcutHint() {
const isMac = typeof navigator !== 'undefined' && navigator.platform?.startsWith('Mac');
const fallback = isMac ? '⌥⇧E' : 'Alt+Shift+E';
const fallback = IS_MAC ? '⌥⇧E' : 'Alt+Shift+E';
const [hint, setHint] = useState(fallback);
useEffect(() => {
let cancelled = false;
try {
chrome.commands?.getAll?.((commands) => {
if (cancelled || !Array.isArray(commands)) return;
const cmd = commands.find((c) => c.name === 'edit-this-page');
if (cmd) setHint(cmd.shortcut || null);
if (!cmd) return;
const shortcut = cmd.shortcut || null;
setHint(shortcut && IS_MAC ? toMacGlyphs(shortcut) : shortcut);
});
} catch (_) {
/* commands API unavailable — keep the suggested-key fallback */
Expand Down
47 changes: 4 additions & 43 deletions src/popup/popup.scss
Original file line number Diff line number Diff line change
Expand Up @@ -355,17 +355,6 @@ body {
padding: 12px var(--wpd-pad-x) 14px;
}

.wpd-section__label {
display: block;
font-size: 11px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--wpd-ink-dim);
margin-bottom: 8px;
padding: 0 2px;
}

.wpd-section__items {
display: flex;
flex-direction: column;
Expand Down Expand Up @@ -826,26 +815,6 @@ body {
letter-spacing: 0;
}

.wpd-siteinfo__row-tag {
font-size: 10px;
font-weight: 500;
text-transform: uppercase;
letter-spacing: 0.04em;
padding: 1px 6px;
border-radius: 999px;
background: var(--wpd-border);
color: var(--wpd-ink-dim);
}

/* The version pill sits on --wpd-border, which is light enough in dark mode
* that --wpd-ink-dim text only reaches ~2.6:1; brighten the label to clear
* WCAG AA (≥3:1) without darkening the pill (a shared border token). */
@media (prefers-color-scheme: dark) {
.wpd-siteinfo__row-tag {
color: #bbbbbb;
}
}

.wpd-siteinfo__row-sub {
display: flex;
align-items: center;
Expand Down Expand Up @@ -933,18 +902,6 @@ body {

/* Info row (admin bar disabled hint) ----------------------------------- */

.wpd-info-row {
padding: 12px 14px;
background: var(--wpds-color-bg-surface-info-weak, rgba(34, 113, 177, 0.08));
border: 1px solid var(--wpd-border);
border-radius: var(--wpd-radius);
font-size: 12px;
color: var(--wpd-ink-dim);
display: flex;
flex-direction: column;
gap: 4px;
}

.wpd-info-row__link {
color: var(--wpd-accent);
background: none;
Expand Down Expand Up @@ -1044,6 +1001,10 @@ body {
padding: 28px var(--wpd-pad-x) 32px;
background: var(--wpd-surface);
margin: 0 auto;
/* EmptyState.Root ships max-width: 320px; without this override the surface
* sits inset in the 380px popup and --wpd-bg shows through as a band in dark
* mode, where every other view is full-bleed. */
max-width: none;
}

/* Loading & empty states ----------------------------------------------- */
Expand Down
Loading