Disable XBL. The loadBindings call was taking 0.1-0.25%. While I know how to get...
[WebKit-https.git] / WebCore / khtml / xbl / xbl_binding_manager.cpp
1 #ifndef KHTML_NO_XBL
2
3 #include "qptrdict.h"
4 #include "xml/dom_docimpl.h"
5 #include "xml/dom_elementimpl.h"
6 #include "rendering/render_style.h"
7 #include "xbl_binding_manager.h"
8 #include "xbl_binding.h"
9
10 using DOM::DocumentImpl;
11 using DOM::NodeImpl;
12 using DOM::ElementImpl;
13 using khtml::BindingURI;
14
15 namespace XBL {
16
17 XBLBindingManager::XBLBindingManager(DocumentImpl* doc)
18 :m_document(doc), m_bindingChainTable(0)
19 {
20 }
21
22 XBLBindingManager::~XBLBindingManager()
23 {
24     if (m_bindingChainTable) {
25         m_bindingChainTable->setAutoDelete(true);
26         delete m_bindingChainTable;
27     }
28 }
29
30 XBLBindingChain* XBLBindingManager::getBindingChain(NodeImpl* node)
31 {
32     if (!m_bindingChainTable)
33         return 0;
34     
35     return m_bindingChainTable->find(node);
36 }
37
38 void XBLBindingManager::setBindingChain(NodeImpl* node, XBLBindingChain* bindingChain)
39 {
40     if (!m_bindingChainTable)
41         m_bindingChainTable = new QPtrDict<XBLBindingChain>;
42     
43     if (bindingChain)
44         m_bindingChainTable->replace(node, bindingChain);
45     else
46         m_bindingChainTable->remove(node);
47 }
48
49 bool XBLBindingManager::loadBindings(NodeImpl* node, BindingURI* bindingURIs, 
50                                      bool isStyleBinding, bool* resolveStyle)
51 {
52     if (resolveStyle) *resolveStyle = false;
53     if (!node->isElementNode()) return true;
54     bool dirty = false;
55     XBLBindingChain* bindingChain = getBindingChain(node);
56     if (bindingChain && isStyleBinding) {
57         // Check to see if the binding is already installed.  If so, then we don't need
58         // to do anything.
59         XBLBindingChain* styleBindingChain = bindingChain->firstStyleBindingChain();
60         if (styleBindingChain) {
61             if (styleBindingChain->markedForDeath())
62                 return false; // The old bindings haven't destroyed themselves/fired their destructors yet.
63             
64             // See if the URIs match.
65             BindingURI* currURI = bindingURIs;
66             XBLBindingChain* currBindingChain = styleBindingChain;
67             for ( ; currURI && currBindingChain;
68                   currURI = currURI->next(), currBindingChain = currBindingChain->nextChain()) {
69                 if (currBindingChain->uri() != currURI->uri()) {
70                     styleBindingChain->markForDeath();
71                     return false;
72                 }
73             }
74             if ((currURI && !currBindingChain) || (currBindingChain && !currURI)) {
75                 styleBindingChain->markForDeath();
76                 return false;
77             }
78             
79             return bindingChain->loaded();
80         }
81     }
82
83     bindingChain = getBindingChain(node);
84     ElementImpl* elt = static_cast<ElementImpl*>(node);
85     for (BindingURI* currURI = bindingURIs; currURI; currURI = currURI->next()) {
86         XBLBindingChain* newBindingChain = new XBLBindingChain(elt, currURI->uri(), isStyleBinding);
87         if (newBindingChain) {
88             if (bindingChain && isStyleBinding)
89                 // Style bindings go on the end.  Regular bindings go on the front.
90                 bindingChain->lastBindingChain()->insertBindingChain(newBindingChain);
91             else {
92                 // Place on the front.
93                 newBindingChain->insertBindingChain(bindingChain);
94                 setBindingChain(node, newBindingChain); 
95             }
96             
97             dirty = true;
98         }
99         
100         bindingChain = newBindingChain;
101     }
102     
103     if (!bindingChain) return true; // We did nothing.
104     
105     // If the binding is completely loaded, then return true.  Otherwise return false.
106     bindingChain = getBindingChain(node);
107     bool loaded = bindingChain->loaded();
108     if (loaded && resolveStyle)
109         *resolveStyle = bindingChain->hasStylesheets();
110     return loaded;
111 }
112
113 void XBLBindingManager::checkLoadState(ElementImpl* elt)
114 {
115     XBLBindingChain* chain = getBindingChain(elt);
116     if (chain && chain->loaded())
117         elt->setChanged();
118 }
119
120 }
121
122 #endif // KHTML_NO_XBL