feat: upgrade to core v0.8.0-alpha.1, replace banned stdlib imports
Replace fmt, errors, strings, encoding/json with Core primitives. Keep strings.EqualFold, json.NewEncoder (no core equivalents). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ab48e6c373
commit
96f18346d9
8 changed files with 77 additions and 77 deletions
28
actions.go
28
actions.go
|
|
@ -3,9 +3,9 @@ package webview
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
|
|
@ -84,7 +84,7 @@ type ScrollAction struct {
|
|||
|
||||
// Execute performs the scroll action.
|
||||
func (a ScrollAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("window.scrollTo(%d, %d)", a.X, a.Y)
|
||||
script := core.Sprintf("window.scrollTo(%d, %d)", a.X, a.Y)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ type ScrollIntoViewAction struct {
|
|||
|
||||
// Execute scrolls the element into view.
|
||||
func (a ScrollIntoViewAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.scrollIntoView({behavior: 'smooth', block: 'center'})", a.Selector)
|
||||
script := core.Sprintf("document.querySelector(%q)?.scrollIntoView({behavior: 'smooth', block: 'center'})", a.Selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -108,7 +108,7 @@ type FocusAction struct {
|
|||
|
||||
// Execute focuses the element.
|
||||
func (a FocusAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.focus()", a.Selector)
|
||||
script := core.Sprintf("document.querySelector(%q)?.focus()", a.Selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ type BlurAction struct {
|
|||
|
||||
// Execute removes focus from the element.
|
||||
func (a BlurAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.blur()", a.Selector)
|
||||
script := core.Sprintf("document.querySelector(%q)?.blur()", a.Selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -132,7 +132,7 @@ type ClearAction struct {
|
|||
|
||||
// Execute clears the input value.
|
||||
func (a ClearAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el) {
|
||||
el.value = '';
|
||||
|
|
@ -152,7 +152,7 @@ type SelectAction struct {
|
|||
|
||||
// Execute selects the option.
|
||||
func (a SelectAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el) {
|
||||
el.value = %q;
|
||||
|
|
@ -171,7 +171,7 @@ type CheckAction struct {
|
|||
|
||||
// Execute checks/unchecks the checkbox.
|
||||
func (a CheckAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el && el.checked !== %t) {
|
||||
el.click();
|
||||
|
|
@ -222,7 +222,7 @@ func (a DoubleClickAction) Execute(ctx context.Context, wv *Webview) error {
|
|||
|
||||
if elem.BoundingBox == nil {
|
||||
// Fallback to JavaScript
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el) {
|
||||
const event = new MouseEvent('dblclick', {bubbles: true, cancelable: true, view: window});
|
||||
|
|
@ -269,7 +269,7 @@ func (a RightClickAction) Execute(ctx context.Context, wv *Webview) error {
|
|||
|
||||
if elem.BoundingBox == nil {
|
||||
// Fallback to JavaScript
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el) {
|
||||
const event = new MouseEvent('contextmenu', {bubbles: true, cancelable: true, view: window});
|
||||
|
|
@ -377,7 +377,7 @@ type SetAttributeAction struct {
|
|||
|
||||
// Execute sets the attribute.
|
||||
func (a SetAttributeAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.setAttribute(%q, %q)", a.Selector, a.Attribute, a.Value)
|
||||
script := core.Sprintf("document.querySelector(%q)?.setAttribute(%q, %q)", a.Selector, a.Attribute, a.Value)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -390,7 +390,7 @@ type RemoveAttributeAction struct {
|
|||
|
||||
// Execute removes the attribute.
|
||||
func (a RemoveAttributeAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.removeAttribute(%q)", a.Selector, a.Attribute)
|
||||
script := core.Sprintf("document.querySelector(%q)?.removeAttribute(%q)", a.Selector, a.Attribute)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -403,7 +403,7 @@ type SetValueAction struct {
|
|||
|
||||
// Execute sets the value.
|
||||
func (a SetValueAction) Execute(ctx context.Context, wv *Webview) error {
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
const el = document.querySelector(%q);
|
||||
if (el) {
|
||||
el.value = %q;
|
||||
|
|
@ -462,7 +462,7 @@ func (s *ActionSequence) WaitForSelector(selector string) *ActionSequence {
|
|||
func (s *ActionSequence) Execute(ctx context.Context, wv *Webview) error {
|
||||
for i, action := range s.actions {
|
||||
if err := action.Execute(ctx, wv); err != nil {
|
||||
return coreerr.E("ActionSequence.Execute", fmt.Sprintf("action %d failed", i), err)
|
||||
return coreerr.E("ActionSequence.Execute", core.Sprintf("action %d failed", i), err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
|
|
|||
36
angular.go
36
angular.go
|
|
@ -3,11 +3,9 @@ package webview
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
|
|
@ -209,7 +207,7 @@ func (ah *AngularHelper) NavigateByRouter(path string) error {
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const roots = window.getAllAngularRootElements ? window.getAllAngularRootElements() : [];
|
||||
if (roots.length === 0) {
|
||||
|
|
@ -326,7 +324,7 @@ func (ah *AngularHelper) GetComponentProperty(selector, propertyName string) (an
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const selector = %s;
|
||||
const propertyName = %s;
|
||||
|
|
@ -350,7 +348,7 @@ func (ah *AngularHelper) SetComponentProperty(selector, propertyName string, val
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const selector = %s;
|
||||
const propertyName = %s;
|
||||
|
|
@ -383,7 +381,7 @@ func (ah *AngularHelper) CallComponentMethod(selector, methodName string, args .
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
var argsStr strings.Builder
|
||||
argsStr := core.NewBuilder()
|
||||
for i, arg := range args {
|
||||
if i > 0 {
|
||||
argsStr.WriteString(", ")
|
||||
|
|
@ -391,7 +389,7 @@ func (ah *AngularHelper) CallComponentMethod(selector, methodName string, args .
|
|||
argsStr.WriteString(formatJSValue(arg))
|
||||
}
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const selector = %s;
|
||||
const methodName = %s;
|
||||
|
|
@ -454,7 +452,7 @@ func (ah *AngularHelper) GetService(serviceName string) (any, error) {
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const roots = window.getAllAngularRootElements ? window.getAllAngularRootElements() : [];
|
||||
for (const root of roots) {
|
||||
|
|
@ -481,7 +479,7 @@ func (ah *AngularHelper) WaitForComponent(selector string) error {
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const element = document.querySelector(%q);
|
||||
if (!element) return false;
|
||||
|
|
@ -523,7 +521,7 @@ func (ah *AngularHelper) DispatchEvent(selector, eventName string, detail any) e
|
|||
detailStr = formatJSValue(detail)
|
||||
}
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const selector = %s;
|
||||
const eventName = %s;
|
||||
|
|
@ -546,7 +544,7 @@ func (ah *AngularHelper) GetNgModel(selector string) (any, error) {
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const element = document.querySelector(%q);
|
||||
if (!element) return null;
|
||||
|
|
@ -573,7 +571,7 @@ func (ah *AngularHelper) SetNgModel(selector string, value any) error {
|
|||
ctx, cancel := context.WithTimeout(ah.wv.ctx, ah.timeout)
|
||||
defer cancel()
|
||||
|
||||
script := fmt.Sprintf(`
|
||||
script := core.Sprintf(`
|
||||
(function() {
|
||||
const selector = %s;
|
||||
const element = document.querySelector(selector);
|
||||
|
|
@ -616,14 +614,14 @@ func getString(m map[string]any, key string) string {
|
|||
}
|
||||
|
||||
func formatJSValue(v any) string {
|
||||
data, err := json.Marshal(v)
|
||||
if err == nil {
|
||||
return string(data)
|
||||
r := core.JSONMarshal(v)
|
||||
if r.OK {
|
||||
return string(r.Value.([]byte))
|
||||
}
|
||||
|
||||
fallback, fallbackErr := json.Marshal(fmt.Sprint(v))
|
||||
if fallbackErr == nil {
|
||||
return string(fallback)
|
||||
r = core.JSONMarshal(core.Sprint(v))
|
||||
if r.OK {
|
||||
return string(r.Value.([]byte))
|
||||
}
|
||||
|
||||
return "null"
|
||||
|
|
|
|||
|
|
@ -4,15 +4,15 @@ package webview
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ func (s *fakeCDPServer) addTarget(id string) *fakeCDPTarget {
|
|||
func (s *fakeCDPServer) newTarget() *fakeCDPTarget {
|
||||
s.mu.Lock()
|
||||
s.nextTarget++
|
||||
id := fmt.Sprintf("target-%d", s.nextTarget+1)
|
||||
id := core.Sprintf("target-%d", s.nextTarget+1)
|
||||
s.mu.Unlock()
|
||||
|
||||
return s.addTarget(id)
|
||||
|
|
@ -100,8 +100,8 @@ func (s *fakeCDPServer) handle(w http.ResponseWriter, r *http.Request) {
|
|||
s.writeJSON(w, map[string]string{
|
||||
"Browser": "Chrome/123.0",
|
||||
})
|
||||
case strings.HasPrefix(r.URL.Path, "/devtools/page/"):
|
||||
s.handleWebSocket(w, r, strings.TrimPrefix(r.URL.Path, "/devtools/page/"))
|
||||
case core.HasPrefix(r.URL.Path, "/devtools/page/"):
|
||||
s.handleWebSocket(w, r, core.TrimPrefix(r.URL.Path, "/devtools/page/"))
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
|
@ -209,7 +209,7 @@ func (tgt *fakeCDPTarget) readLoop() {
|
|||
}
|
||||
|
||||
var msg cdpMessage
|
||||
if err := json.Unmarshal(data, &msg); err != nil {
|
||||
if r := core.JSONUnmarshal(data, &msg); !r.OK {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -451,7 +451,7 @@ func TestNewCDPClient_Bad_RejectsCrossHostWebSocket(t *testing.T) {
|
|||
if err == nil {
|
||||
t.Fatal("NewCDPClient succeeded with a cross-host WebSocket URL")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "invalid target WebSocket URL") {
|
||||
if !core.Contains(err.Error(), "invalid target WebSocket URL") {
|
||||
t.Fatalf("NewCDPClient error = %v, want cross-host WebSocket validation failure", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -543,13 +543,13 @@ func TestAngularHelperSetNgModel_Good_EscapesSelectorAndValue(t *testing.T) {
|
|||
}
|
||||
|
||||
expression, _ := target.waitForMessage(t).Params["expression"].(string)
|
||||
if !strings.Contains(expression, "const selector = "+formatJSValue(selector)+";") {
|
||||
if !core.Contains(expression, "const selector = "+formatJSValue(selector)+";") {
|
||||
t.Fatalf("expression did not contain safely quoted selector: %s", expression)
|
||||
}
|
||||
if !strings.Contains(expression, "element.value = "+formatJSValue(value)+";") {
|
||||
if !core.Contains(expression, "element.value = "+formatJSValue(value)+";") {
|
||||
t.Fatalf("expression did not contain safely quoted value: %s", expression)
|
||||
}
|
||||
if strings.Contains(expression, "throw new Error('Element not found: "+selector+"')") {
|
||||
if core.Contains(expression, "throw new Error('Element not found: "+selector+"')") {
|
||||
t.Fatalf("expression still embedded selector directly in error text: %s", expression)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
35
cdp.go
35
cdp.go
|
|
@ -3,8 +3,6 @@ package webview
|
|||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"iter"
|
||||
"net"
|
||||
|
|
@ -17,9 +15,10 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
const debugEndpointTimeout = 10 * time.Second
|
||||
|
|
@ -31,7 +30,7 @@ var (
|
|||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
errCDPClientClosed = errors.New("cdp client closed")
|
||||
errCDPClientClosed = core.NewError("cdp client closed")
|
||||
)
|
||||
|
||||
// CDPClient handles communication with Chrome DevTools Protocol via WebSocket.
|
||||
|
|
@ -225,7 +224,7 @@ func (c *CDPClient) readLoop() {
|
|||
}
|
||||
|
||||
var netErr net.Error
|
||||
if errors.As(err, &netErr) && netErr.Timeout() {
|
||||
if core.As(err, &netErr) && netErr.Timeout() {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
@ -235,7 +234,7 @@ func (c *CDPClient) readLoop() {
|
|||
|
||||
// Try to parse as response
|
||||
var resp cdpResponse
|
||||
if err := json.Unmarshal(data, &resp); err == nil && resp.ID > 0 {
|
||||
if r := core.JSONUnmarshal(data, &resp); r.OK && resp.ID > 0 {
|
||||
c.pendMu.Lock()
|
||||
if ch, ok := c.pending[resp.ID]; ok {
|
||||
respCopy := resp
|
||||
|
|
@ -250,7 +249,7 @@ func (c *CDPClient) readLoop() {
|
|||
|
||||
// Try to parse as event
|
||||
var event cdpEvent
|
||||
if err := json.Unmarshal(data, &event); err == nil && event.Method != "" {
|
||||
if r := core.JSONUnmarshal(data, &event); r.OK && event.Method != "" {
|
||||
c.dispatchEvent(event.Method, event.Params)
|
||||
}
|
||||
}
|
||||
|
|
@ -392,8 +391,8 @@ func GetVersion(debugURL string) (map[string]string, error) {
|
|||
}
|
||||
|
||||
var version map[string]string
|
||||
if err := json.Unmarshal(body, &version); err != nil {
|
||||
return nil, coreerr.E("GetVersion", "failed to parse version", err)
|
||||
if r := core.JSONUnmarshal(body, &version); !r.OK {
|
||||
return nil, coreerr.E("GetVersion", "failed to parse version", nil)
|
||||
}
|
||||
|
||||
return version, nil
|
||||
|
|
@ -447,7 +446,7 @@ func parseDebugURL(raw string) (*url.URL, error) {
|
|||
}
|
||||
|
||||
func canonicalDebugURL(debugURL *url.URL) string {
|
||||
return strings.TrimSuffix(debugURL.String(), "/")
|
||||
return core.TrimSuffix(debugURL.String(), "/")
|
||||
}
|
||||
|
||||
func doDebugRequest(ctx context.Context, debugBase *url.URL, endpoint, rawQuery string) ([]byte, error) {
|
||||
|
|
@ -486,8 +485,8 @@ func listTargetsAt(ctx context.Context, debugBase *url.URL) ([]TargetInfo, error
|
|||
}
|
||||
|
||||
var targets []TargetInfo
|
||||
if err := json.Unmarshal(body, &targets); err != nil {
|
||||
return nil, err
|
||||
if r := core.JSONUnmarshal(body, &targets); !r.OK {
|
||||
return nil, coreerr.E("CDPClient.listTargetsAt", "failed to parse targets", nil)
|
||||
}
|
||||
|
||||
return targets, nil
|
||||
|
|
@ -505,8 +504,8 @@ func createTargetAt(ctx context.Context, debugBase *url.URL, pageURL string) (*T
|
|||
}
|
||||
|
||||
var target TargetInfo
|
||||
if err := json.Unmarshal(body, &target); err != nil {
|
||||
return nil, err
|
||||
if r := core.JSONUnmarshal(body, &target); !r.OK {
|
||||
return nil, coreerr.E("CDPClient.createTargetAt", "failed to parse target", nil)
|
||||
}
|
||||
|
||||
return &target, nil
|
||||
|
|
@ -551,7 +550,7 @@ func targetIDFromWebSocketURL(raw string) (string, error) {
|
|||
return "", err
|
||||
}
|
||||
|
||||
targetID := path.Base(strings.TrimSuffix(wsURL.Path, "/"))
|
||||
targetID := path.Base(core.TrimSuffix(wsURL.Path, "/"))
|
||||
if targetID == "." || targetID == "/" || targetID == "" {
|
||||
return "", coreerr.E("CDPClient.targetIDFromWebSocketURL", "missing target ID in WebSocket URL", nil)
|
||||
}
|
||||
|
|
@ -595,11 +594,11 @@ func isTerminalReadError(err error) bool {
|
|||
if err == nil {
|
||||
return false
|
||||
}
|
||||
if errors.Is(err, net.ErrClosed) || errors.Is(err, websocket.ErrCloseSent) {
|
||||
if core.Is(err, net.ErrClosed) || core.Is(err, websocket.ErrCloseSent) {
|
||||
return true
|
||||
}
|
||||
var closeErr *websocket.CloseError
|
||||
return errors.As(err, &closeErr)
|
||||
return core.As(err, &closeErr)
|
||||
}
|
||||
|
||||
func cloneMapAny(src map[string]any) map[string]any {
|
||||
|
|
|
|||
16
console.go
16
console.go
|
|
@ -3,13 +3,13 @@ package webview
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
||||
// ConsoleWatcher provides advanced console message watching capabilities.
|
||||
|
|
@ -272,14 +272,14 @@ func (cw *ConsoleWatcher) handleConsoleEvent(params map[string]any) {
|
|||
|
||||
// Extract args
|
||||
args, _ := params["args"].([]any)
|
||||
var text strings.Builder
|
||||
text := core.NewBuilder()
|
||||
for i, arg := range args {
|
||||
if argMap, ok := arg.(map[string]any); ok {
|
||||
if val, ok := argMap["value"]; ok {
|
||||
if i > 0 {
|
||||
text.WriteString(" ")
|
||||
}
|
||||
text.WriteString(fmt.Sprint(val))
|
||||
text.WriteString(core.Sprint(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -525,7 +525,7 @@ func (ew *ExceptionWatcher) handleException(params map[string]any) {
|
|||
url, _ := exceptionDetails["url"].(string)
|
||||
|
||||
// Extract stack trace
|
||||
var stackTrace strings.Builder
|
||||
stackTrace := core.NewBuilder()
|
||||
if st, ok := exceptionDetails["stackTrace"].(map[string]any); ok {
|
||||
if frames, ok := st["callFrames"].([]any); ok {
|
||||
for _, f := range frames {
|
||||
|
|
@ -534,7 +534,7 @@ func (ew *ExceptionWatcher) handleException(params map[string]any) {
|
|||
frameURL, _ := frame["url"].(string)
|
||||
frameLine, _ := frame["lineNumber"].(float64)
|
||||
frameCol, _ := frame["columnNumber"].(float64)
|
||||
stackTrace.WriteString(fmt.Sprintf(" at %s (%s:%d:%d)\n", funcName, frameURL, int(frameLine), int(frameCol)))
|
||||
stackTrace.WriteString(core.Sprintf(" at %s (%s:%d:%d)\n", funcName, frameURL, int(frameLine), int(frameCol)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -569,7 +569,7 @@ func (ew *ExceptionWatcher) handleException(params map[string]any) {
|
|||
|
||||
// FormatConsoleOutput formats console messages for display.
|
||||
func FormatConsoleOutput(messages []ConsoleMessage) string {
|
||||
var output strings.Builder
|
||||
output := core.NewBuilder()
|
||||
for _, msg := range messages {
|
||||
prefix := ""
|
||||
switch msg.Type {
|
||||
|
|
@ -585,7 +585,7 @@ func FormatConsoleOutput(messages []ConsoleMessage) string {
|
|||
prefix = "[LOG]"
|
||||
}
|
||||
timestamp := msg.Timestamp.Format("15:04:05.000")
|
||||
output.WriteString(fmt.Sprintf("%s %s %s\n", timestamp, prefix, msg.Text))
|
||||
output.WriteString(core.Sprintf("%s %s %s\n", timestamp, prefix, msg.Text))
|
||||
}
|
||||
return output.String()
|
||||
}
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -5,3 +5,5 @@ go 1.26.0
|
|||
require github.com/gorilla/websocket v1.5.3
|
||||
|
||||
require dappco.re/go/core/log v0.1.0
|
||||
|
||||
require dappco.re/go/core v0.8.0-alpha.1
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -1,3 +1,5 @@
|
|||
dappco.re/go/core v0.8.0-alpha.1 h1:gj7+Scv+L63Z7wMxbJYHhaRFkHJo2u4MMPuUSv/Dhtk=
|
||||
dappco.re/go/core v0.8.0-alpha.1/go.mod h1:f2/tBZ3+3IqDrg2F5F598llv0nmb/4gJVCFzM5geE4A=
|
||||
dappco.re/go/core/log v0.1.0 h1:pa71Vq2TD2aoEUQWFKwNcaJ3GBY8HbaNGqtE688Unyc=
|
||||
dappco.re/go/core/log v0.1.0/go.mod h1:Nkqb8gsXhZAO8VLpx7B8i1iAmohhzqA20b9Zr8VUcJs=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
|
|
|
|||
15
webview.go
15
webview.go
|
|
@ -25,13 +25,12 @@ package webview
|
|||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"iter"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
coreerr "dappco.re/go/core/log"
|
||||
)
|
||||
|
||||
|
|
@ -337,7 +336,7 @@ func (wv *Webview) GetHTML(selector string) (string, error) {
|
|||
if selector == "" {
|
||||
script = "document.documentElement.outerHTML"
|
||||
} else {
|
||||
script = fmt.Sprintf("document.querySelector(%q)?.outerHTML || ''", selector)
|
||||
script = core.Sprintf("document.querySelector(%q)?.outerHTML || ''", selector)
|
||||
}
|
||||
|
||||
result, err := wv.evaluate(ctx, script)
|
||||
|
|
@ -463,14 +462,14 @@ func (wv *Webview) handleConsoleEvent(params map[string]any) {
|
|||
|
||||
// Extract args
|
||||
args, _ := params["args"].([]any)
|
||||
var text strings.Builder
|
||||
text := core.NewBuilder()
|
||||
for i, arg := range args {
|
||||
if argMap, ok := arg.(map[string]any); ok {
|
||||
if val, ok := argMap["value"]; ok {
|
||||
if i > 0 {
|
||||
text.WriteString(" ")
|
||||
}
|
||||
text.WriteString(fmt.Sprint(val))
|
||||
text.WriteString(core.Sprint(val))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -526,7 +525,7 @@ func (wv *Webview) waitForSelector(ctx context.Context, selector string) error {
|
|||
ticker := time.NewTicker(100 * time.Millisecond)
|
||||
defer ticker.Stop()
|
||||
|
||||
script := fmt.Sprintf("!!document.querySelector(%q)", selector)
|
||||
script := core.Sprintf("!!document.querySelector(%q)", selector)
|
||||
|
||||
for {
|
||||
select {
|
||||
|
|
@ -719,7 +718,7 @@ func (wv *Webview) click(ctx context.Context, selector string) error {
|
|||
|
||||
if elem.BoundingBox == nil {
|
||||
// Fallback to JavaScript click
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.click()", selector)
|
||||
script := core.Sprintf("document.querySelector(%q)?.click()", selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
return err
|
||||
}
|
||||
|
|
@ -748,7 +747,7 @@ func (wv *Webview) click(ctx context.Context, selector string) error {
|
|||
// typeText types text into an element.
|
||||
func (wv *Webview) typeText(ctx context.Context, selector, text string) error {
|
||||
// Focus the element first
|
||||
script := fmt.Sprintf("document.querySelector(%q)?.focus()", selector)
|
||||
script := core.Sprintf("document.querySelector(%q)?.focus()", selector)
|
||||
_, err := wv.evaluate(ctx, script)
|
||||
if err != nil {
|
||||
return coreerr.E("Webview.typeText", "failed to focus element", err)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue