-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
serialize.go
95 lines (84 loc) · 2.73 KB
/
serialize.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
*
* k6 - a next-generation load testing tool
* Copyright (C) 2016 Load Impact
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package html
import (
neturl "net/url"
"github.com/PuerkitoBio/goquery"
"github.com/dop251/goja"
)
type FormValue struct {
Name string
Value goja.Value
}
// nolint: goconst
func (s Selection) SerializeArray() []FormValue {
submittableSelector := "input,select,textarea,keygen"
var formElements *goquery.Selection
if s.sel.Is("form") {
formElements = s.sel.Find(submittableSelector)
} else {
formElements = s.sel.Filter(submittableSelector)
}
formElements = formElements.FilterFunction(func(i int, sel *goquery.Selection) bool {
name := sel.AttrOr("name", "")
inputType := sel.AttrOr("type", "")
disabled := sel.AttrOr("disabled", "")
checked := sel.AttrOr("checked", "")
return name != "" && // Must have a non-empty name
disabled != "disabled" && // Must not be disabled
inputType != "submit" && // Must not be a button
inputType != "button" &&
inputType != "reset" &&
inputType != "image" && // Must not be an image or file
inputType != "file" &&
(checked == "checked" || (inputType != "checkbox" && inputType != "radio")) // Must be checked if it is an checkbox or radio
})
result := make([]FormValue, len(formElements.Nodes))
formElements.Each(func(i int, sel *goquery.Selection) {
element := Selection{s.rt, sel, s.URL}
name, _ := sel.Attr("name")
result[i] = FormValue{Name: name, Value: element.Val()}
})
return result
}
func (s Selection) SerializeObject() map[string]goja.Value {
formValues := s.SerializeArray()
result := make(map[string]goja.Value)
for i := range formValues {
formValue := formValues[i]
result[formValue.Name] = formValue.Value
}
return result
}
func (s Selection) Serialize() string {
formValues := s.SerializeArray()
urlValues := make(neturl.Values, len(formValues))
for i := range formValues {
formValue := formValues[i]
value := formValue.Value.Export()
switch v := value.(type) {
case string:
urlValues.Set(formValue.Name, v)
case []string:
urlValues[formValue.Name] = v
}
}
return urlValues.Encode()
}