github.com/MontFerret/ferret@v0.18.0/pkg/drivers/common/setter.go (about) 1 package common 2 3 import ( 4 "context" 5 6 "github.com/MontFerret/ferret/pkg/drivers" 7 "github.com/MontFerret/ferret/pkg/runtime/core" 8 "github.com/MontFerret/ferret/pkg/runtime/values" 9 "github.com/MontFerret/ferret/pkg/runtime/values/types" 10 ) 11 12 func SetInPage(ctx context.Context, path []core.Value, page drivers.HTMLPage, value core.Value) core.PathError { 13 if len(path) == 0 { 14 return nil 15 } 16 17 return SetInDocument(ctx, path, page.GetMainFrame(), value) 18 } 19 20 func SetInDocument(ctx context.Context, path []core.Value, doc drivers.HTMLDocument, value core.Value) core.PathError { 21 if len(path) == 0 { 22 return nil 23 } 24 25 return SetInNode(ctx, path, doc, value) 26 } 27 28 func SetInElement(ctx context.Context, path []core.Value, el drivers.HTMLElement, value core.Value) core.PathError { 29 if len(path) == 0 { 30 return nil 31 } 32 33 segmentIdx := 0 34 segment := path[segmentIdx] 35 36 if segment.Type() == types.String { 37 segment := segment.(values.String) 38 39 switch segment { 40 case "attributes": 41 if len(path) > 1 { 42 attrName := path[1] 43 err := el.SetAttribute(ctx, values.NewString(attrName.String()), values.NewString(value.String())) 44 45 if err != nil { 46 return core.NewPathError(err, segmentIdx) 47 } 48 49 return nil 50 } 51 52 err := core.ValidateType(value, types.Object) 53 54 if err != nil { 55 return core.NewPathError(err, segmentIdx) 56 } 57 58 curr, err := el.GetAttributes(ctx) 59 60 if err != nil { 61 return core.NewPathError(err, segmentIdx) 62 } 63 64 // remove all previous attributes 65 err = el.RemoveAttribute(ctx, curr.Keys()...) 66 67 if err != nil { 68 return core.NewPathError(err, segmentIdx) 69 } 70 71 obj := value.(*values.Object) 72 obj.ForEach(func(value core.Value, key string) bool { 73 err = el.SetAttribute(ctx, values.NewString(key), values.NewString(value.String())) 74 75 return err == nil 76 }) 77 78 if err != nil { 79 return core.NewPathError(err, segmentIdx) 80 } 81 82 return nil 83 case "style": 84 if len(path) > 1 { 85 attrName := path[1] 86 87 err := el.SetStyle(ctx, values.NewString(attrName.String()), values.NewString(value.String())) 88 89 if err != nil { 90 return core.NewPathError(err, segmentIdx) 91 } 92 93 return nil 94 } 95 96 err := core.ValidateType(value, types.Object) 97 98 if err != nil { 99 return core.NewPathError(err, segmentIdx) 100 } 101 102 styles, err := el.GetStyles(ctx) 103 104 if err != nil { 105 return core.NewPathError(err, segmentIdx) 106 } 107 108 err = el.RemoveStyle(ctx, styles.Keys()...) 109 110 obj := value.(*values.Object) 111 obj.ForEach(func(value core.Value, key string) bool { 112 err = el.SetStyle(ctx, values.NewString(key), values.NewString(value.String())) 113 114 return err == nil 115 }) 116 117 if err != nil { 118 return core.NewPathError(err, segmentIdx) 119 } 120 121 return nil 122 case "value": 123 if len(path) > 1 { 124 return core.NewPathError(ErrInvalidPath, segmentIdx+1) 125 } 126 127 err := el.SetValue(ctx, value) 128 129 if err != nil { 130 return core.NewPathError(err, segmentIdx) 131 } 132 133 return nil 134 } 135 } 136 137 return SetInNode(ctx, path, el, value) 138 } 139 140 func SetInNode(_ context.Context, path []core.Value, _ drivers.HTMLNode, _ core.Value) core.PathError { 141 if len(path) == 0 { 142 return nil 143 } 144 145 return core.NewPathError(ErrReadOnly, 0) 146 }