mirror of
				https://github.com/MontFerret/ferret.git
				synced 2025-10-30 23:37:40 +02:00 
			
		
		
		
	Added element syncrhonization
This commit is contained in:
		| @@ -149,3 +149,18 @@ func (t *Array) IndexOf(item core.Value) Int { | |||||||
|  |  | ||||||
| 	return res | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (t *Array) Insert(idx Int, value core.Value) { | ||||||
|  | 	t.value = append(t.value[:idx], append([]core.Value{value}, t.value[idx:]...)...) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (t *Array) RemoveAt(idx Int) { | ||||||
|  | 	i := int(idx) | ||||||
|  | 	max := len(t.value) - 1 | ||||||
|  |  | ||||||
|  | 	if i > max { | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t.value = append(t.value[:i], t.value[i+1:]...) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -271,4 +271,89 @@ func TestArray(t *testing.T) { | |||||||
| 			So(len(s2), ShouldEqual, arr.Length()-2) | 			So(len(s2), ShouldEqual, arr.Length()-2) | ||||||
| 		}) | 		}) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
|  | 	Convey(".Insert", t, func() { | ||||||
|  | 		Convey("Should insert an item in the middle of an array", func() { | ||||||
|  | 			arr := values.NewArrayWith( | ||||||
|  | 				values.NewInt(0), | ||||||
|  | 				values.NewInt(1), | ||||||
|  | 				values.NewInt(2), | ||||||
|  | 				values.NewInt(3), | ||||||
|  | 				values.NewInt(4), | ||||||
|  | 				values.NewInt(5), | ||||||
|  | 			) | ||||||
|  |  | ||||||
|  | 			lenBefore := arr.Length() | ||||||
|  |  | ||||||
|  | 			arr.Insert(3, values.NewInt(100)) | ||||||
|  |  | ||||||
|  | 			lenAfter := arr.Length() | ||||||
|  |  | ||||||
|  | 			So(lenAfter, ShouldBeGreaterThan, lenBefore) | ||||||
|  | 			So(arr.Get(3), ShouldEqual, 100) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	Convey(".RemoveAt", t, func() { | ||||||
|  | 		Convey("Should remove an item from the middle", func() { | ||||||
|  | 			arr := values.NewArrayWith( | ||||||
|  | 				values.NewInt(0), | ||||||
|  | 				values.NewInt(1), | ||||||
|  | 				values.NewInt(2), | ||||||
|  | 				values.NewInt(3), | ||||||
|  | 				values.NewInt(4), | ||||||
|  | 				values.NewInt(5), | ||||||
|  | 			) | ||||||
|  |  | ||||||
|  | 			lenBefore := arr.Length() | ||||||
|  |  | ||||||
|  | 			arr.RemoveAt(3) | ||||||
|  |  | ||||||
|  | 			lenAfter := arr.Length() | ||||||
|  |  | ||||||
|  | 			So(lenAfter, ShouldBeLessThan, lenBefore) | ||||||
|  | 			So(arr.Get(3), ShouldEqual, 4) | ||||||
|  | 		}) | ||||||
|  |  | ||||||
|  | 		Convey("Should remove an item from the end", func() { | ||||||
|  | 			arr := values.NewArrayWith( | ||||||
|  | 				values.NewInt(0), | ||||||
|  | 				values.NewInt(1), | ||||||
|  | 				values.NewInt(2), | ||||||
|  | 				values.NewInt(3), | ||||||
|  | 				values.NewInt(4), | ||||||
|  | 				values.NewInt(5), | ||||||
|  | 			) | ||||||
|  |  | ||||||
|  | 			lenBefore := arr.Length() | ||||||
|  |  | ||||||
|  | 			arr.RemoveAt(5) | ||||||
|  |  | ||||||
|  | 			lenAfter := arr.Length() | ||||||
|  |  | ||||||
|  | 			So(lenAfter, ShouldBeLessThan, lenBefore) | ||||||
|  | 			So(lenAfter, ShouldEqual, 5) | ||||||
|  | 			So(arr.Get(4), ShouldEqual, 4) | ||||||
|  | 		}) | ||||||
|  |  | ||||||
|  | 		Convey("Should remove an item from the beginning", func() { | ||||||
|  | 			arr := values.NewArrayWith( | ||||||
|  | 				values.NewInt(0), | ||||||
|  | 				values.NewInt(1), | ||||||
|  | 				values.NewInt(2), | ||||||
|  | 				values.NewInt(3), | ||||||
|  | 				values.NewInt(4), | ||||||
|  | 				values.NewInt(5), | ||||||
|  | 			) | ||||||
|  |  | ||||||
|  | 			lenBefore := arr.Length() | ||||||
|  |  | ||||||
|  | 			arr.RemoveAt(0) | ||||||
|  |  | ||||||
|  | 			lenAfter := arr.Length() | ||||||
|  |  | ||||||
|  | 			So(lenAfter, ShouldBeLessThan, lenBefore) | ||||||
|  | 			So(arr.Get(0), ShouldEqual, 1) | ||||||
|  | 		}) | ||||||
|  | 	}) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -150,6 +150,10 @@ func (t *Object) Set(key String, value core.Value) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (t *Object) Remove(key String) { | ||||||
|  | 	delete(t.value, string(key)) | ||||||
|  | } | ||||||
|  |  | ||||||
| func (t *Object) SetIn(path []core.Value, value core.Value) error { | func (t *Object) SetIn(path []core.Value, value core.Value) error { | ||||||
| 	return SetIn(t, path, value) | 	return SetIn(t, path, value) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -27,6 +27,13 @@ func NewLazyValue(factory LazyFactory) *LazyValue { | |||||||
| 	return lz | 	return lz | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (lv *LazyValue) Ready() bool { | ||||||
|  | 	lv.Lock() | ||||||
|  | 	defer lv.Unlock() | ||||||
|  | 
 | ||||||
|  | 	return lv.ready | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (lv *LazyValue) Value() (core.Value, error) { | func (lv *LazyValue) Value() (core.Value, error) { | ||||||
| 	lv.Lock() | 	lv.Lock() | ||||||
| 	defer lv.Unlock() | 	defer lv.Unlock() | ||||||
							
								
								
									
										32
									
								
								pkg/stdlib/html/driver/common/sync-value.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								pkg/stdlib/html/driver/common/sync-value.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | |||||||
|  | package common | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"github.com/MontFerret/ferret/pkg/runtime/core" | ||||||
|  | 	"sync" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | type SyncValue struct { | ||||||
|  | 	sync.Mutex | ||||||
|  | 	value core.Value | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func NewSyncValue(init core.Value) *SyncValue { | ||||||
|  | 	val := new(SyncValue) | ||||||
|  | 	val.value = init | ||||||
|  |  | ||||||
|  | 	return val | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (sv *SyncValue) Get() core.Value { | ||||||
|  | 	sv.Lock() | ||||||
|  | 	defer sv.Unlock() | ||||||
|  |  | ||||||
|  | 	return sv.value | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (sv *SyncValue) Set(val core.Value) { | ||||||
|  | 	sv.Lock() | ||||||
|  | 	defer sv.Unlock() | ||||||
|  |  | ||||||
|  | 	sv.value = val | ||||||
|  | } | ||||||
| @@ -23,11 +23,11 @@ type HtmlElement struct { | |||||||
| 	sync.Mutex | 	sync.Mutex | ||||||
| 	client         *cdp.Client | 	client         *cdp.Client | ||||||
| 	broker         *events.EventBroker | 	broker         *events.EventBroker | ||||||
| 	connected      bool | 	connected      *common.SyncValue | ||||||
| 	id             dom.NodeID | 	id             dom.NodeID | ||||||
| 	nodeType       values.Int | 	nodeType       values.Int | ||||||
| 	nodeName       values.String | 	nodeName       values.String | ||||||
| 	innerHtml      values.String | 	innerHtml      *common.SyncValue | ||||||
| 	innerText      *common.LazyValue | 	innerText      *common.LazyValue | ||||||
| 	value          string | 	value          string | ||||||
| 	attributes     *common.LazyValue | 	attributes     *common.LazyValue | ||||||
| @@ -53,17 +53,14 @@ func LoadElement( | |||||||
| 		dom. | 		dom. | ||||||
| 			NewDescribeNodeArgs(). | 			NewDescribeNodeArgs(). | ||||||
| 			SetNodeID(id). | 			SetNodeID(id). | ||||||
| 			SetDepth(-1), | 			SetDepth(1), | ||||||
| 	) | 	) | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, core.Error(err, strconv.Itoa(int(id))) | 		return nil, core.Error(err, strconv.Itoa(int(id))) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	innerHtml, err := client.DOM.GetOuterHTML( | 	innerHtml, err := loadInnerHtml(client, id) | ||||||
| 		ctx, |  | ||||||
| 		dom.NewGetOuterHTMLArgs().SetNodeID(id), |  | ||||||
| 	) |  | ||||||
|  |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, core.Error(err, strconv.Itoa(int(id))) | 		return nil, core.Error(err, strconv.Itoa(int(id))) | ||||||
| @@ -74,7 +71,7 @@ func LoadElement( | |||||||
| 		broker, | 		broker, | ||||||
| 		id, | 		id, | ||||||
| 		node.Node, | 		node.Node, | ||||||
| 		values.NewString(innerHtml.OuterHTML), | 		innerHtml, | ||||||
| 	), nil | 	), nil | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -88,11 +85,11 @@ func NewHtmlElement( | |||||||
| 	el := new(HtmlElement) | 	el := new(HtmlElement) | ||||||
| 	el.client = client | 	el.client = client | ||||||
| 	el.broker = broker | 	el.broker = broker | ||||||
| 	el.connected = true | 	el.connected = common.NewSyncValue(values.True) | ||||||
| 	el.id = id | 	el.id = id | ||||||
| 	el.nodeType = values.NewInt(node.NodeType) | 	el.nodeType = values.NewInt(node.NodeType) | ||||||
| 	el.nodeName = values.NewString(node.NodeName) | 	el.nodeName = values.NewString(node.NodeName) | ||||||
| 	el.innerHtml = innerHtml | 	el.innerHtml = common.NewSyncValue(innerHtml) | ||||||
| 	el.innerText = common.NewLazyValue(func() (core.Value, error) { | 	el.innerText = common.NewLazyValue(func() (core.Value, error) { | ||||||
| 		h := el.InnerHtml() | 		h := el.InnerHtml() | ||||||
|  |  | ||||||
| @@ -115,24 +112,235 @@ func NewHtmlElement( | |||||||
| 	}) | 	}) | ||||||
| 	el.value = "" | 	el.value = "" | ||||||
| 	el.loadedChildren = common.NewLazyValue(func() (core.Value, error) { | 	el.loadedChildren = common.NewLazyValue(func() (core.Value, error) { | ||||||
|  | 		if !el.IsConnected() { | ||||||
|  | 			return values.NewArray(0), nil | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		return loadNodes(client, broker, el.children) | 		return loadNodes(client, broker, el.children) | ||||||
| 	}) | 	}) | ||||||
|  |  | ||||||
| 	var childCount int |  | ||||||
|  |  | ||||||
| 	if node.ChildNodeCount != nil { |  | ||||||
| 		childCount = *node.ChildNodeCount |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if node.Value != nil { | 	if node.Value != nil { | ||||||
| 		el.value = *node.Value | 		el.value = *node.Value | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	el.children = make([]dom.NodeID, childCount) | 	el.children = createChildrenArray(node.Children) | ||||||
|  |  | ||||||
| 	for idx, child := range node.Children { | 	broker.AddEventListener("reload", func(_ interface{}) { | ||||||
| 		el.children[idx] = child.NodeID | 		el.connected.Set(values.False) | ||||||
| 	} | 	}) | ||||||
|  |  | ||||||
|  | 	broker.AddEventListener("attr:modified", func(message interface{}) { | ||||||
|  | 		reply, ok := message.(*dom.AttributeModifiedReply) | ||||||
|  |  | ||||||
|  | 		// well.... | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// it's not for this element | ||||||
|  | 		if reply.NodeID != el.id { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// they are not event loaded | ||||||
|  | 		// just ignore the event | ||||||
|  | 		if !el.attributes.Ready() { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		val, err := el.attributes.Value() | ||||||
|  |  | ||||||
|  | 		// failed to load | ||||||
|  | 		// TODO: Log | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		attrs, ok := val.(*values.Object) | ||||||
|  |  | ||||||
|  | 		// TODO: Log | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// TODO: actually, we need to sync it too... | ||||||
|  | 		attrs.Set(values.NewString(reply.Name), values.NewString(reply.Value)) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	broker.AddEventListener("attr:removed", func(message interface{}) { | ||||||
|  | 		reply, ok := message.(*dom.AttributeRemovedReply) | ||||||
|  |  | ||||||
|  | 		// well.... | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// it's not for this element | ||||||
|  | 		if reply.NodeID != el.id { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// they are not event loaded | ||||||
|  | 		// just ignore the event | ||||||
|  | 		if !el.attributes.Ready() { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		val, err := el.attributes.Value() | ||||||
|  |  | ||||||
|  | 		// failed to load | ||||||
|  | 		// TODO: Log | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		attrs, ok := val.(*values.Object) | ||||||
|  |  | ||||||
|  | 		// TODO: Log | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// TODO: actually, we need to sync it too... | ||||||
|  | 		attrs.Remove(values.NewString(reply.Name)) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	broker.AddEventListener("children:count", func(message interface{}) { | ||||||
|  | 		reply, ok := message.(*dom.ChildNodeCountUpdatedReply) | ||||||
|  |  | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if reply.NodeID != el.id { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		node, err := client.DOM.DescribeNode(context.Background(), dom.NewDescribeNodeArgs()) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		el.Lock() | ||||||
|  | 		defer el.Unlock() | ||||||
|  |  | ||||||
|  | 		el.children = createChildrenArray(node.Node.Children) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	broker.AddEventListener("children:inserted", func(message interface{}) { | ||||||
|  | 		reply, ok := message.(*dom.ChildNodeInsertedReply) | ||||||
|  |  | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if reply.ParentNodeID != el.id { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		targetIdx := -1 | ||||||
|  | 		prevId := reply.PreviousNodeID | ||||||
|  | 		nextId := reply.Node.NodeID | ||||||
|  |  | ||||||
|  | 		el.Lock() | ||||||
|  | 		defer el.Unlock() | ||||||
|  |  | ||||||
|  | 		for idx, id := range el.children { | ||||||
|  | 			if id == prevId { | ||||||
|  | 				targetIdx = idx | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if targetIdx == -1 { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		arr := el.children | ||||||
|  | 		el.children = append(arr[:targetIdx], append([]dom.NodeID{nextId}, arr[targetIdx:]...)...) | ||||||
|  |  | ||||||
|  | 		if !el.loadedChildren.Ready() { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		loaded, err := el.loadedChildren.Value() | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		loadedArr := loaded.(*values.Array) | ||||||
|  |  | ||||||
|  | 		loadedEl, err := LoadElement(el.client, el.broker, nextId) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		loadedArr.Insert(values.NewInt(targetIdx), loadedEl) | ||||||
|  |  | ||||||
|  | 		newInnerHtml, err := loadInnerHtml(el.client, el.id) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		el.innerHtml.Set(newInnerHtml) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
|  | 	broker.AddEventListener("children:deleted", func(message interface{}) { | ||||||
|  | 		reply, ok := message.(*dom.ChildNodeRemovedReply) | ||||||
|  |  | ||||||
|  | 		if !ok { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if reply.ParentNodeID != el.id { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		targetIdx := -1 | ||||||
|  | 		targetId := reply.NodeID | ||||||
|  |  | ||||||
|  | 		el.Lock() | ||||||
|  | 		defer el.Unlock() | ||||||
|  |  | ||||||
|  | 		for idx, id := range el.children { | ||||||
|  | 			if id == targetId { | ||||||
|  | 				targetIdx = idx | ||||||
|  | 				break | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		if targetIdx == -1 { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		arr := el.children | ||||||
|  | 		el.children = append(arr[:targetIdx], arr[targetIdx+1:]...) | ||||||
|  |  | ||||||
|  | 		if !el.loadedChildren.Ready() { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		loaded, err := el.loadedChildren.Value() | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		loadedArr := loaded.(*values.Array) | ||||||
|  | 		loadedArr.RemoveAt(values.NewInt(targetIdx)) | ||||||
|  |  | ||||||
|  | 		newInnerHtml, err := loadInnerHtml(el.client, el.id) | ||||||
|  |  | ||||||
|  | 		if err != nil { | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		el.innerHtml.Set(newInnerHtml) | ||||||
|  | 	}) | ||||||
|  |  | ||||||
| 	return el | 	return el | ||||||
| } | } | ||||||
| @@ -325,7 +533,7 @@ func (el *HtmlElement) InnerText() values.String { | |||||||
| } | } | ||||||
|  |  | ||||||
| func (el *HtmlElement) InnerHtml() values.String { | func (el *HtmlElement) InnerHtml() values.String { | ||||||
| 	return el.innerHtml | 	return el.innerHtml.Get().(values.String) | ||||||
| } | } | ||||||
|  |  | ||||||
| func (el *HtmlElement) Click() (values.Boolean, error) { | func (el *HtmlElement) Click() (values.Boolean, error) { | ||||||
| @@ -335,3 +543,7 @@ func (el *HtmlElement) Click() (values.Boolean, error) { | |||||||
|  |  | ||||||
| 	return events.DispatchEvent(ctx, el.client, el.id, "click") | 	return events.DispatchEvent(ctx, el.client, el.id, "click") | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func (el *HtmlElement) IsConnected() values.Boolean { | ||||||
|  | 	return el.connected.Get().(values.Boolean) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -177,14 +177,20 @@ func (broker *EventBroker) Close() error { | |||||||
|  |  | ||||||
| func (broker *EventBroker) emit(name string, message interface{}) { | func (broker *EventBroker) emit(name string, message interface{}) { | ||||||
| 	broker.Lock() | 	broker.Lock() | ||||||
| 	defer broker.Unlock() |  | ||||||
| 	listeners, ok := broker.listeners[name] | 	listeners, ok := broker.listeners[name] | ||||||
|  |  | ||||||
| 	if !ok { | 	if !ok { | ||||||
|  | 		broker.Unlock() | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	for _, listener := range listeners { | 	// we copy the list of listeners and unlock the broker before the execution. | ||||||
|  | 	// we do it in order to avoid deadlocks during calls of event listeners | ||||||
|  | 	snapshot := listeners[:] | ||||||
|  | 	broker.Unlock() | ||||||
|  |  | ||||||
|  | 	for _, listener := range snapshot { | ||||||
| 		listener(message) | 		listener(message) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -50,6 +50,26 @@ func parseAttrs(attrs []string) *values.Object { | |||||||
| 	return res | 	return res | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func loadInnerHtml(client *cdp.Client, id dom.NodeID) (values.String, error) { | ||||||
|  | 	res, err := client.DOM.GetOuterHTML(context.Background(), dom.NewGetOuterHTMLArgs().SetNodeID(id)) | ||||||
|  |  | ||||||
|  | 	if err != nil { | ||||||
|  | 		return "", err | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return values.NewString(res.OuterHTML), err | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func createChildrenArray(nodes []dom.Node) []dom.NodeID { | ||||||
|  | 	children := make([]dom.NodeID, len(nodes)) | ||||||
|  |  | ||||||
|  | 	for idx, child := range nodes { | ||||||
|  | 		children[idx] = child.NodeID | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	return children | ||||||
|  | } | ||||||
|  |  | ||||||
| func loadNodes(client *cdp.Client, broker *events.EventBroker, nodes []dom.NodeID) (*values.Array, error) { | func loadNodes(client *cdp.Client, broker *events.EventBroker, nodes []dom.NodeID) (*values.Array, error) { | ||||||
| 	arr := values.NewArray(len(nodes)) | 	arr := values.NewArray(len(nodes)) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user