www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - arsd.dom appenChild method gives assertion message

reply Erdem <farukerdemoncel gmail.com> writes:
I would like to add first documents content inside a div element 
like this.

import arsd.dom;
import std.stdio;

void main()
{

    auto document = new Document();

    document.parseGarbage(`<html>
      <head>
      <title>Test Document1</title>
      </head>
      <body>
      <p>This is the first paragraph of our <a 
href="test.html">test document</a>.
      <p>This second paragraph also has a <a 
href="test2.html">link</a>.
      <p id="custom-paragraph">Old text</p>
      </body>
      </html>`);

    auto document2 =  new Document();

    document2.parseGarbage(`<html>
      <head>
      <title>Test Document</title>
      </head>
      <body>
      <div id="foo"></div>
      <a href="www.example.com"></a>
      <div id="content">
      </div>
      <p id="custom-paragraph">Old text</p>
      </body>
      </html>`);

    Element content = 
document2.getElementsBySelector(`div[id="content"]`)[0];

    writeln(content);

    Element[] firstElements = 
document.getElementsBySelector("body");
    writeln (firstElements);

    content.appendChild(firstElements[0]);
}

The program compiles fine. But when I try to execute it gives an 
assertion error like this.

??:? _d_assert_msg [0x80cc048]
??:? 
_D4arsd3dom7Element11appendChildMFC4arsd3dom7ElementZ9__requireMFZv [0x80a6f62]
??:? arsd.dom.Element 
arsd.dom.Element.appendChild(arsd.dom.Element) [0x80a6df1]
??:? _Dmain [0x809f73c]
??:? 
_D2rt6dmain211_d_run_mainUiPPaPUAAaZiZ6runAllMFZ9__lambda1MFZv 
[0x80cd792]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) [0x80cd6dc]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).runAll() [0x80cd74e]
??:? void rt.dmain2._d_run_main(int, char**, extern (C) int 
function(char[][])*).tryExec(scope void delegate()) [0x80cd6dc]
??:? _d_run_main [0x80cd66e]
??:? main [0x809fc93]
??:? __libc_start_main [0x129532]

How should one use appendChild or similiar methods of arsd.dom 
library?
Dec 11 2016
next sibling parent reply Erdem <farukerdemoncel gmail.com> writes:
Ok this seems to work as expected.

import arsd.dom;
import std.stdio;

void main()
{
    auto document = new Document();

    document.parseGarbage(`<html>
      <head>
      <title>Test Document1</title>
      </head>
      <body>
      <p>This is the first paragraph of our <a 
href="test.html">test document</a>.
      <p>This second paragraph also has a <a 
href="test2.html">link</a>.
      <p id="custom-paragraph">Old text</p>
      </body>
      </html>`);

    auto document2 =  new Document();

    document2.parseGarbage(`<html>
      <head>
      <title>Test Document</title>
      </head>
      <body>
      <div id="foo"></div>
      <a href="www.example.com"></a>
      <div id="content">
      </div>
      <p id="custom-paragraph">Old text</p>
      </body>
      </html>`);

    Element content = 
document2.getElementsBySelector(`div[id="content"]`)[0];

    writeln(content);
    writeln();

    Element[] firstElements = 
document.getElementsBySelector("body")[0].children;

    foreach (element; firstElements)
    {
        element.parentNode = null;
        content.appendChild(element);
    }

    writeln(document2.toString());
}
Dec 11 2016
parent Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 11 December 2016 at 18:30:53 UTC, Erdem wrote:
        element.parentNode = null;
        content.appendChild(element);
That works too, but could lead to data corruption later because the other document thinks it still owns the element, but the element doesn't know that. So if you descend through children of either ones, you'll see it, but then if you go back up through the parents, you won't end up back where you started.
Dec 11 2016
prev sibling parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 11 December 2016 at 17:52:29 UTC, Erdem wrote:
    content.appendChild(firstElements[0]);
 How should one use appendChild or similiar methods
 of arsd.dom library?
You need to remove the element from the first document before trying to append it to another. Try something like: content.appendChild(firstElements[0].removeFromTree()); removeFromTree is a convenience method to do parentNode.removeChild(this). Since an element can only exist in one place in a tree at a time, it will give the assert error if you try to add it to two places at once.
Dec 11 2016
parent Erdem <farukerdemoncel gmail.com> writes:
On Sunday, 11 December 2016 at 22:11:51 UTC, Adam D. Ruppe wrote:
 On Sunday, 11 December 2016 at 17:52:29 UTC, Erdem wrote:
[...]
 Try something like:

 content.appendChild(firstElements[0].removeFromTree());
Thanks this method also works. foreach (element; firstElements) { element.removeFromTree(); content.appendChild(element); }
Dec 12 2016