github.com/MontFerret/ferret@v0.18.0/pkg/drivers/http/element.go (about)

     1  package http
     2  
     3  import (
     4  	"context"
     5  	"hash/fnv"
     6  	"strings"
     7  
     8  	"golang.org/x/net/html"
     9  
    10  	"github.com/PuerkitoBio/goquery"
    11  	"github.com/wI2L/jettison"
    12  
    13  	"github.com/MontFerret/ferret/pkg/drivers"
    14  	"github.com/MontFerret/ferret/pkg/drivers/common"
    15  	"github.com/MontFerret/ferret/pkg/runtime/core"
    16  	"github.com/MontFerret/ferret/pkg/runtime/values"
    17  )
    18  
    19  type HTMLElement struct {
    20  	selection *goquery.Selection
    21  	attrs     *values.Object
    22  	styles    *values.Object
    23  	children  *values.Array
    24  }
    25  
    26  func NewHTMLElement(node *goquery.Selection) (drivers.HTMLElement, error) {
    27  	if node == nil {
    28  		return nil, core.Error(core.ErrMissedArgument, "element selection")
    29  	}
    30  
    31  	return &HTMLElement{node, nil, nil, nil}, nil
    32  }
    33  
    34  func (el *HTMLElement) MarshalJSON() ([]byte, error) {
    35  	return jettison.MarshalOpts(el.String(), jettison.NoHTMLEscaping())
    36  }
    37  
    38  func (el *HTMLElement) Type() core.Type {
    39  	return drivers.HTMLElementType
    40  }
    41  
    42  func (el *HTMLElement) String() string {
    43  	ih, err := el.GetInnerHTML(context.Background())
    44  
    45  	if err != nil {
    46  		return ""
    47  	}
    48  
    49  	return ih.String()
    50  }
    51  
    52  func (el *HTMLElement) Compare(other core.Value) int64 {
    53  	switch other.Type() {
    54  	case drivers.HTMLElementType:
    55  		other := other.(drivers.HTMLElement)
    56  
    57  		return int64(strings.Compare(el.String(), other.String()))
    58  	default:
    59  		return drivers.Compare(el.Type(), other.Type())
    60  	}
    61  }
    62  
    63  func (el *HTMLElement) Unwrap() interface{} {
    64  	return el.selection
    65  }
    66  
    67  func (el *HTMLElement) Hash() uint64 {
    68  	str, err := el.selection.Html()
    69  
    70  	if err != nil {
    71  		return 0
    72  	}
    73  
    74  	h := fnv.New64a()
    75  
    76  	h.Write([]byte(el.Type().String()))
    77  	h.Write([]byte(":"))
    78  	h.Write([]byte(str))
    79  
    80  	return h.Sum64()
    81  }
    82  
    83  func (el *HTMLElement) Copy() core.Value {
    84  	c, _ := NewHTMLElement(el.selection.Clone())
    85  
    86  	return c
    87  }
    88  
    89  func (el *HTMLElement) GetNodeType(_ context.Context) (values.Int, error) {
    90  	nodes := el.selection.Nodes
    91  
    92  	if len(nodes) == 0 {
    93  		return 0, nil
    94  	}
    95  
    96  	return values.NewInt(common.FromHTMLType(nodes[0].Type)), nil
    97  }
    98  
    99  func (el *HTMLElement) Close() error {
   100  	return nil
   101  }
   102  
   103  func (el *HTMLElement) GetNodeName(_ context.Context) (values.String, error) {
   104  	return values.NewString(goquery.NodeName(el.selection)), nil
   105  }
   106  
   107  func (el *HTMLElement) Length() values.Int {
   108  	if el.children == nil {
   109  		el.children = el.parseChildren()
   110  	}
   111  
   112  	return el.children.Length()
   113  }
   114  
   115  func (el *HTMLElement) GetValue(_ context.Context) (core.Value, error) {
   116  	val, ok := el.selection.Attr("value")
   117  
   118  	if ok {
   119  		return values.NewString(val), nil
   120  	}
   121  
   122  	return values.EmptyString, nil
   123  }
   124  
   125  func (el *HTMLElement) SetValue(_ context.Context, value core.Value) error {
   126  	el.selection.SetAttr("value", value.String())
   127  
   128  	return nil
   129  }
   130  
   131  func (el *HTMLElement) GetInnerText(_ context.Context) (values.String, error) {
   132  	return values.NewString(el.selection.Text()), nil
   133  }
   134  
   135  func (el *HTMLElement) SetInnerText(_ context.Context, innerText values.String) error {
   136  	el.selection.SetText(innerText.String())
   137  
   138  	return nil
   139  }
   140  
   141  func (el *HTMLElement) GetInnerHTML(_ context.Context) (values.String, error) {
   142  	h, err := el.selection.Html()
   143  
   144  	if err != nil {
   145  		return values.EmptyString, err
   146  	}
   147  
   148  	return values.NewString(h), nil
   149  }
   150  
   151  func (el *HTMLElement) SetInnerHTML(_ context.Context, value values.String) error {
   152  	el.selection.SetHtml(value.String())
   153  
   154  	return nil
   155  }
   156  
   157  func (el *HTMLElement) GetStyles(ctx context.Context) (*values.Object, error) {
   158  	if err := el.ensureStyles(ctx); err != nil {
   159  		return values.NewObject(), err
   160  	}
   161  
   162  	return el.styles.Copy().(*values.Object), nil
   163  }
   164  
   165  func (el *HTMLElement) GetStyle(ctx context.Context, name values.String) (core.Value, error) {
   166  	if err := el.ensureStyles(ctx); err != nil {
   167  		return values.None, err
   168  	}
   169  
   170  	return el.styles.MustGet(name), nil
   171  }
   172  
   173  func (el *HTMLElement) SetStyle(ctx context.Context, name, value values.String) error {
   174  	if err := el.ensureStyles(ctx); err != nil {
   175  		return err
   176  	}
   177  
   178  	el.styles.Set(name, value)
   179  
   180  	str := common.SerializeStyles(ctx, el.styles)
   181  
   182  	return el.SetAttribute(ctx, "style", str)
   183  }
   184  
   185  func (el *HTMLElement) SetStyles(ctx context.Context, newStyles *values.Object) error {
   186  	if newStyles == nil {
   187  		return nil
   188  	}
   189  
   190  	if err := el.ensureStyles(ctx); err != nil {
   191  		return err
   192  	}
   193  
   194  	newStyles.ForEach(func(i core.Value, key string) bool {
   195  		el.styles.Set(values.NewString(key), i)
   196  
   197  		return true
   198  	})
   199  
   200  	str := common.SerializeStyles(ctx, el.styles)
   201  
   202  	return el.SetAttribute(ctx, "style", str)
   203  }
   204  
   205  func (el *HTMLElement) RemoveStyle(ctx context.Context, name ...values.String) error {
   206  	if len(name) == 0 {
   207  		return nil
   208  	}
   209  
   210  	if err := el.ensureStyles(ctx); err != nil {
   211  		return err
   212  	}
   213  
   214  	for _, s := range name {
   215  		el.styles.Remove(s)
   216  	}
   217  
   218  	str := common.SerializeStyles(ctx, el.styles)
   219  
   220  	return el.SetAttribute(ctx, "style", str)
   221  }
   222  
   223  func (el *HTMLElement) SetAttributes(ctx context.Context, attrs *values.Object) error {
   224  	if attrs == nil {
   225  		return nil
   226  	}
   227  
   228  	el.ensureAttrs()
   229  
   230  	var err error
   231  
   232  	attrs.ForEach(func(value core.Value, key string) bool {
   233  		err = el.SetAttribute(ctx, values.NewString(key), values.NewString(value.String()))
   234  
   235  		return err == nil
   236  	})
   237  
   238  	return err
   239  }
   240  
   241  func (el *HTMLElement) GetAttributes(_ context.Context) (*values.Object, error) {
   242  	el.ensureAttrs()
   243  
   244  	return el.attrs.Copy().(*values.Object), nil
   245  }
   246  
   247  func (el *HTMLElement) GetAttribute(ctx context.Context, name values.String) (core.Value, error) {
   248  	el.ensureAttrs()
   249  
   250  	if name == common.AttrNameStyle {
   251  		return el.GetStyles(ctx)
   252  	}
   253  
   254  	return el.attrs.MustGet(name), nil
   255  }
   256  
   257  func (el *HTMLElement) SetAttribute(_ context.Context, name, value values.String) error {
   258  	el.ensureAttrs()
   259  
   260  	if name == common.AttrNameStyle {
   261  		el.styles = nil
   262  	}
   263  
   264  	el.attrs.Set(name, value)
   265  	el.selection.SetAttr(string(name), string(value))
   266  
   267  	return nil
   268  }
   269  
   270  func (el *HTMLElement) RemoveAttribute(_ context.Context, name ...values.String) error {
   271  	el.ensureAttrs()
   272  
   273  	for _, attr := range name {
   274  		el.attrs.Remove(attr)
   275  		el.selection.RemoveAttr(attr.String())
   276  	}
   277  
   278  	return nil
   279  }
   280  
   281  func (el *HTMLElement) GetChildNodes(_ context.Context) (*values.Array, error) {
   282  	if el.children == nil {
   283  		el.children = el.parseChildren()
   284  	}
   285  
   286  	return el.children.Copy().(*values.Array), nil
   287  }
   288  
   289  func (el *HTMLElement) GetChildNode(_ context.Context, idx values.Int) (core.Value, error) {
   290  	if el.children == nil {
   291  		el.children = el.parseChildren()
   292  	}
   293  
   294  	return el.children.Get(idx), nil
   295  }
   296  
   297  func (el *HTMLElement) QuerySelector(_ context.Context, selector drivers.QuerySelector) (core.Value, error) {
   298  	if selector.Kind() == drivers.CSSSelector {
   299  		selection := el.selection.Find(selector.String())
   300  
   301  		if selection.Length() == 0 {
   302  			return values.None, drivers.ErrNotFound
   303  		}
   304  
   305  		res, err := NewHTMLElement(selection)
   306  
   307  		if err != nil {
   308  			return values.None, err
   309  		}
   310  
   311  		return res, nil
   312  	}
   313  
   314  	found, err := EvalXPathToNode(el.selection, selector.String())
   315  
   316  	if err != nil {
   317  		return values.None, err
   318  	}
   319  
   320  	if found == nil {
   321  		return values.None, drivers.ErrNotFound
   322  	}
   323  
   324  	return found, nil
   325  }
   326  
   327  func (el *HTMLElement) QuerySelectorAll(_ context.Context, selector drivers.QuerySelector) (*values.Array, error) {
   328  	if selector.Kind() == drivers.CSSSelector {
   329  		selection := el.selection.Find(selector.String())
   330  
   331  		if selection.Length() == 0 {
   332  			return values.NewArray(0), nil
   333  		}
   334  
   335  		arr := values.NewArray(selection.Length())
   336  
   337  		selection.Each(func(i int, selection *goquery.Selection) {
   338  			el, err := NewHTMLElement(selection)
   339  
   340  			if err == nil {
   341  				arr.Push(el)
   342  			}
   343  		})
   344  
   345  		return arr, nil
   346  	}
   347  
   348  	return EvalXPathToNodes(el.selection, selector.String())
   349  }
   350  
   351  func (el *HTMLElement) XPath(_ context.Context, expression values.String) (core.Value, error) {
   352  	return EvalXPathTo(el.selection, expression.String())
   353  }
   354  
   355  func (el *HTMLElement) SetInnerHTMLBySelector(ctx context.Context, selector drivers.QuerySelector, innerHTML values.String) error {
   356  	if selector.Kind() == drivers.CSSSelector {
   357  		selection := el.selection.Find(selector.String())
   358  
   359  		if selection.Length() == 0 {
   360  			return drivers.ErrNotFound
   361  		}
   362  
   363  		selection.SetHtml(innerHTML.String())
   364  	}
   365  
   366  	found, err := EvalXPathToElement(el.selection, selector.String())
   367  
   368  	if err != nil {
   369  		return err
   370  	}
   371  
   372  	if found == nil {
   373  		return drivers.ErrNotFound
   374  	}
   375  
   376  	return found.SetInnerHTML(ctx, innerHTML)
   377  }
   378  
   379  func (el *HTMLElement) GetInnerHTMLBySelector(ctx context.Context, selector drivers.QuerySelector) (values.String, error) {
   380  	if selector.Kind() == drivers.CSSSelector {
   381  		selection := el.selection.Find(selector.String())
   382  
   383  		if selection.Length() == 0 {
   384  			return values.EmptyString, drivers.ErrNotFound
   385  		}
   386  
   387  		str, err := selection.Html()
   388  
   389  		if err != nil {
   390  			return values.EmptyString, err
   391  		}
   392  
   393  		return values.NewString(str), nil
   394  	}
   395  
   396  	found, err := EvalXPathToElement(el.selection, selector.String())
   397  
   398  	if err != nil {
   399  		return values.EmptyString, err
   400  	}
   401  
   402  	if found == nil {
   403  		return values.EmptyString, drivers.ErrNotFound
   404  	}
   405  
   406  	return found.GetInnerHTML(ctx)
   407  }
   408  
   409  func (el *HTMLElement) GetInnerHTMLBySelectorAll(ctx context.Context, selector drivers.QuerySelector) (*values.Array, error) {
   410  	if selector.Kind() == drivers.CSSSelector {
   411  		var err error
   412  		selection := el.selection.Find(selector.String())
   413  		arr := values.NewArray(selection.Length())
   414  
   415  		selection.EachWithBreak(func(_ int, selection *goquery.Selection) bool {
   416  			str, e := selection.Html()
   417  
   418  			if e != nil {
   419  				err = e
   420  				return false
   421  			}
   422  
   423  			arr.Push(values.NewString(strings.TrimSpace(str)))
   424  
   425  			return true
   426  		})
   427  
   428  		if err != nil {
   429  			return values.NewArray(0), err
   430  		}
   431  
   432  		return arr, nil
   433  	}
   434  
   435  	return EvalXPathToNodesWith(el.selection, selector.String(), func(node *html.Node) (core.Value, error) {
   436  		n, err := parseXPathNode(node)
   437  
   438  		if err != nil {
   439  			return values.None, err
   440  		}
   441  
   442  		found, err := drivers.ToElement(n)
   443  
   444  		if err != nil {
   445  			return values.None, err
   446  		}
   447  
   448  		return found.GetInnerHTML(ctx)
   449  	})
   450  }
   451  
   452  func (el *HTMLElement) GetInnerTextBySelector(ctx context.Context, selector drivers.QuerySelector) (values.String, error) {
   453  	if selector.Kind() == drivers.CSSSelector {
   454  		selection := el.selection.Find(selector.String())
   455  
   456  		if selection.Length() == 0 {
   457  			return values.EmptyString, drivers.ErrNotFound
   458  		}
   459  
   460  		return values.NewString(selection.Text()), nil
   461  	}
   462  
   463  	found, err := EvalXPathToElement(el.selection, selector.String())
   464  
   465  	if err != nil {
   466  		return values.EmptyString, err
   467  	}
   468  
   469  	if found == nil {
   470  		return values.EmptyString, drivers.ErrNotFound
   471  	}
   472  
   473  	return found.GetInnerText(ctx)
   474  }
   475  
   476  func (el *HTMLElement) SetInnerTextBySelector(ctx context.Context, selector drivers.QuerySelector, innerText values.String) error {
   477  	if selector.Kind() == drivers.CSSSelector {
   478  		selection := el.selection.Find(selector.String())
   479  
   480  		if selection.Length() == 0 {
   481  			return drivers.ErrNotFound
   482  		}
   483  
   484  		selection.SetHtml(innerText.String())
   485  
   486  		return nil
   487  	}
   488  
   489  	found, err := EvalXPathToElement(el.selection, selector.String())
   490  
   491  	if err != nil {
   492  		return err
   493  	}
   494  
   495  	if found == nil {
   496  		return drivers.ErrNotFound
   497  	}
   498  
   499  	return found.SetInnerText(ctx, innerText)
   500  }
   501  
   502  func (el *HTMLElement) GetInnerTextBySelectorAll(ctx context.Context, selector drivers.QuerySelector) (*values.Array, error) {
   503  	if selector.Kind() == drivers.CSSSelector {
   504  		selection := el.selection.Find(selector.String())
   505  		arr := values.NewArray(selection.Length())
   506  
   507  		selection.Each(func(_ int, selection *goquery.Selection) {
   508  			arr.Push(values.NewString(selection.Text()))
   509  		})
   510  
   511  		return arr, nil
   512  	}
   513  
   514  	return EvalXPathToNodesWith(el.selection, selector.String(), func(node *html.Node) (core.Value, error) {
   515  		n, err := parseXPathNode(node)
   516  
   517  		if err != nil {
   518  			return values.None, err
   519  		}
   520  
   521  		found, err := drivers.ToElement(n)
   522  
   523  		if err != nil {
   524  			return values.None, err
   525  		}
   526  
   527  		return found.GetInnerText(ctx)
   528  	})
   529  }
   530  
   531  func (el *HTMLElement) CountBySelector(_ context.Context, selector drivers.QuerySelector) (values.Int, error) {
   532  	if selector.Kind() == drivers.CSSSelector {
   533  		selection := el.selection.Find(selector.String())
   534  
   535  		return values.NewInt(selection.Length()), nil
   536  	}
   537  
   538  	arr, err := EvalXPathToNodesWith(el.selection, selector.String(), func(node *html.Node) (core.Value, error) {
   539  		return values.None, nil
   540  	})
   541  
   542  	if err != nil {
   543  		return values.ZeroInt, err
   544  	}
   545  
   546  	return arr.Length(), nil
   547  }
   548  
   549  func (el *HTMLElement) ExistsBySelector(_ context.Context, selector drivers.QuerySelector) (values.Boolean, error) {
   550  	if selector.Kind() == drivers.CSSSelector {
   551  		selection := el.selection.Find(selector.String())
   552  
   553  		if selection.Length() == 0 {
   554  			return values.False, nil
   555  		}
   556  
   557  		return values.True, nil
   558  	}
   559  
   560  	found, err := EvalXPathToNode(el.selection, selector.String())
   561  
   562  	if err != nil {
   563  		return values.False, err
   564  	}
   565  
   566  	return values.NewBoolean(found != nil), nil
   567  }
   568  
   569  func (el *HTMLElement) GetIn(ctx context.Context, path []core.Value) (core.Value, core.PathError) {
   570  	return common.GetInElement(ctx, path, el)
   571  }
   572  
   573  func (el *HTMLElement) SetIn(ctx context.Context, path []core.Value, value core.Value) core.PathError {
   574  	return common.SetInElement(ctx, path, el, value)
   575  }
   576  
   577  func (el *HTMLElement) Iterate(_ context.Context) (core.Iterator, error) {
   578  	return common.NewIterator(el)
   579  }
   580  
   581  func (el *HTMLElement) GetParentElement(_ context.Context) (core.Value, error) {
   582  	parent := el.selection.Parent()
   583  
   584  	if parent == nil {
   585  		return values.None, nil
   586  	}
   587  
   588  	return NewHTMLElement(parent)
   589  }
   590  
   591  func (el *HTMLElement) GetPreviousElementSibling(_ context.Context) (core.Value, error) {
   592  	sibling := el.selection.Prev()
   593  
   594  	if sibling == nil {
   595  		return values.None, nil
   596  	}
   597  
   598  	return NewHTMLElement(sibling)
   599  }
   600  
   601  func (el *HTMLElement) GetNextElementSibling(_ context.Context) (core.Value, error) {
   602  	sibling := el.selection.Next()
   603  
   604  	if sibling == nil {
   605  		return values.None, nil
   606  	}
   607  
   608  	return NewHTMLElement(sibling)
   609  }
   610  
   611  func (el *HTMLElement) Click(_ context.Context, _ values.Int) error {
   612  	return core.ErrNotSupported
   613  }
   614  
   615  func (el *HTMLElement) ClickBySelector(_ context.Context, _ drivers.QuerySelector, _ values.Int) error {
   616  	return core.ErrNotSupported
   617  }
   618  
   619  func (el *HTMLElement) ClickBySelectorAll(_ context.Context, _ drivers.QuerySelector, _ values.Int) error {
   620  	return core.ErrNotSupported
   621  }
   622  
   623  func (el *HTMLElement) Clear(_ context.Context) error {
   624  	return core.ErrNotSupported
   625  }
   626  
   627  func (el *HTMLElement) ClearBySelector(_ context.Context, _ drivers.QuerySelector) error {
   628  	return core.ErrNotSupported
   629  }
   630  
   631  func (el *HTMLElement) Input(_ context.Context, _ core.Value, _ values.Int) error {
   632  	return core.ErrNotSupported
   633  }
   634  
   635  func (el *HTMLElement) InputBySelector(_ context.Context, _ drivers.QuerySelector, _ core.Value, _ values.Int) error {
   636  	return core.ErrNotSupported
   637  }
   638  
   639  func (el *HTMLElement) Press(_ context.Context, _ []values.String, _ values.Int) error {
   640  	return core.ErrNotSupported
   641  }
   642  
   643  func (el *HTMLElement) PressBySelector(_ context.Context, _ drivers.QuerySelector, _ []values.String, _ values.Int) error {
   644  	return core.ErrNotSupported
   645  }
   646  
   647  func (el *HTMLElement) Select(_ context.Context, _ *values.Array) (*values.Array, error) {
   648  	return nil, core.ErrNotSupported
   649  }
   650  
   651  func (el *HTMLElement) SelectBySelector(_ context.Context, _ drivers.QuerySelector, _ *values.Array) (*values.Array, error) {
   652  	return nil, core.ErrNotSupported
   653  }
   654  
   655  func (el *HTMLElement) ScrollIntoView(_ context.Context, _ drivers.ScrollOptions) error {
   656  	return core.ErrNotSupported
   657  }
   658  
   659  func (el *HTMLElement) Focus(_ context.Context) error {
   660  	return core.ErrNotSupported
   661  }
   662  
   663  func (el *HTMLElement) FocusBySelector(_ context.Context, _ drivers.QuerySelector) error {
   664  	return core.ErrNotSupported
   665  }
   666  
   667  func (el *HTMLElement) Blur(_ context.Context) error {
   668  	return core.ErrNotSupported
   669  }
   670  
   671  func (el *HTMLElement) BlurBySelector(_ context.Context, _ drivers.QuerySelector) error {
   672  	return core.ErrNotSupported
   673  }
   674  
   675  func (el *HTMLElement) Hover(_ context.Context) error {
   676  	return core.ErrNotSupported
   677  }
   678  
   679  func (el *HTMLElement) HoverBySelector(_ context.Context, _ drivers.QuerySelector) error {
   680  	return core.ErrNotSupported
   681  }
   682  
   683  func (el *HTMLElement) WaitForClass(_ context.Context, _ values.String, _ drivers.WaitEvent) error {
   684  	return core.ErrNotSupported
   685  }
   686  
   687  func (el *HTMLElement) WaitForElement(_ context.Context, _ drivers.QuerySelector, _ drivers.WaitEvent) error {
   688  	return core.ErrNotSupported
   689  }
   690  
   691  func (el *HTMLElement) WaitForElementAll(_ context.Context, _ drivers.QuerySelector, _ drivers.WaitEvent) error {
   692  	return core.ErrNotSupported
   693  }
   694  
   695  func (el *HTMLElement) WaitForAttribute(_ context.Context, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   696  	return core.ErrNotSupported
   697  }
   698  
   699  func (el *HTMLElement) WaitForAttributeBySelector(_ context.Context, _ drivers.QuerySelector, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   700  	return core.ErrNotSupported
   701  }
   702  
   703  func (el *HTMLElement) WaitForAttributeBySelectorAll(_ context.Context, _ drivers.QuerySelector, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   704  	return core.ErrNotSupported
   705  }
   706  
   707  func (el *HTMLElement) WaitForStyle(_ context.Context, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   708  	return core.ErrNotSupported
   709  }
   710  
   711  func (el *HTMLElement) WaitForStyleBySelector(_ context.Context, _ drivers.QuerySelector, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   712  	return core.ErrNotSupported
   713  }
   714  
   715  func (el *HTMLElement) WaitForStyleBySelectorAll(_ context.Context, _ drivers.QuerySelector, _ values.String, _ core.Value, _ drivers.WaitEvent) error {
   716  	return core.ErrNotSupported
   717  }
   718  
   719  func (el *HTMLElement) WaitForClassBySelector(_ context.Context, _ drivers.QuerySelector, _ values.String, _ drivers.WaitEvent) error {
   720  	return core.ErrNotSupported
   721  }
   722  
   723  func (el *HTMLElement) WaitForClassBySelectorAll(_ context.Context, _ drivers.QuerySelector, _ values.String, _ drivers.WaitEvent) error {
   724  	return core.ErrNotSupported
   725  }
   726  
   727  func (el *HTMLElement) ensureStyles(ctx context.Context) error {
   728  	if el.styles == nil {
   729  		styles, err := el.parseStyles(ctx)
   730  
   731  		if err != nil {
   732  			return err
   733  		}
   734  
   735  		el.styles = styles
   736  	}
   737  
   738  	return nil
   739  }
   740  
   741  func (el *HTMLElement) parseStyles(ctx context.Context) (*values.Object, error) {
   742  	str, err := el.GetAttribute(ctx, "style")
   743  
   744  	if err != nil {
   745  		return values.NewObject(), err
   746  	}
   747  
   748  	if str == values.None {
   749  		return values.NewObject(), nil
   750  	}
   751  
   752  	styles, err := common.DeserializeStyles(values.NewString(str.String()))
   753  
   754  	if err != nil {
   755  		return nil, err
   756  	}
   757  
   758  	return styles, nil
   759  }
   760  
   761  func (el *HTMLElement) ensureAttrs() {
   762  	if el.attrs == nil {
   763  		el.attrs = el.parseAttrs()
   764  	}
   765  }
   766  
   767  func (el *HTMLElement) parseAttrs() *values.Object {
   768  	obj := values.NewObject()
   769  
   770  	if len(el.selection.Nodes) == 0 {
   771  		return obj
   772  	}
   773  
   774  	node := el.selection.Nodes[0]
   775  
   776  	for _, attr := range node.Attr {
   777  		obj.Set(values.NewString(attr.Key), values.NewString(attr.Val))
   778  	}
   779  
   780  	return obj
   781  }
   782  
   783  func (el *HTMLElement) parseChildren() *values.Array {
   784  	children := el.selection.Children()
   785  
   786  	arr := values.NewArray(10)
   787  
   788  	children.Each(func(i int, selection *goquery.Selection) {
   789  		child, err := NewHTMLElement(selection)
   790  
   791  		if err == nil {
   792  			arr.Push(child)
   793  		}
   794  	})
   795  
   796  	return arr
   797  }