Skip to content

Commit 78d99b9

Browse files
add jQuery API
1 parent 35a1a04 commit 78d99b9

21 files changed

+1491
-1155
lines changed

README.md

Lines changed: 73 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,15 @@
99
<p align="center">
1010
<a href="https://pkg.go.dev/github.com/bringmetheaugust/goDOM"><img src="https://pkg.go.dev/badge/github.com/stretchr/testify" alt="Doc reference"></a>
1111
<a href="https://lh3.googleusercontent.com/proxy/w2a-pc4X9z2kuDWoXKnSF8pY6ngZvjVuZOAXMz3ZR8NwaUj9a-KsJnpcjtUSRO9QtFV6vMb3YoHWWv6k43Cb6bHOJEka19uE54GWtVx7Lru8gi10I_968eA2thkA0dL1O-zA8WT24cI"><img src="https://img.shields.io/badge/go%20version-1.21.5-61CFDD.svg?style=flat-square" alt="Golang version"></a>
12-
<a href="https://cs4.pikabu.ru/post_img/big/2014/12/15/4/1418619408_1209550583.jpg"><img src="https://img.shields.io/badge/version-0.2.2-blue" alt="project version"></a>
12+
<a href="https://cs4.pikabu.ru/post_img/big/2014/12/15/4/1418619408_1209550583.jpg"><img src="https://img.shields.io/badge/version-0.3.0-blue" alt="project version"></a>
1313
</p>
1414

1515
Made by front-ender for front-enders.
16-
Package provide method to parse HTML and get browser-like [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction#what_is_the_dom) and DOM API.
17-
It's only for reading DOM, searching elements and getting their data.
18-
Doesn't have methods to mutate DOM.
16+
Package provide method to parse HTML and get browser-like [DOM](https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model/Introduction#what_is_the_dom) and DOM API.
17+
It also has [jQuery](https://jquery.com/)-like API.
1918

19+
⚠️It's only for reading DOM, searching elements and getting their data.
20+
Package doesn't have methods to mutate DOM.
2021
⚠️Before using it You should remember that sites can detect You as a bot and return unexpected HTML response.
2122

2223
## Installation
@@ -25,39 +26,57 @@ Doesn't have methods to mutate DOM.
2526

2627
## Examples
2728

28-
* First, we'll get document
29+
#### Using DOM-like API
2930

3031
```go
3132
package motherfckrs
3233

3334
import "github.com/bringmetheaugust/goDOM"
3435

3536
func main() {
37+
// First, we'll get document
3638
bytes := // HTML markup as bytes (from HTTP request, files, etc.)
37-
document, domErr := goDom.Create(bytes) // create document (DOM with DOM API, like in browser)
38-
if domErr != nil {return} // also check if markup is valid
39+
document, _, err := goDom.Create(bytes) // create document (DOM with DOM API, like in browser)
40+
if err != nil {return} // also check if markup is valid
41+
42+
// Want to find some element by `id`?
43+
el, err := document.GetElementById("lol") // <a id="lol" class="pipi" href="http://lol.com">
44+
if err != nil {return} // check if element exists
45+
print(el.ClassList) // ["pipi"]
46+
print(el.Attributes) // {"id": "lol", class: "pipi", "href": "http://lol.com"}
47+
attr, _ := el.GetAttribute("href") // "http://lol.com"
48+
49+
// Or get a lot of elements by query selector?
50+
elements, err := document.QuerySelectorAll(".weee") // all elements in DOM which have class "weee"
51+
if err != nil {return} // check if elements are existed
52+
for _, el := range elements { // loop slice with existed elements
53+
// your best code here
54+
}
3955
```
40-
* Find some element by `id`
56+
57+
#### Using jQuery-like API
4158
4259
```go
43-
el, elErr := document.GetElementById("lol") // <a id="lol" class="pipi" href="http://lol.com">
44-
if elErr != nil {return} // check if element exists
45-
fmt.Println(el.ClassList) // ["pipi"]
46-
fmt.Println(el.Attributes) // {"id": "lol", class: "pipi", "href": "http://lol.com"}
47-
fmt.Println(el.GetAttribute("href")) // "http://lol.com"
48-
```
60+
package motherfckrs
61+
62+
import "github.com/bringmetheaugust/goDOM"
4963

50-
* Or get a lot of elements by [query selector](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll)
64+
func main() {
65+
// First, we'll get document
66+
bytes := // HTML markup as bytes (from HTTP request, files, etc.)
67+
_, jQ, err := goDom.Create(bytes) // create jQ (jQuery with jQUery-like API)
68+
if err != nil {return} // also check if markup is valid
5169

52-
```go
53-
elements, elementsErr := document.QuerySelectorAll(".weee") // all elements in DOM which have class "weee"
54-
if elementsErr != nil {return} // check if elements are existed
55-
for _, el := range elements { // loop slice with existed elements
56-
// your best code here
57-
}
70+
// Want to find some element by `id` ?
71+
attr, err := jQ("#lol").Attr("href") // "http://lol.com" from <a id="lol" class="pipi" href="http://lol.com">
72+
73+
// Or get `data-lol` attributes from elements with class `.wee` which have inside itself links with class `.piu`?
74+
jQ(".wee").Has("a.piu").Each(func(q) {
75+
a, _ := q.Attr("data-lol")
76+
})
5877
```
5978
60-
#### More real examples [here](./examples/).
79+
#### More real examples [here](./examples).
6180
6281
## Docs
6382
@@ -91,6 +110,7 @@ func main() {
91110
* [GetElementById](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById)
92111
* [GetElementsByClassName](https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName)
93112
* [GetElementsByTagName](https://developer.mozilla.org/en-US/docs/Web/API/Element/getElementsByTagName)
113+
* [Contains](https://developer.mozilla.org/en-US/docs/Web/API/Node/contains)
94114
95115
* fields
96116
@@ -105,6 +125,37 @@ func main() {
105125
* [NextElementSibling](https://developer.mozilla.org/en-US/docs/Web/API/Element/nextElementSibling)
106126
* [PreviousElementSibling](https://developer.mozilla.org/en-US/docs/Web/API/Element/previousElementSibling)
107127
128+
### jQuery
129+
130+
* [Attr](https://api.jquery.com/attr)
131+
* [Children](https://api.jquery.com/children)
132+
* [Each](https://api.jquery.com/each)
133+
* [Filter](https://api.jquery.com/filter)
134+
* [Find](https://api.jquery.com/find)
135+
* [First](https://api.jquery.com/first)
136+
* [Has](https://api.jquery.com/has)
137+
138+
## Something about jQuery API
139+
140+
This package uses jQuery API as the origin jQuery library (using JavaScript).
141+
For example in Golang with best practice, we should return data and/or errors almost from each function. How it should look like:
142+
143+
```go
144+
a, err := jQ(".li") // get elements with `li` classes
145+
if err != nil { return } // check if elements exist
146+
b, err := a.Has("a.my-link") // filter if they have links with class `my-link` inside itself
147+
if err != nil { return } // check if elements exist
148+
c, err := b.Find("div[data-lol=lala]") // find `div` elements with attribute `data-lol=lala` inside
149+
if err != nil {return} // check if elements exist
150+
c.Each(func (q) { print(q) })
151+
```
152+
153+
As You know, this package provides the original jQuery API, so every method (except `Attr`) always returns another jQuery element, even if elements are not found and a slice of elements is empty. So we can use jQuery as in origin jQuery library like this:
154+
155+
```go
156+
jQ(".li").Has("a.my-link").Find("div[data-lol=lala]").Each(func (q) { print(q) })
157+
```
158+
108159
## Development
109160
110161
via Makefile

assets/repo_logo.png

23.7 KB
Loading

buildDOM.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ rootLopp:
6666
topFromParentStack.TextContent = currEl.TextContent
6767
}
6868

69-
// append Children
7069
if len(parentStack) > 0 {
7170
parent := parentStack[len(parentStack)-1]
7271
parent.Children = append(parent.Children, topFromParentStack)
@@ -108,6 +107,14 @@ rootLopp:
108107
}
109108
}
110109

110+
// set ParentElement
111+
switch {
112+
case currEl != nil:
113+
newEl.ParentElement = currEl
114+
case len(parentStack) > 0:
115+
newEl.ParentElement = parentStack[len(parentStack)-1]
116+
}
117+
111118
switch {
112119
case t.Type == html.SelfClosingTagToken, t.Type == html.StartTagToken && isSelfClosingTag(t.Data):
113120
if currEl != nil {
@@ -119,8 +126,6 @@ rootLopp:
119126
case t.Type == html.StartTagToken:
120127
if currEl != nil {
121128
parentStack = append(parentStack, currEl)
122-
// currEl.Children = append(currEl.Children, newEl)
123-
newEl.ParentElement = currEl
124129
}
125130

126131
currEl = newEl

0 commit comments

Comments
 (0)