Usage analytics existed as five of the nine colliding globals creator-frame.md counted (ANALYTICS_KEY, analyticsLoad, analyticsSave, downloadAnalytics, showAnalytics), twice - and the wizard's copy had no caller, because the button lived on the creator. The admin console had a THIRD private reader (usageLoad/downloadUsage) that only saw the wizard's key. Now: ONE core, html/wp-usage.js (window.WPUsage: load/save/track/download + the two pre-move storage keys, verbatim). The creator and wizard keep only a thin track() wrapper - page state like the creator's dev-mode pause belongs to the page - and record exactly what they recorded before, under the same keys, so everything captured before this task still reads (probe plants a legacy-format event and finds it in the report). The "Usage data" button left the creator toolbar; the report lives in admin.html's usage card, covering BOTH tools with a download each, behind the same admin gate as the rest of the console (a non-admin sees the denied card and nothing else), usable at 390px. Two probes re-pointed, both with the reason in the code: - cards_check pinned admin.js byte-identical to HEAD - right for T6.5, but as a standing probe it would fail every legitimate later edit; D5 targets admin.js by name. A7's localization is protected by the feature checks and the end-to-end drive, plus a wiring assertion on the block itself. - frame_check listed "Usage data" among the toolbar buttons that must be visible; it now asserts the button is GONE, so the duplicate cannot quietly return. Verification (each probe run alone): NEW tests/usage_check.py 15/15 (grep half: WPUsage defined once, no page touches the keys directly, none of the five globals survives anywhere). Regressions: cards_check ALL PASS, frame_check 39/39. Items: D5 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
59 lines
2.3 KiB
JavaScript
59 lines
2.3 KiB
JavaScript
/* Usage analytics core — the ONE implementation (D5 / T7.10).
|
|
|
|
This existed three times: the creator's copy, the wizard's copy (which had no
|
|
caller — the button lived on the creator), and the admin console's own reader.
|
|
Once the creator stopped being an iframe (B7/T7.1) the first two sat in one
|
|
document as five colliding globals; an unreferenced duplicate is exactly what
|
|
produced D5. One core now; the pages keep only a thin track() wrapper because
|
|
page state (the creator's dev-mode pause) belongs to the page.
|
|
|
|
The storage KEYS are unchanged on purpose: everything recorded before this
|
|
file existed is still readable through it. No field VALUES are ever stored —
|
|
a field-edit event records the field id, nothing else.
|
|
|
|
Classic script, no modules: exposes window.WPUsage. */
|
|
'use strict';
|
|
|
|
(function () {
|
|
var SESSION = 's_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 6);
|
|
|
|
function load(key) {
|
|
try { return JSON.parse(localStorage.getItem(key)) || { events: [] }; }
|
|
catch (e) { return { events: [] }; }
|
|
}
|
|
|
|
function save(key, data) {
|
|
try { localStorage.setItem(key, JSON.stringify(data)); }
|
|
catch (e) { /* storage unavailable — degrade silently */ }
|
|
}
|
|
|
|
function track(key, event, detail) {
|
|
try {
|
|
var d = load(key);
|
|
d.events.push({ ts: new Date().toISOString(), session: SESSION, event: event, detail: detail || null });
|
|
if (d.events.length > 5000) d.events = d.events.slice(-5000);
|
|
save(key, d);
|
|
} catch (e) { /* never let telemetry break the tool it watches */ }
|
|
}
|
|
|
|
function download(key, prefix) {
|
|
var blob = new Blob([JSON.stringify(load(key), null, 2)], { type: 'application/json' });
|
|
var a = document.createElement('a');
|
|
a.href = URL.createObjectURL(blob);
|
|
a.download = (prefix || 'wp-usage') + '-' + new Date().toISOString().slice(0, 10) + '.json';
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
a.remove();
|
|
setTimeout(function () { URL.revokeObjectURL(a.href); }, 1000);
|
|
}
|
|
|
|
window.WPUsage = {
|
|
load: load,
|
|
save: save,
|
|
track: track,
|
|
download: download,
|
|
// The pre-D5 keys, verbatim — continuity of the recorded data is a done-when.
|
|
KEYS: { creator: 'wp_iwp_analytics_v1', wizard: 'wp_suite_analytics_v1' },
|
|
};
|
|
})();
|