2017-01-24 15:09:23 +00:00
|
|
|
{% import (
|
2017-01-26 07:28:34 +00:00
|
|
|
"github.com/knq/chromedp/cmd/chromedp-gen/internal"
|
2017-01-24 15:09:23 +00:00
|
|
|
) %}
|
|
|
|
|
|
|
|
// ExtraTimestampTemplate is a special template for the Timestamp type that
|
|
|
|
// defines its JSON unmarshaling.
|
2017-01-26 07:28:34 +00:00
|
|
|
{% func ExtraTimestampTemplate(t *internal.Type, d *internal.Domain) %}{%code
|
2017-01-24 15:09:23 +00:00
|
|
|
typ := t.IdOrName()
|
|
|
|
%}
|
|
|
|
// MarshalEasyJSON satisfies easyjson.Marshaler.
|
|
|
|
func (t {%s= typ %}) MarshalEasyJSON(out *jwriter.Writer) {
|
|
|
|
out.Float64(float64(time.Time(t).Sub(sysutil.BootTime()))/float64(time.Second))
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalJSON satisfies json.Marshaler.
|
|
|
|
func (t {%s= typ %}) MarshalJSON() ([]byte, error) {
|
|
|
|
return easyjson.Marshal(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
|
|
|
func (t *{%s= typ %}) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
|
|
|
*t = {%s= typ %}(sysutil.BootTime().Add(time.Duration(in.Float64()*float64(time.Second))))
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON satisfies json.Unmarshaler.
|
|
|
|
func (t *{%s= typ %}) UnmarshalJSON(buf []byte) error {
|
|
|
|
return easyjson.Unmarshal(buf, t)
|
|
|
|
}
|
|
|
|
{% endfunc %}
|
|
|
|
|
|
|
|
// ExtraFrameTemplate is a special template for the Page.Frame type, adding FrameState.
|
|
|
|
{% func ExtraFrameTemplate() %}
|
|
|
|
// FrameState is the state of a Frame.
|
|
|
|
type FrameState uint16
|
|
|
|
|
|
|
|
// FrameState enum values.
|
|
|
|
const (
|
|
|
|
FrameDOMContentEventFired FrameState = 1 << (15 - iota)
|
|
|
|
FrameLoadEventFired
|
|
|
|
FrameAttached
|
|
|
|
FrameNavigated
|
|
|
|
FrameLoading
|
|
|
|
FrameScheduledNavigation
|
|
|
|
)
|
|
|
|
|
|
|
|
// frameStateNames are the names of the frame states.
|
|
|
|
var frameStateNames = map[FrameState]string{
|
|
|
|
FrameDOMContentEventFired: "DOMContentEventFired",
|
|
|
|
FrameLoadEventFired: "LoadEventFired",
|
|
|
|
FrameAttached: "Attached",
|
|
|
|
FrameNavigated: "Navigated",
|
|
|
|
FrameLoading: "Loading",
|
|
|
|
FrameScheduledNavigation: "ScheduledNavigation",
|
|
|
|
}
|
|
|
|
|
|
|
|
// String satisfies stringer interface.
|
|
|
|
func (fs FrameState) String() string {
|
|
|
|
var s []string
|
|
|
|
for k, v := range frameStateNames {
|
|
|
|
if fs&k != 0 {
|
|
|
|
s = append(s, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "[" + strings.Join(s, " ") + "]"
|
|
|
|
}
|
|
|
|
{% endfunc %}
|
|
|
|
|
|
|
|
// ExtraNodeTemplate is a special template for the DOM.Node type, adding NodeState.
|
|
|
|
{% func ExtraNodeTemplate() %}
|
|
|
|
// AttributeValue returns the named attribute for the node.
|
|
|
|
func (n *Node) AttributeValue(name string) string {
|
|
|
|
n.RLock()
|
|
|
|
defer n.RUnlock()
|
|
|
|
|
|
|
|
for i := 0; i < len(n.Attributes); i+=2 {
|
|
|
|
if n.Attributes[i] == name {
|
|
|
|
return n.Attributes[i+1]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
// xpath builds the xpath string.
|
|
|
|
func (n *Node) xpath(stopWhenID bool) string {
|
|
|
|
p := ""
|
|
|
|
pos := ""
|
|
|
|
id := n.AttributeValue("id")
|
|
|
|
switch {
|
|
|
|
case n.Parent == nil:
|
|
|
|
return n.LocalName
|
|
|
|
|
|
|
|
case stopWhenID && id != "":
|
|
|
|
p = "/"
|
|
|
|
pos = `[@id='`+id+`']`
|
|
|
|
|
|
|
|
case n.Parent != nil:
|
|
|
|
i := 0
|
|
|
|
var found bool
|
|
|
|
for j := 0; j < len(n.Parent.Children); j++ {
|
|
|
|
if n.Parent.Children[j].LocalName == n.LocalName {
|
|
|
|
i++
|
|
|
|
}
|
|
|
|
if n.Parent.Children[j].NodeID == n.NodeID {
|
|
|
|
found = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
p = n.Parent.xpath(stopWhenID)
|
|
|
|
if found {
|
|
|
|
pos = "["+strconv.Itoa(i)+"]"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return p + "/" + n.LocalName + pos
|
|
|
|
}
|
|
|
|
|
|
|
|
// XPathByID returns the XPath tree for the node, stopping at the first parent
|
|
|
|
// with an id attribute.
|
|
|
|
func (n *Node) XPathByID() string {
|
|
|
|
return n.xpath(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
// XPath returns the full XPath tree for the node.
|
|
|
|
func (n *Node) XPath() string {
|
|
|
|
return n.xpath(false)
|
|
|
|
}
|
|
|
|
|
|
|
|
// NodeState is the state of a DOM node.
|
|
|
|
type NodeState uint8
|
|
|
|
|
|
|
|
// NodeState enum values.
|
|
|
|
const (
|
|
|
|
NodeReady NodeState = 1 << (7 - iota)
|
|
|
|
NodeVisible
|
|
|
|
NodeHighlighted
|
|
|
|
)
|
|
|
|
|
|
|
|
// nodeStateNames are the names of the node states.
|
|
|
|
var nodeStateNames = map[NodeState]string{
|
|
|
|
NodeReady: "Ready",
|
|
|
|
NodeVisible: "Visible",
|
|
|
|
NodeHighlighted: "Highlighted",
|
|
|
|
}
|
|
|
|
|
|
|
|
// String satisfies stringer interface.
|
|
|
|
func (ns NodeState) String() string {
|
|
|
|
var s []string
|
|
|
|
for k, v := range nodeStateNames {
|
|
|
|
if ns&k != 0 {
|
|
|
|
s = append(s, v)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "[" + strings.Join(s, " ") + "]"
|
|
|
|
}
|
|
|
|
{% endfunc %}
|
|
|
|
|
|
|
|
// ExtraFixStringUnmarshaler is a template that forces values to be parsed properly.
|
|
|
|
{% func ExtraFixStringUnmarshaler(typ, parseFunc, extra string) %}
|
|
|
|
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
|
|
|
|
func (t *{%s= typ %}) UnmarshalEasyJSON(in *jlexer.Lexer) {
|
|
|
|
buf := in.Raw()
|
|
|
|
if l := len(buf); l > 2 && buf[0] == '"' && buf[l-1] == '"' {
|
|
|
|
buf = buf[1:l-1]
|
|
|
|
}
|
|
|
|
{% if parseFunc != "" %}
|
|
|
|
v, err := strconv.{%s= parseFunc %}(string(buf){%s= extra %})
|
|
|
|
if err != nil {
|
|
|
|
in.AddError(err)
|
|
|
|
}
|
|
|
|
{% endif %}
|
|
|
|
*t = {%s= typ %}({% if parseFunc != "" %}v{% else %}buf{% end %})
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON satisfies json.Unmarshaler.
|
|
|
|
func (t *{%s= typ %}) UnmarshalJSON(buf []byte) error {
|
|
|
|
return easyjson.Unmarshal(buf, t)
|
|
|
|
}
|
|
|
|
{% endfunc %}
|
|
|
|
|
2017-01-26 07:28:34 +00:00
|
|
|
// ExtraCDPTypes is the template for additional internal type
|
2017-01-24 15:09:23 +00:00
|
|
|
// declarations.
|
2017-01-26 07:28:34 +00:00
|
|
|
{% func ExtraCDPTypes() %}
|
2017-01-24 15:09:23 +00:00
|
|
|
|
|
|
|
// Error satisfies the error interface.
|
|
|
|
func (t ErrorType) Error() string {
|
|
|
|
return string(t)
|
|
|
|
}
|
|
|
|
|
|
|
|
// FrameHandler is the common interface for a frame handler.
|
|
|
|
type FrameHandler interface {
|
|
|
|
SetActive(context.Context, FrameID) error
|
|
|
|
GetRoot(context.Context) (*Node, error)
|
|
|
|
WaitFrame(context.Context, FrameID) (*Frame, error)
|
|
|
|
WaitNode(context.Context, *Frame, NodeID) (*Node, error)
|
|
|
|
Listen(...MethodType) <-chan interface{}
|
|
|
|
|
|
|
|
// Execute executes the specified command using the supplied context and
|
|
|
|
// parameters.
|
|
|
|
Execute(context.Context, MethodType, easyjson.RawMessage) <-chan interface{}
|
|
|
|
}
|
|
|
|
|
2017-01-26 07:28:34 +00:00
|
|
|
// Empty is an empty JSON object message.
|
2017-01-24 15:09:23 +00:00
|
|
|
var Empty = easyjson.RawMessage(`{}`)
|
|
|
|
{% endfunc %}
|
|
|
|
|
|
|
|
// ExtraUtilTemplate generates the decode func for the Message type.
|
2017-01-26 07:28:34 +00:00
|
|
|
{% func ExtraUtilTemplate(domains []*internal.Domain) %}
|
2017-01-24 15:09:23 +00:00
|
|
|
type empty struct{}
|
|
|
|
var emptyVal = &empty{}
|
|
|
|
|
|
|
|
// UnmarshalMessage unmarshals the message result or params.
|
2017-01-26 07:28:34 +00:00
|
|
|
func UnmarshalMessage(msg *cdp.Message) (interface{}, error) {
|
2017-01-24 15:09:23 +00:00
|
|
|
var v easyjson.Unmarshaler
|
|
|
|
switch msg.Method {{% for _, d := range domains %}{% for _, c := range d.Commands %}
|
2017-01-26 07:28:34 +00:00
|
|
|
case cdp.{%s= c.CommandMethodType(d) %}:{% if len(c.Returns) == 0 %}
|
2017-01-24 15:09:23 +00:00
|
|
|
return emptyVal, nil{% else %}
|
|
|
|
v = new({%s= d.PackageRefName() %}.{%s= c.CommandReturnsType() %}){% endif %}
|
|
|
|
{% endfor %}{% for _, e := range d.Events %}
|
2017-01-26 07:28:34 +00:00
|
|
|
case cdp.{%s= e.EventMethodType(d) %}:
|
2017-01-24 15:09:23 +00:00
|
|
|
v = new({%s= d.PackageRefName() %}.{%s= e.EventType() %})
|
|
|
|
{% endfor %}{% endfor %}}
|
|
|
|
|
|
|
|
var buf easyjson.RawMessage
|
|
|
|
switch {
|
|
|
|
case msg.Params != nil:
|
|
|
|
buf = msg.Params
|
|
|
|
|
|
|
|
case msg.Result != nil:
|
|
|
|
buf = msg.Result
|
|
|
|
|
|
|
|
default:
|
|
|
|
return nil, errors.New("msg missing params or result")
|
|
|
|
}
|
|
|
|
|
|
|
|
err := easyjson.Unmarshal(buf, v)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return v, nil
|
|
|
|
}
|
|
|
|
{% endfunc %}
|
|
|
|
|
|
|
|
{% func ExtraMethodTypeDomainDecoder() %}
|
|
|
|
// Domain returns the Chrome Debugging Protocol domain of the event or command.
|
|
|
|
func (t MethodType) Domain() string {
|
|
|
|
return string(t[:strings.IndexByte(string(t), '.')])
|
|
|
|
}
|
|
|
|
{% endfunc %}
|