diff --git a/manipulation.go b/manipulation.go index ce7731d..43b676b 100644 --- a/manipulation.go +++ b/manipulation.go @@ -449,8 +449,10 @@ func (s *Selection) WrapAllHtml(htmlStr string) *Selection { var context *html.Node var nodes []*html.Node if len(s.Nodes) > 0 { - context = s.Nodes[0] - if context.Parent != nil { + // The wrapper takes the place of the first node, so parse it in the + // context of that node's parent, as WrapHtml does. + context = s.Nodes[0].Parent + if context != nil && context.Type == html.ElementNode { nodes = parseHtmlWithContext(htmlStr, context, s.parseOpts()) } else { nodes = parseHtml(htmlStr, s.parseOpts()) diff --git a/manipulation_test.go b/manipulation_test.go index cb5145b..8415ecf 100644 --- a/manipulation_test.go +++ b/manipulation_test.go @@ -618,6 +618,22 @@ func TestWrapAllHtml(t *testing.T) { printSel(t, doc.Selection) } +func TestWrapAllHtmlRawTextElement(t *testing.T) { + // The wrapper must be parsed in the parent's context. Parsed inside a + // textarea it would become text, and the textarea would be lost. + doc := loadString(t, ``) + doc.Find("textarea").WrapAllHtml(`
`) + assertLength(t, doc.Find("body > div.wrap > textarea").Nodes, 1) + printSel(t, doc.Selection) +} + +func TestWrapAllHtmlTextNode(t *testing.T) { + doc := loadString(t, `

a b

`) + doc.Find("p").Contents().WrapAllHtml(``) + assertLength(t, doc.Find("p > span.wrap > b").Nodes, 1) + printSel(t, doc.Selection) +} + func TestWrapInnerNoContent(t *testing.T) { doc := Doc2Clone() doc.Find(".one").WrapInner(".two")