├── .gitignore ├── LICENSE ├── README.md ├── build-scripts ├── convert_protocol.js └── protocol │ ├── browser_protocol.json │ └── js_protocol.json ├── config └── config.go ├── dbgClient ├── breakpoints.go ├── client.go ├── debugging.go ├── proc.go └── types.go ├── debug ├── demo ├── debug └── helloworld.go ├── gdd.go ├── protocol ├── accessibility │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── animation │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── applicationcache │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── cachestorage │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── console │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── css │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── database │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── debugger │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── deviceorientation │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── dom │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── domdebugger │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── domstorage │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── emulation │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── heapprofiler │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── indexeddb │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── input │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── inspector │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── io │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── layertree │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── log │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── memory │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── network │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── page │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── profiler │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── rendering │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── runtime │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── schema │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── security │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── serviceworker │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── shared │ └── types.go ├── storage │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── systeminfo │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── target │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── tethering │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go └── tracing │ ├── agent.go │ ├── commands.go │ ├── events.go │ └── sharedTypes.go ├── proxies ├── debugger │ └── proxy.go ├── page │ └── proxy.go └── runtime │ └── proxy.go └── run.sh /.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allada/gdd/076f285bd9936f6eb2e823301d7590b2077ef567/.gitignore -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GDD - Go Debugger Devtools 2 | 3 | Go debugger using Chrome Devtools as a front-end environment. 4 | 5 | ## Notes 6 | 7 | This is in an alpha stage. Most of the features do not work. This is to experiment there is no promise that this project will continue to exist either. I could use as much help as possible on this project, so if you want to do some of the wiring to Delve or Devtools it would be much appreciated. 8 | 9 | ## Installation 10 | 11 | 1. Install Go 12 | 2. Install Chrome 13 | 3. Install and setup Delve (DLV) [This is the most difficult part. Instructions here: https://github.com/derekparker/delve] 14 | 4. Run `go get github.com/allada/gdd` 15 | 5. Run `go install github.com/allada/gdd` 16 | 17 | ## Demo Usage 18 | 19 | * Run `cd $GOPATH/src/github.com/allada/gdd/demo` 20 | * Run `$GOPATH/bin/gdd helloworld.go` 21 | 22 | This should output a link in the terminal. Open that link in a recent version of Chrome and begin playing. 23 | 24 | ## Usage Help 25 | 26 | ``` 27 | GDD is a simple debuger that binds Chrome Devtools debugger as a front-end and 28 | uses DLV as a backend. 29 | 30 | Usage: 31 | 32 | gdd go-file-to-debug [options] [-- args-to-pass-to-file ...] 33 | 34 | Options: 35 | 36 | --port=PORT Port Number to use to communicate to Chrome Devtools 37 | front-end. Default 9922. 38 | --dlv=FILE Location of DLV installed on machine. Default (tries to 39 | find 'dlv' in system path. 40 | --help Prints this help dialog. 41 | ``` 42 | 43 | ## License 44 | Copyright 2017 Nathan Bruer 45 | 46 | Licensed under the Apache License, Version 2.0 (the "License"); 47 | you may not use this file except in compliance with the License. 48 | You may obtain a copy of the License at 49 | 50 | http://www.apache.org/licenses/LICENSE-2.0 51 | 52 | Unless required by applicable law or agreed to in writing, software 53 | distributed under the License is distributed on an "AS IS" BASIS, 54 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 55 | See the License for the specific language governing permissions and 56 | limitations under the License. -------------------------------------------------------------------------------- /config/config.go: -------------------------------------------------------------------------------- 1 | package config 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "strconv" 7 | "os" 8 | ) 9 | 10 | type Config struct { 11 | Port string 12 | DlvPath string 13 | DebugSession struct { 14 | File string 15 | Args []string 16 | } 17 | } 18 | 19 | func fileFromArg(c *Config, fileToDebug string) bool { 20 | if !fileExists(fileToDebug) { 21 | fmt.Println("Invalid file path for first argument") 22 | return false 23 | } 24 | c.DebugSession.File = fileToDebug 25 | return true 26 | } 27 | 28 | func portFromArg(c *Config, port string) bool { 29 | if _, err := strconv.Atoi(port); err != nil { 30 | fmt.Println("Value for 'port' must be a valid number.") 31 | return false 32 | } 33 | c.Port = port 34 | return true 35 | } 36 | 37 | func fileExists(path string) bool { 38 | if finfo, err := os.Stat(path); err != nil || finfo.IsDir() { 39 | return false 40 | } 41 | return true 42 | } 43 | 44 | func dlvFromArg(c *Config, dlvPath string) bool { 45 | if !fileExists(dlvPath) { 46 | fmt.Println("Invalid file for 'dlv' argument.") 47 | return false 48 | } 49 | c.DlvPath = dlvPath 50 | return true 51 | } 52 | 53 | var boundArgsInfo = map[string]func(*Config, string)bool{ 54 | "0": fileFromArg, 55 | "--port": portFromArg, 56 | "--dlv": dlvFromArg, 57 | "--help": func (_ *Config, _ string) bool { 58 | printHelp() 59 | return false 60 | }, 61 | } 62 | 63 | func NewFromArgs(args []string) *Config { 64 | if len(args) <= 0 { 65 | printHelp(); 66 | return nil 67 | } 68 | 69 | defaultDlvPath := "" 70 | if val, ok := os.LookupEnv("PATH"); ok { 71 | for _, folder := range strings.Split(val, ":") { 72 | file := folder + "/dlv" 73 | if fileExists(file) { 74 | defaultDlvPath = file 75 | break 76 | } 77 | } 78 | } 79 | 80 | 81 | config := &Config{ 82 | Port: "9922", 83 | DlvPath: defaultDlvPath, 84 | } 85 | 86 | curNumbPos := 0 87 | i := 0 88 | for ; i < len(args); i++ { 89 | arg := args[i] 90 | if !strings.HasPrefix(arg, "--") { 91 | fn, ok := boundArgsInfo[strconv.Itoa(curNumbPos)] 92 | curNumbPos++ 93 | if ok { 94 | if fn(config, arg) { 95 | continue 96 | } 97 | } else { 98 | fmt.Println("Unknown arguemnt '" + arg + "'") 99 | } 100 | return nil 101 | } 102 | keyValue := strings.SplitN(arg, "=", 2) 103 | fn, ok := boundArgsInfo[keyValue[0]] 104 | if !ok { 105 | fmt.Println("Unknown argument '" + args[i] + "'") 106 | return nil 107 | } 108 | 109 | value := keyValue[0] 110 | if len(keyValue) >= 2 { 111 | value = keyValue[1] 112 | } 113 | ok = fn(config, value) 114 | if !ok { 115 | return nil 116 | } 117 | } 118 | return config 119 | } 120 | 121 | func printHelp() { 122 | data := []string{ 123 | "GDD is a simple debuger that binds Chrome Devtools debugger as a front-end and", 124 | "uses DLV as a backend.", 125 | "", 126 | "Usage:", 127 | "", 128 | " gdd go-file-to-debug [options] [-- args-to-pass-to-file ...]", 129 | "", 130 | "Options:", 131 | "", 132 | " --port=PORT Port Number to use to communicate to Chrome Devtools", 133 | " front-end. Default 9922.", 134 | " --dlv=FILE Location of DLV installed on machine. Default (tries to", 135 | " find 'dlv' in system path.", 136 | " --help Prints this help dialog.", 137 | "", 138 | } 139 | for _, line := range data { 140 | fmt.Println(line) 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /dbgClient/breakpoints.go: -------------------------------------------------------------------------------- 1 | package dbgClient 2 | 3 | import ( 4 | "unsafe" 5 | "github.com/derekparker/delve/service/api" 6 | ) 7 | 8 | // PC: Program counter 9 | func (c *Client) CreateBreakpointAtPC(pc uint64) { 10 | c.rpcClient.CreateBreakpoint(&api.Breakpoint{ 11 | Addr: pc, 12 | }) 13 | } 14 | 15 | func (c *Client) CreateBreakpointAtLine(file string, line int, name string) (*Breakpoint, error) { 16 | breakpoint, err := c.rpcClient.CreateBreakpoint(&api.Breakpoint{ 17 | File: file, 18 | Line: line, 19 | Name: name, 20 | }) 21 | return (*Breakpoint)(breakpoint), err 22 | } 23 | 24 | func (c *Client) ListAllBreakpoints() ([]*Breakpoint, error) { 25 | breakpoints, err := c.rpcClient.ListBreakpoints() 26 | // This pattern is here because we cannot convert between slices of same underlying types but different toplevel types. 27 | return *(*[]*Breakpoint)(unsafe.Pointer(&breakpoints)), err 28 | } 29 | 30 | func (c *Client) ClearAllBreakpoints() { 31 | breakpoints, err := c.rpcClient.ListBreakpoints() 32 | if err != nil { 33 | panic(err) 34 | } 35 | for _, breakpoint := range breakpoints { 36 | err := c.ClearBreakpoint(breakpoint.ID) 37 | if err != nil { 38 | panic(err) 39 | } 40 | } 41 | } 42 | 43 | func (c *Client) ClearBreakpoint(id int) error { 44 | _, err := c.rpcClient.ClearBreakpoint(id) 45 | return err 46 | } 47 | 48 | func (c *Client) ClearBreakpointByName(name string) error { 49 | _, err := c.rpcClient.ClearBreakpointByName(name) 50 | return err 51 | } 52 | -------------------------------------------------------------------------------- /dbgClient/client.go: -------------------------------------------------------------------------------- 1 | package dbgClient 2 | 3 | import ( 4 | "io" 5 | "os/exec" 6 | "fmt" 7 | "github.com/allada/gdd/config" 8 | "unsafe" 9 | "sync" 10 | "sync/atomic" 11 | "github.com/derekparker/delve/service/rpc2" 12 | ) 13 | 14 | const API_PORT_LISTENING_STRING string = "API server listening at: 127.0.0.1:%d\n" 15 | 16 | type ProcessState int32 17 | const ( 18 | StartingState = iota 19 | RunningState 20 | KilledState 21 | ) 22 | 23 | type Client struct{ 24 | File string 25 | Args []string 26 | isReadyLock sync.Mutex 27 | rpcClient *rpc2.RPCClient 28 | cmd *exec.Cmd 29 | runningState ProcessState // Since Go does not have atomic_flag I use int32 30 | stdout io.ReadCloser 31 | stderr io.ReadCloser 32 | stdin io.WriteCloser 33 | } 34 | 35 | func (c *Client) Start(config config.Config) { 36 | defer func() { 37 | if r := recover(); r != nil { 38 | c.Kill() 39 | } 40 | c.isReadyLock.Unlock() 41 | }() 42 | c.isReadyLock.Lock() 43 | args := []string{ 44 | "debug", 45 | "--headless", 46 | "--build-flags=-gcflags='-N -l'", 47 | "--api-version=2", 48 | "--listen=localhost:0", 49 | c.File, 50 | } 51 | if len(args) > 0 { 52 | args = append(args, "--") 53 | args = append(args, c.Args...) 54 | } 55 | // Looks like we were told to die before we started. Lets die now. 56 | if c.Killed() { 57 | return 58 | } 59 | c.cmd = exec.Command(config.DlvPath, args...) 60 | 61 | var err error 62 | c.stdout, err = c.cmd.StdoutPipe() 63 | if err != nil { 64 | panic(err) 65 | } 66 | 67 | c.stderr, err = c.cmd.StderrPipe() 68 | if err != nil { 69 | panic(err) 70 | } 71 | 72 | c.stdin, err = c.cmd.StdinPipe() 73 | if err != nil { 74 | panic(err) 75 | } 76 | 77 | if err = c.cmd.Start(); err != nil { 78 | panic(err) 79 | } 80 | 81 | var port int 82 | fmt.Fscanf(c.stdout, API_PORT_LISTENING_STRING, &port) 83 | if port == 0 { 84 | panic("Did not get good output from dlv or 0 for port number.") 85 | } 86 | 87 | c.rpcClient = rpc2.NewClient("localhost:" + fmt.Sprintf("%d", port)) 88 | if ProcessState(atomic.SwapInt32((*int32)(&c.runningState), RunningState)) == KilledState { 89 | // Looks like we got a kill signal while we were starting. 90 | c.Kill() 91 | return 92 | } 93 | 94 | c.setupBreakOnStart() 95 | // Continue to newly created breakpoint. We should now be at first instruction in main(). 96 | 97 | <-c.Continue() 98 | breakpoints, err := c.ListAllBreakpoints() 99 | if err != nil { 100 | panic(err) 101 | } 102 | for _, breakpoint := range breakpoints { 103 | c.ClearBreakpoint((*breakpoint).ID) 104 | } 105 | } 106 | 107 | func (c *Client) Starting() bool { 108 | return ProcessState(atomic.LoadInt32((*int32)(&c.runningState))) == StartingState 109 | } 110 | 111 | func (c *Client) Killed() bool { 112 | return ProcessState(atomic.LoadInt32((*int32)(&c.runningState))) == KilledState 113 | } 114 | 115 | func (c *Client) Kill() { 116 | // This ensures we only execute stuff after this if statment once per agent. 117 | if atomic.SwapInt32((*int32)(&c.runningState), KilledState) != RunningState { 118 | return 119 | } 120 | fmt.Println("Killing debugging process") 121 | c.Detach(false) 122 | c.stdout.Close() 123 | c.stderr.Close() 124 | c.stdin.Close() 125 | c.cmd.Process.Kill() 126 | c.cmd.Wait() 127 | fmt.Println("Killed debugging process") 128 | } 129 | 130 | func (c *Client) GetStdout() (io.ReadCloser, error) { 131 | c.BlockUntilReady() 132 | return c.stdout, nil 133 | } 134 | 135 | func (c *Client) GetStderr() (io.ReadCloser, error) { 136 | c.BlockUntilReady() 137 | return c.stderr, nil 138 | } 139 | 140 | func (c *Client) setupBreakOnStart() { 141 | scope, err := c.FindLocation(EvalScope{ 142 | GoroutineID: -1, 143 | Frame: 0, 144 | }, "main.main") 145 | if err != nil { 146 | panic(err) 147 | } 148 | if len(scope) < 1 { 149 | panic("Expected scope to have at least 1 item in it.") 150 | } 151 | c.CreateBreakpointAtPC(scope[0].PC) 152 | } 153 | 154 | func (c *Client) BlockUntilReady() { 155 | c.isReadyLock.Lock() 156 | c.isReadyLock.Unlock() 157 | } 158 | 159 | func (c *Client) FindLocation(scope EvalScope, location string) ([]Location, error) { 160 | loc, err := c.rpcClient.FindLocation(scope.conv(), location) 161 | // This pattern is here because we cannot convert between slices of same underlying types but different toplevel types. 162 | return *(*[]Location)(unsafe.Pointer(&loc)), err 163 | } 164 | 165 | func (c *Client) ListSources() ([]string, error) { 166 | return c.rpcClient.ListSources("") 167 | } -------------------------------------------------------------------------------- /dbgClient/debugging.go: -------------------------------------------------------------------------------- 1 | package dbgClient 2 | 3 | import ( 4 | "unsafe" 5 | "github.com/derekparker/delve/service/api" 6 | ) 7 | 8 | func (c *Client) ListGoroutines() ([]*Goroutine, error) { 9 | goRoutines, err := c.rpcClient.ListGoroutines() 10 | return *(*[]*Goroutine)(unsafe.Pointer(&goRoutines)), err 11 | } 12 | 13 | func (c *Client) ListThreads() ([]*Thread, error) { 14 | threads, err := c.rpcClient.ListThreads() 15 | return *(*[]*Thread)(unsafe.Pointer(&threads)), err 16 | } 17 | 18 | func (c *Client) Stacktrace(goroutineID int, depth int, cfg *LoadConfig) ([]Stackframe, error) { 19 | stack, err := c.rpcClient.Stacktrace(goroutineID, depth, (*api.LoadConfig)(cfg)) 20 | return *(*[]Stackframe)(unsafe.Pointer(&stack)), err 21 | } 22 | 23 | func (c *Client) GetState() (*DebuggerState, error) { 24 | debuggerState, err := c.rpcClient.GetState() 25 | return (*DebuggerState)(debuggerState), err 26 | } 27 | 28 | func (c *Client) Continue() <-chan *DebuggerState { 29 | debuggerState := c.rpcClient.Continue() 30 | return *(*<-chan *DebuggerState)(unsafe.Pointer(&debuggerState)) 31 | } 32 | 33 | func (c *Client) Next() (*DebuggerState, error) { 34 | debuggerState, err := c.rpcClient.Next() 35 | return (*DebuggerState)(debuggerState), err 36 | } 37 | 38 | func (c *Client) Step() (*DebuggerState, error) { 39 | debuggerState, err := c.rpcClient.Step() 40 | return (*DebuggerState)(debuggerState), err 41 | } 42 | 43 | func (c *Client) StepOut() (*DebuggerState, error) { 44 | debuggerState, err := c.rpcClient.StepOut() 45 | return (*DebuggerState)(debuggerState), err 46 | } 47 | 48 | func (c *Client) SwitchGoroutine(goroutineID int) (*DebuggerState, error) { 49 | debuggerState, err := c.rpcClient.SwitchGoroutine(goroutineID) 50 | return (*DebuggerState)(debuggerState), err 51 | } 52 | 53 | func (c *Client) SwitchThread(threadID int) (*DebuggerState, error) { 54 | debuggerState, err := c.rpcClient.SwitchThread(threadID) 55 | return (*DebuggerState)(debuggerState), err 56 | } 57 | 58 | func (c *Client) ListLocalVariables(scope EvalScope, cfg LoadConfig) ([]Variable, error) { 59 | variables, err := c.rpcClient.ListLocalVariables(api.EvalScope(scope), api.LoadConfig(cfg)) 60 | return *(*[]Variable)(unsafe.Pointer(&variables)), err 61 | } 62 | 63 | func (c *Client) EvalVariable(scope EvalScope, expr string, cfg LoadConfig) (*Variable, error) { 64 | variable, err := c.rpcClient.EvalVariable(api.EvalScope(scope), expr, api.LoadConfig(cfg)) 65 | return (*Variable)(variable), err 66 | } 67 | -------------------------------------------------------------------------------- /dbgClient/proc.go: -------------------------------------------------------------------------------- 1 | package dbgClient 2 | 3 | func (c *Client) Detach(kill bool) error { 4 | return c.rpcClient.Detach(true) 5 | } 6 | -------------------------------------------------------------------------------- /dbgClient/types.go: -------------------------------------------------------------------------------- 1 | package dbgClient 2 | 3 | import ( 4 | "github.com/derekparker/delve/service/api" 5 | ) 6 | 7 | type EvalScope api.EvalScope 8 | 9 | func (a EvalScope) conv() api.EvalScope { 10 | return api.EvalScope(a) 11 | } 12 | 13 | type Location api.Location 14 | 15 | func (a Location) conv() api.Location { 16 | return api.Location(a) 17 | } 18 | 19 | type Breakpoint api.Breakpoint 20 | 21 | func (a Breakpoint) conv() api.Breakpoint { 22 | return api.Breakpoint(a) 23 | } 24 | 25 | type DebuggerState api.DebuggerState 26 | 27 | func (a DebuggerState) conv() api.DebuggerState { 28 | return api.DebuggerState(a) 29 | } 30 | 31 | type Goroutine api.Goroutine 32 | 33 | func (a Goroutine) conv() api.Goroutine { 34 | return api.Goroutine(a) 35 | } 36 | 37 | type LoadConfig api.LoadConfig 38 | 39 | func (a LoadConfig) conv() api.LoadConfig { 40 | return api.LoadConfig(a) 41 | } 42 | 43 | type Stackframe api.Stackframe 44 | 45 | func (a Stackframe) conv() api.Stackframe { 46 | return api.Stackframe(a) 47 | } 48 | 49 | type Thread api.Thread 50 | 51 | func (a Thread) conv() api.Thread { 52 | return api.Thread(a) 53 | } 54 | 55 | type Variable api.Variable 56 | 57 | func (a Variable) conv() api.Variable { 58 | return api.Variable(a) 59 | } 60 | -------------------------------------------------------------------------------- /debug: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allada/gdd/076f285bd9936f6eb2e823301d7590b2077ef567/debug -------------------------------------------------------------------------------- /demo/debug: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/allada/gdd/076f285bd9936f6eb2e823301d7590b2077ef567/demo/debug -------------------------------------------------------------------------------- /demo/helloworld.go: -------------------------------------------------------------------------------- 1 | package main 2 | import "fmt" 3 | func main() { 4 | helloWorldVar := "hello world" 5 | fmt.Println(helloWorldVar) 6 | helloWorldVar = "goodnight world" 7 | fmt.Println(helloWorldVar) 8 | waitChan := make(chan bool) 9 | go PrintStuffOut(waitChan) 10 | fmt.Println("hello world") 11 | <-waitChan 12 | } 13 | 14 | func PrintStuffOut(waitChan chan<- bool) { 15 | data := "hello world" 16 | fmt.Println(data) 17 | waitChan <-true 18 | return 19 | fmt.Println("hello world") 20 | } -------------------------------------------------------------------------------- /gdd.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "os" 5 | "net" 6 | "net/http" 7 | "time" 8 | "github.com/allada/gdd/protocol/shared" 9 | "github.com/allada/gdd/proxies/debugger" 10 | "github.com/allada/gdd/proxies/page" 11 | "github.com/allada/gdd/proxies/runtime" 12 | "github.com/allada/gdd/dbgClient" 13 | "github.com/allada/gdd/config" 14 | "fmt" 15 | ) 16 | 17 | type handler struct { 18 | Config config.Config 19 | } 20 | 21 | func (h handler) handleDebugRequest(conn *shared.Connection) { 22 | client := &dbgClient.Client{ 23 | File: h.Config.DebugSession.File, 24 | Args: h.Config.DebugSession.Args, 25 | } 26 | go client.Start(h.Config) 27 | 28 | go func() { 29 | for { 30 | // This just ensures we syncronize our sockets if either dies, they both die. 31 | if client.Killed() || conn.Closed() { 32 | client.Kill() 33 | conn.Close() 34 | return 35 | } 36 | time.Sleep(300 * time.Millisecond) 37 | } 38 | }() 39 | 40 | runtimeProxy := runtime.NewProxy(conn, client) 41 | go runtimeProxy.Start() 42 | go debugger.NewProxy(conn, client).Start(runtimeProxy) 43 | go page.NewProxy(conn, client).Start() 44 | } 45 | 46 | func printHelp() { 47 | 48 | } 49 | 50 | func configureFromArgs(args []string) { 51 | 52 | } 53 | 54 | func main() { 55 | config := config.NewFromArgs(os.Args[1:]) 56 | if config == nil { 57 | return 58 | } 59 | h := handler{ 60 | Config: *config, 61 | } 62 | 63 | http.Handle("/", shared.Handler(h.handleDebugRequest)) 64 | listener, err := net.Listen("tcp", ":" + (*config).Port); 65 | if err != nil { 66 | panic("Listen: " + err.Error()) 67 | } 68 | fmt.Println("https://chrome-devtools-frontend.appspot.com/serve_file/@3f9be266524354849e17f6a123ee20dd6e7d53e0/inspector.html?experiments=true&ws=localhost:9922/go-devtools-debug") 69 | err = http.Serve(listener, nil) 70 | if err != nil { 71 | panic("Serve: " + err.Error()) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /protocol/accessibility/agent.go: -------------------------------------------------------------------------------- 1 | package accessibility 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type GetPartialAXTreeCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(GetPartialAXTreeCommand) 13 | } 14 | 15 | func (a *GetPartialAXTreeCommandFn) Load() func(GetPartialAXTreeCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *GetPartialAXTreeCommandFn) Store(fn func(GetPartialAXTreeCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type AccessibilityAgent struct { 28 | conn *shared.Connection 29 | commandHandlers struct { 30 | GetPartialAXTree GetPartialAXTreeCommandFn 31 | } 32 | } 33 | func NewAgent(conn *shared.Connection) *AccessibilityAgent { 34 | agent := &AccessibilityAgent{ 35 | conn: conn, 36 | } 37 | conn.RegisterAgent(agent) 38 | return agent 39 | } 40 | 41 | func (agent *AccessibilityAgent) Name() string { 42 | return "Accessibility" 43 | } 44 | 45 | func (agent *AccessibilityAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 46 | defer shared.TryRecoverFromPanic(agent.conn) 47 | switch (funcName) { 48 | case "getPartialAXTree": 49 | var out GetPartialAXTreeCommand 50 | agent.conn.SetupCommand(id, targetId, data, &out) 51 | fn := agent.commandHandlers.GetPartialAXTree.Load() 52 | if fn == nil { 53 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 54 | break 55 | } 56 | fn(out) 57 | default: 58 | fmt.Printf("Command %s unknown\n", funcName) 59 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 60 | } 61 | } 62 | 63 | // Dispatchable Events 64 | 65 | // Commands Sent From Frontend 66 | func (agent *AccessibilityAgent) SetGetPartialAXTreeHandler(handler func(GetPartialAXTreeCommand)) { 67 | agent.commandHandlers.GetPartialAXTree.Store(handler) 68 | } 69 | func init() { 70 | 71 | } 72 | -------------------------------------------------------------------------------- /protocol/accessibility/commands.go: -------------------------------------------------------------------------------- 1 | package accessibility 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "github.com/allada/gdd/protocol/dom" 7 | ) 8 | 9 | type GetPartialAXTreeCommand struct { 10 | DestinationTargetID string 11 | responseId int64 12 | conn *shared.Connection 13 | NodeId dom.NodeId `json:"nodeId"`// ID of node to get the partial accessibility tree for. 14 | FetchRelatives *bool `json:"fetchRelatives,omitempty"`// Whether to fetch this nodes ancestors, siblings and children. Defaults to true. 15 | } 16 | type GetPartialAXTreeReturn struct { 17 | Nodes []AXNode `json:"nodes"`// The Accessibility.AXNode for this DOM node, if it exists, plus its ancestors, siblings and children, if requested. 18 | } 19 | 20 | func (c *GetPartialAXTreeCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 21 | c.DestinationTargetID = targetId 22 | c.responseId = responseId 23 | c.conn = conn 24 | } 25 | 26 | func (c *GetPartialAXTreeCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 27 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 28 | } 29 | 30 | func (c *GetPartialAXTreeCommand) Respond(r *GetPartialAXTreeReturn) { 31 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 32 | } 33 | -------------------------------------------------------------------------------- /protocol/accessibility/events.go: -------------------------------------------------------------------------------- 1 | package accessibility 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/animation/events.go: -------------------------------------------------------------------------------- 1 | package animation 2 | 3 | 4 | type AnimationCreatedEvent struct { 5 | Id string `json:"id"`// Id of the animation that was created. 6 | } 7 | type AnimationStartedEvent struct { 8 | Animation Animation `json:"animation"`// Animation that was started. 9 | } 10 | type AnimationCanceledEvent struct { 11 | Id string `json:"id"`// Id of the animation that was cancelled. 12 | } -------------------------------------------------------------------------------- /protocol/animation/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package animation 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/dom" 6 | ) 7 | type AnimationTypeEnum string 8 | const ( 9 | AnimationTypeCSSTransition AnimationTypeEnum = "CSSTransition" 10 | AnimationTypeCSSAnimation AnimationTypeEnum = "CSSAnimation" 11 | AnimationTypeWebAnimation AnimationTypeEnum = "WebAnimation" 12 | ) 13 | type Animation struct { 14 | Id string `json:"id"`// Animation's id. 15 | Name string `json:"name"`// Animation's name. 16 | PausedState bool `json:"pausedState"`// [Experimental] Animation's internal paused state. 17 | PlayState string `json:"playState"`// Animation's play state. 18 | PlaybackRate float64 `json:"playbackRate"`// Animation's playback rate. 19 | StartTime float64 `json:"startTime"`// Animation's start time. 20 | CurrentTime float64 `json:"currentTime"`// Animation's current time. 21 | Source AnimationEffect `json:"source"`// Animation's source animation node. 22 | Type AnimationTypeEnum `json:"type"`// Animation type of Animation. 23 | CssId *string `json:"cssId,omitempty"`// A unique ID for Animation representing the sources that triggered this CSS animation/transition. 24 | } 25 | 26 | type AnimationEffect struct { 27 | Delay float64 `json:"delay"`// AnimationEffect's delay. 28 | EndDelay float64 `json:"endDelay"`// AnimationEffect's end delay. 29 | IterationStart float64 `json:"iterationStart"`// AnimationEffect's iteration start. 30 | Iterations float64 `json:"iterations"`// AnimationEffect's iterations. 31 | Duration float64 `json:"duration"`// AnimationEffect's iteration duration. 32 | Direction string `json:"direction"`// AnimationEffect's playback direction. 33 | Fill string `json:"fill"`// AnimationEffect's fill mode. 34 | BackendNodeId dom.BackendNodeId `json:"backendNodeId"`// AnimationEffect's target node. 35 | KeyframesRule *KeyframesRule `json:"keyframesRule,omitempty"`// AnimationEffect's keyframes. 36 | Easing string `json:"easing"`// AnimationEffect's timing function. 37 | } 38 | 39 | type KeyframesRule struct { 40 | Name *string `json:"name,omitempty"`// CSS keyframed animation's name. 41 | Keyframes []KeyframeStyle `json:"keyframes"`// List of animation keyframes. 42 | } 43 | 44 | type KeyframeStyle struct { 45 | Offset string `json:"offset"`// Keyframe's time offset. 46 | Easing string `json:"easing"`// AnimationEffect's timing function. 47 | } 48 | -------------------------------------------------------------------------------- /protocol/applicationcache/agent.go: -------------------------------------------------------------------------------- 1 | package applicationcache 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type GetFramesWithManifestsCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(GetFramesWithManifestsCommand) 13 | } 14 | 15 | func (a *GetFramesWithManifestsCommandFn) Load() func(GetFramesWithManifestsCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *GetFramesWithManifestsCommandFn) Store(fn func(GetFramesWithManifestsCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type EnableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(EnableCommand) 30 | } 31 | 32 | func (a *EnableCommandFn) Load() func(EnableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type GetManifestForFrameCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(GetManifestForFrameCommand) 47 | } 48 | 49 | func (a *GetManifestForFrameCommandFn) Load() func(GetManifestForFrameCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *GetManifestForFrameCommandFn) Store(fn func(GetManifestForFrameCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type GetApplicationCacheForFrameCommandFn struct { 62 | mux sync.RWMutex 63 | fn func(GetApplicationCacheForFrameCommand) 64 | } 65 | 66 | func (a *GetApplicationCacheForFrameCommandFn) Load() func(GetApplicationCacheForFrameCommand) { 67 | a.mux.RLock() 68 | defer a.mux.RUnlock() 69 | return a.fn 70 | } 71 | 72 | func (a *GetApplicationCacheForFrameCommandFn) Store(fn func(GetApplicationCacheForFrameCommand)) { 73 | a.mux.Lock() 74 | defer a.mux.Unlock() 75 | a.fn = fn 76 | } 77 | 78 | type ApplicationCacheAgent struct { 79 | conn *shared.Connection 80 | commandHandlers struct { 81 | GetFramesWithManifests GetFramesWithManifestsCommandFn 82 | Enable EnableCommandFn 83 | GetManifestForFrame GetManifestForFrameCommandFn 84 | GetApplicationCacheForFrame GetApplicationCacheForFrameCommandFn 85 | } 86 | } 87 | func NewAgent(conn *shared.Connection) *ApplicationCacheAgent { 88 | agent := &ApplicationCacheAgent{ 89 | conn: conn, 90 | } 91 | conn.RegisterAgent(agent) 92 | return agent 93 | } 94 | 95 | func (agent *ApplicationCacheAgent) Name() string { 96 | return "ApplicationCache" 97 | } 98 | 99 | func (agent *ApplicationCacheAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 100 | defer shared.TryRecoverFromPanic(agent.conn) 101 | switch (funcName) { 102 | case "getFramesWithManifests": 103 | var out GetFramesWithManifestsCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.GetFramesWithManifests.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | case "enable": 112 | var out EnableCommand 113 | agent.conn.SetupCommand(id, targetId, data, &out) 114 | fn := agent.commandHandlers.Enable.Load() 115 | if fn == nil { 116 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 117 | break 118 | } 119 | fn(out) 120 | case "getManifestForFrame": 121 | var out GetManifestForFrameCommand 122 | agent.conn.SetupCommand(id, targetId, data, &out) 123 | fn := agent.commandHandlers.GetManifestForFrame.Load() 124 | if fn == nil { 125 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 126 | break 127 | } 128 | fn(out) 129 | case "getApplicationCacheForFrame": 130 | var out GetApplicationCacheForFrameCommand 131 | agent.conn.SetupCommand(id, targetId, data, &out) 132 | fn := agent.commandHandlers.GetApplicationCacheForFrame.Load() 133 | if fn == nil { 134 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 135 | break 136 | } 137 | fn(out) 138 | default: 139 | fmt.Printf("Command %s unknown\n", funcName) 140 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 141 | } 142 | } 143 | 144 | // Dispatchable Events 145 | func (agent *ApplicationCacheAgent) FireApplicationCacheStatusUpdated(event ApplicationCacheStatusUpdatedEvent) { 146 | agent.conn.Send(shared.Notification{ 147 | Method: "ApplicationCache.applicationCacheStatusUpdated", 148 | Params: event, 149 | }) 150 | } 151 | func (agent *ApplicationCacheAgent) FireApplicationCacheStatusUpdatedOnTarget(targetId string,event ApplicationCacheStatusUpdatedEvent) { 152 | agent.conn.SendToTarget(targetId, shared.Notification{ 153 | Method: "ApplicationCache.applicationCacheStatusUpdated", 154 | Params: event, 155 | }) 156 | } 157 | func (agent *ApplicationCacheAgent) FireNetworkStateUpdated(event NetworkStateUpdatedEvent) { 158 | agent.conn.Send(shared.Notification{ 159 | Method: "ApplicationCache.networkStateUpdated", 160 | Params: event, 161 | }) 162 | } 163 | func (agent *ApplicationCacheAgent) FireNetworkStateUpdatedOnTarget(targetId string,event NetworkStateUpdatedEvent) { 164 | agent.conn.SendToTarget(targetId, shared.Notification{ 165 | Method: "ApplicationCache.networkStateUpdated", 166 | Params: event, 167 | }) 168 | } 169 | 170 | // Commands Sent From Frontend 171 | func (agent *ApplicationCacheAgent) SetGetFramesWithManifestsHandler(handler func(GetFramesWithManifestsCommand)) { 172 | agent.commandHandlers.GetFramesWithManifests.Store(handler) 173 | } 174 | func (agent *ApplicationCacheAgent) SetEnableHandler(handler func(EnableCommand)) { 175 | agent.commandHandlers.Enable.Store(handler) 176 | } 177 | func (agent *ApplicationCacheAgent) SetGetManifestForFrameHandler(handler func(GetManifestForFrameCommand)) { 178 | agent.commandHandlers.GetManifestForFrame.Store(handler) 179 | } 180 | func (agent *ApplicationCacheAgent) SetGetApplicationCacheForFrameHandler(handler func(GetApplicationCacheForFrameCommand)) { 181 | agent.commandHandlers.GetApplicationCacheForFrame.Store(handler) 182 | } 183 | func init() { 184 | 185 | } 186 | -------------------------------------------------------------------------------- /protocol/applicationcache/commands.go: -------------------------------------------------------------------------------- 1 | package applicationcache 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "github.com/allada/gdd/protocol/page" 7 | ) 8 | 9 | type GetFramesWithManifestsCommand struct { 10 | DestinationTargetID string 11 | responseId int64 12 | conn *shared.Connection 13 | } 14 | type GetFramesWithManifestsReturn struct { 15 | FrameIds []FrameWithManifest `json:"frameIds"`// Array of frame identifiers with manifest urls for each frame containing a document associated with some application cache. 16 | } 17 | 18 | func (c *GetFramesWithManifestsCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 19 | c.DestinationTargetID = targetId 20 | c.responseId = responseId 21 | c.conn = conn 22 | } 23 | 24 | func (c *GetFramesWithManifestsCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 25 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 26 | } 27 | 28 | func (c *GetFramesWithManifestsCommand) Respond(r *GetFramesWithManifestsReturn) { 29 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 30 | } 31 | 32 | type EnableCommand struct { 33 | DestinationTargetID string 34 | responseId int64 35 | conn *shared.Connection 36 | } 37 | type EnableReturn struct { 38 | } 39 | 40 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 41 | c.DestinationTargetID = targetId 42 | c.responseId = responseId 43 | c.conn = conn 44 | } 45 | 46 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 47 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 48 | } 49 | 50 | func (c *EnableCommand) Respond() { 51 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 52 | } 53 | 54 | type GetManifestForFrameCommand struct { 55 | DestinationTargetID string 56 | responseId int64 57 | conn *shared.Connection 58 | FrameId page.FrameId `json:"frameId"`// Identifier of the frame containing document whose manifest is retrieved. 59 | } 60 | type GetManifestForFrameReturn struct { 61 | ManifestURL string `json:"manifestURL"`// Manifest URL for document in the given frame. 62 | } 63 | 64 | func (c *GetManifestForFrameCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 65 | c.DestinationTargetID = targetId 66 | c.responseId = responseId 67 | c.conn = conn 68 | } 69 | 70 | func (c *GetManifestForFrameCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 71 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 72 | } 73 | 74 | func (c *GetManifestForFrameCommand) Respond(r *GetManifestForFrameReturn) { 75 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 76 | } 77 | 78 | type GetApplicationCacheForFrameCommand struct { 79 | DestinationTargetID string 80 | responseId int64 81 | conn *shared.Connection 82 | FrameId page.FrameId `json:"frameId"`// Identifier of the frame containing document whose application cache is retrieved. 83 | } 84 | type GetApplicationCacheForFrameReturn struct { 85 | ApplicationCache ApplicationCache `json:"applicationCache"`// Relevant application cache data for the document in given frame. 86 | } 87 | 88 | func (c *GetApplicationCacheForFrameCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 89 | c.DestinationTargetID = targetId 90 | c.responseId = responseId 91 | c.conn = conn 92 | } 93 | 94 | func (c *GetApplicationCacheForFrameCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 95 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 96 | } 97 | 98 | func (c *GetApplicationCacheForFrameCommand) Respond(r *GetApplicationCacheForFrameReturn) { 99 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 100 | } 101 | -------------------------------------------------------------------------------- /protocol/applicationcache/events.go: -------------------------------------------------------------------------------- 1 | package applicationcache 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/page" 6 | ) 7 | 8 | type ApplicationCacheStatusUpdatedEvent struct { 9 | FrameId page.FrameId `json:"frameId"`// Identifier of the frame containing document whose application cache updated status. 10 | ManifestURL string `json:"manifestURL"`// Manifest URL. 11 | Status int64 `json:"status"`// Updated application cache status. 12 | } 13 | type NetworkStateUpdatedEvent struct { 14 | IsNowOnline bool `json:"isNowOnline"` 15 | } -------------------------------------------------------------------------------- /protocol/applicationcache/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package applicationcache 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/page" 6 | ) 7 | type ApplicationCacheResource struct { 8 | Url string `json:"url"`// Resource url. 9 | Size int64 `json:"size"`// Resource size. 10 | Type string `json:"type"`// Resource type. 11 | } 12 | 13 | type ApplicationCache struct { 14 | ManifestURL string `json:"manifestURL"`// Manifest URL. 15 | Size float64 `json:"size"`// Application cache size. 16 | CreationTime float64 `json:"creationTime"`// Application cache creation time. 17 | UpdateTime float64 `json:"updateTime"`// Application cache update time. 18 | Resources []ApplicationCacheResource `json:"resources"`// Application cache resources. 19 | } 20 | 21 | type FrameWithManifest struct { 22 | FrameId page.FrameId `json:"frameId"`// Frame identifier. 23 | ManifestURL string `json:"manifestURL"`// Manifest URL. 24 | Status int64 `json:"status"`// Application cache status. 25 | } 26 | -------------------------------------------------------------------------------- /protocol/cachestorage/agent.go: -------------------------------------------------------------------------------- 1 | package cachestorage 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type RequestCacheNamesCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(RequestCacheNamesCommand) 13 | } 14 | 15 | func (a *RequestCacheNamesCommandFn) Load() func(RequestCacheNamesCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *RequestCacheNamesCommandFn) Store(fn func(RequestCacheNamesCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type RequestEntriesCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(RequestEntriesCommand) 30 | } 31 | 32 | func (a *RequestEntriesCommandFn) Load() func(RequestEntriesCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *RequestEntriesCommandFn) Store(fn func(RequestEntriesCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type DeleteCacheCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(DeleteCacheCommand) 47 | } 48 | 49 | func (a *DeleteCacheCommandFn) Load() func(DeleteCacheCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *DeleteCacheCommandFn) Store(fn func(DeleteCacheCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type DeleteEntryCommandFn struct { 62 | mux sync.RWMutex 63 | fn func(DeleteEntryCommand) 64 | } 65 | 66 | func (a *DeleteEntryCommandFn) Load() func(DeleteEntryCommand) { 67 | a.mux.RLock() 68 | defer a.mux.RUnlock() 69 | return a.fn 70 | } 71 | 72 | func (a *DeleteEntryCommandFn) Store(fn func(DeleteEntryCommand)) { 73 | a.mux.Lock() 74 | defer a.mux.Unlock() 75 | a.fn = fn 76 | } 77 | 78 | type CacheStorageAgent struct { 79 | conn *shared.Connection 80 | commandHandlers struct { 81 | RequestCacheNames RequestCacheNamesCommandFn 82 | RequestEntries RequestEntriesCommandFn 83 | DeleteCache DeleteCacheCommandFn 84 | DeleteEntry DeleteEntryCommandFn 85 | } 86 | } 87 | func NewAgent(conn *shared.Connection) *CacheStorageAgent { 88 | agent := &CacheStorageAgent{ 89 | conn: conn, 90 | } 91 | conn.RegisterAgent(agent) 92 | return agent 93 | } 94 | 95 | func (agent *CacheStorageAgent) Name() string { 96 | return "CacheStorage" 97 | } 98 | 99 | func (agent *CacheStorageAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 100 | defer shared.TryRecoverFromPanic(agent.conn) 101 | switch (funcName) { 102 | case "requestCacheNames": 103 | var out RequestCacheNamesCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.RequestCacheNames.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | case "requestEntries": 112 | var out RequestEntriesCommand 113 | agent.conn.SetupCommand(id, targetId, data, &out) 114 | fn := agent.commandHandlers.RequestEntries.Load() 115 | if fn == nil { 116 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 117 | break 118 | } 119 | fn(out) 120 | case "deleteCache": 121 | var out DeleteCacheCommand 122 | agent.conn.SetupCommand(id, targetId, data, &out) 123 | fn := agent.commandHandlers.DeleteCache.Load() 124 | if fn == nil { 125 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 126 | break 127 | } 128 | fn(out) 129 | case "deleteEntry": 130 | var out DeleteEntryCommand 131 | agent.conn.SetupCommand(id, targetId, data, &out) 132 | fn := agent.commandHandlers.DeleteEntry.Load() 133 | if fn == nil { 134 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 135 | break 136 | } 137 | fn(out) 138 | default: 139 | fmt.Printf("Command %s unknown\n", funcName) 140 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 141 | } 142 | } 143 | 144 | // Dispatchable Events 145 | 146 | // Commands Sent From Frontend 147 | func (agent *CacheStorageAgent) SetRequestCacheNamesHandler(handler func(RequestCacheNamesCommand)) { 148 | agent.commandHandlers.RequestCacheNames.Store(handler) 149 | } 150 | func (agent *CacheStorageAgent) SetRequestEntriesHandler(handler func(RequestEntriesCommand)) { 151 | agent.commandHandlers.RequestEntries.Store(handler) 152 | } 153 | func (agent *CacheStorageAgent) SetDeleteCacheHandler(handler func(DeleteCacheCommand)) { 154 | agent.commandHandlers.DeleteCache.Store(handler) 155 | } 156 | func (agent *CacheStorageAgent) SetDeleteEntryHandler(handler func(DeleteEntryCommand)) { 157 | agent.commandHandlers.DeleteEntry.Store(handler) 158 | } 159 | func init() { 160 | 161 | } 162 | -------------------------------------------------------------------------------- /protocol/cachestorage/commands.go: -------------------------------------------------------------------------------- 1 | package cachestorage 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type RequestCacheNamesCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 13 | } 14 | type RequestCacheNamesReturn struct { 15 | Caches []Cache `json:"caches"`// Caches for the security origin. 16 | } 17 | 18 | func (c *RequestCacheNamesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 19 | c.DestinationTargetID = targetId 20 | c.responseId = responseId 21 | c.conn = conn 22 | } 23 | 24 | func (c *RequestCacheNamesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 25 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 26 | } 27 | 28 | func (c *RequestCacheNamesCommand) Respond(r *RequestCacheNamesReturn) { 29 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 30 | } 31 | 32 | type RequestEntriesCommand struct { 33 | DestinationTargetID string 34 | responseId int64 35 | conn *shared.Connection 36 | CacheId CacheId `json:"cacheId"`// ID of cache to get entries from. 37 | SkipCount int64 `json:"skipCount"`// Number of records to skip. 38 | PageSize int64 `json:"pageSize"`// Number of records to fetch. 39 | } 40 | type RequestEntriesReturn struct { 41 | CacheDataEntries []DataEntry `json:"cacheDataEntries"`// Array of object store data entries. 42 | HasMore bool `json:"hasMore"`// If true, there are more entries to fetch in the given range. 43 | } 44 | 45 | func (c *RequestEntriesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 46 | c.DestinationTargetID = targetId 47 | c.responseId = responseId 48 | c.conn = conn 49 | } 50 | 51 | func (c *RequestEntriesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 52 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 53 | } 54 | 55 | func (c *RequestEntriesCommand) Respond(r *RequestEntriesReturn) { 56 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 57 | } 58 | 59 | type DeleteCacheCommand struct { 60 | DestinationTargetID string 61 | responseId int64 62 | conn *shared.Connection 63 | CacheId CacheId `json:"cacheId"`// Id of cache for deletion. 64 | } 65 | type DeleteCacheReturn struct { 66 | } 67 | 68 | func (c *DeleteCacheCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 69 | c.DestinationTargetID = targetId 70 | c.responseId = responseId 71 | c.conn = conn 72 | } 73 | 74 | func (c *DeleteCacheCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 75 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 76 | } 77 | 78 | func (c *DeleteCacheCommand) Respond() { 79 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 80 | } 81 | 82 | type DeleteEntryCommand struct { 83 | DestinationTargetID string 84 | responseId int64 85 | conn *shared.Connection 86 | CacheId CacheId `json:"cacheId"`// Id of cache where the entry will be deleted. 87 | Request string `json:"request"`// URL spec of the request. 88 | } 89 | type DeleteEntryReturn struct { 90 | } 91 | 92 | func (c *DeleteEntryCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 93 | c.DestinationTargetID = targetId 94 | c.responseId = responseId 95 | c.conn = conn 96 | } 97 | 98 | func (c *DeleteEntryCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 99 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 100 | } 101 | 102 | func (c *DeleteEntryCommand) Respond() { 103 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 104 | } 105 | -------------------------------------------------------------------------------- /protocol/cachestorage/events.go: -------------------------------------------------------------------------------- 1 | package cachestorage 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/cachestorage/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package cachestorage 2 | 3 | type CacheId string 4 | 5 | type DataEntry struct { 6 | Request string `json:"request"`// Request url spec. 7 | Response string `json:"response"`// Response stataus text. 8 | } 9 | 10 | type Cache struct { 11 | CacheId CacheId `json:"cacheId"`// An opaque unique id of the cache. 12 | SecurityOrigin string `json:"securityOrigin"`// Security origin of the cache. 13 | CacheName string `json:"cacheName"`// The name of the cache. 14 | } 15 | -------------------------------------------------------------------------------- /protocol/console/agent.go: -------------------------------------------------------------------------------- 1 | package console 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type EnableCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(EnableCommand) 13 | } 14 | 15 | func (a *EnableCommandFn) Load() func(EnableCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type DisableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(DisableCommand) 30 | } 31 | 32 | func (a *DisableCommandFn) Load() func(DisableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *DisableCommandFn) Store(fn func(DisableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type ClearMessagesCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(ClearMessagesCommand) 47 | } 48 | 49 | func (a *ClearMessagesCommandFn) Load() func(ClearMessagesCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *ClearMessagesCommandFn) Store(fn func(ClearMessagesCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type ConsoleAgent struct { 62 | conn *shared.Connection 63 | commandHandlers struct { 64 | Enable EnableCommandFn 65 | Disable DisableCommandFn 66 | ClearMessages ClearMessagesCommandFn 67 | } 68 | } 69 | func NewAgent(conn *shared.Connection) *ConsoleAgent { 70 | agent := &ConsoleAgent{ 71 | conn: conn, 72 | } 73 | conn.RegisterAgent(agent) 74 | return agent 75 | } 76 | 77 | func (agent *ConsoleAgent) Name() string { 78 | return "Console" 79 | } 80 | 81 | func (agent *ConsoleAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 82 | defer shared.TryRecoverFromPanic(agent.conn) 83 | switch (funcName) { 84 | case "enable": 85 | var out EnableCommand 86 | agent.conn.SetupCommand(id, targetId, data, &out) 87 | fn := agent.commandHandlers.Enable.Load() 88 | if fn == nil { 89 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 90 | break 91 | } 92 | fn(out) 93 | case "disable": 94 | var out DisableCommand 95 | agent.conn.SetupCommand(id, targetId, data, &out) 96 | fn := agent.commandHandlers.Disable.Load() 97 | if fn == nil { 98 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 99 | break 100 | } 101 | fn(out) 102 | case "clearMessages": 103 | var out ClearMessagesCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.ClearMessages.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | default: 112 | fmt.Printf("Command %s unknown\n", funcName) 113 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 114 | } 115 | } 116 | 117 | // Dispatchable Events 118 | func (agent *ConsoleAgent) FireMessageAdded(event MessageAddedEvent) { 119 | agent.conn.Send(shared.Notification{ 120 | Method: "Console.messageAdded", 121 | Params: event, 122 | }) 123 | } 124 | func (agent *ConsoleAgent) FireMessageAddedOnTarget(targetId string,event MessageAddedEvent) { 125 | agent.conn.SendToTarget(targetId, shared.Notification{ 126 | Method: "Console.messageAdded", 127 | Params: event, 128 | }) 129 | } 130 | 131 | // Commands Sent From Frontend 132 | func (agent *ConsoleAgent) SetEnableHandler(handler func(EnableCommand)) { 133 | agent.commandHandlers.Enable.Store(handler) 134 | } 135 | func (agent *ConsoleAgent) SetDisableHandler(handler func(DisableCommand)) { 136 | agent.commandHandlers.Disable.Store(handler) 137 | } 138 | func (agent *ConsoleAgent) SetClearMessagesHandler(handler func(ClearMessagesCommand)) { 139 | agent.commandHandlers.ClearMessages.Store(handler) 140 | } 141 | func init() { 142 | 143 | } 144 | -------------------------------------------------------------------------------- /protocol/console/commands.go: -------------------------------------------------------------------------------- 1 | package console 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type ClearMessagesCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | } 57 | type ClearMessagesReturn struct { 58 | } 59 | 60 | func (c *ClearMessagesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 61 | c.DestinationTargetID = targetId 62 | c.responseId = responseId 63 | c.conn = conn 64 | } 65 | 66 | func (c *ClearMessagesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 67 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 68 | } 69 | 70 | func (c *ClearMessagesCommand) Respond() { 71 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 72 | } 73 | -------------------------------------------------------------------------------- /protocol/console/events.go: -------------------------------------------------------------------------------- 1 | package console 2 | 3 | 4 | type MessageAddedEvent struct { 5 | Message ConsoleMessage `json:"message"`// Console message that has been added. 6 | } -------------------------------------------------------------------------------- /protocol/console/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package console 2 | 3 | type ConsoleMessageSourceEnum string 4 | const ( 5 | ConsoleMessageSourceXml ConsoleMessageSourceEnum = "xml" 6 | ConsoleMessageSourceJavascript ConsoleMessageSourceEnum = "javascript" 7 | ConsoleMessageSourceNetwork ConsoleMessageSourceEnum = "network" 8 | ConsoleMessageSourceConsoleDashapi ConsoleMessageSourceEnum = "console-api" 9 | ConsoleMessageSourceStorage ConsoleMessageSourceEnum = "storage" 10 | ConsoleMessageSourceAppcache ConsoleMessageSourceEnum = "appcache" 11 | ConsoleMessageSourceRendering ConsoleMessageSourceEnum = "rendering" 12 | ConsoleMessageSourceSecurity ConsoleMessageSourceEnum = "security" 13 | ConsoleMessageSourceOther ConsoleMessageSourceEnum = "other" 14 | ConsoleMessageSourceDeprecation ConsoleMessageSourceEnum = "deprecation" 15 | ConsoleMessageSourceWorker ConsoleMessageSourceEnum = "worker" 16 | ) 17 | 18 | type ConsoleMessageLevelEnum string 19 | const ( 20 | ConsoleMessageLevelLog ConsoleMessageLevelEnum = "log" 21 | ConsoleMessageLevelWarning ConsoleMessageLevelEnum = "warning" 22 | ConsoleMessageLevelError ConsoleMessageLevelEnum = "error" 23 | ConsoleMessageLevelDebug ConsoleMessageLevelEnum = "debug" 24 | ConsoleMessageLevelInfo ConsoleMessageLevelEnum = "info" 25 | ) 26 | type ConsoleMessage struct { 27 | Source ConsoleMessageSourceEnum `json:"source"`// Message source. 28 | Level ConsoleMessageLevelEnum `json:"level"`// Message severity. 29 | Text string `json:"text"`// Message text. 30 | Url *string `json:"url,omitempty"`// URL of the message origin. 31 | Line *int64 `json:"line,omitempty"`// Line number in the resource that generated this message (1-based). 32 | Column *int64 `json:"column,omitempty"`// Column number in the resource that generated this message (1-based). 33 | } 34 | -------------------------------------------------------------------------------- /protocol/css/events.go: -------------------------------------------------------------------------------- 1 | package css 2 | 3 | 4 | type MediaQueryResultChangedEvent struct { 5 | } 6 | type FontsUpdatedEvent struct { 7 | } 8 | type StyleSheetChangedEvent struct { 9 | StyleSheetId StyleSheetId `json:"styleSheetId"` 10 | } 11 | type StyleSheetAddedEvent struct { 12 | Header CSSStyleSheetHeader `json:"header"`// Added stylesheet metainfo. 13 | } 14 | type StyleSheetRemovedEvent struct { 15 | StyleSheetId StyleSheetId `json:"styleSheetId"`// Identifier of the removed stylesheet. 16 | } -------------------------------------------------------------------------------- /protocol/database/agent.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type EnableCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(EnableCommand) 13 | } 14 | 15 | func (a *EnableCommandFn) Load() func(EnableCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type DisableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(DisableCommand) 30 | } 31 | 32 | func (a *DisableCommandFn) Load() func(DisableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *DisableCommandFn) Store(fn func(DisableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type GetDatabaseTableNamesCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(GetDatabaseTableNamesCommand) 47 | } 48 | 49 | func (a *GetDatabaseTableNamesCommandFn) Load() func(GetDatabaseTableNamesCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *GetDatabaseTableNamesCommandFn) Store(fn func(GetDatabaseTableNamesCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type ExecuteSQLCommandFn struct { 62 | mux sync.RWMutex 63 | fn func(ExecuteSQLCommand) 64 | } 65 | 66 | func (a *ExecuteSQLCommandFn) Load() func(ExecuteSQLCommand) { 67 | a.mux.RLock() 68 | defer a.mux.RUnlock() 69 | return a.fn 70 | } 71 | 72 | func (a *ExecuteSQLCommandFn) Store(fn func(ExecuteSQLCommand)) { 73 | a.mux.Lock() 74 | defer a.mux.Unlock() 75 | a.fn = fn 76 | } 77 | 78 | type DatabaseAgent struct { 79 | conn *shared.Connection 80 | commandHandlers struct { 81 | Enable EnableCommandFn 82 | Disable DisableCommandFn 83 | GetDatabaseTableNames GetDatabaseTableNamesCommandFn 84 | ExecuteSQL ExecuteSQLCommandFn 85 | } 86 | } 87 | func NewAgent(conn *shared.Connection) *DatabaseAgent { 88 | agent := &DatabaseAgent{ 89 | conn: conn, 90 | } 91 | conn.RegisterAgent(agent) 92 | return agent 93 | } 94 | 95 | func (agent *DatabaseAgent) Name() string { 96 | return "Database" 97 | } 98 | 99 | func (agent *DatabaseAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 100 | defer shared.TryRecoverFromPanic(agent.conn) 101 | switch (funcName) { 102 | case "enable": 103 | var out EnableCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.Enable.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | case "disable": 112 | var out DisableCommand 113 | agent.conn.SetupCommand(id, targetId, data, &out) 114 | fn := agent.commandHandlers.Disable.Load() 115 | if fn == nil { 116 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 117 | break 118 | } 119 | fn(out) 120 | case "getDatabaseTableNames": 121 | var out GetDatabaseTableNamesCommand 122 | agent.conn.SetupCommand(id, targetId, data, &out) 123 | fn := agent.commandHandlers.GetDatabaseTableNames.Load() 124 | if fn == nil { 125 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 126 | break 127 | } 128 | fn(out) 129 | case "executeSQL": 130 | var out ExecuteSQLCommand 131 | agent.conn.SetupCommand(id, targetId, data, &out) 132 | fn := agent.commandHandlers.ExecuteSQL.Load() 133 | if fn == nil { 134 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 135 | break 136 | } 137 | fn(out) 138 | default: 139 | fmt.Printf("Command %s unknown\n", funcName) 140 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 141 | } 142 | } 143 | 144 | // Dispatchable Events 145 | func (agent *DatabaseAgent) FireAddDatabase(event AddDatabaseEvent) { 146 | agent.conn.Send(shared.Notification{ 147 | Method: "Database.addDatabase", 148 | Params: event, 149 | }) 150 | } 151 | func (agent *DatabaseAgent) FireAddDatabaseOnTarget(targetId string,event AddDatabaseEvent) { 152 | agent.conn.SendToTarget(targetId, shared.Notification{ 153 | Method: "Database.addDatabase", 154 | Params: event, 155 | }) 156 | } 157 | 158 | // Commands Sent From Frontend 159 | func (agent *DatabaseAgent) SetEnableHandler(handler func(EnableCommand)) { 160 | agent.commandHandlers.Enable.Store(handler) 161 | } 162 | func (agent *DatabaseAgent) SetDisableHandler(handler func(DisableCommand)) { 163 | agent.commandHandlers.Disable.Store(handler) 164 | } 165 | func (agent *DatabaseAgent) SetGetDatabaseTableNamesHandler(handler func(GetDatabaseTableNamesCommand)) { 166 | agent.commandHandlers.GetDatabaseTableNames.Store(handler) 167 | } 168 | func (agent *DatabaseAgent) SetExecuteSQLHandler(handler func(ExecuteSQLCommand)) { 169 | agent.commandHandlers.ExecuteSQL.Store(handler) 170 | } 171 | func init() { 172 | 173 | } 174 | -------------------------------------------------------------------------------- /protocol/database/commands.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type GetDatabaseTableNamesCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | DatabaseId DatabaseId `json:"databaseId"` 57 | } 58 | type GetDatabaseTableNamesReturn struct { 59 | TableNames []string `json:"tableNames"` 60 | } 61 | 62 | func (c *GetDatabaseTableNamesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 63 | c.DestinationTargetID = targetId 64 | c.responseId = responseId 65 | c.conn = conn 66 | } 67 | 68 | func (c *GetDatabaseTableNamesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 69 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 70 | } 71 | 72 | func (c *GetDatabaseTableNamesCommand) Respond(r *GetDatabaseTableNamesReturn) { 73 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 74 | } 75 | 76 | type ExecuteSQLCommand struct { 77 | DestinationTargetID string 78 | responseId int64 79 | conn *shared.Connection 80 | DatabaseId DatabaseId `json:"databaseId"` 81 | Query string `json:"query"` 82 | } 83 | type ExecuteSQLReturn struct { 84 | ColumnNames *[]string `json:"columnNames,omitempty"` 85 | Values *[]interface{} `json:"values,omitempty"` 86 | SqlError *Error `json:"sqlError,omitempty"` 87 | } 88 | 89 | func (c *ExecuteSQLCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 90 | c.DestinationTargetID = targetId 91 | c.responseId = responseId 92 | c.conn = conn 93 | } 94 | 95 | func (c *ExecuteSQLCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 96 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 97 | } 98 | 99 | func (c *ExecuteSQLCommand) Respond(r *ExecuteSQLReturn) { 100 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 101 | } 102 | -------------------------------------------------------------------------------- /protocol/database/events.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | 4 | type AddDatabaseEvent struct { 5 | Database Database `json:"database"` 6 | } -------------------------------------------------------------------------------- /protocol/database/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package database 2 | 3 | type DatabaseId string 4 | 5 | type Database struct { 6 | Id DatabaseId `json:"id"`// Database ID. 7 | Domain string `json:"domain"`// Database domain. 8 | Name string `json:"name"`// Database name. 9 | Version string `json:"version"`// Database version. 10 | } 11 | 12 | type Error struct { 13 | Message string `json:"message"`// Error message. 14 | Code int64 `json:"code"`// Error code. 15 | } 16 | -------------------------------------------------------------------------------- /protocol/debugger/events.go: -------------------------------------------------------------------------------- 1 | package debugger 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | 8 | type ScriptParsedEvent struct { 9 | ScriptId runtime.ScriptId `json:"scriptId"`// Identifier of the script parsed. 10 | Url string `json:"url"`// URL or name of the script parsed (if any). 11 | StartLine int64 `json:"startLine"`// Line offset of the script within the resource with given URL (for script tags). 12 | StartColumn int64 `json:"startColumn"`// Column offset of the script within the resource with given URL. 13 | EndLine int64 `json:"endLine"`// Last line of the script. 14 | EndColumn int64 `json:"endColumn"`// Length of the last line of the script. 15 | ExecutionContextId runtime.ExecutionContextId `json:"executionContextId"`// Specifies script creation context. 16 | Hash string `json:"hash"`// Content hash of the script. 17 | ExecutionContextAuxData *map[string]string `json:"executionContextAuxData,omitempty"`// Embedder-specific auxiliary data. 18 | IsLiveEdit *bool `json:"isLiveEdit,omitempty"`// [Experimental] True, if this script is generated as a result of the live edit operation. 19 | SourceMapURL *string `json:"sourceMapURL,omitempty"`// URL of source map associated with script (if any). 20 | HasSourceURL *bool `json:"hasSourceURL,omitempty"`// [Experimental] True, if this script has sourceURL. 21 | IsModule *bool `json:"isModule,omitempty"`// [Experimental] True, if this script is ES6 module. 22 | } 23 | type ScriptFailedToParseEvent struct { 24 | ScriptId runtime.ScriptId `json:"scriptId"`// Identifier of the script parsed. 25 | Url string `json:"url"`// URL or name of the script parsed (if any). 26 | StartLine int64 `json:"startLine"`// Line offset of the script within the resource with given URL (for script tags). 27 | StartColumn int64 `json:"startColumn"`// Column offset of the script within the resource with given URL. 28 | EndLine int64 `json:"endLine"`// Last line of the script. 29 | EndColumn int64 `json:"endColumn"`// Length of the last line of the script. 30 | ExecutionContextId runtime.ExecutionContextId `json:"executionContextId"`// Specifies script creation context. 31 | Hash string `json:"hash"`// Content hash of the script. 32 | ExecutionContextAuxData *map[string]string `json:"executionContextAuxData,omitempty"`// Embedder-specific auxiliary data. 33 | SourceMapURL *string `json:"sourceMapURL,omitempty"`// URL of source map associated with script (if any). 34 | HasSourceURL *bool `json:"hasSourceURL,omitempty"`// [Experimental] True, if this script has sourceURL. 35 | IsModule *bool `json:"isModule,omitempty"`// [Experimental] True, if this script is ES6 module. 36 | } 37 | type BreakpointResolvedEvent struct { 38 | BreakpointId BreakpointId `json:"breakpointId"`// Breakpoint unique identifier. 39 | Location Location `json:"location"`// Actual breakpoint location. 40 | } 41 | type PausedEvent struct { 42 | CallFrames []CallFrame `json:"callFrames"`// Call stack the virtual machine stopped on. 43 | Reason PausedReasonEnum `json:"reason"`// Pause reason. 44 | Data *map[string]string `json:"data,omitempty"`// Object containing break-specific auxiliary properties. 45 | HitBreakpoints *[]string `json:"hitBreakpoints,omitempty"`// Hit breakpoints IDs 46 | AsyncStackTrace *runtime.StackTrace `json:"asyncStackTrace,omitempty"`// Async stack trace, if any. 47 | } 48 | type ResumedEvent struct { 49 | } -------------------------------------------------------------------------------- /protocol/debugger/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package debugger 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | type PausedReasonEnum string 8 | const ( 9 | PausedReasonXHR PausedReasonEnum = "XHR" 10 | PausedReasonDOM PausedReasonEnum = "DOM" 11 | PausedReasonEventListener PausedReasonEnum = "EventListener" 12 | PausedReasonException PausedReasonEnum = "exception" 13 | PausedReasonAssert PausedReasonEnum = "assert" 14 | PausedReasonDebugCommand PausedReasonEnum = "debugCommand" 15 | PausedReasonPromiseRejection PausedReasonEnum = "promiseRejection" 16 | PausedReasonOOM PausedReasonEnum = "OOM" 17 | PausedReasonOther PausedReasonEnum = "other" 18 | PausedReasonAmbiguous PausedReasonEnum = "ambiguous" 19 | ) 20 | 21 | type ScopeTypeEnum string 22 | const ( 23 | ScopeTypeGlobal ScopeTypeEnum = "global" 24 | ScopeTypeLocal ScopeTypeEnum = "local" 25 | ScopeTypeWith ScopeTypeEnum = "with" 26 | ScopeTypeClosure ScopeTypeEnum = "closure" 27 | ScopeTypeCatch ScopeTypeEnum = "catch" 28 | ScopeTypeBlock ScopeTypeEnum = "block" 29 | ScopeTypeScript ScopeTypeEnum = "script" 30 | ScopeTypeEval ScopeTypeEnum = "eval" 31 | ScopeTypeModule ScopeTypeEnum = "module" 32 | ) 33 | 34 | type SetPauseOnExceptionsStateEnum string 35 | const ( 36 | SetPauseOnExceptionsStateNone SetPauseOnExceptionsStateEnum = "none" 37 | SetPauseOnExceptionsStateUncaught SetPauseOnExceptionsStateEnum = "uncaught" 38 | SetPauseOnExceptionsStateAll SetPauseOnExceptionsStateEnum = "all" 39 | ) 40 | type BreakpointId string 41 | 42 | type CallFrameId string 43 | 44 | type Location struct { 45 | ScriptId runtime.ScriptId `json:"scriptId"`// Script identifier as reported in the Debugger.scriptParsed. 46 | LineNumber int64 `json:"lineNumber"`// Line number in the script (0-based). 47 | ColumnNumber *int64 `json:"columnNumber,omitempty"`// Column number in the script (0-based). 48 | } 49 | 50 | type ScriptPosition struct { 51 | LineNumber int64 `json:"lineNumber"` 52 | ColumnNumber int64 `json:"columnNumber"` 53 | } 54 | 55 | type CallFrame struct { 56 | CallFrameId CallFrameId `json:"callFrameId"`// Call frame identifier. This identifier is only valid while the virtual machine is paused. 57 | FunctionName string `json:"functionName"`// Name of the JavaScript function called on this call frame. 58 | FunctionLocation *Location `json:"functionLocation,omitempty"`// [Experimental] Location in the source code. 59 | Location Location `json:"location"`// Location in the source code. 60 | ScopeChain []Scope `json:"scopeChain"`// Scope chain for this call frame. 61 | This runtime.RemoteObject `json:"this"`// this object for this call frame. 62 | ReturnValue *runtime.RemoteObject `json:"returnValue,omitempty"`// The value being returned, if the function is at return point. 63 | } 64 | 65 | type Scope struct { 66 | Type ScopeTypeEnum `json:"type"`// Scope type. 67 | Object runtime.RemoteObject `json:"object"`// Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties. 68 | Name *string `json:"name,omitempty"` 69 | StartLocation *Location `json:"startLocation,omitempty"`// Location in the source code where scope starts 70 | EndLocation *Location `json:"endLocation,omitempty"`// Location in the source code where scope ends 71 | } 72 | 73 | type SearchMatch struct { 74 | LineNumber float64 `json:"lineNumber"`// Line number in resource content. 75 | LineContent string `json:"lineContent"`// Line with match content. 76 | } 77 | -------------------------------------------------------------------------------- /protocol/deviceorientation/agent.go: -------------------------------------------------------------------------------- 1 | package deviceorientation 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type SetDeviceOrientationOverrideCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(SetDeviceOrientationOverrideCommand) 13 | } 14 | 15 | func (a *SetDeviceOrientationOverrideCommandFn) Load() func(SetDeviceOrientationOverrideCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *SetDeviceOrientationOverrideCommandFn) Store(fn func(SetDeviceOrientationOverrideCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type ClearDeviceOrientationOverrideCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(ClearDeviceOrientationOverrideCommand) 30 | } 31 | 32 | func (a *ClearDeviceOrientationOverrideCommandFn) Load() func(ClearDeviceOrientationOverrideCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *ClearDeviceOrientationOverrideCommandFn) Store(fn func(ClearDeviceOrientationOverrideCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type DeviceOrientationAgent struct { 45 | conn *shared.Connection 46 | commandHandlers struct { 47 | SetDeviceOrientationOverride SetDeviceOrientationOverrideCommandFn 48 | ClearDeviceOrientationOverride ClearDeviceOrientationOverrideCommandFn 49 | } 50 | } 51 | func NewAgent(conn *shared.Connection) *DeviceOrientationAgent { 52 | agent := &DeviceOrientationAgent{ 53 | conn: conn, 54 | } 55 | conn.RegisterAgent(agent) 56 | return agent 57 | } 58 | 59 | func (agent *DeviceOrientationAgent) Name() string { 60 | return "DeviceOrientation" 61 | } 62 | 63 | func (agent *DeviceOrientationAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 64 | defer shared.TryRecoverFromPanic(agent.conn) 65 | switch (funcName) { 66 | case "setDeviceOrientationOverride": 67 | var out SetDeviceOrientationOverrideCommand 68 | agent.conn.SetupCommand(id, targetId, data, &out) 69 | fn := agent.commandHandlers.SetDeviceOrientationOverride.Load() 70 | if fn == nil { 71 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 72 | break 73 | } 74 | fn(out) 75 | case "clearDeviceOrientationOverride": 76 | var out ClearDeviceOrientationOverrideCommand 77 | agent.conn.SetupCommand(id, targetId, data, &out) 78 | fn := agent.commandHandlers.ClearDeviceOrientationOverride.Load() 79 | if fn == nil { 80 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 81 | break 82 | } 83 | fn(out) 84 | default: 85 | fmt.Printf("Command %s unknown\n", funcName) 86 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 87 | } 88 | } 89 | 90 | // Dispatchable Events 91 | 92 | // Commands Sent From Frontend 93 | func (agent *DeviceOrientationAgent) SetSetDeviceOrientationOverrideHandler(handler func(SetDeviceOrientationOverrideCommand)) { 94 | agent.commandHandlers.SetDeviceOrientationOverride.Store(handler) 95 | } 96 | func (agent *DeviceOrientationAgent) SetClearDeviceOrientationOverrideHandler(handler func(ClearDeviceOrientationOverrideCommand)) { 97 | agent.commandHandlers.ClearDeviceOrientationOverride.Store(handler) 98 | } 99 | func init() { 100 | 101 | } 102 | -------------------------------------------------------------------------------- /protocol/deviceorientation/commands.go: -------------------------------------------------------------------------------- 1 | package deviceorientation 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type SetDeviceOrientationOverrideCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Alpha float64 `json:"alpha"`// Mock alpha 13 | Beta float64 `json:"beta"`// Mock beta 14 | Gamma float64 `json:"gamma"`// Mock gamma 15 | } 16 | type SetDeviceOrientationOverrideReturn struct { 17 | } 18 | 19 | func (c *SetDeviceOrientationOverrideCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 20 | c.DestinationTargetID = targetId 21 | c.responseId = responseId 22 | c.conn = conn 23 | } 24 | 25 | func (c *SetDeviceOrientationOverrideCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 26 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 27 | } 28 | 29 | func (c *SetDeviceOrientationOverrideCommand) Respond() { 30 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 31 | } 32 | 33 | type ClearDeviceOrientationOverrideCommand struct { 34 | DestinationTargetID string 35 | responseId int64 36 | conn *shared.Connection 37 | } 38 | type ClearDeviceOrientationOverrideReturn struct { 39 | } 40 | 41 | func (c *ClearDeviceOrientationOverrideCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 42 | c.DestinationTargetID = targetId 43 | c.responseId = responseId 44 | c.conn = conn 45 | } 46 | 47 | func (c *ClearDeviceOrientationOverrideCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 48 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 49 | } 50 | 51 | func (c *ClearDeviceOrientationOverrideCommand) Respond() { 52 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 53 | } 54 | -------------------------------------------------------------------------------- /protocol/deviceorientation/events.go: -------------------------------------------------------------------------------- 1 | package deviceorientation 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/deviceorientation/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package deviceorientation 2 | 3 | -------------------------------------------------------------------------------- /protocol/dom/events.go: -------------------------------------------------------------------------------- 1 | package dom 2 | 3 | 4 | type DocumentUpdatedEvent struct { 5 | } 6 | type InspectNodeRequestedEvent struct { 7 | BackendNodeId BackendNodeId `json:"backendNodeId"`// Id of the node to inspect. 8 | } 9 | type SetChildNodesEvent struct { 10 | ParentId NodeId `json:"parentId"`// Parent node id to populate with children. 11 | Nodes []Node `json:"nodes"`// Child nodes array. 12 | } 13 | type AttributeModifiedEvent struct { 14 | NodeId NodeId `json:"nodeId"`// Id of the node that has changed. 15 | Name string `json:"name"`// Attribute name. 16 | Value string `json:"value"`// Attribute value. 17 | } 18 | type AttributeRemovedEvent struct { 19 | NodeId NodeId `json:"nodeId"`// Id of the node that has changed. 20 | Name string `json:"name"`// A ttribute name. 21 | } 22 | type InlineStyleInvalidatedEvent struct { 23 | NodeIds []NodeId `json:"nodeIds"`// Ids of the nodes for which the inline styles have been invalidated. 24 | } 25 | type CharacterDataModifiedEvent struct { 26 | NodeId NodeId `json:"nodeId"`// Id of the node that has changed. 27 | CharacterData string `json:"characterData"`// New text value. 28 | } 29 | type ChildNodeCountUpdatedEvent struct { 30 | NodeId NodeId `json:"nodeId"`// Id of the node that has changed. 31 | ChildNodeCount int64 `json:"childNodeCount"`// New node count. 32 | } 33 | type ChildNodeInsertedEvent struct { 34 | ParentNodeId NodeId `json:"parentNodeId"`// Id of the node that has changed. 35 | PreviousNodeId NodeId `json:"previousNodeId"`// If of the previous siblint. 36 | Node Node `json:"node"`// Inserted node data. 37 | } 38 | type ChildNodeRemovedEvent struct { 39 | ParentNodeId NodeId `json:"parentNodeId"`// Parent id. 40 | NodeId NodeId `json:"nodeId"`// Id of the node that has been removed. 41 | } 42 | type ShadowRootPushedEvent struct { 43 | HostId NodeId `json:"hostId"`// Host element id. 44 | Root Node `json:"root"`// Shadow root. 45 | } 46 | type ShadowRootPoppedEvent struct { 47 | HostId NodeId `json:"hostId"`// Host element id. 48 | RootId NodeId `json:"rootId"`// Shadow root id. 49 | } 50 | type PseudoElementAddedEvent struct { 51 | ParentId NodeId `json:"parentId"`// Pseudo element's parent element id. 52 | PseudoElement Node `json:"pseudoElement"`// The added pseudo element. 53 | } 54 | type PseudoElementRemovedEvent struct { 55 | ParentId NodeId `json:"parentId"`// Pseudo element's parent element id. 56 | PseudoElementId NodeId `json:"pseudoElementId"`// The removed pseudo element id. 57 | } 58 | type DistributedNodesUpdatedEvent struct { 59 | InsertionPointId NodeId `json:"insertionPointId"`// Insertion point where distrubuted nodes were updated. 60 | DistributedNodes []BackendNode `json:"distributedNodes"`// Distributed nodes for given insertion point. 61 | } 62 | type NodeHighlightRequestedEvent struct { 63 | NodeId NodeId `json:"nodeId"` 64 | } -------------------------------------------------------------------------------- /protocol/domdebugger/events.go: -------------------------------------------------------------------------------- 1 | package domdebugger 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/domdebugger/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package domdebugger 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | "github.com/allada/gdd/protocol/dom" 7 | ) 8 | const ( 9 | DOMBreakpointTypeSubtreeDashmodified DOMBreakpointType = "subtree-modified" 10 | DOMBreakpointTypeAttributeDashmodified DOMBreakpointType = "attribute-modified" 11 | DOMBreakpointTypeNodeDashremoved DOMBreakpointType = "node-removed" 12 | ) 13 | type DOMBreakpointType string 14 | 15 | type EventListener struct { 16 | Type string `json:"type"`// EventListener's type. 17 | UseCapture bool `json:"useCapture"`// EventListener's useCapture. 18 | Passive bool `json:"passive"`// EventListener's passive flag. 19 | Once bool `json:"once"`// EventListener's once flag. 20 | ScriptId runtime.ScriptId `json:"scriptId"`// Script id of the handler code. 21 | LineNumber int64 `json:"lineNumber"`// Line number in the script (0-based). 22 | ColumnNumber int64 `json:"columnNumber"`// Column number in the script (0-based). 23 | Handler *runtime.RemoteObject `json:"handler,omitempty"`// Event handler function value. 24 | OriginalHandler *runtime.RemoteObject `json:"originalHandler,omitempty"`// Event original handler function value. 25 | BackendNodeId *dom.BackendNodeId `json:"backendNodeId,omitempty"`// Node the listener is added to (if any). 26 | } 27 | -------------------------------------------------------------------------------- /protocol/domstorage/commands.go: -------------------------------------------------------------------------------- 1 | package domstorage 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type ClearCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | StorageId StorageId `json:"storageId"` 57 | } 58 | type ClearReturn struct { 59 | } 60 | 61 | func (c *ClearCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 62 | c.DestinationTargetID = targetId 63 | c.responseId = responseId 64 | c.conn = conn 65 | } 66 | 67 | func (c *ClearCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 68 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 69 | } 70 | 71 | func (c *ClearCommand) Respond() { 72 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 73 | } 74 | 75 | type GetDOMStorageItemsCommand struct { 76 | DestinationTargetID string 77 | responseId int64 78 | conn *shared.Connection 79 | StorageId StorageId `json:"storageId"` 80 | } 81 | type GetDOMStorageItemsReturn struct { 82 | Entries []Item `json:"entries"` 83 | } 84 | 85 | func (c *GetDOMStorageItemsCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 86 | c.DestinationTargetID = targetId 87 | c.responseId = responseId 88 | c.conn = conn 89 | } 90 | 91 | func (c *GetDOMStorageItemsCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 92 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 93 | } 94 | 95 | func (c *GetDOMStorageItemsCommand) Respond(r *GetDOMStorageItemsReturn) { 96 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 97 | } 98 | 99 | type SetDOMStorageItemCommand struct { 100 | DestinationTargetID string 101 | responseId int64 102 | conn *shared.Connection 103 | StorageId StorageId `json:"storageId"` 104 | Key string `json:"key"` 105 | Value string `json:"value"` 106 | } 107 | type SetDOMStorageItemReturn struct { 108 | } 109 | 110 | func (c *SetDOMStorageItemCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 111 | c.DestinationTargetID = targetId 112 | c.responseId = responseId 113 | c.conn = conn 114 | } 115 | 116 | func (c *SetDOMStorageItemCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 117 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 118 | } 119 | 120 | func (c *SetDOMStorageItemCommand) Respond() { 121 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 122 | } 123 | 124 | type RemoveDOMStorageItemCommand struct { 125 | DestinationTargetID string 126 | responseId int64 127 | conn *shared.Connection 128 | StorageId StorageId `json:"storageId"` 129 | Key string `json:"key"` 130 | } 131 | type RemoveDOMStorageItemReturn struct { 132 | } 133 | 134 | func (c *RemoveDOMStorageItemCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 135 | c.DestinationTargetID = targetId 136 | c.responseId = responseId 137 | c.conn = conn 138 | } 139 | 140 | func (c *RemoveDOMStorageItemCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 141 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 142 | } 143 | 144 | func (c *RemoveDOMStorageItemCommand) Respond() { 145 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 146 | } 147 | -------------------------------------------------------------------------------- /protocol/domstorage/events.go: -------------------------------------------------------------------------------- 1 | package domstorage 2 | 3 | 4 | type DomStorageItemsClearedEvent struct { 5 | StorageId StorageId `json:"storageId"` 6 | } 7 | type DomStorageItemRemovedEvent struct { 8 | StorageId StorageId `json:"storageId"` 9 | Key string `json:"key"` 10 | } 11 | type DomStorageItemAddedEvent struct { 12 | StorageId StorageId `json:"storageId"` 13 | Key string `json:"key"` 14 | NewValue string `json:"newValue"` 15 | } 16 | type DomStorageItemUpdatedEvent struct { 17 | StorageId StorageId `json:"storageId"` 18 | Key string `json:"key"` 19 | OldValue string `json:"oldValue"` 20 | NewValue string `json:"newValue"` 21 | } -------------------------------------------------------------------------------- /protocol/domstorage/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package domstorage 2 | 3 | type StorageId struct { 4 | SecurityOrigin string `json:"securityOrigin"`// Security origin for the storage. 5 | IsLocalStorage bool `json:"isLocalStorage"`// Whether the storage is local storage (not session storage). 6 | } 7 | 8 | type Item []string 9 | -------------------------------------------------------------------------------- /protocol/emulation/events.go: -------------------------------------------------------------------------------- 1 | package emulation 2 | 3 | 4 | type VirtualTimeBudgetExpiredEvent struct { 5 | } -------------------------------------------------------------------------------- /protocol/emulation/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package emulation 2 | 3 | type ScreenOrientationTypeEnum string 4 | const ( 5 | ScreenOrientationTypePortraitPrimary ScreenOrientationTypeEnum = "portraitPrimary" 6 | ScreenOrientationTypePortraitSecondary ScreenOrientationTypeEnum = "portraitSecondary" 7 | ScreenOrientationTypeLandscapePrimary ScreenOrientationTypeEnum = "landscapePrimary" 8 | ScreenOrientationTypeLandscapeSecondary ScreenOrientationTypeEnum = "landscapeSecondary" 9 | ) 10 | 11 | const ( 12 | VirtualTimePolicyAdvance VirtualTimePolicy = "advance" 13 | VirtualTimePolicyPause VirtualTimePolicy = "pause" 14 | VirtualTimePolicyPauseIfNetworkFetchesPending VirtualTimePolicy = "pauseIfNetworkFetchesPending" 15 | ) 16 | 17 | type SetTouchEmulationEnabledConfigurationEnum string 18 | const ( 19 | SetTouchEmulationEnabledConfigurationMobile SetTouchEmulationEnabledConfigurationEnum = "mobile" 20 | SetTouchEmulationEnabledConfigurationDesktop SetTouchEmulationEnabledConfigurationEnum = "desktop" 21 | ) 22 | type ScreenOrientation struct { 23 | Type ScreenOrientationTypeEnum `json:"type"`// Orientation type. 24 | Angle int64 `json:"angle"`// Orientation angle. 25 | } 26 | 27 | type VirtualTimePolicy string 28 | -------------------------------------------------------------------------------- /protocol/heapprofiler/events.go: -------------------------------------------------------------------------------- 1 | package heapprofiler 2 | 3 | 4 | type AddHeapSnapshotChunkEvent struct { 5 | Chunk string `json:"chunk"` 6 | } 7 | type ResetProfilesEvent struct { 8 | } 9 | type ReportHeapSnapshotProgressEvent struct { 10 | Done int64 `json:"done"` 11 | Total int64 `json:"total"` 12 | Finished *bool `json:"finished,omitempty"` 13 | } 14 | type LastSeenObjectIdEvent struct { 15 | LastSeenObjectId int64 `json:"lastSeenObjectId"` 16 | Timestamp float64 `json:"timestamp"` 17 | } 18 | type HeapStatsUpdateEvent struct { 19 | StatsUpdate []int64 `json:"statsUpdate"`// An array of triplets. Each triplet describes a fragment. The first integer is the fragment index, the second integer is a total count of objects for the fragment, the third integer is a total size of the objects for the fragment. 20 | } -------------------------------------------------------------------------------- /protocol/heapprofiler/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package heapprofiler 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | type HeapSnapshotObjectId string 8 | 9 | type SamplingHeapProfileNode struct { 10 | CallFrame runtime.CallFrame `json:"callFrame"`// Function location. 11 | SelfSize float64 `json:"selfSize"`// Allocations size in bytes for the node excluding children. 12 | Children []SamplingHeapProfileNode `json:"children"`// Child nodes. 13 | } 14 | 15 | type SamplingHeapProfile struct { 16 | Head SamplingHeapProfileNode `json:"head"` 17 | } 18 | -------------------------------------------------------------------------------- /protocol/indexeddb/commands.go: -------------------------------------------------------------------------------- 1 | package indexeddb 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type RequestDatabaseNamesCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 57 | } 58 | type RequestDatabaseNamesReturn struct { 59 | DatabaseNames []string `json:"databaseNames"`// Database names for origin. 60 | } 61 | 62 | func (c *RequestDatabaseNamesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 63 | c.DestinationTargetID = targetId 64 | c.responseId = responseId 65 | c.conn = conn 66 | } 67 | 68 | func (c *RequestDatabaseNamesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 69 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 70 | } 71 | 72 | func (c *RequestDatabaseNamesCommand) Respond(r *RequestDatabaseNamesReturn) { 73 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 74 | } 75 | 76 | type RequestDatabaseCommand struct { 77 | DestinationTargetID string 78 | responseId int64 79 | conn *shared.Connection 80 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 81 | DatabaseName string `json:"databaseName"`// Database name. 82 | } 83 | type RequestDatabaseReturn struct { 84 | DatabaseWithObjectStores DatabaseWithObjectStores `json:"databaseWithObjectStores"`// Database with an array of object stores. 85 | } 86 | 87 | func (c *RequestDatabaseCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 88 | c.DestinationTargetID = targetId 89 | c.responseId = responseId 90 | c.conn = conn 91 | } 92 | 93 | func (c *RequestDatabaseCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 94 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 95 | } 96 | 97 | func (c *RequestDatabaseCommand) Respond(r *RequestDatabaseReturn) { 98 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 99 | } 100 | 101 | type RequestDataCommand struct { 102 | DestinationTargetID string 103 | responseId int64 104 | conn *shared.Connection 105 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 106 | DatabaseName string `json:"databaseName"`// Database name. 107 | ObjectStoreName string `json:"objectStoreName"`// Object store name. 108 | IndexName string `json:"indexName"`// Index name, empty string for object store data requests. 109 | SkipCount int64 `json:"skipCount"`// Number of records to skip. 110 | PageSize int64 `json:"pageSize"`// Number of records to fetch. 111 | KeyRange *KeyRange `json:"keyRange,omitempty"`// Key range. 112 | } 113 | type RequestDataReturn struct { 114 | ObjectStoreDataEntries []DataEntry `json:"objectStoreDataEntries"`// Array of object store data entries. 115 | HasMore bool `json:"hasMore"`// If true, there are more entries to fetch in the given range. 116 | } 117 | 118 | func (c *RequestDataCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 119 | c.DestinationTargetID = targetId 120 | c.responseId = responseId 121 | c.conn = conn 122 | } 123 | 124 | func (c *RequestDataCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 125 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 126 | } 127 | 128 | func (c *RequestDataCommand) Respond(r *RequestDataReturn) { 129 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 130 | } 131 | 132 | type ClearObjectStoreCommand struct { 133 | DestinationTargetID string 134 | responseId int64 135 | conn *shared.Connection 136 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 137 | DatabaseName string `json:"databaseName"`// Database name. 138 | ObjectStoreName string `json:"objectStoreName"`// Object store name. 139 | } 140 | type ClearObjectStoreReturn struct { 141 | } 142 | 143 | func (c *ClearObjectStoreCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 144 | c.DestinationTargetID = targetId 145 | c.responseId = responseId 146 | c.conn = conn 147 | } 148 | 149 | func (c *ClearObjectStoreCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 150 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 151 | } 152 | 153 | func (c *ClearObjectStoreCommand) Respond(r *ClearObjectStoreReturn) { 154 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 155 | } 156 | 157 | type DeleteDatabaseCommand struct { 158 | DestinationTargetID string 159 | responseId int64 160 | conn *shared.Connection 161 | SecurityOrigin string `json:"securityOrigin"`// Security origin. 162 | DatabaseName string `json:"databaseName"`// Database name. 163 | } 164 | type DeleteDatabaseReturn struct { 165 | } 166 | 167 | func (c *DeleteDatabaseCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 168 | c.DestinationTargetID = targetId 169 | c.responseId = responseId 170 | c.conn = conn 171 | } 172 | 173 | func (c *DeleteDatabaseCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 174 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 175 | } 176 | 177 | func (c *DeleteDatabaseCommand) Respond(r *DeleteDatabaseReturn) { 178 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 179 | } 180 | -------------------------------------------------------------------------------- /protocol/indexeddb/events.go: -------------------------------------------------------------------------------- 1 | package indexeddb 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/indexeddb/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package indexeddb 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | type KeyTypeEnum string 8 | const ( 9 | KeyTypeNumber KeyTypeEnum = "number" 10 | KeyTypeString KeyTypeEnum = "string" 11 | KeyTypeDate KeyTypeEnum = "date" 12 | KeyTypeArray KeyTypeEnum = "array" 13 | ) 14 | 15 | type KeyPathTypeEnum string 16 | const ( 17 | KeyPathTypeNull KeyPathTypeEnum = "null" 18 | KeyPathTypeString KeyPathTypeEnum = "string" 19 | KeyPathTypeArray KeyPathTypeEnum = "array" 20 | ) 21 | type DatabaseWithObjectStores struct { 22 | Name string `json:"name"`// Database name. 23 | Version int64 `json:"version"`// Database version. 24 | ObjectStores []ObjectStore `json:"objectStores"`// Object stores in this database. 25 | } 26 | 27 | type ObjectStore struct { 28 | Name string `json:"name"`// Object store name. 29 | KeyPath KeyPath `json:"keyPath"`// Object store key path. 30 | AutoIncrement bool `json:"autoIncrement"`// If true, object store has auto increment flag set. 31 | Indexes []ObjectStoreIndex `json:"indexes"`// Indexes in this object store. 32 | } 33 | 34 | type ObjectStoreIndex struct { 35 | Name string `json:"name"`// Index name. 36 | KeyPath KeyPath `json:"keyPath"`// Index key path. 37 | Unique bool `json:"unique"`// If true, index is unique. 38 | MultiEntry bool `json:"multiEntry"`// If true, index allows multiple entries for a key. 39 | } 40 | 41 | type Key struct { 42 | Type KeyTypeEnum `json:"type"`// Key type. 43 | Number *float64 `json:"number,omitempty"`// Number value. 44 | String *string `json:"string,omitempty"`// String value. 45 | Date *float64 `json:"date,omitempty"`// Date value. 46 | Array *[]Key `json:"array,omitempty"`// Array value. 47 | } 48 | 49 | type KeyRange struct { 50 | Lower *Key `json:"lower,omitempty"`// Lower bound. 51 | Upper *Key `json:"upper,omitempty"`// Upper bound. 52 | LowerOpen bool `json:"lowerOpen"`// If true lower bound is open. 53 | UpperOpen bool `json:"upperOpen"`// If true upper bound is open. 54 | } 55 | 56 | type DataEntry struct { 57 | Key runtime.RemoteObject `json:"key"`// Key object. 58 | PrimaryKey runtime.RemoteObject `json:"primaryKey"`// Primary key object. 59 | Value runtime.RemoteObject `json:"value"`// Value object. 60 | } 61 | 62 | type KeyPath struct { 63 | Type KeyPathTypeEnum `json:"type"`// Key path type. 64 | String *string `json:"string,omitempty"`// String value. 65 | Array *[]string `json:"array,omitempty"`// Array value. 66 | } 67 | -------------------------------------------------------------------------------- /protocol/input/events.go: -------------------------------------------------------------------------------- 1 | package input 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/input/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package input 2 | 3 | type TouchPointStateEnum string 4 | const ( 5 | TouchPointStateTouchPressed TouchPointStateEnum = "touchPressed" 6 | TouchPointStateTouchReleased TouchPointStateEnum = "touchReleased" 7 | TouchPointStateTouchMoved TouchPointStateEnum = "touchMoved" 8 | TouchPointStateTouchStationary TouchPointStateEnum = "touchStationary" 9 | TouchPointStateTouchCancelled TouchPointStateEnum = "touchCancelled" 10 | ) 11 | 12 | const ( 13 | GestureSourceTypeDefault GestureSourceType = "default" 14 | GestureSourceTypeTouch GestureSourceType = "touch" 15 | GestureSourceTypeMouse GestureSourceType = "mouse" 16 | ) 17 | 18 | type DispatchKeyEventTypeEnum string 19 | const ( 20 | DispatchKeyEventTypeKeyDown DispatchKeyEventTypeEnum = "keyDown" 21 | DispatchKeyEventTypeKeyUp DispatchKeyEventTypeEnum = "keyUp" 22 | DispatchKeyEventTypeRawKeyDown DispatchKeyEventTypeEnum = "rawKeyDown" 23 | DispatchKeyEventTypeChar DispatchKeyEventTypeEnum = "char" 24 | ) 25 | 26 | type DispatchMouseEventTypeEnum string 27 | const ( 28 | DispatchMouseEventTypeMousePressed DispatchMouseEventTypeEnum = "mousePressed" 29 | DispatchMouseEventTypeMouseReleased DispatchMouseEventTypeEnum = "mouseReleased" 30 | DispatchMouseEventTypeMouseMoved DispatchMouseEventTypeEnum = "mouseMoved" 31 | ) 32 | 33 | type DispatchMouseEventButtonEnum string 34 | const ( 35 | DispatchMouseEventButtonNone DispatchMouseEventButtonEnum = "none" 36 | DispatchMouseEventButtonLeft DispatchMouseEventButtonEnum = "left" 37 | DispatchMouseEventButtonMiddle DispatchMouseEventButtonEnum = "middle" 38 | DispatchMouseEventButtonRight DispatchMouseEventButtonEnum = "right" 39 | ) 40 | 41 | type DispatchTouchEventTypeEnum string 42 | const ( 43 | DispatchTouchEventTypeTouchStart DispatchTouchEventTypeEnum = "touchStart" 44 | DispatchTouchEventTypeTouchEnd DispatchTouchEventTypeEnum = "touchEnd" 45 | DispatchTouchEventTypeTouchMove DispatchTouchEventTypeEnum = "touchMove" 46 | ) 47 | 48 | type EmulateTouchFromMouseEventTypeEnum string 49 | const ( 50 | EmulateTouchFromMouseEventTypeMousePressed EmulateTouchFromMouseEventTypeEnum = "mousePressed" 51 | EmulateTouchFromMouseEventTypeMouseReleased EmulateTouchFromMouseEventTypeEnum = "mouseReleased" 52 | EmulateTouchFromMouseEventTypeMouseMoved EmulateTouchFromMouseEventTypeEnum = "mouseMoved" 53 | EmulateTouchFromMouseEventTypeMouseWheel EmulateTouchFromMouseEventTypeEnum = "mouseWheel" 54 | ) 55 | 56 | type EmulateTouchFromMouseEventButtonEnum string 57 | const ( 58 | EmulateTouchFromMouseEventButtonNone EmulateTouchFromMouseEventButtonEnum = "none" 59 | EmulateTouchFromMouseEventButtonLeft EmulateTouchFromMouseEventButtonEnum = "left" 60 | EmulateTouchFromMouseEventButtonMiddle EmulateTouchFromMouseEventButtonEnum = "middle" 61 | EmulateTouchFromMouseEventButtonRight EmulateTouchFromMouseEventButtonEnum = "right" 62 | ) 63 | type TouchPoint struct { 64 | State TouchPointStateEnum `json:"state"`// State of the touch point. 65 | X int64 `json:"x"`// X coordinate of the event relative to the main frame's viewport. 66 | Y int64 `json:"y"`// Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport. 67 | RadiusX *int64 `json:"radiusX,omitempty"`// X radius of the touch area (default: 1). 68 | RadiusY *int64 `json:"radiusY,omitempty"`// Y radius of the touch area (default: 1). 69 | RotationAngle *float64 `json:"rotationAngle,omitempty"`// Rotation angle (default: 0.0). 70 | Force *float64 `json:"force,omitempty"`// Force (default: 1.0). 71 | Id *float64 `json:"id,omitempty"`// Identifier used to track touch sources between events, must be unique within an event. 72 | } 73 | 74 | type GestureSourceType string 75 | -------------------------------------------------------------------------------- /protocol/inspector/agent.go: -------------------------------------------------------------------------------- 1 | package inspector 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type EnableCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(EnableCommand) 13 | } 14 | 15 | func (a *EnableCommandFn) Load() func(EnableCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type DisableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(DisableCommand) 30 | } 31 | 32 | func (a *DisableCommandFn) Load() func(DisableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *DisableCommandFn) Store(fn func(DisableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type InspectorAgent struct { 45 | conn *shared.Connection 46 | commandHandlers struct { 47 | Enable EnableCommandFn 48 | Disable DisableCommandFn 49 | } 50 | } 51 | func NewAgent(conn *shared.Connection) *InspectorAgent { 52 | agent := &InspectorAgent{ 53 | conn: conn, 54 | } 55 | conn.RegisterAgent(agent) 56 | return agent 57 | } 58 | 59 | func (agent *InspectorAgent) Name() string { 60 | return "Inspector" 61 | } 62 | 63 | func (agent *InspectorAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 64 | defer shared.TryRecoverFromPanic(agent.conn) 65 | switch (funcName) { 66 | case "enable": 67 | var out EnableCommand 68 | agent.conn.SetupCommand(id, targetId, data, &out) 69 | fn := agent.commandHandlers.Enable.Load() 70 | if fn == nil { 71 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 72 | break 73 | } 74 | fn(out) 75 | case "disable": 76 | var out DisableCommand 77 | agent.conn.SetupCommand(id, targetId, data, &out) 78 | fn := agent.commandHandlers.Disable.Load() 79 | if fn == nil { 80 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 81 | break 82 | } 83 | fn(out) 84 | default: 85 | fmt.Printf("Command %s unknown\n", funcName) 86 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 87 | } 88 | } 89 | 90 | // Dispatchable Events 91 | func (agent *InspectorAgent) FireDetached(event DetachedEvent) { 92 | agent.conn.Send(shared.Notification{ 93 | Method: "Inspector.detached", 94 | Params: event, 95 | }) 96 | } 97 | func (agent *InspectorAgent) FireDetachedOnTarget(targetId string,event DetachedEvent) { 98 | agent.conn.SendToTarget(targetId, shared.Notification{ 99 | Method: "Inspector.detached", 100 | Params: event, 101 | }) 102 | } 103 | func (agent *InspectorAgent) FireTargetCrashed() { 104 | agent.conn.Send(shared.Notification{ 105 | Method: "Inspector.targetCrashed", 106 | }) 107 | } 108 | func (agent *InspectorAgent) FireTargetCrashedOnTarget(targetId string) { 109 | agent.conn.SendToTarget(targetId, shared.Notification{ 110 | Method: "Inspector.targetCrashed", 111 | }) 112 | } 113 | 114 | // Commands Sent From Frontend 115 | func (agent *InspectorAgent) SetEnableHandler(handler func(EnableCommand)) { 116 | agent.commandHandlers.Enable.Store(handler) 117 | } 118 | func (agent *InspectorAgent) SetDisableHandler(handler func(DisableCommand)) { 119 | agent.commandHandlers.Disable.Store(handler) 120 | } 121 | func init() { 122 | 123 | } 124 | -------------------------------------------------------------------------------- /protocol/inspector/commands.go: -------------------------------------------------------------------------------- 1 | package inspector 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | -------------------------------------------------------------------------------- /protocol/inspector/events.go: -------------------------------------------------------------------------------- 1 | package inspector 2 | 3 | 4 | type DetachedEvent struct { 5 | Reason string `json:"reason"`// The reason why connection has been terminated. 6 | } 7 | type TargetCrashedEvent struct { 8 | } -------------------------------------------------------------------------------- /protocol/inspector/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package inspector 2 | 3 | -------------------------------------------------------------------------------- /protocol/io/agent.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type ReadCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(ReadCommand) 13 | } 14 | 15 | func (a *ReadCommandFn) Load() func(ReadCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *ReadCommandFn) Store(fn func(ReadCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type CloseCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(CloseCommand) 30 | } 31 | 32 | func (a *CloseCommandFn) Load() func(CloseCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *CloseCommandFn) Store(fn func(CloseCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type IOAgent struct { 45 | conn *shared.Connection 46 | commandHandlers struct { 47 | Read ReadCommandFn 48 | Close CloseCommandFn 49 | } 50 | } 51 | func NewAgent(conn *shared.Connection) *IOAgent { 52 | agent := &IOAgent{ 53 | conn: conn, 54 | } 55 | conn.RegisterAgent(agent) 56 | return agent 57 | } 58 | 59 | func (agent *IOAgent) Name() string { 60 | return "IO" 61 | } 62 | 63 | func (agent *IOAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 64 | defer shared.TryRecoverFromPanic(agent.conn) 65 | switch (funcName) { 66 | case "read": 67 | var out ReadCommand 68 | agent.conn.SetupCommand(id, targetId, data, &out) 69 | fn := agent.commandHandlers.Read.Load() 70 | if fn == nil { 71 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 72 | break 73 | } 74 | fn(out) 75 | case "close": 76 | var out CloseCommand 77 | agent.conn.SetupCommand(id, targetId, data, &out) 78 | fn := agent.commandHandlers.Close.Load() 79 | if fn == nil { 80 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 81 | break 82 | } 83 | fn(out) 84 | default: 85 | fmt.Printf("Command %s unknown\n", funcName) 86 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 87 | } 88 | } 89 | 90 | // Dispatchable Events 91 | 92 | // Commands Sent From Frontend 93 | func (agent *IOAgent) SetReadHandler(handler func(ReadCommand)) { 94 | agent.commandHandlers.Read.Store(handler) 95 | } 96 | func (agent *IOAgent) SetCloseHandler(handler func(CloseCommand)) { 97 | agent.commandHandlers.Close.Store(handler) 98 | } 99 | func init() { 100 | 101 | } 102 | -------------------------------------------------------------------------------- /protocol/io/commands.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type ReadCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Handle StreamHandle `json:"handle"`// Handle of the stream to read. 13 | Offset *int64 `json:"offset,omitempty"`// Seek to the specified offset before reading (if not specificed, proceed with offset following the last read). 14 | Size *int64 `json:"size,omitempty"`// Maximum number of bytes to read (left upon the agent discretion if not specified). 15 | } 16 | type ReadReturn struct { 17 | Data string `json:"data"`// Data that were read. 18 | Eof bool `json:"eof"`// Set if the end-of-file condition occured while reading. 19 | } 20 | 21 | func (c *ReadCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 22 | c.DestinationTargetID = targetId 23 | c.responseId = responseId 24 | c.conn = conn 25 | } 26 | 27 | func (c *ReadCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 28 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 29 | } 30 | 31 | func (c *ReadCommand) Respond(r *ReadReturn) { 32 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 33 | } 34 | 35 | type CloseCommand struct { 36 | DestinationTargetID string 37 | responseId int64 38 | conn *shared.Connection 39 | Handle StreamHandle `json:"handle"`// Handle of the stream to close. 40 | } 41 | type CloseReturn struct { 42 | } 43 | 44 | func (c *CloseCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 45 | c.DestinationTargetID = targetId 46 | c.responseId = responseId 47 | c.conn = conn 48 | } 49 | 50 | func (c *CloseCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 51 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 52 | } 53 | 54 | func (c *CloseCommand) Respond() { 55 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 56 | } 57 | -------------------------------------------------------------------------------- /protocol/io/events.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/io/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package io 2 | 3 | type StreamHandle string 4 | -------------------------------------------------------------------------------- /protocol/layertree/events.go: -------------------------------------------------------------------------------- 1 | package layertree 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/dom" 6 | ) 7 | 8 | type LayerTreeDidChangeEvent struct { 9 | Layers *[]Layer `json:"layers,omitempty"`// Layer tree, absent if not in the comspositing mode. 10 | } 11 | type LayerPaintedEvent struct { 12 | LayerId LayerId `json:"layerId"`// The id of the painted layer. 13 | Clip dom.Rect `json:"clip"`// Clip rectangle. 14 | } -------------------------------------------------------------------------------- /protocol/layertree/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package layertree 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/dom" 6 | ) 7 | type ScrollRectTypeEnum string 8 | const ( 9 | ScrollRectTypeRepaintsOnScroll ScrollRectTypeEnum = "RepaintsOnScroll" 10 | ScrollRectTypeTouchEventHandler ScrollRectTypeEnum = "TouchEventHandler" 11 | ScrollRectTypeWheelEventHandler ScrollRectTypeEnum = "WheelEventHandler" 12 | ) 13 | type LayerId string 14 | 15 | type SnapshotId string 16 | 17 | type ScrollRect struct { 18 | Rect dom.Rect `json:"rect"`// Rectangle itself. 19 | Type ScrollRectTypeEnum `json:"type"`// Reason for rectangle to force scrolling on the main thread 20 | } 21 | 22 | type PictureTile struct { 23 | X float64 `json:"x"`// Offset from owning layer left boundary 24 | Y float64 `json:"y"`// Offset from owning layer top boundary 25 | Picture string `json:"picture"`// Base64-encoded snapshot data. 26 | } 27 | 28 | type Layer struct { 29 | LayerId LayerId `json:"layerId"`// The unique id for this layer. 30 | ParentLayerId *LayerId `json:"parentLayerId,omitempty"`// The id of parent (not present for root). 31 | BackendNodeId *dom.BackendNodeId `json:"backendNodeId,omitempty"`// The backend id for the node associated with this layer. 32 | OffsetX float64 `json:"offsetX"`// Offset from parent layer, X coordinate. 33 | OffsetY float64 `json:"offsetY"`// Offset from parent layer, Y coordinate. 34 | Width float64 `json:"width"`// Layer width. 35 | Height float64 `json:"height"`// Layer height. 36 | Transform *[]float64 `json:"transform,omitempty"`// Transformation matrix for layer, default is identity matrix 37 | AnchorX *float64 `json:"anchorX,omitempty"`// Transform anchor point X, absent if no transform specified 38 | AnchorY *float64 `json:"anchorY,omitempty"`// Transform anchor point Y, absent if no transform specified 39 | AnchorZ *float64 `json:"anchorZ,omitempty"`// Transform anchor point Z, absent if no transform specified 40 | PaintCount int64 `json:"paintCount"`// Indicates how many time this layer has painted. 41 | DrawsContent bool `json:"drawsContent"`// Indicates whether this layer hosts any content, rather than being used for transform/scrolling purposes only. 42 | Invisible *bool `json:"invisible,omitempty"`// Set if layer is not visible. 43 | ScrollRects *[]ScrollRect `json:"scrollRects,omitempty"`// Rectangles scrolling on main thread only. 44 | } 45 | 46 | type PaintProfile []float64 47 | -------------------------------------------------------------------------------- /protocol/log/agent.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type EnableCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(EnableCommand) 13 | } 14 | 15 | func (a *EnableCommandFn) Load() func(EnableCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type DisableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(DisableCommand) 30 | } 31 | 32 | func (a *DisableCommandFn) Load() func(DisableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *DisableCommandFn) Store(fn func(DisableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type ClearCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(ClearCommand) 47 | } 48 | 49 | func (a *ClearCommandFn) Load() func(ClearCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *ClearCommandFn) Store(fn func(ClearCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type StartViolationsReportCommandFn struct { 62 | mux sync.RWMutex 63 | fn func(StartViolationsReportCommand) 64 | } 65 | 66 | func (a *StartViolationsReportCommandFn) Load() func(StartViolationsReportCommand) { 67 | a.mux.RLock() 68 | defer a.mux.RUnlock() 69 | return a.fn 70 | } 71 | 72 | func (a *StartViolationsReportCommandFn) Store(fn func(StartViolationsReportCommand)) { 73 | a.mux.Lock() 74 | defer a.mux.Unlock() 75 | a.fn = fn 76 | } 77 | 78 | type StopViolationsReportCommandFn struct { 79 | mux sync.RWMutex 80 | fn func(StopViolationsReportCommand) 81 | } 82 | 83 | func (a *StopViolationsReportCommandFn) Load() func(StopViolationsReportCommand) { 84 | a.mux.RLock() 85 | defer a.mux.RUnlock() 86 | return a.fn 87 | } 88 | 89 | func (a *StopViolationsReportCommandFn) Store(fn func(StopViolationsReportCommand)) { 90 | a.mux.Lock() 91 | defer a.mux.Unlock() 92 | a.fn = fn 93 | } 94 | 95 | type LogAgent struct { 96 | conn *shared.Connection 97 | commandHandlers struct { 98 | Enable EnableCommandFn 99 | Disable DisableCommandFn 100 | Clear ClearCommandFn 101 | StartViolationsReport StartViolationsReportCommandFn 102 | StopViolationsReport StopViolationsReportCommandFn 103 | } 104 | } 105 | func NewAgent(conn *shared.Connection) *LogAgent { 106 | agent := &LogAgent{ 107 | conn: conn, 108 | } 109 | conn.RegisterAgent(agent) 110 | return agent 111 | } 112 | 113 | func (agent *LogAgent) Name() string { 114 | return "Log" 115 | } 116 | 117 | func (agent *LogAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 118 | defer shared.TryRecoverFromPanic(agent.conn) 119 | switch (funcName) { 120 | case "enable": 121 | var out EnableCommand 122 | agent.conn.SetupCommand(id, targetId, data, &out) 123 | fn := agent.commandHandlers.Enable.Load() 124 | if fn == nil { 125 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 126 | break 127 | } 128 | fn(out) 129 | case "disable": 130 | var out DisableCommand 131 | agent.conn.SetupCommand(id, targetId, data, &out) 132 | fn := agent.commandHandlers.Disable.Load() 133 | if fn == nil { 134 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 135 | break 136 | } 137 | fn(out) 138 | case "clear": 139 | var out ClearCommand 140 | agent.conn.SetupCommand(id, targetId, data, &out) 141 | fn := agent.commandHandlers.Clear.Load() 142 | if fn == nil { 143 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 144 | break 145 | } 146 | fn(out) 147 | case "startViolationsReport": 148 | var out StartViolationsReportCommand 149 | agent.conn.SetupCommand(id, targetId, data, &out) 150 | fn := agent.commandHandlers.StartViolationsReport.Load() 151 | if fn == nil { 152 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 153 | break 154 | } 155 | fn(out) 156 | case "stopViolationsReport": 157 | var out StopViolationsReportCommand 158 | agent.conn.SetupCommand(id, targetId, data, &out) 159 | fn := agent.commandHandlers.StopViolationsReport.Load() 160 | if fn == nil { 161 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 162 | break 163 | } 164 | fn(out) 165 | default: 166 | fmt.Printf("Command %s unknown\n", funcName) 167 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 168 | } 169 | } 170 | 171 | // Dispatchable Events 172 | func (agent *LogAgent) FireEntryAdded(event EntryAddedEvent) { 173 | agent.conn.Send(shared.Notification{ 174 | Method: "Log.entryAdded", 175 | Params: event, 176 | }) 177 | } 178 | func (agent *LogAgent) FireEntryAddedOnTarget(targetId string,event EntryAddedEvent) { 179 | agent.conn.SendToTarget(targetId, shared.Notification{ 180 | Method: "Log.entryAdded", 181 | Params: event, 182 | }) 183 | } 184 | 185 | // Commands Sent From Frontend 186 | func (agent *LogAgent) SetEnableHandler(handler func(EnableCommand)) { 187 | agent.commandHandlers.Enable.Store(handler) 188 | } 189 | func (agent *LogAgent) SetDisableHandler(handler func(DisableCommand)) { 190 | agent.commandHandlers.Disable.Store(handler) 191 | } 192 | func (agent *LogAgent) SetClearHandler(handler func(ClearCommand)) { 193 | agent.commandHandlers.Clear.Store(handler) 194 | } 195 | func (agent *LogAgent) SetStartViolationsReportHandler(handler func(StartViolationsReportCommand)) { 196 | agent.commandHandlers.StartViolationsReport.Store(handler) 197 | } 198 | func (agent *LogAgent) SetStopViolationsReportHandler(handler func(StopViolationsReportCommand)) { 199 | agent.commandHandlers.StopViolationsReport.Store(handler) 200 | } 201 | func init() { 202 | 203 | } 204 | -------------------------------------------------------------------------------- /protocol/log/commands.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type ClearCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | } 57 | type ClearReturn struct { 58 | } 59 | 60 | func (c *ClearCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 61 | c.DestinationTargetID = targetId 62 | c.responseId = responseId 63 | c.conn = conn 64 | } 65 | 66 | func (c *ClearCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 67 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 68 | } 69 | 70 | func (c *ClearCommand) Respond() { 71 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 72 | } 73 | 74 | type StartViolationsReportCommand struct { 75 | DestinationTargetID string 76 | responseId int64 77 | conn *shared.Connection 78 | Config []ViolationSetting `json:"config"`// Configuration for violations. 79 | } 80 | type StartViolationsReportReturn struct { 81 | } 82 | 83 | func (c *StartViolationsReportCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 84 | c.DestinationTargetID = targetId 85 | c.responseId = responseId 86 | c.conn = conn 87 | } 88 | 89 | func (c *StartViolationsReportCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 90 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 91 | } 92 | 93 | func (c *StartViolationsReportCommand) Respond() { 94 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 95 | } 96 | 97 | type StopViolationsReportCommand struct { 98 | DestinationTargetID string 99 | responseId int64 100 | conn *shared.Connection 101 | } 102 | type StopViolationsReportReturn struct { 103 | } 104 | 105 | func (c *StopViolationsReportCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 106 | c.DestinationTargetID = targetId 107 | c.responseId = responseId 108 | c.conn = conn 109 | } 110 | 111 | func (c *StopViolationsReportCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 112 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 113 | } 114 | 115 | func (c *StopViolationsReportCommand) Respond() { 116 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 117 | } 118 | -------------------------------------------------------------------------------- /protocol/log/events.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | 4 | type EntryAddedEvent struct { 5 | Entry LogEntry `json:"entry"`// The entry. 6 | } -------------------------------------------------------------------------------- /protocol/log/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | "github.com/allada/gdd/protocol/network" 7 | ) 8 | type LogEntrySourceEnum string 9 | const ( 10 | LogEntrySourceXml LogEntrySourceEnum = "xml" 11 | LogEntrySourceJavascript LogEntrySourceEnum = "javascript" 12 | LogEntrySourceNetwork LogEntrySourceEnum = "network" 13 | LogEntrySourceStorage LogEntrySourceEnum = "storage" 14 | LogEntrySourceAppcache LogEntrySourceEnum = "appcache" 15 | LogEntrySourceRendering LogEntrySourceEnum = "rendering" 16 | LogEntrySourceSecurity LogEntrySourceEnum = "security" 17 | LogEntrySourceDeprecation LogEntrySourceEnum = "deprecation" 18 | LogEntrySourceWorker LogEntrySourceEnum = "worker" 19 | LogEntrySourceViolation LogEntrySourceEnum = "violation" 20 | LogEntrySourceIntervention LogEntrySourceEnum = "intervention" 21 | LogEntrySourceOther LogEntrySourceEnum = "other" 22 | ) 23 | 24 | type LogEntryLevelEnum string 25 | const ( 26 | LogEntryLevelVerbose LogEntryLevelEnum = "verbose" 27 | LogEntryLevelInfo LogEntryLevelEnum = "info" 28 | LogEntryLevelWarning LogEntryLevelEnum = "warning" 29 | LogEntryLevelError LogEntryLevelEnum = "error" 30 | ) 31 | 32 | type ViolationSettingNameEnum string 33 | const ( 34 | ViolationSettingNameLongTask ViolationSettingNameEnum = "longTask" 35 | ViolationSettingNameLongLayout ViolationSettingNameEnum = "longLayout" 36 | ViolationSettingNameBlockedEvent ViolationSettingNameEnum = "blockedEvent" 37 | ViolationSettingNameBlockedParser ViolationSettingNameEnum = "blockedParser" 38 | ViolationSettingNameDiscouragedAPIUse ViolationSettingNameEnum = "discouragedAPIUse" 39 | ViolationSettingNameHandler ViolationSettingNameEnum = "handler" 40 | ViolationSettingNameRecurringHandler ViolationSettingNameEnum = "recurringHandler" 41 | ) 42 | type LogEntry struct { 43 | Source LogEntrySourceEnum `json:"source"`// Log entry source. 44 | Level LogEntryLevelEnum `json:"level"`// Log entry severity. 45 | Text string `json:"text"`// Logged text. 46 | Timestamp runtime.Timestamp `json:"timestamp"`// Timestamp when this entry was added. 47 | Url *string `json:"url,omitempty"`// URL of the resource if known. 48 | LineNumber *int64 `json:"lineNumber,omitempty"`// Line number in the resource. 49 | StackTrace *runtime.StackTrace `json:"stackTrace,omitempty"`// JavaScript stack trace. 50 | NetworkRequestId *network.RequestId `json:"networkRequestId,omitempty"`// Identifier of the network request associated with this entry. 51 | WorkerId *string `json:"workerId,omitempty"`// Identifier of the worker associated with this entry. 52 | } 53 | 54 | type ViolationSetting struct { 55 | Name ViolationSettingNameEnum `json:"name"`// Violation type. 56 | Threshold float64 `json:"threshold"`// Time threshold to trigger upon. 57 | } 58 | -------------------------------------------------------------------------------- /protocol/memory/agent.go: -------------------------------------------------------------------------------- 1 | package memory 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type GetDOMCountersCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(GetDOMCountersCommand) 13 | } 14 | 15 | func (a *GetDOMCountersCommandFn) Load() func(GetDOMCountersCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *GetDOMCountersCommandFn) Store(fn func(GetDOMCountersCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type SetPressureNotificationsSuppressedCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(SetPressureNotificationsSuppressedCommand) 30 | } 31 | 32 | func (a *SetPressureNotificationsSuppressedCommandFn) Load() func(SetPressureNotificationsSuppressedCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *SetPressureNotificationsSuppressedCommandFn) Store(fn func(SetPressureNotificationsSuppressedCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type SimulatePressureNotificationCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(SimulatePressureNotificationCommand) 47 | } 48 | 49 | func (a *SimulatePressureNotificationCommandFn) Load() func(SimulatePressureNotificationCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *SimulatePressureNotificationCommandFn) Store(fn func(SimulatePressureNotificationCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type MemoryAgent struct { 62 | conn *shared.Connection 63 | commandHandlers struct { 64 | GetDOMCounters GetDOMCountersCommandFn 65 | SetPressureNotificationsSuppressed SetPressureNotificationsSuppressedCommandFn 66 | SimulatePressureNotification SimulatePressureNotificationCommandFn 67 | } 68 | } 69 | func NewAgent(conn *shared.Connection) *MemoryAgent { 70 | agent := &MemoryAgent{ 71 | conn: conn, 72 | } 73 | conn.RegisterAgent(agent) 74 | return agent 75 | } 76 | 77 | func (agent *MemoryAgent) Name() string { 78 | return "Memory" 79 | } 80 | 81 | func (agent *MemoryAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 82 | defer shared.TryRecoverFromPanic(agent.conn) 83 | switch (funcName) { 84 | case "getDOMCounters": 85 | var out GetDOMCountersCommand 86 | agent.conn.SetupCommand(id, targetId, data, &out) 87 | fn := agent.commandHandlers.GetDOMCounters.Load() 88 | if fn == nil { 89 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 90 | break 91 | } 92 | fn(out) 93 | case "setPressureNotificationsSuppressed": 94 | var out SetPressureNotificationsSuppressedCommand 95 | agent.conn.SetupCommand(id, targetId, data, &out) 96 | fn := agent.commandHandlers.SetPressureNotificationsSuppressed.Load() 97 | if fn == nil { 98 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 99 | break 100 | } 101 | fn(out) 102 | case "simulatePressureNotification": 103 | var out SimulatePressureNotificationCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.SimulatePressureNotification.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | default: 112 | fmt.Printf("Command %s unknown\n", funcName) 113 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 114 | } 115 | } 116 | 117 | // Dispatchable Events 118 | 119 | // Commands Sent From Frontend 120 | func (agent *MemoryAgent) SetGetDOMCountersHandler(handler func(GetDOMCountersCommand)) { 121 | agent.commandHandlers.GetDOMCounters.Store(handler) 122 | } 123 | func (agent *MemoryAgent) SetSetPressureNotificationsSuppressedHandler(handler func(SetPressureNotificationsSuppressedCommand)) { 124 | agent.commandHandlers.SetPressureNotificationsSuppressed.Store(handler) 125 | } 126 | func (agent *MemoryAgent) SetSimulatePressureNotificationHandler(handler func(SimulatePressureNotificationCommand)) { 127 | agent.commandHandlers.SimulatePressureNotification.Store(handler) 128 | } 129 | func init() { 130 | 131 | } 132 | -------------------------------------------------------------------------------- /protocol/memory/commands.go: -------------------------------------------------------------------------------- 1 | package memory 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type GetDOMCountersCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type GetDOMCountersReturn struct { 14 | Documents int64 `json:"documents"` 15 | Nodes int64 `json:"nodes"` 16 | JsEventListeners int64 `json:"jsEventListeners"` 17 | } 18 | 19 | func (c *GetDOMCountersCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 20 | c.DestinationTargetID = targetId 21 | c.responseId = responseId 22 | c.conn = conn 23 | } 24 | 25 | func (c *GetDOMCountersCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 26 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 27 | } 28 | 29 | func (c *GetDOMCountersCommand) Respond(r *GetDOMCountersReturn) { 30 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 31 | } 32 | 33 | type SetPressureNotificationsSuppressedCommand struct { 34 | DestinationTargetID string 35 | responseId int64 36 | conn *shared.Connection 37 | Suppressed bool `json:"suppressed"`// If true, memory pressure notifications will be suppressed. 38 | } 39 | type SetPressureNotificationsSuppressedReturn struct { 40 | } 41 | 42 | func (c *SetPressureNotificationsSuppressedCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 43 | c.DestinationTargetID = targetId 44 | c.responseId = responseId 45 | c.conn = conn 46 | } 47 | 48 | func (c *SetPressureNotificationsSuppressedCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 49 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 50 | } 51 | 52 | func (c *SetPressureNotificationsSuppressedCommand) Respond() { 53 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 54 | } 55 | 56 | type SimulatePressureNotificationCommand struct { 57 | DestinationTargetID string 58 | responseId int64 59 | conn *shared.Connection 60 | Level PressureLevel `json:"level"`// Memory pressure level of the notification. 61 | } 62 | type SimulatePressureNotificationReturn struct { 63 | } 64 | 65 | func (c *SimulatePressureNotificationCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 66 | c.DestinationTargetID = targetId 67 | c.responseId = responseId 68 | c.conn = conn 69 | } 70 | 71 | func (c *SimulatePressureNotificationCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 72 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 73 | } 74 | 75 | func (c *SimulatePressureNotificationCommand) Respond() { 76 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 77 | } 78 | -------------------------------------------------------------------------------- /protocol/memory/events.go: -------------------------------------------------------------------------------- 1 | package memory 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/memory/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package memory 2 | 3 | const ( 4 | PressureLevelModerate PressureLevel = "moderate" 5 | PressureLevelCritical PressureLevel = "critical" 6 | ) 7 | type PressureLevel string 8 | -------------------------------------------------------------------------------- /protocol/network/events.go: -------------------------------------------------------------------------------- 1 | package network 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/page" 6 | "github.com/allada/gdd/protocol/runtime" 7 | ) 8 | 9 | type ResourceChangedPriorityEvent struct { 10 | RequestId RequestId `json:"requestId"`// Request identifier. 11 | NewPriority ResourcePriority `json:"newPriority"`// New priority 12 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 13 | } 14 | type RequestWillBeSentEvent struct { 15 | RequestId RequestId `json:"requestId"`// Request identifier. 16 | FrameId page.FrameId `json:"frameId"`// [Experimental] Frame identifier. 17 | LoaderId LoaderId `json:"loaderId"`// Loader identifier. 18 | DocumentURL string `json:"documentURL"`// URL of the document this request is loaded for. 19 | Request Request `json:"request"`// Request data. 20 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 21 | WallTime Timestamp `json:"wallTime"`// [Experimental] UTC Timestamp. 22 | Initiator Initiator `json:"initiator"`// Request initiator. 23 | RedirectResponse *Response `json:"redirectResponse,omitempty"`// Redirect response data. 24 | Type *runtime.ResourceType `json:"type,omitempty"`// [Experimental] Type of this resource. 25 | } 26 | type RequestServedFromCacheEvent struct { 27 | RequestId RequestId `json:"requestId"`// Request identifier. 28 | } 29 | type ResponseReceivedEvent struct { 30 | RequestId RequestId `json:"requestId"`// Request identifier. 31 | FrameId page.FrameId `json:"frameId"`// [Experimental] Frame identifier. 32 | LoaderId LoaderId `json:"loaderId"`// Loader identifier. 33 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 34 | Type runtime.ResourceType `json:"type"`// Resource type. 35 | Response Response `json:"response"`// Response data. 36 | } 37 | type DataReceivedEvent struct { 38 | RequestId RequestId `json:"requestId"`// Request identifier. 39 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 40 | DataLength int64 `json:"dataLength"`// Data chunk length. 41 | EncodedDataLength int64 `json:"encodedDataLength"`// Actual bytes received (might be less than dataLength for compressed encodings). 42 | } 43 | type LoadingFinishedEvent struct { 44 | RequestId RequestId `json:"requestId"`// Request identifier. 45 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 46 | EncodedDataLength float64 `json:"encodedDataLength"`// Total number of bytes received for this request. 47 | } 48 | type LoadingFailedEvent struct { 49 | RequestId RequestId `json:"requestId"`// Request identifier. 50 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 51 | Type runtime.ResourceType `json:"type"`// Resource type. 52 | ErrorText string `json:"errorText"`// User friendly error message. 53 | Canceled *bool `json:"canceled,omitempty"`// True if loading was canceled. 54 | BlockedReason *BlockedReason `json:"blockedReason,omitempty"`// [Experimental] The reason why loading was blocked, if any. 55 | } 56 | type WebSocketWillSendHandshakeRequestEvent struct { 57 | RequestId RequestId `json:"requestId"`// Request identifier. 58 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 59 | WallTime Timestamp `json:"wallTime"`// [Experimental] UTC Timestamp. 60 | Request WebSocketRequest `json:"request"`// WebSocket request data. 61 | } 62 | type WebSocketHandshakeResponseReceivedEvent struct { 63 | RequestId RequestId `json:"requestId"`// Request identifier. 64 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 65 | Response WebSocketResponse `json:"response"`// WebSocket response data. 66 | } 67 | type WebSocketCreatedEvent struct { 68 | RequestId RequestId `json:"requestId"`// Request identifier. 69 | Url string `json:"url"`// WebSocket request URL. 70 | Initiator *Initiator `json:"initiator,omitempty"`// Request initiator. 71 | } 72 | type WebSocketClosedEvent struct { 73 | RequestId RequestId `json:"requestId"`// Request identifier. 74 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 75 | } 76 | type WebSocketFrameReceivedEvent struct { 77 | RequestId RequestId `json:"requestId"`// Request identifier. 78 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 79 | Response WebSocketFrame `json:"response"`// WebSocket response data. 80 | } 81 | type WebSocketFrameErrorEvent struct { 82 | RequestId RequestId `json:"requestId"`// Request identifier. 83 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 84 | ErrorMessage string `json:"errorMessage"`// WebSocket frame error message. 85 | } 86 | type WebSocketFrameSentEvent struct { 87 | RequestId RequestId `json:"requestId"`// Request identifier. 88 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 89 | Response WebSocketFrame `json:"response"`// WebSocket response data. 90 | } 91 | type EventSourceMessageReceivedEvent struct { 92 | RequestId RequestId `json:"requestId"`// Request identifier. 93 | Timestamp Timestamp `json:"timestamp"`// Timestamp. 94 | EventName string `json:"eventName"`// Message type. 95 | EventId string `json:"eventId"`// Message identifier. 96 | Data string `json:"data"`// Message content. 97 | } -------------------------------------------------------------------------------- /protocol/page/events.go: -------------------------------------------------------------------------------- 1 | package page 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/dom" 6 | ) 7 | 8 | type DomContentEventFiredEvent struct { 9 | Timestamp float64 `json:"timestamp"` 10 | } 11 | type LoadEventFiredEvent struct { 12 | Timestamp float64 `json:"timestamp"` 13 | } 14 | type FrameAttachedEvent struct { 15 | FrameId FrameId `json:"frameId"`// Id of the frame that has been attached. 16 | ParentFrameId FrameId `json:"parentFrameId"`// Parent frame identifier. 17 | } 18 | type FrameNavigatedEvent struct { 19 | Frame Frame `json:"frame"`// Frame object. 20 | } 21 | type FrameDetachedEvent struct { 22 | FrameId FrameId `json:"frameId"`// Id of the frame that has been detached. 23 | } 24 | type FrameStartedLoadingEvent struct { 25 | FrameId FrameId `json:"frameId"`// Id of the frame that has started loading. 26 | } 27 | type FrameStoppedLoadingEvent struct { 28 | FrameId FrameId `json:"frameId"`// Id of the frame that has stopped loading. 29 | } 30 | type FrameScheduledNavigationEvent struct { 31 | FrameId FrameId `json:"frameId"`// Id of the frame that has scheduled a navigation. 32 | Delay float64 `json:"delay"`// Delay (in seconds) until the navigation is scheduled to begin. The navigation is not guaranteed to start. 33 | } 34 | type FrameClearedScheduledNavigationEvent struct { 35 | FrameId FrameId `json:"frameId"`// Id of the frame that has cleared its scheduled navigation. 36 | } 37 | type FrameResizedEvent struct { 38 | } 39 | type JavascriptDialogOpeningEvent struct { 40 | Message string `json:"message"`// Message that will be displayed by the dialog. 41 | Type DialogType `json:"type"`// Dialog type. 42 | } 43 | type JavascriptDialogClosedEvent struct { 44 | Result bool `json:"result"`// Whether dialog was confirmed. 45 | } 46 | type ScreencastFrameEvent struct { 47 | Data string `json:"data"`// Base64-encoded compressed image. 48 | Metadata ScreencastFrameMetadata `json:"metadata"`// Screencast frame metadata. 49 | SessionId int64 `json:"sessionId"`// Frame number. 50 | } 51 | type ScreencastVisibilityChangedEvent struct { 52 | Visible bool `json:"visible"`// True if the page is visible. 53 | } 54 | type ColorPickedEvent struct { 55 | Color dom.RGBA `json:"color"`// RGBA of the picked color. 56 | } 57 | type InterstitialShownEvent struct { 58 | } 59 | type InterstitialHiddenEvent struct { 60 | } 61 | type NavigationRequestedEvent struct { 62 | IsInMainFrame bool `json:"isInMainFrame"`// Whether the navigation is taking place in the main frame or in a subframe. 63 | IsRedirect bool `json:"isRedirect"`// Whether the navigation has encountered a server redirect or not. 64 | NavigationId int64 `json:"navigationId"` 65 | Url string `json:"url"`// URL of requested navigation. 66 | } -------------------------------------------------------------------------------- /protocol/page/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package page 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | const ( 8 | DialogTypeAlert DialogType = "alert" 9 | DialogTypeConfirm DialogType = "confirm" 10 | DialogTypePrompt DialogType = "prompt" 11 | DialogTypeBeforeunload DialogType = "beforeunload" 12 | ) 13 | 14 | const ( 15 | NavigationResponseProceed NavigationResponse = "Proceed" 16 | NavigationResponseCancel NavigationResponse = "Cancel" 17 | NavigationResponseCancelAndIgnore NavigationResponse = "CancelAndIgnore" 18 | ) 19 | 20 | type SetTouchEmulationEnabledConfigurationEnum string 21 | const ( 22 | SetTouchEmulationEnabledConfigurationMobile SetTouchEmulationEnabledConfigurationEnum = "mobile" 23 | SetTouchEmulationEnabledConfigurationDesktop SetTouchEmulationEnabledConfigurationEnum = "desktop" 24 | ) 25 | 26 | type CaptureScreenshotFormatEnum string 27 | const ( 28 | CaptureScreenshotFormatJpeg CaptureScreenshotFormatEnum = "jpeg" 29 | CaptureScreenshotFormatPng CaptureScreenshotFormatEnum = "png" 30 | ) 31 | 32 | type StartScreencastFormatEnum string 33 | const ( 34 | StartScreencastFormatJpeg StartScreencastFormatEnum = "jpeg" 35 | StartScreencastFormatPng StartScreencastFormatEnum = "png" 36 | ) 37 | type FrameId string 38 | 39 | type Frame struct { 40 | Id string `json:"id"`// Frame unique identifier. 41 | ParentId *string `json:"parentId,omitempty"`// Parent frame identifier. 42 | LoaderId string `json:"loaderId"`// Identifier of the loader associated with this frame. 43 | Name *string `json:"name,omitempty"`// Frame's name as specified in the tag. 44 | Url string `json:"url"`// Frame document's URL. 45 | SecurityOrigin string `json:"securityOrigin"`// Frame document's security origin. 46 | MimeType string `json:"mimeType"`// Frame document's mimeType as determined by the browser. 47 | } 48 | 49 | type FrameResource struct { 50 | Url string `json:"url"`// Resource URL. 51 | Type runtime.ResourceType `json:"type"`// Type of this resource. 52 | MimeType string `json:"mimeType"`// Resource mimeType as determined by the browser. 53 | LastModified *float64 `json:"lastModified,omitempty"`// last-modified timestamp as reported by server. 54 | ContentSize *float64 `json:"contentSize,omitempty"`// Resource content size. 55 | Failed *bool `json:"failed,omitempty"`// True if the resource failed to load. 56 | Canceled *bool `json:"canceled,omitempty"`// True if the resource was canceled during loading. 57 | } 58 | 59 | type FrameResourceTree struct { 60 | Frame Frame `json:"frame"`// Frame information for this tree item. 61 | ChildFrames *[]FrameResourceTree `json:"childFrames,omitempty"`// Child frames. 62 | Resources []FrameResource `json:"resources"`// Information about frame resources. 63 | } 64 | 65 | type ScriptIdentifier string 66 | 67 | type NavigationEntry struct { 68 | Id int64 `json:"id"`// Unique id of the navigation history entry. 69 | Url string `json:"url"`// URL of the navigation history entry. 70 | Title string `json:"title"`// Title of the navigation history entry. 71 | } 72 | 73 | type ScreencastFrameMetadata struct { 74 | OffsetTop float64 `json:"offsetTop"`// [Experimental] Top offset in DIP. 75 | PageScaleFactor float64 `json:"pageScaleFactor"`// [Experimental] Page scale factor. 76 | DeviceWidth float64 `json:"deviceWidth"`// [Experimental] Device screen width in DIP. 77 | DeviceHeight float64 `json:"deviceHeight"`// [Experimental] Device screen height in DIP. 78 | ScrollOffsetX float64 `json:"scrollOffsetX"`// [Experimental] Position of horizontal scroll in CSS pixels. 79 | ScrollOffsetY float64 `json:"scrollOffsetY"`// [Experimental] Position of vertical scroll in CSS pixels. 80 | Timestamp *float64 `json:"timestamp,omitempty"`// [Experimental] Frame swap timestamp. 81 | } 82 | 83 | type DialogType string 84 | 85 | type AppManifestError struct { 86 | Message string `json:"message"`// Error message. 87 | Critical int64 `json:"critical"`// If criticial, this is a non-recoverable parse error. 88 | Line int64 `json:"line"`// Error line. 89 | Column int64 `json:"column"`// Error column. 90 | } 91 | 92 | type NavigationResponse string 93 | 94 | type LayoutViewport struct { 95 | PageX int64 `json:"pageX"`// Horizontal offset relative to the document (CSS pixels). 96 | PageY int64 `json:"pageY"`// Vertical offset relative to the document (CSS pixels). 97 | ClientWidth int64 `json:"clientWidth"`// Width (CSS pixels), excludes scrollbar if present. 98 | ClientHeight int64 `json:"clientHeight"`// Height (CSS pixels), excludes scrollbar if present. 99 | } 100 | 101 | type VisualViewport struct { 102 | OffsetX float64 `json:"offsetX"`// Horizontal offset relative to the layout viewport (CSS pixels). 103 | OffsetY float64 `json:"offsetY"`// Vertical offset relative to the layout viewport (CSS pixels). 104 | PageX float64 `json:"pageX"`// Horizontal offset relative to the document (CSS pixels). 105 | PageY float64 `json:"pageY"`// Vertical offset relative to the document (CSS pixels). 106 | ClientWidth float64 `json:"clientWidth"`// Width (CSS pixels), excludes scrollbar if present. 107 | ClientHeight float64 `json:"clientHeight"`// Height (CSS pixels), excludes scrollbar if present. 108 | Scale float64 `json:"scale"`// Scale relative to the ideal viewport (size at width=device-width). 109 | } 110 | -------------------------------------------------------------------------------- /protocol/profiler/commands.go: -------------------------------------------------------------------------------- 1 | package profiler 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type SetSamplingIntervalCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | Interval int64 `json:"interval"`// New sampling interval in microseconds. 57 | } 58 | type SetSamplingIntervalReturn struct { 59 | } 60 | 61 | func (c *SetSamplingIntervalCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 62 | c.DestinationTargetID = targetId 63 | c.responseId = responseId 64 | c.conn = conn 65 | } 66 | 67 | func (c *SetSamplingIntervalCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 68 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 69 | } 70 | 71 | func (c *SetSamplingIntervalCommand) Respond() { 72 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 73 | } 74 | 75 | type StartCommand struct { 76 | DestinationTargetID string 77 | responseId int64 78 | conn *shared.Connection 79 | } 80 | type StartReturn struct { 81 | } 82 | 83 | func (c *StartCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 84 | c.DestinationTargetID = targetId 85 | c.responseId = responseId 86 | c.conn = conn 87 | } 88 | 89 | func (c *StartCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 90 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 91 | } 92 | 93 | func (c *StartCommand) Respond() { 94 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 95 | } 96 | 97 | type StopCommand struct { 98 | DestinationTargetID string 99 | responseId int64 100 | conn *shared.Connection 101 | } 102 | type StopReturn struct { 103 | Profile Profile `json:"profile"`// Recorded profile. 104 | } 105 | 106 | func (c *StopCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 107 | c.DestinationTargetID = targetId 108 | c.responseId = responseId 109 | c.conn = conn 110 | } 111 | 112 | func (c *StopCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 113 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 114 | } 115 | 116 | func (c *StopCommand) Respond(r *StopReturn) { 117 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 118 | } 119 | 120 | type StartPreciseCoverageCommand struct { 121 | DestinationTargetID string 122 | responseId int64 123 | conn *shared.Connection 124 | } 125 | type StartPreciseCoverageReturn struct { 126 | } 127 | 128 | func (c *StartPreciseCoverageCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 129 | c.DestinationTargetID = targetId 130 | c.responseId = responseId 131 | c.conn = conn 132 | } 133 | 134 | func (c *StartPreciseCoverageCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 135 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 136 | } 137 | 138 | func (c *StartPreciseCoverageCommand) Respond() { 139 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 140 | } 141 | 142 | type StopPreciseCoverageCommand struct { 143 | DestinationTargetID string 144 | responseId int64 145 | conn *shared.Connection 146 | } 147 | type StopPreciseCoverageReturn struct { 148 | } 149 | 150 | func (c *StopPreciseCoverageCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 151 | c.DestinationTargetID = targetId 152 | c.responseId = responseId 153 | c.conn = conn 154 | } 155 | 156 | func (c *StopPreciseCoverageCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 157 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 158 | } 159 | 160 | func (c *StopPreciseCoverageCommand) Respond() { 161 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 162 | } 163 | 164 | type TakePreciseCoverageCommand struct { 165 | DestinationTargetID string 166 | responseId int64 167 | conn *shared.Connection 168 | } 169 | type TakePreciseCoverageReturn struct { 170 | Result []ScriptCoverage `json:"result"`// Coverage data for the current isolate. 171 | } 172 | 173 | func (c *TakePreciseCoverageCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 174 | c.DestinationTargetID = targetId 175 | c.responseId = responseId 176 | c.conn = conn 177 | } 178 | 179 | func (c *TakePreciseCoverageCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 180 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 181 | } 182 | 183 | func (c *TakePreciseCoverageCommand) Respond(r *TakePreciseCoverageReturn) { 184 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 185 | } 186 | 187 | type GetBestEffortCoverageCommand struct { 188 | DestinationTargetID string 189 | responseId int64 190 | conn *shared.Connection 191 | } 192 | type GetBestEffortCoverageReturn struct { 193 | Result []ScriptCoverage `json:"result"`// Coverage data for the current isolate. 194 | } 195 | 196 | func (c *GetBestEffortCoverageCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 197 | c.DestinationTargetID = targetId 198 | c.responseId = responseId 199 | c.conn = conn 200 | } 201 | 202 | func (c *GetBestEffortCoverageCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 203 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 204 | } 205 | 206 | func (c *GetBestEffortCoverageCommand) Respond(r *GetBestEffortCoverageReturn) { 207 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 208 | } 209 | -------------------------------------------------------------------------------- /protocol/profiler/events.go: -------------------------------------------------------------------------------- 1 | package profiler 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/debugger" 6 | ) 7 | 8 | type ConsoleProfileStartedEvent struct { 9 | Id string `json:"id"` 10 | Location debugger.Location `json:"location"`// Location of console.profile(). 11 | Title *string `json:"title,omitempty"`// Profile title passed as an argument to console.profile(). 12 | } 13 | type ConsoleProfileFinishedEvent struct { 14 | Id string `json:"id"` 15 | Location debugger.Location `json:"location"`// Location of console.profileEnd(). 16 | Profile Profile `json:"profile"` 17 | Title *string `json:"title,omitempty"`// Profile title passed as an argument to console.profile(). 18 | } -------------------------------------------------------------------------------- /protocol/profiler/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package profiler 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/runtime" 6 | ) 7 | type ProfileNode struct { 8 | Id int64 `json:"id"`// Unique id of the node. 9 | CallFrame runtime.CallFrame `json:"callFrame"`// Function location. 10 | HitCount *int64 `json:"hitCount,omitempty"`// [Experimental] Number of samples where this node was on top of the call stack. 11 | Children *[]int64 `json:"children,omitempty"`// Child node ids. 12 | DeoptReason *string `json:"deoptReason,omitempty"`// The reason of being not optimized. The function may be deoptimized or marked as don't optimize. 13 | PositionTicks *[]PositionTickInfo `json:"positionTicks,omitempty"`// [Experimental] An array of source position ticks. 14 | } 15 | 16 | type Profile struct { 17 | Nodes []ProfileNode `json:"nodes"`// The list of profile nodes. First item is the root node. 18 | StartTime float64 `json:"startTime"`// Profiling start timestamp in microseconds. 19 | EndTime float64 `json:"endTime"`// Profiling end timestamp in microseconds. 20 | Samples *[]int64 `json:"samples,omitempty"`// Ids of samples top nodes. 21 | TimeDeltas *[]int64 `json:"timeDeltas,omitempty"`// Time intervals between adjacent samples in microseconds. The first delta is relative to the profile startTime. 22 | } 23 | 24 | type PositionTickInfo struct { 25 | Line int64 `json:"line"`// Source line number (1-based). 26 | Ticks int64 `json:"ticks"`// Number of samples attributed to the source line. 27 | } 28 | 29 | type CoverageRange struct { 30 | StartLineNumber int64 `json:"startLineNumber"`// JavaScript script line number (0-based) for the range start. 31 | StartColumnNumber int64 `json:"startColumnNumber"`// JavaScript script column number (0-based) for the range start. 32 | EndLineNumber int64 `json:"endLineNumber"`// JavaScript script line number (0-based) for the range end. 33 | EndColumnNumber int64 `json:"endColumnNumber"`// JavaScript script column number (0-based) for the range end. 34 | Count int64 `json:"count"`// Collected execution count of the source range. 35 | } 36 | 37 | type FunctionCoverage struct { 38 | FunctionName string `json:"functionName"`// JavaScript function name. 39 | Ranges []CoverageRange `json:"ranges"`// Source ranges inside the function with coverage data. 40 | } 41 | 42 | type ScriptCoverage struct { 43 | ScriptId runtime.ScriptId `json:"scriptId"`// JavaScript script id. 44 | Url string `json:"url"`// JavaScript script name or url. 45 | Functions []FunctionCoverage `json:"functions"`// Functions contained in the script that has coverage data. 46 | } 47 | -------------------------------------------------------------------------------- /protocol/rendering/agent.go: -------------------------------------------------------------------------------- 1 | package rendering 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type SetShowPaintRectsCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(SetShowPaintRectsCommand) 13 | } 14 | 15 | func (a *SetShowPaintRectsCommandFn) Load() func(SetShowPaintRectsCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *SetShowPaintRectsCommandFn) Store(fn func(SetShowPaintRectsCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type SetShowDebugBordersCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(SetShowDebugBordersCommand) 30 | } 31 | 32 | func (a *SetShowDebugBordersCommandFn) Load() func(SetShowDebugBordersCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *SetShowDebugBordersCommandFn) Store(fn func(SetShowDebugBordersCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type SetShowFPSCounterCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(SetShowFPSCounterCommand) 47 | } 48 | 49 | func (a *SetShowFPSCounterCommandFn) Load() func(SetShowFPSCounterCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *SetShowFPSCounterCommandFn) Store(fn func(SetShowFPSCounterCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type SetShowScrollBottleneckRectsCommandFn struct { 62 | mux sync.RWMutex 63 | fn func(SetShowScrollBottleneckRectsCommand) 64 | } 65 | 66 | func (a *SetShowScrollBottleneckRectsCommandFn) Load() func(SetShowScrollBottleneckRectsCommand) { 67 | a.mux.RLock() 68 | defer a.mux.RUnlock() 69 | return a.fn 70 | } 71 | 72 | func (a *SetShowScrollBottleneckRectsCommandFn) Store(fn func(SetShowScrollBottleneckRectsCommand)) { 73 | a.mux.Lock() 74 | defer a.mux.Unlock() 75 | a.fn = fn 76 | } 77 | 78 | type SetShowViewportSizeOnResizeCommandFn struct { 79 | mux sync.RWMutex 80 | fn func(SetShowViewportSizeOnResizeCommand) 81 | } 82 | 83 | func (a *SetShowViewportSizeOnResizeCommandFn) Load() func(SetShowViewportSizeOnResizeCommand) { 84 | a.mux.RLock() 85 | defer a.mux.RUnlock() 86 | return a.fn 87 | } 88 | 89 | func (a *SetShowViewportSizeOnResizeCommandFn) Store(fn func(SetShowViewportSizeOnResizeCommand)) { 90 | a.mux.Lock() 91 | defer a.mux.Unlock() 92 | a.fn = fn 93 | } 94 | 95 | type RenderingAgent struct { 96 | conn *shared.Connection 97 | commandHandlers struct { 98 | SetShowPaintRects SetShowPaintRectsCommandFn 99 | SetShowDebugBorders SetShowDebugBordersCommandFn 100 | SetShowFPSCounter SetShowFPSCounterCommandFn 101 | SetShowScrollBottleneckRects SetShowScrollBottleneckRectsCommandFn 102 | SetShowViewportSizeOnResize SetShowViewportSizeOnResizeCommandFn 103 | } 104 | } 105 | func NewAgent(conn *shared.Connection) *RenderingAgent { 106 | agent := &RenderingAgent{ 107 | conn: conn, 108 | } 109 | conn.RegisterAgent(agent) 110 | return agent 111 | } 112 | 113 | func (agent *RenderingAgent) Name() string { 114 | return "Rendering" 115 | } 116 | 117 | func (agent *RenderingAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 118 | defer shared.TryRecoverFromPanic(agent.conn) 119 | switch (funcName) { 120 | case "setShowPaintRects": 121 | var out SetShowPaintRectsCommand 122 | agent.conn.SetupCommand(id, targetId, data, &out) 123 | fn := agent.commandHandlers.SetShowPaintRects.Load() 124 | if fn == nil { 125 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 126 | break 127 | } 128 | fn(out) 129 | case "setShowDebugBorders": 130 | var out SetShowDebugBordersCommand 131 | agent.conn.SetupCommand(id, targetId, data, &out) 132 | fn := agent.commandHandlers.SetShowDebugBorders.Load() 133 | if fn == nil { 134 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 135 | break 136 | } 137 | fn(out) 138 | case "setShowFPSCounter": 139 | var out SetShowFPSCounterCommand 140 | agent.conn.SetupCommand(id, targetId, data, &out) 141 | fn := agent.commandHandlers.SetShowFPSCounter.Load() 142 | if fn == nil { 143 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 144 | break 145 | } 146 | fn(out) 147 | case "setShowScrollBottleneckRects": 148 | var out SetShowScrollBottleneckRectsCommand 149 | agent.conn.SetupCommand(id, targetId, data, &out) 150 | fn := agent.commandHandlers.SetShowScrollBottleneckRects.Load() 151 | if fn == nil { 152 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 153 | break 154 | } 155 | fn(out) 156 | case "setShowViewportSizeOnResize": 157 | var out SetShowViewportSizeOnResizeCommand 158 | agent.conn.SetupCommand(id, targetId, data, &out) 159 | fn := agent.commandHandlers.SetShowViewportSizeOnResize.Load() 160 | if fn == nil { 161 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 162 | break 163 | } 164 | fn(out) 165 | default: 166 | fmt.Printf("Command %s unknown\n", funcName) 167 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 168 | } 169 | } 170 | 171 | // Dispatchable Events 172 | 173 | // Commands Sent From Frontend 174 | func (agent *RenderingAgent) SetSetShowPaintRectsHandler(handler func(SetShowPaintRectsCommand)) { 175 | agent.commandHandlers.SetShowPaintRects.Store(handler) 176 | } 177 | func (agent *RenderingAgent) SetSetShowDebugBordersHandler(handler func(SetShowDebugBordersCommand)) { 178 | agent.commandHandlers.SetShowDebugBorders.Store(handler) 179 | } 180 | func (agent *RenderingAgent) SetSetShowFPSCounterHandler(handler func(SetShowFPSCounterCommand)) { 181 | agent.commandHandlers.SetShowFPSCounter.Store(handler) 182 | } 183 | func (agent *RenderingAgent) SetSetShowScrollBottleneckRectsHandler(handler func(SetShowScrollBottleneckRectsCommand)) { 184 | agent.commandHandlers.SetShowScrollBottleneckRects.Store(handler) 185 | } 186 | func (agent *RenderingAgent) SetSetShowViewportSizeOnResizeHandler(handler func(SetShowViewportSizeOnResizeCommand)) { 187 | agent.commandHandlers.SetShowViewportSizeOnResize.Store(handler) 188 | } 189 | func init() { 190 | 191 | } 192 | -------------------------------------------------------------------------------- /protocol/rendering/commands.go: -------------------------------------------------------------------------------- 1 | package rendering 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type SetShowPaintRectsCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Result bool `json:"result"`// True for showing paint rectangles 13 | } 14 | type SetShowPaintRectsReturn struct { 15 | } 16 | 17 | func (c *SetShowPaintRectsCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 18 | c.DestinationTargetID = targetId 19 | c.responseId = responseId 20 | c.conn = conn 21 | } 22 | 23 | func (c *SetShowPaintRectsCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 24 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 25 | } 26 | 27 | func (c *SetShowPaintRectsCommand) Respond() { 28 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 29 | } 30 | 31 | type SetShowDebugBordersCommand struct { 32 | DestinationTargetID string 33 | responseId int64 34 | conn *shared.Connection 35 | Show bool `json:"show"`// True for showing debug borders 36 | } 37 | type SetShowDebugBordersReturn struct { 38 | } 39 | 40 | func (c *SetShowDebugBordersCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 41 | c.DestinationTargetID = targetId 42 | c.responseId = responseId 43 | c.conn = conn 44 | } 45 | 46 | func (c *SetShowDebugBordersCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 47 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 48 | } 49 | 50 | func (c *SetShowDebugBordersCommand) Respond() { 51 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 52 | } 53 | 54 | type SetShowFPSCounterCommand struct { 55 | DestinationTargetID string 56 | responseId int64 57 | conn *shared.Connection 58 | Show bool `json:"show"`// True for showing the FPS counter 59 | } 60 | type SetShowFPSCounterReturn struct { 61 | } 62 | 63 | func (c *SetShowFPSCounterCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 64 | c.DestinationTargetID = targetId 65 | c.responseId = responseId 66 | c.conn = conn 67 | } 68 | 69 | func (c *SetShowFPSCounterCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 70 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 71 | } 72 | 73 | func (c *SetShowFPSCounterCommand) Respond() { 74 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 75 | } 76 | 77 | type SetShowScrollBottleneckRectsCommand struct { 78 | DestinationTargetID string 79 | responseId int64 80 | conn *shared.Connection 81 | Show bool `json:"show"`// True for showing scroll bottleneck rects 82 | } 83 | type SetShowScrollBottleneckRectsReturn struct { 84 | } 85 | 86 | func (c *SetShowScrollBottleneckRectsCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 87 | c.DestinationTargetID = targetId 88 | c.responseId = responseId 89 | c.conn = conn 90 | } 91 | 92 | func (c *SetShowScrollBottleneckRectsCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 93 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 94 | } 95 | 96 | func (c *SetShowScrollBottleneckRectsCommand) Respond() { 97 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 98 | } 99 | 100 | type SetShowViewportSizeOnResizeCommand struct { 101 | DestinationTargetID string 102 | responseId int64 103 | conn *shared.Connection 104 | Show bool `json:"show"`// Whether to paint size or not. 105 | } 106 | type SetShowViewportSizeOnResizeReturn struct { 107 | } 108 | 109 | func (c *SetShowViewportSizeOnResizeCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 110 | c.DestinationTargetID = targetId 111 | c.responseId = responseId 112 | c.conn = conn 113 | } 114 | 115 | func (c *SetShowViewportSizeOnResizeCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 116 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 117 | } 118 | 119 | func (c *SetShowViewportSizeOnResizeCommand) Respond() { 120 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 121 | } 122 | -------------------------------------------------------------------------------- /protocol/rendering/events.go: -------------------------------------------------------------------------------- 1 | package rendering 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/rendering/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package rendering 2 | 3 | -------------------------------------------------------------------------------- /protocol/runtime/events.go: -------------------------------------------------------------------------------- 1 | package runtime 2 | 3 | 4 | type ExecutionContextCreatedEvent struct { 5 | Context ExecutionContextDescription `json:"context"`// A newly created execution contex. 6 | } 7 | type ExecutionContextDestroyedEvent struct { 8 | ExecutionContextId ExecutionContextId `json:"executionContextId"`// Id of the destroyed context 9 | } 10 | type ExecutionContextsClearedEvent struct { 11 | } 12 | type ExceptionThrownEvent struct { 13 | Timestamp Timestamp `json:"timestamp"`// Timestamp of the exception. 14 | ExceptionDetails ExceptionDetails `json:"exceptionDetails"` 15 | } 16 | type ExceptionRevokedEvent struct { 17 | Reason string `json:"reason"`// Reason describing why exception was revoked. 18 | ExceptionId int64 `json:"exceptionId"`// The id of revoked exception, as reported in exceptionUnhandled. 19 | } 20 | type ConsoleAPICalledEvent struct { 21 | Type ConsoleAPICalledTypeEnum `json:"type"`// Type of the call. 22 | Args []RemoteObject `json:"args"`// Call arguments. 23 | ExecutionContextId ExecutionContextId `json:"executionContextId"`// Identifier of the context where the call was made. 24 | Timestamp Timestamp `json:"timestamp"`// Call timestamp. 25 | StackTrace *StackTrace `json:"stackTrace,omitempty"`// Stack trace captured when the call was made. 26 | } 27 | type InspectRequestedEvent struct { 28 | Object RemoteObject `json:"object"` 29 | Hints map[string]string `json:"hints"` 30 | } -------------------------------------------------------------------------------- /protocol/schema/agent.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type GetDomainsCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(GetDomainsCommand) 13 | } 14 | 15 | func (a *GetDomainsCommandFn) Load() func(GetDomainsCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *GetDomainsCommandFn) Store(fn func(GetDomainsCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type SchemaAgent struct { 28 | conn *shared.Connection 29 | commandHandlers struct { 30 | GetDomains GetDomainsCommandFn 31 | } 32 | } 33 | func NewAgent(conn *shared.Connection) *SchemaAgent { 34 | agent := &SchemaAgent{ 35 | conn: conn, 36 | } 37 | conn.RegisterAgent(agent) 38 | return agent 39 | } 40 | 41 | func (agent *SchemaAgent) Name() string { 42 | return "Schema" 43 | } 44 | 45 | func (agent *SchemaAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 46 | defer shared.TryRecoverFromPanic(agent.conn) 47 | switch (funcName) { 48 | case "getDomains": 49 | var out GetDomainsCommand 50 | agent.conn.SetupCommand(id, targetId, data, &out) 51 | fn := agent.commandHandlers.GetDomains.Load() 52 | if fn == nil { 53 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 54 | break 55 | } 56 | fn(out) 57 | default: 58 | fmt.Printf("Command %s unknown\n", funcName) 59 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 60 | } 61 | } 62 | 63 | // Dispatchable Events 64 | 65 | // Commands Sent From Frontend 66 | func (agent *SchemaAgent) SetGetDomainsHandler(handler func(GetDomainsCommand)) { 67 | agent.commandHandlers.GetDomains.Store(handler) 68 | } 69 | func init() { 70 | 71 | } 72 | -------------------------------------------------------------------------------- /protocol/schema/commands.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type GetDomainsCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type GetDomainsReturn struct { 14 | Domains []Domain `json:"domains"`// List of supported domains. 15 | } 16 | 17 | func (c *GetDomainsCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 18 | c.DestinationTargetID = targetId 19 | c.responseId = responseId 20 | c.conn = conn 21 | } 22 | 23 | func (c *GetDomainsCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 24 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 25 | } 26 | 27 | func (c *GetDomainsCommand) Respond(r *GetDomainsReturn) { 28 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 29 | } 30 | -------------------------------------------------------------------------------- /protocol/schema/events.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/schema/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package schema 2 | 3 | type Domain struct { 4 | Name string `json:"name"`// Domain name. 5 | Version string `json:"version"`// Domain version. 6 | } 7 | -------------------------------------------------------------------------------- /protocol/security/agent.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type EnableCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(EnableCommand) 13 | } 14 | 15 | func (a *EnableCommandFn) Load() func(EnableCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *EnableCommandFn) Store(fn func(EnableCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type DisableCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(DisableCommand) 30 | } 31 | 32 | func (a *DisableCommandFn) Load() func(DisableCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *DisableCommandFn) Store(fn func(DisableCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type ShowCertificateViewerCommandFn struct { 45 | mux sync.RWMutex 46 | fn func(ShowCertificateViewerCommand) 47 | } 48 | 49 | func (a *ShowCertificateViewerCommandFn) Load() func(ShowCertificateViewerCommand) { 50 | a.mux.RLock() 51 | defer a.mux.RUnlock() 52 | return a.fn 53 | } 54 | 55 | func (a *ShowCertificateViewerCommandFn) Store(fn func(ShowCertificateViewerCommand)) { 56 | a.mux.Lock() 57 | defer a.mux.Unlock() 58 | a.fn = fn 59 | } 60 | 61 | type SecurityAgent struct { 62 | conn *shared.Connection 63 | commandHandlers struct { 64 | Enable EnableCommandFn 65 | Disable DisableCommandFn 66 | ShowCertificateViewer ShowCertificateViewerCommandFn 67 | } 68 | } 69 | func NewAgent(conn *shared.Connection) *SecurityAgent { 70 | agent := &SecurityAgent{ 71 | conn: conn, 72 | } 73 | conn.RegisterAgent(agent) 74 | return agent 75 | } 76 | 77 | func (agent *SecurityAgent) Name() string { 78 | return "Security" 79 | } 80 | 81 | func (agent *SecurityAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 82 | defer shared.TryRecoverFromPanic(agent.conn) 83 | switch (funcName) { 84 | case "enable": 85 | var out EnableCommand 86 | agent.conn.SetupCommand(id, targetId, data, &out) 87 | fn := agent.commandHandlers.Enable.Load() 88 | if fn == nil { 89 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 90 | break 91 | } 92 | fn(out) 93 | case "disable": 94 | var out DisableCommand 95 | agent.conn.SetupCommand(id, targetId, data, &out) 96 | fn := agent.commandHandlers.Disable.Load() 97 | if fn == nil { 98 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 99 | break 100 | } 101 | fn(out) 102 | case "showCertificateViewer": 103 | var out ShowCertificateViewerCommand 104 | agent.conn.SetupCommand(id, targetId, data, &out) 105 | fn := agent.commandHandlers.ShowCertificateViewer.Load() 106 | if fn == nil { 107 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 108 | break 109 | } 110 | fn(out) 111 | default: 112 | fmt.Printf("Command %s unknown\n", funcName) 113 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 114 | } 115 | } 116 | 117 | // Dispatchable Events 118 | func (agent *SecurityAgent) FireSecurityStateChanged(event SecurityStateChangedEvent) { 119 | agent.conn.Send(shared.Notification{ 120 | Method: "Security.securityStateChanged", 121 | Params: event, 122 | }) 123 | } 124 | func (agent *SecurityAgent) FireSecurityStateChangedOnTarget(targetId string,event SecurityStateChangedEvent) { 125 | agent.conn.SendToTarget(targetId, shared.Notification{ 126 | Method: "Security.securityStateChanged", 127 | Params: event, 128 | }) 129 | } 130 | 131 | // Commands Sent From Frontend 132 | func (agent *SecurityAgent) SetEnableHandler(handler func(EnableCommand)) { 133 | agent.commandHandlers.Enable.Store(handler) 134 | } 135 | func (agent *SecurityAgent) SetDisableHandler(handler func(DisableCommand)) { 136 | agent.commandHandlers.Disable.Store(handler) 137 | } 138 | func (agent *SecurityAgent) SetShowCertificateViewerHandler(handler func(ShowCertificateViewerCommand)) { 139 | agent.commandHandlers.ShowCertificateViewer.Store(handler) 140 | } 141 | func init() { 142 | 143 | } 144 | -------------------------------------------------------------------------------- /protocol/security/commands.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type EnableCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type EnableReturn struct { 14 | } 15 | 16 | func (c *EnableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 17 | c.DestinationTargetID = targetId 18 | c.responseId = responseId 19 | c.conn = conn 20 | } 21 | 22 | func (c *EnableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 23 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 24 | } 25 | 26 | func (c *EnableCommand) Respond() { 27 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 28 | } 29 | 30 | type DisableCommand struct { 31 | DestinationTargetID string 32 | responseId int64 33 | conn *shared.Connection 34 | } 35 | type DisableReturn struct { 36 | } 37 | 38 | func (c *DisableCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 39 | c.DestinationTargetID = targetId 40 | c.responseId = responseId 41 | c.conn = conn 42 | } 43 | 44 | func (c *DisableCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 45 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 46 | } 47 | 48 | func (c *DisableCommand) Respond() { 49 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 50 | } 51 | 52 | type ShowCertificateViewerCommand struct { 53 | DestinationTargetID string 54 | responseId int64 55 | conn *shared.Connection 56 | } 57 | type ShowCertificateViewerReturn struct { 58 | } 59 | 60 | func (c *ShowCertificateViewerCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 61 | c.DestinationTargetID = targetId 62 | c.responseId = responseId 63 | c.conn = conn 64 | } 65 | 66 | func (c *ShowCertificateViewerCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 67 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 68 | } 69 | 70 | func (c *ShowCertificateViewerCommand) Respond() { 71 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 72 | } 73 | -------------------------------------------------------------------------------- /protocol/security/events.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | 4 | type SecurityStateChangedEvent struct { 5 | SecurityState SecurityState `json:"securityState"`// Security state. 6 | SchemeIsCryptographic bool `json:"schemeIsCryptographic"`// True if the page was loaded over cryptographic transport such as HTTPS. 7 | Explanations []SecurityStateExplanation `json:"explanations"`// List of explanations for the security state. If the overall security state is `insecure` or `warning`, at least one corresponding explanation should be included. 8 | InsecureContentStatus InsecureContentStatus `json:"insecureContentStatus"`// Information about insecure content on the page. 9 | Summary *string `json:"summary,omitempty"`// Overrides user-visible description of the state. 10 | } -------------------------------------------------------------------------------- /protocol/security/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package security 2 | 3 | const ( 4 | SecurityStateUnknown SecurityState = "unknown" 5 | SecurityStateNeutral SecurityState = "neutral" 6 | SecurityStateInsecure SecurityState = "insecure" 7 | SecurityStateWarning SecurityState = "warning" 8 | SecurityStateSecure SecurityState = "secure" 9 | SecurityStateInfo SecurityState = "info" 10 | ) 11 | type CertificateId int64 12 | 13 | type SecurityState string 14 | 15 | type SecurityStateExplanation struct { 16 | SecurityState SecurityState `json:"securityState"`// Security state representing the severity of the factor being explained. 17 | Summary string `json:"summary"`// Short phrase describing the type of factor. 18 | Description string `json:"description"`// Full text explanation of the factor. 19 | HasCertificate bool `json:"hasCertificate"`// True if the page has a certificate. 20 | } 21 | 22 | type InsecureContentStatus struct { 23 | RanMixedContent bool `json:"ranMixedContent"`// True if the page was loaded over HTTPS and ran mixed (HTTP) content such as scripts. 24 | DisplayedMixedContent bool `json:"displayedMixedContent"`// True if the page was loaded over HTTPS and displayed mixed (HTTP) content such as images. 25 | RanContentWithCertErrors bool `json:"ranContentWithCertErrors"`// True if the page was loaded over HTTPS without certificate errors, and ran content such as scripts that were loaded with certificate errors. 26 | DisplayedContentWithCertErrors bool `json:"displayedContentWithCertErrors"`// True if the page was loaded over HTTPS without certificate errors, and displayed content such as images that were loaded with certificate errors. 27 | RanInsecureContentStyle SecurityState `json:"ranInsecureContentStyle"`// Security state representing a page that ran insecure content. 28 | DisplayedInsecureContentStyle SecurityState `json:"displayedInsecureContentStyle"`// Security state representing a page that displayed insecure content. 29 | } 30 | -------------------------------------------------------------------------------- /protocol/serviceworker/events.go: -------------------------------------------------------------------------------- 1 | package serviceworker 2 | 3 | 4 | type WorkerRegistrationUpdatedEvent struct { 5 | Registrations []ServiceWorkerRegistration `json:"registrations"` 6 | } 7 | type WorkerVersionUpdatedEvent struct { 8 | Versions []ServiceWorkerVersion `json:"versions"` 9 | } 10 | type WorkerErrorReportedEvent struct { 11 | ErrorMessage ServiceWorkerErrorMessage `json:"errorMessage"` 12 | } -------------------------------------------------------------------------------- /protocol/serviceworker/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package serviceworker 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/target" 6 | ) 7 | const ( 8 | ServiceWorkerVersionRunningStatusStopped ServiceWorkerVersionRunningStatus = "stopped" 9 | ServiceWorkerVersionRunningStatusStarting ServiceWorkerVersionRunningStatus = "starting" 10 | ServiceWorkerVersionRunningStatusRunning ServiceWorkerVersionRunningStatus = "running" 11 | ServiceWorkerVersionRunningStatusStopping ServiceWorkerVersionRunningStatus = "stopping" 12 | ) 13 | 14 | const ( 15 | ServiceWorkerVersionStatusNew ServiceWorkerVersionStatus = "new" 16 | ServiceWorkerVersionStatusInstalling ServiceWorkerVersionStatus = "installing" 17 | ServiceWorkerVersionStatusInstalled ServiceWorkerVersionStatus = "installed" 18 | ServiceWorkerVersionStatusActivating ServiceWorkerVersionStatus = "activating" 19 | ServiceWorkerVersionStatusActivated ServiceWorkerVersionStatus = "activated" 20 | ServiceWorkerVersionStatusRedundant ServiceWorkerVersionStatus = "redundant" 21 | ) 22 | type ServiceWorkerRegistration struct { 23 | RegistrationId string `json:"registrationId"` 24 | ScopeURL string `json:"scopeURL"` 25 | IsDeleted bool `json:"isDeleted"` 26 | } 27 | 28 | type ServiceWorkerVersionRunningStatus string 29 | 30 | type ServiceWorkerVersionStatus string 31 | 32 | type ServiceWorkerVersion struct { 33 | VersionId string `json:"versionId"` 34 | RegistrationId string `json:"registrationId"` 35 | ScriptURL string `json:"scriptURL"` 36 | RunningStatus ServiceWorkerVersionRunningStatus `json:"runningStatus"` 37 | Status ServiceWorkerVersionStatus `json:"status"` 38 | ScriptLastModified *float64 `json:"scriptLastModified,omitempty"`// The Last-Modified header value of the main script. 39 | ScriptResponseTime *float64 `json:"scriptResponseTime,omitempty"`// The time at which the response headers of the main script were received from the server. For cached script it is the last time the cache entry was validated. 40 | ControlledClients *[]target.TargetID `json:"controlledClients,omitempty"` 41 | TargetId *target.TargetID `json:"targetId,omitempty"` 42 | } 43 | 44 | type ServiceWorkerErrorMessage struct { 45 | ErrorMessage string `json:"errorMessage"` 46 | RegistrationId string `json:"registrationId"` 47 | VersionId string `json:"versionId"` 48 | SourceURL string `json:"sourceURL"` 49 | LineNumber int64 `json:"lineNumber"` 50 | ColumnNumber int64 `json:"columnNumber"` 51 | } 52 | -------------------------------------------------------------------------------- /protocol/storage/agent.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type ClearDataForOriginCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(ClearDataForOriginCommand) 13 | } 14 | 15 | func (a *ClearDataForOriginCommandFn) Load() func(ClearDataForOriginCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *ClearDataForOriginCommandFn) Store(fn func(ClearDataForOriginCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type StorageAgent struct { 28 | conn *shared.Connection 29 | commandHandlers struct { 30 | ClearDataForOrigin ClearDataForOriginCommandFn 31 | } 32 | } 33 | func NewAgent(conn *shared.Connection) *StorageAgent { 34 | agent := &StorageAgent{ 35 | conn: conn, 36 | } 37 | conn.RegisterAgent(agent) 38 | return agent 39 | } 40 | 41 | func (agent *StorageAgent) Name() string { 42 | return "Storage" 43 | } 44 | 45 | func (agent *StorageAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 46 | defer shared.TryRecoverFromPanic(agent.conn) 47 | switch (funcName) { 48 | case "clearDataForOrigin": 49 | var out ClearDataForOriginCommand 50 | agent.conn.SetupCommand(id, targetId, data, &out) 51 | fn := agent.commandHandlers.ClearDataForOrigin.Load() 52 | if fn == nil { 53 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 54 | break 55 | } 56 | fn(out) 57 | default: 58 | fmt.Printf("Command %s unknown\n", funcName) 59 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 60 | } 61 | } 62 | 63 | // Dispatchable Events 64 | 65 | // Commands Sent From Frontend 66 | func (agent *StorageAgent) SetClearDataForOriginHandler(handler func(ClearDataForOriginCommand)) { 67 | agent.commandHandlers.ClearDataForOrigin.Store(handler) 68 | } 69 | func init() { 70 | 71 | } 72 | -------------------------------------------------------------------------------- /protocol/storage/commands.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type ClearDataForOriginCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Origin string `json:"origin"`// Security origin. 13 | StorageTypes string `json:"storageTypes"`// Comma separated origin names. 14 | } 15 | type ClearDataForOriginReturn struct { 16 | } 17 | 18 | func (c *ClearDataForOriginCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 19 | c.DestinationTargetID = targetId 20 | c.responseId = responseId 21 | c.conn = conn 22 | } 23 | 24 | func (c *ClearDataForOriginCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 25 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 26 | } 27 | 28 | func (c *ClearDataForOriginCommand) Respond() { 29 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 30 | } 31 | -------------------------------------------------------------------------------- /protocol/storage/events.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/storage/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package storage 2 | 3 | const ( 4 | StorageTypeAppcache StorageType = "appcache" 5 | StorageTypeCookies StorageType = "cookies" 6 | StorageTypeFile_systems StorageType = "file_systems" 7 | StorageTypeIndexeddb StorageType = "indexeddb" 8 | StorageTypeLocal_storage StorageType = "local_storage" 9 | StorageTypeShader_cache StorageType = "shader_cache" 10 | StorageTypeWebsql StorageType = "websql" 11 | StorageTypeService_workers StorageType = "service_workers" 12 | StorageTypeCache_storage StorageType = "cache_storage" 13 | StorageTypeAll StorageType = "all" 14 | ) 15 | type StorageType string 16 | -------------------------------------------------------------------------------- /protocol/systeminfo/agent.go: -------------------------------------------------------------------------------- 1 | package systeminfo 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type GetInfoCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(GetInfoCommand) 13 | } 14 | 15 | func (a *GetInfoCommandFn) Load() func(GetInfoCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *GetInfoCommandFn) Store(fn func(GetInfoCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type SystemInfoAgent struct { 28 | conn *shared.Connection 29 | commandHandlers struct { 30 | GetInfo GetInfoCommandFn 31 | } 32 | } 33 | func NewAgent(conn *shared.Connection) *SystemInfoAgent { 34 | agent := &SystemInfoAgent{ 35 | conn: conn, 36 | } 37 | conn.RegisterAgent(agent) 38 | return agent 39 | } 40 | 41 | func (agent *SystemInfoAgent) Name() string { 42 | return "SystemInfo" 43 | } 44 | 45 | func (agent *SystemInfoAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 46 | defer shared.TryRecoverFromPanic(agent.conn) 47 | switch (funcName) { 48 | case "getInfo": 49 | var out GetInfoCommand 50 | agent.conn.SetupCommand(id, targetId, data, &out) 51 | fn := agent.commandHandlers.GetInfo.Load() 52 | if fn == nil { 53 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 54 | break 55 | } 56 | fn(out) 57 | default: 58 | fmt.Printf("Command %s unknown\n", funcName) 59 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 60 | } 61 | } 62 | 63 | // Dispatchable Events 64 | 65 | // Commands Sent From Frontend 66 | func (agent *SystemInfoAgent) SetGetInfoHandler(handler func(GetInfoCommand)) { 67 | agent.commandHandlers.GetInfo.Store(handler) 68 | } 69 | func init() { 70 | 71 | } 72 | -------------------------------------------------------------------------------- /protocol/systeminfo/commands.go: -------------------------------------------------------------------------------- 1 | package systeminfo 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type GetInfoCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | } 13 | type GetInfoReturn struct { 14 | Gpu GPUInfo `json:"gpu"`// Information about the GPUs on the system. 15 | ModelName string `json:"modelName"`// A platform-dependent description of the model of the machine. On Mac OS, this is, for example, 'MacBookPro'. Will be the empty string if not supported. 16 | ModelVersion string `json:"modelVersion"`// A platform-dependent description of the version of the machine. On Mac OS, this is, for example, '10.1'. Will be the empty string if not supported. 17 | } 18 | 19 | func (c *GetInfoCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 20 | c.DestinationTargetID = targetId 21 | c.responseId = responseId 22 | c.conn = conn 23 | } 24 | 25 | func (c *GetInfoCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 26 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 27 | } 28 | 29 | func (c *GetInfoCommand) Respond(r *GetInfoReturn) { 30 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 31 | } 32 | -------------------------------------------------------------------------------- /protocol/systeminfo/events.go: -------------------------------------------------------------------------------- 1 | package systeminfo 2 | 3 | 4 | -------------------------------------------------------------------------------- /protocol/systeminfo/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package systeminfo 2 | 3 | type GPUDevice struct { 4 | VendorId float64 `json:"vendorId"`// PCI ID of the GPU vendor, if available; 0 otherwise. 5 | DeviceId float64 `json:"deviceId"`// PCI ID of the GPU device, if available; 0 otherwise. 6 | VendorString string `json:"vendorString"`// String description of the GPU vendor, if the PCI ID is not available. 7 | DeviceString string `json:"deviceString"`// String description of the GPU device, if the PCI ID is not available. 8 | } 9 | 10 | type GPUInfo struct { 11 | Devices []GPUDevice `json:"devices"`// The graphics devices on the system. Element 0 is the primary GPU. 12 | AuxAttributes *map[string]string `json:"auxAttributes,omitempty"`// An optional dictionary of additional GPU related attributes. 13 | FeatureStatus *map[string]string `json:"featureStatus,omitempty"`// An optional dictionary of graphics features and their status. 14 | DriverBugWorkarounds []string `json:"driverBugWorkarounds"`// An optional array of GPU driver bug workarounds. 15 | } 16 | -------------------------------------------------------------------------------- /protocol/target/events.go: -------------------------------------------------------------------------------- 1 | package target 2 | 3 | 4 | type TargetCreatedEvent struct { 5 | TargetInfo TargetInfo `json:"targetInfo"` 6 | } 7 | type TargetDestroyedEvent struct { 8 | TargetId TargetID `json:"targetId"` 9 | } 10 | type AttachedToTargetEvent struct { 11 | TargetInfo TargetInfo `json:"targetInfo"` 12 | WaitingForDebugger bool `json:"waitingForDebugger"` 13 | } 14 | type DetachedFromTargetEvent struct { 15 | TargetId TargetID `json:"targetId"` 16 | } 17 | type ReceivedMessageFromTargetEvent struct { 18 | TargetId TargetID `json:"targetId"` 19 | Message string `json:"message"` 20 | } -------------------------------------------------------------------------------- /protocol/target/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package target 2 | 3 | type TargetID string 4 | 5 | type BrowserContextID string 6 | 7 | type TargetInfo struct { 8 | TargetId TargetID `json:"targetId"` 9 | Type string `json:"type"` 10 | Title string `json:"title"` 11 | Url string `json:"url"` 12 | } 13 | 14 | type RemoteLocation struct { 15 | Host string `json:"host"` 16 | Port int64 `json:"port"` 17 | } 18 | -------------------------------------------------------------------------------- /protocol/tethering/agent.go: -------------------------------------------------------------------------------- 1 | package tethering 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | "sync" 7 | "encoding/json" 8 | "fmt" 9 | ) 10 | type BindCommandFn struct { 11 | mux sync.RWMutex 12 | fn func(BindCommand) 13 | } 14 | 15 | func (a *BindCommandFn) Load() func(BindCommand) { 16 | a.mux.RLock() 17 | defer a.mux.RUnlock() 18 | return a.fn 19 | } 20 | 21 | func (a *BindCommandFn) Store(fn func(BindCommand)) { 22 | a.mux.Lock() 23 | defer a.mux.Unlock() 24 | a.fn = fn 25 | } 26 | 27 | type UnbindCommandFn struct { 28 | mux sync.RWMutex 29 | fn func(UnbindCommand) 30 | } 31 | 32 | func (a *UnbindCommandFn) Load() func(UnbindCommand) { 33 | a.mux.RLock() 34 | defer a.mux.RUnlock() 35 | return a.fn 36 | } 37 | 38 | func (a *UnbindCommandFn) Store(fn func(UnbindCommand)) { 39 | a.mux.Lock() 40 | defer a.mux.Unlock() 41 | a.fn = fn 42 | } 43 | 44 | type TetheringAgent struct { 45 | conn *shared.Connection 46 | commandHandlers struct { 47 | Bind BindCommandFn 48 | Unbind UnbindCommandFn 49 | } 50 | } 51 | func NewAgent(conn *shared.Connection) *TetheringAgent { 52 | agent := &TetheringAgent{ 53 | conn: conn, 54 | } 55 | conn.RegisterAgent(agent) 56 | return agent 57 | } 58 | 59 | func (agent *TetheringAgent) Name() string { 60 | return "Tethering" 61 | } 62 | 63 | func (agent *TetheringAgent) ProcessCommand(id int64, targetId string, funcName string, data *json.RawMessage) { 64 | defer shared.TryRecoverFromPanic(agent.conn) 65 | switch (funcName) { 66 | case "bind": 67 | var out BindCommand 68 | agent.conn.SetupCommand(id, targetId, data, &out) 69 | fn := agent.commandHandlers.Bind.Load() 70 | if fn == nil { 71 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 72 | break 73 | } 74 | fn(out) 75 | case "unbind": 76 | var out UnbindCommand 77 | agent.conn.SetupCommand(id, targetId, data, &out) 78 | fn := agent.commandHandlers.Unbind.Load() 79 | if fn == nil { 80 | out.RespondWithError(shared.ErrorCodeMethodNotFound, "") 81 | break 82 | } 83 | fn(out) 84 | default: 85 | fmt.Printf("Command %s unknown\n", funcName) 86 | agent.conn.SendErrorResult(id, targetId, shared.ErrorCodeMethodNotFound, "") 87 | } 88 | } 89 | 90 | // Dispatchable Events 91 | func (agent *TetheringAgent) FireAccepted(event AcceptedEvent) { 92 | agent.conn.Send(shared.Notification{ 93 | Method: "Tethering.accepted", 94 | Params: event, 95 | }) 96 | } 97 | func (agent *TetheringAgent) FireAcceptedOnTarget(targetId string,event AcceptedEvent) { 98 | agent.conn.SendToTarget(targetId, shared.Notification{ 99 | Method: "Tethering.accepted", 100 | Params: event, 101 | }) 102 | } 103 | 104 | // Commands Sent From Frontend 105 | func (agent *TetheringAgent) SetBindHandler(handler func(BindCommand)) { 106 | agent.commandHandlers.Bind.Store(handler) 107 | } 108 | func (agent *TetheringAgent) SetUnbindHandler(handler func(UnbindCommand)) { 109 | agent.commandHandlers.Unbind.Store(handler) 110 | } 111 | func init() { 112 | 113 | } 114 | -------------------------------------------------------------------------------- /protocol/tethering/commands.go: -------------------------------------------------------------------------------- 1 | package tethering 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type BindCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Port int64 `json:"port"`// Port number to bind. 13 | } 14 | type BindReturn struct { 15 | } 16 | 17 | func (c *BindCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 18 | c.DestinationTargetID = targetId 19 | c.responseId = responseId 20 | c.conn = conn 21 | } 22 | 23 | func (c *BindCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 24 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 25 | } 26 | 27 | func (c *BindCommand) Respond() { 28 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 29 | } 30 | 31 | type UnbindCommand struct { 32 | DestinationTargetID string 33 | responseId int64 34 | conn *shared.Connection 35 | Port int64 `json:"port"`// Port number to unbind. 36 | } 37 | type UnbindReturn struct { 38 | } 39 | 40 | func (c *UnbindCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 41 | c.DestinationTargetID = targetId 42 | c.responseId = responseId 43 | c.conn = conn 44 | } 45 | 46 | func (c *UnbindCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 47 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 48 | } 49 | 50 | func (c *UnbindCommand) Respond() { 51 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 52 | } 53 | -------------------------------------------------------------------------------- /protocol/tethering/events.go: -------------------------------------------------------------------------------- 1 | package tethering 2 | 3 | 4 | type AcceptedEvent struct { 5 | Port int64 `json:"port"`// Port number that was successfully bound. 6 | ConnectionId string `json:"connectionId"`// Connection id to be used. 7 | } -------------------------------------------------------------------------------- /protocol/tethering/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package tethering 2 | 3 | -------------------------------------------------------------------------------- /protocol/tracing/commands.go: -------------------------------------------------------------------------------- 1 | package tracing 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/shared" 6 | ) 7 | 8 | type StartCommand struct { 9 | DestinationTargetID string 10 | responseId int64 11 | conn *shared.Connection 12 | Categories *string `json:"categories,omitempty"`// Category/tag filter 13 | Options *string `json:"options,omitempty"`// Tracing options 14 | BufferUsageReportingInterval *float64 `json:"bufferUsageReportingInterval,omitempty"`// If set, the agent will issue bufferUsage events at this interval, specified in milliseconds 15 | TransferMode *StartTransferModeEnum `json:"transferMode,omitempty"`// Whether to report trace events as series of dataCollected events or to save trace to a stream (defaults to ReportEvents). 16 | TraceConfig *TraceConfig `json:"traceConfig,omitempty"` 17 | } 18 | type StartReturn struct { 19 | } 20 | 21 | func (c *StartCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 22 | c.DestinationTargetID = targetId 23 | c.responseId = responseId 24 | c.conn = conn 25 | } 26 | 27 | func (c *StartCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 28 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 29 | } 30 | 31 | func (c *StartCommand) Respond() { 32 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 33 | } 34 | 35 | type EndCommand struct { 36 | DestinationTargetID string 37 | responseId int64 38 | conn *shared.Connection 39 | } 40 | type EndReturn struct { 41 | } 42 | 43 | func (c *EndCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 44 | c.DestinationTargetID = targetId 45 | c.responseId = responseId 46 | c.conn = conn 47 | } 48 | 49 | func (c *EndCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 50 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 51 | } 52 | 53 | func (c *EndCommand) Respond() { 54 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 55 | } 56 | 57 | type GetCategoriesCommand struct { 58 | DestinationTargetID string 59 | responseId int64 60 | conn *shared.Connection 61 | } 62 | type GetCategoriesReturn struct { 63 | Categories []string `json:"categories"`// A list of supported tracing categories. 64 | } 65 | 66 | func (c *GetCategoriesCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 67 | c.DestinationTargetID = targetId 68 | c.responseId = responseId 69 | c.conn = conn 70 | } 71 | 72 | func (c *GetCategoriesCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 73 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 74 | } 75 | 76 | func (c *GetCategoriesCommand) Respond(r *GetCategoriesReturn) { 77 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 78 | } 79 | 80 | type RequestMemoryDumpCommand struct { 81 | DestinationTargetID string 82 | responseId int64 83 | conn *shared.Connection 84 | } 85 | type RequestMemoryDumpReturn struct { 86 | DumpGuid string `json:"dumpGuid"`// GUID of the resulting global memory dump. 87 | Success bool `json:"success"`// True iff the global memory dump succeeded. 88 | } 89 | 90 | func (c *RequestMemoryDumpCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 91 | c.DestinationTargetID = targetId 92 | c.responseId = responseId 93 | c.conn = conn 94 | } 95 | 96 | func (c *RequestMemoryDumpCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 97 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 98 | } 99 | 100 | func (c *RequestMemoryDumpCommand) Respond(r *RequestMemoryDumpReturn) { 101 | c.conn.SendResult(c.responseId, c.DestinationTargetID, r) 102 | } 103 | 104 | type RecordClockSyncMarkerCommand struct { 105 | DestinationTargetID string 106 | responseId int64 107 | conn *shared.Connection 108 | SyncId string `json:"syncId"`// The ID of this clock sync marker 109 | } 110 | type RecordClockSyncMarkerReturn struct { 111 | } 112 | 113 | func (c *RecordClockSyncMarkerCommand) Initalize(targetId string, responseId int64, conn *shared.Connection) { 114 | c.DestinationTargetID = targetId 115 | c.responseId = responseId 116 | c.conn = conn 117 | } 118 | 119 | func (c *RecordClockSyncMarkerCommand) RespondWithError(code shared.ResponseErrorCodes, message string) { 120 | c.conn.SendErrorResult(c.responseId, c.DestinationTargetID, code, message) 121 | } 122 | 123 | func (c *RecordClockSyncMarkerCommand) Respond() { 124 | c.conn.SendResult(c.responseId, c.DestinationTargetID, struct{}{}) 125 | } 126 | -------------------------------------------------------------------------------- /protocol/tracing/events.go: -------------------------------------------------------------------------------- 1 | package tracing 2 | 3 | 4 | import ( 5 | "github.com/allada/gdd/protocol/io" 6 | ) 7 | 8 | type DataCollectedEvent struct { 9 | Value []map[string]string `json:"value"` 10 | } 11 | type TracingCompleteEvent struct { 12 | Stream *io.StreamHandle `json:"stream,omitempty"`// A handle of the stream that holds resulting trace data. 13 | } 14 | type BufferUsageEvent struct { 15 | PercentFull *float64 `json:"percentFull,omitempty"`// A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size. 16 | EventCount *float64 `json:"eventCount,omitempty"`// An approximate number of events in the trace log. 17 | Value *float64 `json:"value,omitempty"`// A number in range [0..1] that indicates the used size of event buffer as a fraction of its total size. 18 | } -------------------------------------------------------------------------------- /protocol/tracing/sharedTypes.go: -------------------------------------------------------------------------------- 1 | package tracing 2 | 3 | type TraceConfigRecordModeEnum string 4 | const ( 5 | TraceConfigRecordModeRecordUntilFull TraceConfigRecordModeEnum = "recordUntilFull" 6 | TraceConfigRecordModeRecordContinuously TraceConfigRecordModeEnum = "recordContinuously" 7 | TraceConfigRecordModeRecordAsMuchAsPossible TraceConfigRecordModeEnum = "recordAsMuchAsPossible" 8 | TraceConfigRecordModeEchoToConsole TraceConfigRecordModeEnum = "echoToConsole" 9 | ) 10 | 11 | type StartTransferModeEnum string 12 | const ( 13 | StartTransferModeReportEvents StartTransferModeEnum = "ReportEvents" 14 | StartTransferModeReturnAsStream StartTransferModeEnum = "ReturnAsStream" 15 | ) 16 | type MemoryDumpConfig map[string]string 17 | 18 | type TraceConfig struct { 19 | RecordMode *TraceConfigRecordModeEnum `json:"recordMode,omitempty"`// Controls how the trace buffer stores data. 20 | EnableSampling *bool `json:"enableSampling,omitempty"`// Turns on JavaScript stack sampling. 21 | EnableSystrace *bool `json:"enableSystrace,omitempty"`// Turns on system tracing. 22 | EnableArgumentFilter *bool `json:"enableArgumentFilter,omitempty"`// Turns on argument filter. 23 | IncludedCategories *[]string `json:"includedCategories,omitempty"`// Included category filters. 24 | ExcludedCategories *[]string `json:"excludedCategories,omitempty"`// Excluded category filters. 25 | SyntheticDelays *[]string `json:"syntheticDelays,omitempty"`// Configuration to synthesize the delays in tracing. 26 | MemoryDumpConfig *MemoryDumpConfig `json:"memoryDumpConfig,omitempty"`// Configuration for memory dump triggers. Used only when "memory-infra" category is enabled. 27 | } 28 | -------------------------------------------------------------------------------- /proxies/page/proxy.go: -------------------------------------------------------------------------------- 1 | package page 2 | 3 | import ( 4 | "github.com/allada/gdd/dbgClient" 5 | "github.com/allada/gdd/protocol/shared" 6 | pageAgent "github.com/allada/gdd/protocol/page" 7 | ) 8 | 9 | type proxy struct { 10 | agent *pageAgent.PageAgent 11 | client *dbgClient.Client 12 | } 13 | 14 | func NewProxy(conn *shared.Connection, client *dbgClient.Client) *proxy { 15 | agent := pageAgent.NewAgent(conn) 16 | return &proxy{ 17 | agent: agent, 18 | client: client, 19 | } 20 | } 21 | 22 | func (p *proxy) Agent() *pageAgent.PageAgent { 23 | return p.agent 24 | } 25 | 26 | func (p *proxy) Start() { 27 | // Wait until we are enabled. 28 | p.agent.SetEnableHandler(p.enableAndRespond) 29 | } 30 | 31 | func (p *proxy) enableAndRespond(command pageAgent.EnableCommand) { 32 | command.Respond() 33 | 34 | p.agent.SetGetResourceTreeHandler(p.getResourceTreeAndRespond) 35 | } 36 | 37 | func (p *proxy) getResourceTreeAndRespond(command pageAgent.GetResourceTreeCommand) { 38 | command.Respond(&pageAgent.GetResourceTreeReturn{ 39 | FrameTree: pageAgent.FrameResourceTree{ 40 | Frame: pageAgent.Frame{ 41 | Id: "1", 42 | LoaderId: "1", 43 | Url: "", 44 | SecurityOrigin: "", 45 | MimeType: "", 46 | }, 47 | Resources: []pageAgent.FrameResource{}, 48 | }, 49 | }) 50 | } -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | node ./build-scripts/convert_protocol.js; 3 | echo "Finished building protocol files." && 4 | go install && 5 | echo "Finished building GDD." && 6 | #sh -c "nohup sh -c 'sleep .5; open \"https://chrome-devtools-frontend.appspot.com/serve_file/@939b32ee5ba05c396eef3fd992822fcca9a2e262/inspector.html?experiments=true&ws=localhost:9922/go-devtools-debug\"' /dev/null 2>&1 &" && 7 | $GOPATH/bin/gdd $@ --------------------------------------------------------------------------------