Access to modify HTML DOM elements in CEF

Source: Internet
Author: User

Sometimes you might want to manipulate an element in the HTML directly in your C + + code, such as changing the state of a button (text, color), and so on, you can use the three classes of Cefdomvisitor, Cefdomdocument, Cefdomnode that CEF provides, including cef_ Dom.h can be.

We can use them to accomplish the following tasks:

    • Use the DOM model to access various nodes of HTML (Element, Attribute, Text, CDATA, Comment, document, and so on)
    • Modify the properties of an element
    • Modify the value of a text node

The following is a brief description of the usage of each class.

Cefdomdocument

Cefdomdocument corresponds to the document in JS, but less function, the class declaration is as follows:

Class Cefdomdocument:public virtual Cefbase {public:typedef cef_dom_document_type_t type;  Returns the document type.  /*--CEF (default_retval=dom_document_type_unknown)--*/virtual TYPE GetType () = 0;  Returns the root document node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getdocument () = 0;  Returns the BODY node of an HTML document.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getbody () = 0;  Returns the HEAD node of an HTML document.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> gethead () = 0;  Returns the title of an HTML document.  /*--CEF ()--*/virtual cefstring GetTitle () = 0;  Returns the document element with the specified ID value.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getElementById (const cefstring& ID) = 0;  Returns the node that currently has keyboard focus.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getfocusednode () = 0; REturns true if a portion of the document is selected.  /*--CEF ()--*/virtual bool Hasselection () = 0;  Returns the selection offset within the start node.  /*--CEF ()--*/virtual int getselectionstartoffset () = 0;  Returns the selection offset within the end node.  /*--CEF ()--*/virtual int getselectionendoffset () = 0;  Returns the contents of this selection as markup.  /*--CEF ()--*/virtual cefstring getselectionasmarkup () = 0;  Returns the contents of this selection as text.  /*--CEF ()--*/virtual cefstring getselectionastext () = 0;  Returns the base URL for the document.  /*--CEF ()--*/virtual cefstring getbaseurl () = 0;  Returns a complete URL based the document base URL and the specified//partial URL. /*--CEF ()--*/virtual cefstring getcompleteurl (const cefstring& Partialurl) = 0;};

As you can see, it gets some string value (URL, caption, etc.), can find an element according to ID (in JS we most commonly used the way), can return the document, Head, body and other nodes, the type of these nodes is Cefdomnode.

Note that the method of this class can only be called on the main thread of the RENDERER process (tid_renderer).

Cefdomnode

In the HTML DOM (Document Object model), each part is a node:

    • The document itself is a document node
    • All HTML elements are element nodes
    • All HTML attributes are attribute nodes
    • Text within an HTML element is a text node
    • Comment is a comment node

Cefdomnode represents an HTML DOM node, which is declared as follows:

Class Cefdomnode:public virtual Cefbase {public:typedef std::map<cefstring, cefstring> attributemap;  typedef cef_dom_node_type_t type;  Returns the type for this node.  /*--CEF (default_retval=dom_node_type_unsupported)--*/virtual TYPE GetType () = 0;  Returns true if this is a text node.  /*--CEF ()--*/virtual bool Istext () = 0;  Returns true if this is an element node.  /*--CEF ()--*/virtual bool Iselement () = 0;  Returns true if this is a editable node.  /*--CEF ()--*/virtual bool iseditable () = 0;  Returns true if this is a form control element node.  /*--CEF ()--*/virtual bool Isformcontrolelement () = 0;  Returns the type of this form control element node.  /*--CEF ()--*/virtual cefstring getformcontrolelementtype () = 0;  Returns true if this object was pointing to the same handle as |that|  Object.  /*--CEF ()--*/virtual bool Issame (cefrefptr<cefdomnode> that) = 0; /// Returns the name of this node.  /*--CEF ()--*/virtual cefstring GetName () = 0;  Returns the value of this node.  /*--CEF ()--*/virtual cefstring GetValue () = 0; Set the value of this node.  Returns true on success.  /*--CEF ()--*/virtual bool SetValue (const cefstring& value) = 0;  Returns the contents of this node as markup.  /*--CEF ()--*/virtual cefstring getasmarkup () = 0;  Returns the document associated with this node.  /*--CEF ()--*/virtual cefrefptr<cefdomdocument> getdocument () = 0;  Returns the parent node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> GetParent () = 0;  Returns the previous sibling node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getprevioussibling () = 0;  Returns the next sibling node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getnextsibling () = 0;  Returns true if this node has a child nodes. /*--CEF ()--*/virtual BOol HasChildren () = 0;  Return the first child node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getfirstchild () = 0;  Returns the last child node.  /*--CEF ()--*/virtual cefrefptr<cefdomnode> getlastchild () = 0;  The following methods is valid only for element nodes.  Returns the tag name of this element.  /*--CEF ()--*/virtual cefstring getelementtagname () = 0;  Returns true if this element has attributes.  /*--CEF ()--*/virtual bool Haselementattributes () = 0;  Returns true if this element has a attribute named |attrname|.  /*--CEF ()--*/virtual bool Haselementattribute (const cefstring& attrname) = 0;  Returns the element attribute named |attrname|.  /*--CEF ()--*/virtual cefstring getelementattribute (const cefstring& attrname) = 0;  Returns a map of all element attributes.  /*--CEF ()--*/virtual void getelementattributes (attributemap& attrmap) = 0; Set thE value for the element attribute named |attrname|.  Returns true on//success. /*--CEF ()--*/virtual bool Setelementattribute (const cefstring& Attrname, cons  T cefstring& value) = 0;  Returns the inner text of the element. /*--CEF ()--*/virtual cefstring getelementinnertext () = 0;};

Note that the method of this class can only be called on the main thread of the RENDERER process (tid_renderer).

With the understanding of the HTML DOM node and the code above, we can understand what we can do with Cefdomnode:

    • Use Isxxx or GetType to determine the node type
    • Traversing sibling nodes with Getnextsibling, getprevioussibling
    • If it is a text node (leaf node), SetValue can change its literal
    • If it is an element node, you can use Getfirstchild, getlastchild to get the child, use Setelementattribute (s) to change the property, use Getelementattibute (s) to get the property

HTML DOM element, there are appendchild, InsertBefore and other methods, can be very convenient to dynamically insert nodes to change the DOM and Web page display effect, and this cefdomnode there is no corresponding method, it seems inconvenient ...

Cefdomvisitor

The declaration of this class is as follows:

class CefDOMVisitor : public virtual CefBase { public:  ///  // Method executed for visiting the DOM. The document object passed to this  // method represents a snapshot of the DOM at the time this method is  // executed. DOM objects are only valid for the scope of this method. Do not  // keep references to or attempt to access any DOM objects outside the scope  // of this method.  ///  /*--cef()--*/  virtual void Visit(CefRefPtr<CefDOMDocument> document) =0;};

To access or modify the HTML DOM, you must implement this class, and then pass its object to the Cefframe::visitdom (Cefrefptr visitor) method, and your visit method is called to access or modify the HTML DOM.

See a simple implementation that shows the declaration of the Domvisittestor class:

class DomVisitTestor : public CefDOMVisitor{public:    DomVisitTestor();    void TestAccess(CefRefPtr<CefDOMDocument> document);    void TestModify(CefRefPtr<CefDOMDocument> document);    void Visit(CefRefPtr<CefDOMDocument> document) OVERRIDE;    IMPLEMENT_REFCOUNTING(DomVisitTestor);};

Then there is the realization of domvisittestor:

void Domvisittestor::testaccess (cefrefptr<cefdomdocument> document) {OutputDebugStringW (L "DomVisitTestor::    Testaccess\r\n "); OutputDebugStringW (Document->gettitle ().    Towstring (). C_STR ()); OutputDebugStringW (Document->getbaseurl ().    Towstring (). C_STR ());    cefrefptr<cefdomnode> Headnode = Document->gethead (); OutputDebugStringW (Headnode->getname ().    Towstring (). C_STR ()); OutputDebugStringW (Headnode->getasmarkup ().    Towstring (). C_STR ());    wchar_t szlog[512] = {0};        if (Headnode->haschildren ()) {cefrefptr<cefdomnode> Childnode = Headnode->getfirstchild (); do {swprintf_s (Szlog, N, L "node name-%s, type-%d, value-%s\r\n", Childnode->getna Me ().            Towstring (). C_STR (), Childnode->gettype (), Childnode->getvalue ());        OutputDebugStringW (Szlog);    } while ((Childnode = childnode->getnextsibling ()). get ()); } cefrefptr<cefdomnode> Bodynode = Document->gEtbody (); OutputDebugStringW (Bodynode->getasmarkup ().    Towstring (). C_STR ());        if (Bodynode->haschildren ()) {cefrefptr<cefdomnode> Childnode = Bodynode->getfirstchild (); do {swprintf_s (Szlog, N, L "node name-%s, type-%d, value-%s\r\n", Childnode->getnam E ().            Towstring (). C_STR (), Childnode->gettype (), Childnode->getvalue ());        OutputDebugStringW (Szlog);    } while ((Childnode = childnode->getnextsibling ()). get ()); }}void domvisittestor::testmodify (cefrefptr<cefdomdocument> document) {OutputDebugStringW (L "DomVisitTestor:    : testmodify\r\n ");    cefrefptr<cefdomnode> Bodynode = Document->getbody ();        if (Bodynode->haschildren ()) {cefrefptr<cefdomnode> Childnode = Bodynode->getfirstchild ();        wchar_t szlog[512] = {0}; do{swprintf_s (Szlog, N, L "node name-%s,tagname-%s type-%d, value-%s\r\n", CHILDNODE-&GT;GETN Ame). Towstring (). C_STR (), Childnode->getelementtagname ().            Towstring (). C_STR (), Childnode->gettype (), Childnode->getvalue ());            OutputDebugStringW (Szlog); if (Childnode->iselement () && childnode->getelementtagname () = = "H1" && childnode-&gt ; Getelementattribute ("id") = = "Hello") {cefrefptr<cefdomnode> Textnode = Childnode->get                FirstChild (); swprintf_s (Szlog, MB, L "found Hello, text-%s\r\n", Textnode->getvalue ().                Towstring (). C_STR ());                OutputDebugStringW (Szlog);                Textnode->setvalue ("Hello World modified!");            Break    }} while ((Childnode = childnode->getnextsibling ()). get ());    } cefrefptr<cefdomnode> Hello = Document->getelementbyid ("Hello");        if (Hello.get ()) {Hello->setelementattribute ("align", "center"); OutputDebugStringW (L "Change Hello alIgn\r\n ");    }}void domvisittestor::visit (cefrefptr<cefdomdocument> document) {testaccess (document); Testmodify (document);}

Note that the method of this class should also be used on the main thread (tid_renderer) of the RENDERER process.

The HTML file for the test is as follows:

<!DOCTYPE html>

You may have noticed that I called window within the test () method associated with the Visitdom button. The Domvisittest () method, which I bound to a Window object in C + + code, refers to JavaScript in CEF interacting with C + + .

That's it.

Other reference articles are described in my column: "CEF and Ppapi development ".

Access to modify HTML DOM elements in CEF

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.