@@ -148,6 +148,11 @@ bool Element::IsEnabled() {
148
148
149
149
CComPtr<IHTMLDocument2> doc;
150
150
this ->GetContainingDocument (false , &doc);
151
+
152
+ if (this ->IsXmlDocument (doc)) {
153
+ return false ;
154
+ }
155
+
151
156
Script script_wrapper (doc, script_source, 1 );
152
157
script_wrapper.AddArgument (this ->element_ );
153
158
int status_code = script_wrapper.Execute ();
@@ -161,6 +166,47 @@ bool Element::IsEnabled() {
161
166
return result;
162
167
}
163
168
169
+ bool Element::IsXmlDocument (IHTMLDocument2* doc) {
170
+ LOG (TRACE) << " Entering Element::IsXmlDocument" ;
171
+ // If the document has an xmlVersion property, it can be either an XML
172
+ // document or an XHTML document. Otherwise, it's an HTML document.
173
+ CComPtr<IHTMLDocument7> xml_version_document;
174
+ HRESULT hr = doc->QueryInterface <IHTMLDocument7>(&xml_version_document);
175
+ if (SUCCEEDED (hr) && xml_version_document) {
176
+ CComBSTR xml_version = " " ;
177
+ hr = xml_version_document->get_xmlVersion (&xml_version);
178
+ if (SUCCEEDED (hr) && xml_version && xml_version != L" " ) {
179
+ // The document is either XML or XHTML, so to differentiate between
180
+ // the two cases, check for a doctype of "html". If we can't find
181
+ // a doctype property, or the doctype is anything other than "html",
182
+ // the document is an XML document.
183
+ CComPtr<IHTMLDocument5> doc_type_document;
184
+ hr = doc->QueryInterface <IHTMLDocument5>(&doc_type_document);
185
+ if (SUCCEEDED (hr) && doc_type_document) {
186
+ CComPtr<IHTMLDOMNode> doc_type_dom_node;
187
+ hr = doc_type_document->get_doctype (&doc_type_dom_node);
188
+ if (SUCCEEDED (hr) && doc_type_dom_node) {
189
+ CComPtr<IDOMDocumentType> doc_type;
190
+ hr = doc_type_dom_node->QueryInterface <IDOMDocumentType>(&doc_type);
191
+ if (SUCCEEDED (hr) && doc_type) {
192
+ CComBSTR type_name_bstr = L" " ;
193
+ hr = doc_type->get_name (&type_name_bstr);
194
+ type_name_bstr.ToLower ();
195
+ std::wstring type_name (type_name_bstr);
196
+ LOG (INFO) << LOGWSTRING (type_name);
197
+ if (SUCCEEDED (hr) && type_name != L" html" ) {
198
+ return true ;
199
+ }
200
+ }
201
+ } else {
202
+ return true ;
203
+ }
204
+ }
205
+ }
206
+ }
207
+ return false ;
208
+ }
209
+
164
210
bool Element::IsInteractable () {
165
211
LOG (TRACE) << " Entering Element::IsInteractable" ;
166
212
@@ -517,15 +563,20 @@ int Element::GetCssPropertyValue(const std::string& property_name,
517
563
LOG (TRACE) << " Entering Element::GetCssPropertyValue" ;
518
564
519
565
int status_code = WD_SUCCESS;
566
+ CComPtr<IHTMLDocument2> doc;
567
+ this ->GetContainingDocument (false , &doc);
568
+ if (this ->IsXmlDocument (doc)) {
569
+ *property_value = " " ;
570
+ return status_code;
571
+ }
572
+
520
573
// The atom is just the definition of an anonymous
521
574
// function: "function() {...}"; Wrap it in another function so we can
522
575
// invoke it with our arguments without polluting the current namespace.
523
576
std::wstring script_source = L" (function() { return (" ;
524
577
script_source += atoms::asString (atoms::GET_EFFECTIVE_STYLE);
525
578
script_source += L" )})();" ;
526
579
527
- CComPtr<IHTMLDocument2> doc;
528
- this ->GetContainingDocument (false , &doc);
529
580
Script script_wrapper (doc, script_source, 2 );
530
581
script_wrapper.AddArgument (this ->element_ );
531
582
script_wrapper.AddArgument (property_name);
0 commit comments