2026-04-02 20:51:26 +00:00
|
|
|
// pkg/webview/diagnostics.go
|
2026-04-02 13:29:46 +00:00
|
|
|
package webview
|
|
|
|
|
|
|
|
|
|
import (
|
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.
Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00
|
|
|
corego "dappco.re/go/core"
|
2026-04-02 13:29:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func jsQuote(v string) string {
|
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.
Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00
|
|
|
return corego.JSONMarshalString(v)
|
2026-04-02 13:29:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func computedStyleScript(selector string) string {
|
|
|
|
|
sel := jsQuote(selector)
|
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.
Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00
|
|
|
return corego.Sprintf(`(function(){
|
2026-04-02 13:29:46 +00:00
|
|
|
const el = document.querySelector(%s);
|
|
|
|
|
if (!el) return null;
|
|
|
|
|
const style = window.getComputedStyle(el);
|
|
|
|
|
const out = {};
|
|
|
|
|
for (let i = 0; i < style.length; i++) {
|
|
|
|
|
const key = style[i];
|
|
|
|
|
out[key] = style.getPropertyValue(key);
|
|
|
|
|
}
|
|
|
|
|
return out;
|
|
|
|
|
})()`, sel)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func ComputedStyleScript(selector string) string {
|
|
|
|
|
return computedStyleScript(selector)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func highlightScript(selector, colour string) string {
|
|
|
|
|
sel := jsQuote(selector)
|
|
|
|
|
if colour == "" {
|
|
|
|
|
colour = "#ff9800"
|
|
|
|
|
}
|
|
|
|
|
col := jsQuote(colour)
|
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.
Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00
|
|
|
return corego.Sprintf(`(function(){
|
2026-04-02 13:29:46 +00:00
|
|
|
const el = document.querySelector(%s);
|
|
|
|
|
if (!el) return false;
|
|
|
|
|
if (el.__coreHighlightOrigOutline === undefined) {
|
|
|
|
|
el.__coreHighlightOrigOutline = el.style.outline || "";
|
|
|
|
|
}
|
|
|
|
|
el.style.outline = "3px solid " + %s;
|
|
|
|
|
el.style.outlineOffset = "2px";
|
|
|
|
|
try { el.scrollIntoView({block: "center", inline: "center", behavior: "smooth"}); } catch (e) {}
|
|
|
|
|
return true;
|
|
|
|
|
})()`, sel, col)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func HighlightScript(selector, colour string) string {
|
|
|
|
|
return highlightScript(selector, colour)
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func performanceScript() string {
|
|
|
|
|
return `(function(){
|
|
|
|
|
const nav = performance.getEntriesByType("navigation")[0] || {};
|
|
|
|
|
const paints = performance.getEntriesByType("paint");
|
|
|
|
|
const firstPaint = paints.find((entry) => entry.name === "first-paint");
|
|
|
|
|
const firstContentfulPaint = paints.find((entry) => entry.name === "first-contentful-paint");
|
|
|
|
|
const memory = performance.memory || {};
|
|
|
|
|
return {
|
|
|
|
|
navigationStart: nav.startTime || 0,
|
|
|
|
|
domContentLoaded: nav.domContentLoadedEventEnd || 0,
|
|
|
|
|
loadEventEnd: nav.loadEventEnd || 0,
|
|
|
|
|
firstPaint: firstPaint ? firstPaint.startTime : 0,
|
|
|
|
|
firstContentfulPaint: firstContentfulPaint ? firstContentfulPaint.startTime : 0,
|
|
|
|
|
usedJSHeapSize: memory.usedJSHeapSize || 0,
|
|
|
|
|
totalJSHeapSize: memory.totalJSHeapSize || 0
|
|
|
|
|
};
|
|
|
|
|
})()`
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func PerformanceScript() string {
|
|
|
|
|
return performanceScript()
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func resourcesScript() string {
|
|
|
|
|
return `(function(){
|
|
|
|
|
return performance.getEntriesByType("resource").map((entry) => ({
|
|
|
|
|
name: entry.name,
|
|
|
|
|
entryType: entry.entryType,
|
|
|
|
|
initiatorType: entry.initiatorType,
|
|
|
|
|
startTime: entry.startTime,
|
|
|
|
|
duration: entry.duration,
|
|
|
|
|
transferSize: entry.transferSize || 0,
|
|
|
|
|
encodedBodySize: entry.encodedBodySize || 0,
|
|
|
|
|
decodedBodySize: entry.decodedBodySize || 0
|
|
|
|
|
}));
|
|
|
|
|
})()`
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func ResourcesScript() string {
|
|
|
|
|
return resourcesScript()
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func networkInitScript() string {
|
|
|
|
|
return `(function(){
|
|
|
|
|
if (window.__coreNetworkLog) return true;
|
|
|
|
|
window.__coreNetworkLog = [];
|
|
|
|
|
const log = (entry) => { window.__coreNetworkLog.push(entry); };
|
|
|
|
|
const originalFetch = window.fetch;
|
|
|
|
|
if (originalFetch) {
|
|
|
|
|
window.fetch = async function(input, init) {
|
|
|
|
|
const request = typeof input === "string" ? input : (input && input.url) ? input.url : "";
|
|
|
|
|
const method = (init && init.method) || (input && input.method) || "GET";
|
|
|
|
|
const started = Date.now();
|
|
|
|
|
try {
|
|
|
|
|
const response = await originalFetch.call(this, input, init);
|
|
|
|
|
log({
|
|
|
|
|
url: response.url || request,
|
|
|
|
|
method: method,
|
|
|
|
|
status: response.status,
|
|
|
|
|
ok: response.ok,
|
|
|
|
|
resource: "fetch",
|
|
|
|
|
timestamp: started
|
|
|
|
|
});
|
|
|
|
|
return response;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
log({
|
|
|
|
|
url: request,
|
|
|
|
|
method: method,
|
|
|
|
|
error: String(error),
|
|
|
|
|
resource: "fetch",
|
|
|
|
|
timestamp: started
|
|
|
|
|
});
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
const originalOpen = XMLHttpRequest.prototype.open;
|
|
|
|
|
const originalSend = XMLHttpRequest.prototype.send;
|
|
|
|
|
XMLHttpRequest.prototype.open = function(method, url) {
|
|
|
|
|
this.__coreMethod = method;
|
|
|
|
|
this.__coreUrl = url;
|
|
|
|
|
return originalOpen.apply(this, arguments);
|
|
|
|
|
};
|
|
|
|
|
XMLHttpRequest.prototype.send = function(body) {
|
|
|
|
|
const started = Date.now();
|
|
|
|
|
this.addEventListener("loadend", () => {
|
|
|
|
|
log({
|
|
|
|
|
url: this.__coreUrl || "",
|
|
|
|
|
method: this.__coreMethod || "GET",
|
|
|
|
|
status: this.status || 0,
|
|
|
|
|
ok: this.status >= 200 && this.status < 400,
|
|
|
|
|
resource: "xhr",
|
|
|
|
|
timestamp: started
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
return originalSend.apply(this, arguments);
|
|
|
|
|
};
|
|
|
|
|
return true;
|
|
|
|
|
})()`
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func NetworkInitScript() string {
|
|
|
|
|
return networkInitScript()
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func networkClearScript() string {
|
|
|
|
|
return `(function(){
|
|
|
|
|
window.__coreNetworkLog = [];
|
|
|
|
|
return true;
|
|
|
|
|
})()`
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-15 13:58:56 +01:00
|
|
|
func NetworkClearScript() string {
|
|
|
|
|
return networkClearScript()
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-02 13:29:46 +00:00
|
|
|
func networkLogScript(limit int) string {
|
|
|
|
|
if limit <= 0 {
|
2026-04-15 13:58:56 +01:00
|
|
|
return `((window.__coreNetworkLog && window.__coreNetworkLog.length)
|
|
|
|
|
? window.__coreNetworkLog
|
|
|
|
|
: performance.getEntriesByType("resource").map((entry) => ({
|
|
|
|
|
url: entry.name,
|
|
|
|
|
method: "GET",
|
|
|
|
|
status: 0,
|
|
|
|
|
ok: true,
|
|
|
|
|
resource: entry.initiatorType || entry.entryType,
|
|
|
|
|
timestamp: entry.startTime
|
|
|
|
|
})))`
|
2026-04-02 13:29:46 +00:00
|
|
|
}
|
2026-04-15 13:58:56 +01:00
|
|
|
return corego.Sprintf(`(function(){
|
|
|
|
|
const log = (window.__coreNetworkLog && window.__coreNetworkLog.length)
|
|
|
|
|
? window.__coreNetworkLog
|
|
|
|
|
: performance.getEntriesByType("resource").map((entry) => ({
|
|
|
|
|
url: entry.name,
|
|
|
|
|
method: "GET",
|
|
|
|
|
status: 0,
|
|
|
|
|
ok: true,
|
|
|
|
|
resource: entry.initiatorType || entry.entryType,
|
|
|
|
|
timestamp: entry.startTime
|
|
|
|
|
}));
|
|
|
|
|
return log.slice(-%d);
|
|
|
|
|
})()`, limit)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NetworkLogScript(limit int) string {
|
|
|
|
|
return networkLogScript(limit)
|
2026-04-02 13:29:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func normalizeWhitespace(s string) string {
|
refactor: AX compliance sweep — replace banned stdlib imports with core primitives
Replaced fmt, strings, sort, os, io, sync, encoding/json, path/filepath,
errors, log, reflect with core.Sprintf, core.E, core.Contains, core.Trim,
core.Split, core.Join, core.JoinPath, slices.Sort, c.Fs(), c.Lock(),
core.JSONMarshal, core.ReadAll and other CoreGO v0.8.0 primitives.
Framework boundary exceptions preserved where stdlib types are required
by external interfaces (Gin, net/http, CGo, Wails, bubbletea).
Co-Authored-By: Virgil <virgil@lethean.io>
2026-04-13 09:32:01 +01:00
|
|
|
return corego.Trim(s)
|
2026-04-02 13:29:46 +00:00
|
|
|
}
|