Skip to content

Commit b9218a0

Browse files
authored
fix: There can be repeating anchors. This adds separates levels. (#34)
Refs: - #33
1 parent a3f5443 commit b9218a0

File tree

2 files changed

+54
-49
lines changed

2 files changed

+54
-49
lines changed

diff.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const LiveRendered = "live-rendered"
1717

1818
// liveAnchorPrefix prefixes injected anchors.
1919
const liveAnchorPrefix = "_l"
20+
const liveAnchorSep = -1
2021

2122
// PatchAction available actions to take by a patch.
2223
type PatchAction uint32
@@ -35,7 +36,7 @@ type anchorGenerator struct {
3536
}
3637

3738
func newAnchorGenerator() anchorGenerator {
38-
return anchorGenerator{idx: []int{0}}
39+
return anchorGenerator{idx: []int{}}
3940
}
4041

4142
// inc increment the current index.
@@ -50,14 +51,18 @@ func (n anchorGenerator) inc() anchorGenerator {
5051
func (n anchorGenerator) level() anchorGenerator {
5152
o := make([]int, len(n.idx))
5253
copy(o, n.idx)
53-
o = append(o, 0)
54+
o = append(o, liveAnchorSep, 0)
5455
return anchorGenerator{idx: o}
5556
}
5657

5758
func (n anchorGenerator) String() string {
5859
out := liveAnchorPrefix
5960
for _, i := range n.idx {
60-
out += fmt.Sprintf("%d", i)
61+
if i == liveAnchorSep {
62+
out += "_"
63+
} else {
64+
out += fmt.Sprintf("%d", i)
65+
}
6166
}
6267
return out
6368
}

diff_test.go

+46-46
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func TestSingleTextChange(t *testing.T) {
2020
root: "<div>Hello</div>",
2121
proposed: "<div>World</div>",
2222
patches: []Patch{
23-
{Anchor: "_l0010", Action: Replace, HTML: `<div _l0010="">World</div>`},
23+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div _l_0_1_0="">World</div>`},
2424
},
2525
}, t)
2626
}
@@ -30,8 +30,8 @@ func TestMultipleTextChange(t *testing.T) {
3030
root: `<div>Hello</div><div>World</div>`,
3131
proposed: `<div>World</div><div>Hello</div>`,
3232
patches: []Patch{
33-
{Anchor: "_l0010", Action: Replace, HTML: `<div _l0010="">World</div>`},
34-
{Anchor: "_l0011", Action: Replace, HTML: `<div _l0011="">Hello</div>`},
33+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div _l_0_1_0="">World</div>`},
34+
{Anchor: "_l_0_1_1", Action: Replace, HTML: `<div _l_0_1_1="">Hello</div>`},
3535
},
3636
}, t)
3737
}
@@ -41,15 +41,15 @@ func TestNodeAppend(t *testing.T) {
4141
root: `<div>World</div>`,
4242
proposed: `<div>Hello</div><div>World</div>`,
4343
patches: []Patch{
44-
{Anchor: "_l0010", Action: Replace, HTML: `<div _l0010="">Hello</div>`},
45-
{Anchor: "_l001", Action: Append, HTML: `<div _l0011="">World</div>`},
44+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div _l_0_1_0="">Hello</div>`},
45+
{Anchor: "_l_0_1", Action: Append, HTML: `<div _l_0_1_1="">World</div>`},
4646
},
4747
}, t)
4848
runDiffTest(diffTest{
4949
root: `<div>Hello</div>`,
5050
proposed: `<div>Hello</div><div>World</div>`,
5151
patches: []Patch{
52-
{Anchor: "_l001", Action: Append, HTML: `<div _l0011="">World</div>`},
52+
{Anchor: "_l_0_1", Action: Append, HTML: `<div _l_0_1_1="">World</div>`},
5353
},
5454
}, t)
5555
}
@@ -59,15 +59,15 @@ func TestNodeDeletion(t *testing.T) {
5959
root: `<div>Hello</div><div>World</div>`,
6060
proposed: `<div>World</div>`,
6161
patches: []Patch{
62-
{Anchor: "_l0010", Action: Replace, HTML: `<div _l0010="">World</div>`},
63-
{Anchor: "_l0011", Action: Replace, HTML: ""},
62+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div _l_0_1_0="">World</div>`},
63+
{Anchor: "_l_0_1_1", Action: Replace, HTML: ""},
6464
},
6565
}, t)
6666
runDiffTest(diffTest{
6767
root: `<div>Hello</div><div>World</div>`,
6868
proposed: `<div>Hello</div>`,
6969
patches: []Patch{
70-
{Anchor: "_l0011", Action: Replace, HTML: ""},
70+
{Anchor: "_l_0_1_1", Action: Replace, HTML: ""},
7171
},
7272
}, t)
7373
}
@@ -77,7 +77,7 @@ func TestAttributeValueChange(t *testing.T) {
7777
root: `<div place="World">Hello</div>`,
7878
proposed: `<div place="Change">Hello</div>`,
7979
patches: []Patch{
80-
{Anchor: "_l0010", Action: Replace, HTML: `<div place="Change" _l0010="">Hello</div>`},
80+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div place="Change" _l_0_1_0="">Hello</div>`},
8181
},
8282
}, t)
8383
}
@@ -87,8 +87,8 @@ func TestMultipleAttributeValueChange(t *testing.T) {
8787
root: `<div place="World">World</div><div place="Hello">Hello</div>`,
8888
proposed: `<div place="Hello">Hello</div><div place="World">World</div>`,
8989
patches: []Patch{
90-
{Anchor: "_l0010", Action: Replace, HTML: `<div place="Hello" _l0010="">Hello</div>`},
91-
{Anchor: "_l0011", Action: Replace, HTML: `<div place="World" _l0011="">World</div>`},
90+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div place="Hello" _l_0_1_0="">Hello</div>`},
91+
{Anchor: "_l_0_1_1", Action: Replace, HTML: `<div place="World" _l_0_1_1="">World</div>`},
9292
},
9393
}, t)
9494
}
@@ -99,9 +99,9 @@ func TestNestedAppend(t *testing.T) {
9999
root: `<form><input type="text"/><input type="submit"/></form>`,
100100
proposed: `<form><div>Extra</div><input type="text"/><input type="submit"/></form>`,
101101
patches: []Patch{
102-
{Anchor: "_l00100", Action: Replace, HTML: `<div _l00100="">Extra</div>`},
103-
{Anchor: "_l00101", Action: Replace, HTML: `<input type="text" _l00101=""/>`},
104-
{Anchor: "_l0010", Action: Append, HTML: `<input type="submit" _l00102=""/>`},
102+
{Anchor: "_l_0_1_0_0", Action: Replace, HTML: `<div _l_0_1_0_0="">Extra</div>`},
103+
{Anchor: "_l_0_1_0_1", Action: Replace, HTML: `<input type="text" _l_0_1_0_1=""/>`},
104+
{Anchor: "_l_0_1_0", Action: Append, HTML: `<input type="submit" _l_0_1_0_2=""/>`},
105105
},
106106
},
107107
}
@@ -115,8 +115,8 @@ func TestDoc(t *testing.T) {
115115
root: "<!doctype><html><head><title>1</title></head><body><div>1</div></body></html>",
116116
proposed: "<!doctype><html><head><title>2</title></head><body><div>2</div></body></html>",
117117
patches: []Patch{
118-
{Anchor: "_l0100", Action: Replace, HTML: `<title _l0100="">2</title>`},
119-
{Anchor: "_l0110", Action: Replace, HTML: `<div _l0110="">2</div>`},
118+
{Anchor: "_l_1_0_0", Action: Replace, HTML: `<title _l_1_0_0="">2</title>`},
119+
{Anchor: "_l_1_1_0", Action: Replace, HTML: `<div _l_1_1_0="">2</div>`},
120120
},
121121
}, t)
122122
}
@@ -166,11 +166,11 @@ func TestEarlyChildDeletion(t *testing.T) {
166166
<input type="submit"/>
167167
</form>`,
168168
patches: []Patch{
169-
{Anchor: "_l00100", Action: Replace, HTML: `<input type="text" _l00100=""/>`},
170-
{Anchor: "_l00101", Action: Replace, HTML: `<input type="submit" _l00101=""/>`},
171-
{Anchor: "_l00102", Action: Replace, HTML: ``},
172-
{Anchor: "_l00103", Action: Replace, HTML: ``},
173-
{Anchor: "_l00104", Action: Replace, HTML: ``},
169+
{Anchor: "_l_0_1_0_0", Action: Replace, HTML: `<input type="text" _l_0_1_0_0=""/>`},
170+
{Anchor: "_l_0_1_0_1", Action: Replace, HTML: `<input type="submit" _l_0_1_0_1=""/>`},
171+
{Anchor: "_l_0_1_0_2", Action: Replace, HTML: ``},
172+
{Anchor: "_l_0_1_0_3", Action: Replace, HTML: ``},
173+
{Anchor: "_l_0_1_0_4", Action: Replace, HTML: ``},
174174
},
175175
},
176176
}
@@ -194,9 +194,9 @@ func TestInsignificantWhitespace(t *testing.T) {
194194
<input type="submit"/>
195195
</form>`,
196196
patches: []Patch{
197-
{Anchor: "_l00100", Action: Replace, HTML: `<div _l00100="">Extra</div>`},
198-
{Anchor: "_l00101", Action: Replace, HTML: `<input type="text" _l00101=""/>`},
199-
{Anchor: "_l0010", Action: Append, HTML: `<input type="submit" _l00102=""/>`},
197+
{Anchor: "_l_0_1_0_0", Action: Replace, HTML: `<div _l_0_1_0_0="">Extra</div>`},
198+
{Anchor: "_l_0_1_0_1", Action: Replace, HTML: `<input type="text" _l_0_1_0_1=""/>`},
199+
{Anchor: "_l_0_1_0", Action: Append, HTML: `<input type="submit" _l_0_1_0_2=""/>`},
200200
},
201201
},
202202
}
@@ -211,7 +211,7 @@ func TestLiveUpdate(t *testing.T) {
211211
root: `<div live-update="append"><div>Hello</div></div>`,
212212
proposed: `<div live-update="append"><div>World</div></div>`,
213213
patches: []Patch{
214-
{Anchor: "_l0010", Action: Append, HTML: `<div _l00100="">World</div>`},
214+
{Anchor: "_l_0_1_0", Action: Append, HTML: `<div _l_0_1_0_0="">World</div>`},
215215
},
216216
},
217217
{
@@ -224,28 +224,28 @@ func TestLiveUpdate(t *testing.T) {
224224
<div>World</div>
225225
</div>`,
226226
patches: []Patch{
227-
{Anchor: "_l0010", Action: Append, HTML: `<div _l00100="">World</div>`},
227+
{Anchor: "_l_0_1_0", Action: Append, HTML: `<div _l_0_1_0_0="">World</div>`},
228228
},
229229
},
230230
{
231231
root: `<div live-update="prepend"><div>Hello</div></div>`,
232232
proposed: `<div live-update="prepend"><div>World</div></div>`,
233233
patches: []Patch{
234-
{Anchor: "_l0010", Action: Prepend, HTML: `<div _l00100="">World</div>`},
234+
{Anchor: "_l_0_1_0", Action: Prepend, HTML: `<div _l_0_1_0_0="">World</div>`},
235235
},
236236
},
237237
{
238238
root: `<div live-update="replace"><div>Hello</div></div>`,
239239
proposed: `<div live-update="replace"><div>World</div></div>`,
240240
patches: []Patch{
241-
{Anchor: "_l0010", Action: Replace, HTML: `<div _l00100="">World</div>`},
241+
{Anchor: "_l_0_1_0", Action: Replace, HTML: `<div _l_0_1_0_0="">World</div>`},
242242
},
243243
},
244244
{
245245
root: `<div live-update="ignore"><div>Hello</div></div>`,
246246
proposed: `<div live-update="ignore"><div>World</div></div>`,
247247
patches: []Patch{
248-
{Anchor: "_l0010", Action: Noop, HTML: `<div _l00100="">World</div>`},
248+
{Anchor: "_l_0_1_0", Action: Noop, HTML: `<div _l_0_1_0_0="">World</div>`},
249249
},
250250
},
251251
}
@@ -276,16 +276,16 @@ func TestIssue6(t *testing.T) {
276276
<script src="./live.js"></script>
277277
`,
278278
patches: []Patch{
279-
{Anchor: "_l0011", Action: Replace, HTML: `<pre _l0011="">1</pre>`},
280-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0012=""></script>`},
279+
{Anchor: "_l_0_1_1", Action: Replace, HTML: `<pre _l_0_1_1="">1</pre>`},
280+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_2=""></script>`},
281281
},
282282
},
283283
{
284284
root: `<form><input type="text"/><input type="submit"/></form><script src="./live.js"></script>`,
285285
proposed: `<form><input type="text"/><input type="submit"/></form><pre>1</pre><script src="./live.js"></script>`,
286286
patches: []Patch{
287-
{Anchor: "_l0011", Action: Replace, HTML: `<pre _l0011="">1</pre>`},
288-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0012=""></script>`},
287+
{Anchor: "_l_0_1_1", Action: Replace, HTML: `<pre _l_0_1_1="">1</pre>`},
288+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_2=""></script>`},
289289
},
290290
},
291291
{
@@ -311,16 +311,16 @@ func TestIssue6(t *testing.T) {
311311
<script src="./live.js"></script>
312312
`,
313313
patches: []Patch{
314-
{Anchor: "_l0012", Action: Replace, HTML: `<pre _l0012="">2</pre>`},
315-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0013=""></script>`},
314+
{Anchor: "_l_0_1_2", Action: Replace, HTML: `<pre _l_0_1_2="">2</pre>`},
315+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_3=""></script>`},
316316
},
317317
},
318318
{
319319
root: `<form><input type="text"/><input type="submit"/></form><pre>1</pre><script src="./live.js"></script>`,
320320
proposed: `<form><input type="text"/><input type="submit"/></form><pre>1</pre><pre>2</pre><script src="./live.js"></script>`,
321321
patches: []Patch{
322-
{Anchor: "_l0012", Action: Replace, HTML: `<pre _l0012="">2</pre>`},
323-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0013=""></script>`},
322+
{Anchor: "_l_0_1_2", Action: Replace, HTML: `<pre _l_0_1_2="">2</pre>`},
323+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_3=""></script>`},
324324
},
325325
},
326326
{
@@ -348,16 +348,16 @@ func TestIssue6(t *testing.T) {
348348
<script src="./live.js"></script>
349349
`,
350350
patches: []Patch{
351-
{Anchor: "_l0013", Action: Replace, HTML: `<pre _l0013="">3</pre>`},
352-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0014=""></script>`},
351+
{Anchor: "_l_0_1_3", Action: Replace, HTML: `<pre _l_0_1_3="">3</pre>`},
352+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_4=""></script>`},
353353
},
354354
},
355355
{
356356
root: `<form><input type="text"/><input type="submit"/></form><pre>1</pre><pre>2</pre><script src="./live.js"></script>`,
357357
proposed: `<form><input type="text"/><input type="submit"/></form><pre>1</pre><pre>2</pre><pre>3</pre><script src="./live.js"></script>`,
358358
patches: []Patch{
359-
{Anchor: "_l0013", Action: Replace, HTML: `<pre _l0013="">3</pre>`},
360-
{Anchor: "_l001", Action: Append, HTML: `<script src="./live.js" _l0014=""></script>`},
359+
{Anchor: "_l_0_1_3", Action: Replace, HTML: `<pre _l_0_1_3="">3</pre>`},
360+
{Anchor: "_l_0_1", Action: Append, HTML: `<script src="./live.js" _l_0_1_4=""></script>`},
361361
},
362362
},
363363
}
@@ -385,10 +385,10 @@ func TestListReplace(t *testing.T) {
385385
</table>
386386
`,
387387
patches: []Patch{
388-
{Anchor: "_l0010000", Action: Replace, HTML: `<td colspan="2" _l0010000="">No thingers</td>`},
389-
{Anchor: "_l0010001", Action: Replace, HTML: ``},
390-
{Anchor: "_l001001", Action: Replace, HTML: ``},
391-
{Anchor: "_l001002", Action: Replace, HTML: ``},
388+
{Anchor: "_l_0_1_0_0_0_0", Action: Replace, HTML: `<td colspan="2" _l_0_1_0_0_0_0="">No thingers</td>`},
389+
{Anchor: "_l_0_1_0_0_0_1", Action: Replace, HTML: ``},
390+
{Anchor: "_l_0_1_0_0_1", Action: Replace, HTML: ``},
391+
{Anchor: "_l_0_1_0_0_2", Action: Replace, HTML: ``},
392392
},
393393
}, t)
394394
}

0 commit comments

Comments
 (0)