-- v2: mshtml: Implement DOMParser's parseFromString. mshtml: Implement anchors prop for XML documents. mshtml: Use the doc_type to find out the mimeType when the document has no mshtml: Use Gecko's responseXML to create the XML document in IE10 and up. mshtml: Implement DOMParser constructor and instance object.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 3 + dlls/mshtml/omnavigator.c | 125 ++++++++++++++++++++++++++++++ dlls/mshtml/tests/documentmode.js | 75 +++++++++--------- dlls/mshtml/tests/es5.js | 11 +++ 4 files changed, 179 insertions(+), 35 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 5c81a74b16e..50f147531d1 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -108,6 +108,7 @@ struct constructor; XDIID(DispDOMStorageEvent) \ XDIID(DispDOMUIEvent) \ XDIID(DispDOMDocumentType) \ + XDIID(DispDOMParser) \ XDIID(DispHTMLAnchorElement) \ XDIID(DispHTMLAreaElement) \ XDIID(DispHTMLAttributeCollection) \ @@ -172,6 +173,7 @@ struct constructor; XIID(IDOMStorageEvent) \ XIID(IDOMUIEvent) \ XIID(IDOMDocumentType) \ + XIID(IDOMParser) \ XIID(IDocumentEvent) \ XIID(IDocumentRange) \ XIID(IDocumentSelector) \ @@ -429,6 +431,7 @@ typedef struct { X(Console) \ X(CustomEvent) \ X(DOMImplementation) \ + X(DOMParser) \ X(DOMTokenList) \ X(Document) \ X(DocumentFragment) \ diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index 660510fc3f2..c65fb675372 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -269,6 +269,131 @@ void detach_dom_implementation(IHTMLDOMImplementation *iface) dom_implementation->doc = NULL; }
+struct dom_parser { + DispatchEx dispex; + IDOMParser IDOMParser_iface; +}; + +static inline struct dom_parser *impl_from_IDOMParser(IDOMParser *iface) +{ + return CONTAINING_RECORD(iface, struct dom_parser, IDOMParser_iface); +} + +DISPEX_IDISPATCH_IMPL(dom_parser, IDOMParser, impl_from_IDOMParser(iface)->dispex) + +static HRESULT WINAPI dom_parser_parseFromString(IDOMParser *iface, BSTR string, BSTR mimeType, IHTMLDocument2 **ppNode) +{ + struct dom_parser *This = impl_from_IDOMParser(iface); + + FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(string), debugstr_w(mimeType), ppNode); + + return E_NOTIMPL; +} + +static const IDOMParserVtbl dom_parser_vtbl = { + dom_parser_QueryInterface, + dom_parser_AddRef, + dom_parser_Release, + dom_parser_GetTypeInfoCount, + dom_parser_GetTypeInfo, + dom_parser_GetIDsOfNames, + dom_parser_Invoke, + dom_parser_parseFromString +}; + +static inline struct dom_parser *dom_parser_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct dom_parser, dispex); +} + +static void *dom_parser_query_interface(DispatchEx *dispex, REFIID riid) +{ + struct dom_parser *This = dom_parser_from_DispatchEx(dispex); + + if(IsEqualGUID(&IID_IDOMParser, riid)) + return &This->IDOMParser_iface; + + return NULL; +} + +static void dom_parser_destructor(DispatchEx *dispex) +{ + struct dom_parser *This = dom_parser_from_DispatchEx(dispex); + free(This); +} + +static HRESULT init_dom_parser_ctor(struct constructor*); + +static const dispex_static_data_vtbl_t dom_parser_dispex_vtbl = { + .query_interface = dom_parser_query_interface, + .destructor = dom_parser_destructor, +}; + +static const tid_t dom_parser_iface_tids[] = { + IDOMParser_tid, + 0 +}; + +dispex_static_data_t DOMParser_dispex = { + .id = OBJID_DOMParser, + .init_constructor = &init_dom_parser_ctor, + .vtbl = &dom_parser_dispex_vtbl, + .disp_tid = DispDOMParser_tid, + .iface_tids = dom_parser_iface_tids, +}; + +static HRESULT dom_parser_ctor_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + struct constructor *This = constructor_from_DispatchEx(dispex); + struct dom_parser *ret; + + TRACE("\n"); + + switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; + /* fall through */ + case DISPATCH_METHOD: + case DISPATCH_CONSTRUCT: + break; + default: + FIXME("flags %x not supported\n", flags); + return E_NOTIMPL; + } + + if(!(ret = calloc(1, sizeof(*ret)))) + return E_OUTOFMEMORY; + + ret->IDOMParser_iface.lpVtbl = &dom_parser_vtbl; + init_dispatch(&ret->dispex, &DOMParser_dispex, This->window, dispex_compat_mode(&This->dispex)); + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)&ret->IDOMParser_iface; + return S_OK; +} + +static const dispex_static_data_vtbl_t dom_parser_ctor_dispex_vtbl = { + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, + .value = dom_parser_ctor_value, +}; + +static dispex_static_data_t dom_parser_ctor_dispex = { + .name = "DOMParser", + .constructor_id = OBJID_DOMParser, + .vtbl = &dom_parser_ctor_dispex_vtbl, +}; + +static HRESULT init_dom_parser_ctor(struct constructor *constr) +{ + init_dispatch(&constr->dispex, &dom_parser_ctor_dispex, constr->window, + dispex_compat_mode(&constr->window->event_target.dispex)); + return S_OK; +} + typedef struct { DispatchEx dispex; IHTMLScreen IHTMLScreen_iface; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index d671f43a1f5..6809b957b2f 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -333,6 +333,7 @@ sync_test("builtin_toString", function() { if(v >= 9) { test("computedStyle", window.getComputedStyle(e), "CSSStyleDeclaration"); test("doctype", document.doctype, "DocumentType"); + test("domParser", new DOMParser(), "DOMParser");
test("Event", document.createEvent("Event"), "Event"); test("CustomEvent", document.createEvent("CustomEvent"), "CustomEvent"); @@ -980,6 +981,7 @@ sync_test("window_props", function() { test_exposed("matchMedia", v >= 10); test_exposed("Document", v >= 9); test_exposed("HTMLDocument", v === 8 || v >= 11, v === 8); + test_exposed("DOMParser", v >= 9); test_exposed("MutationObserver", v >= 11); test_exposed("PageTransitionEvent", v >= 11); test_exposed("ProgressEvent", v >= 10); @@ -1202,6 +1204,7 @@ sync_test("constructor props", function() { test_exposed(Image, "create", v < 9); test_exposed(Option, "create", v < 9); test_exposed(XMLHttpRequest, "create", true); + if(v >= 9) test_exposed(DOMParser, "create", false); if(v >= 11) test_exposed(MutationObserver, "create", false); });
@@ -3878,6 +3881,9 @@ sync_test("prototypes", function() { check(document.createElement("option"), HTMLOptionElement.prototype, "option elem"); check(HTMLOptionElement.prototype, HTMLElement.prototype, "option elem prototype"); check(Option, Function.prototype, "Option constructor"); + check(new DOMParser(), DOMParser.prototype, "dom parser"); + check(DOMParser.prototype, Object.prototype, "dom parser prototype"); + check(DOMParser, Function.prototype, "dom parser constructor"); if(v >= 11) { check(new MutationObserver(function() {}), MutationObserver.prototype, "mutation observer"); check(MutationObserver.prototype, Object.prototype, "mutation observer prototype"); @@ -4181,6 +4187,7 @@ sync_test("prototype props", function() { ]); check(DocumentFragment, [ ["attachEvent",9,10], ["detachEvent",9,10], "querySelector", "querySelectorAll", "removeNode", "replaceNode", "swapNode" ]); check(DocumentType, [ "entities", "internalSubset", "name", "notations", "publicId", "systemId" ]); + check(DOMParser, [ "parseFromString" ]); check(Element, [ "childElementCount", "clientHeight", "clientLeft", "clientTop", "clientWidth", ["fireEvent",9,10], "firstElementChild", "getAttribute", "getAttributeNS", "getAttributeNode", "getAttributeNodeNS", "getBoundingClientRect", "getClientRects", @@ -4412,7 +4419,7 @@ sync_test("constructors", function() { if(v < 9) return;
- var ctors = [ "Image", "Option", "XMLHttpRequest" ]; + var ctors = [ "DOMParser", "Image", "Option", "XMLHttpRequest" ]; if (v >= 11) ctors.push("MutationObserver"); for(i = 0; i < ctors.length; i++) { @@ -4543,44 +4550,42 @@ async_test("window own props", function() { ["AesGcmEncryptResult",11], ["ANGLE_instanced_arrays",11], ["AnimationEvent",10], ["ApplicationCache",10], ["ArrayBuffer",9,9], "Audio", ["AudioTrack",10], ["AudioTrackList",10], "BeforeUnloadEvent", ["Blob",10], "BookmarkCollection", "CanvasGradient", "CanvasPattern", "CanvasPixelArray", "CanvasRenderingContext2D", "CDATASection", ["CloseEvent",10], "CompositionEvent", "ControlRangeCollection", "Coordinates", ["Crypto",11], ["CryptoOperation",11], "CSSFontFaceRule", "CSSImportRule", ["CSSKeyframeRule",10], ["CSSKeyframesRule",10], - "CSSMediaRule", "CSSNamespaceRule", "CSSPageRule", "CSSRuleList", "DataTransfer", ["DataView",9,9], "Debug", ["DeviceAcceleration",11], ["DeviceMotionEvent",11], - ["DeviceOrientationEvent",11], ["DeviceRotationRate",11], ["DOMError",10], "DOMException", "DOMParser", ["DOMSettableTokenList",10], ["DOMStringList",10], ["DOMStringMap",11], - "DragEvent", ["ErrorEvent",10], "EventException", ["EXT_texture_filter_anisotropic",11], ["File",10], ["FileList",10], ["FileReader",10], ["Float32Array",10], ["Float64Array",10], - "FocusEvent", ["FormData",10], "Geolocation", "GetObject", ["HTMLAllCollection",11], "HTMLAppletElement", "HTMLAreasCollection", "HTMLAudioElement", "HTMLBaseElement", - "HTMLBaseFontElement", "HTMLBGSoundElement", "HTMLBlockElement", "HTMLBRElement", "HTMLCanvasElement", ["HTMLDataListElement",10], "HTMLDDElement", "HTMLDirectoryElement", - "HTMLDivElement", "HTMLDListElement", "HTMLDTElement", "HTMLFieldSetElement", "HTMLFontElement", "HTMLFrameSetElement", "HTMLHeadingElement", "HTMLHRElement", "HTMLIsIndexElement", - "HTMLLegendElement", "HTMLLIElement", "HTMLMapElement", "HTMLMarqueeElement", "HTMLMediaElement", "HTMLMenuElement", "HTMLModElement", "HTMLNextIdElement", "HTMLOListElement", - "HTMLOptGroupElement", "HTMLParagraphElement", "HTMLParamElement", "HTMLPhraseElement", "HTMLPreElement", ["HTMLProgressElement",10], "HTMLQuoteElement", "HTMLSourceElement", - "HTMLSpanElement", "HTMLTableCaptionElement", "HTMLTableColElement", "HTMLTableHeaderCellElement", "HTMLTableSectionElement", ["HTMLTrackElement",10], "HTMLUListElement", - "HTMLVideoElement", ["IDBCursor",10], ["IDBCursorWithValue",10], ["IDBDatabase",10], ["IDBFactory",10], ["IDBIndex",10], ["IDBKeyRange",10], ["IDBObjectStore",10], ["IDBOpenDBRequest",10], - ["IDBRequest",10], ["IDBTransaction",10], ["IDBVersionChangeEvent",10], "ImageData", ["Int16Array",10], ["Int32Array",10], ["Int8Array",10], ["Intl",11], ["Key",11], ["KeyOperation",11], - ["KeyPair",11], "Location", "MediaError", "MediaList", ["MediaSource",11], ["MessageChannel",10], ["MessagePort",10], ["MimeType",11], ["MimeTypeArray",9,10], "MouseWheelEvent", - "MSBehaviorUrnsCollection", ["MSBlobBuilder",10], "MSCompatibleInfo", "MSCompatibleInfoCollection", ["MSCSSMatrix",10], ["MSGesture",10], ["MSGestureEvent",10], ["MSGraphicsTrust",11], - ["MSInputMethodContext",11], ["MSManipulationEvent",10], ["MSMediaKeyError",11], ["MSMediaKeyMessageEvent",11], ["MSMediaKeyNeededEvent",11], ["MSMediaKeys",11], ["MSMediaKeySession",11], - "MSMimeTypesCollection", ["MSNamespaceInfo",0,9], "MSPluginsCollection", ["MSPointerEvent",10], ["MSPopupWindow",0,10], ["MSRangeCollection",10], "MSSiteModeEvent", ["MSStream",10], - ["MSStreamReader",10], "MutationEvent", ["MutationRecord",11], "NodeFilter", "NodeIterator", ["OES_element_index_uint",11], ["OES_standard_derivatives",11], ["OES_texture_float",11], - ["OES_texture_float_linear",11], "PerformanceEntry", "PerformanceMark", "PerformanceMeasure", ["PerformanceNavigationTiming",11], "PerformanceResourceTiming", ["Plugin",11], - ["PluginArray",9,10], ["PointerEvent",11], ["PopStateEvent",10], "Position", "PositionError", "ProcessingInstruction", "RangeException", "RegExpError", "Selection", ["SourceBuffer",11], - ["SourceBufferList",11], "StyleMedia", "StyleSheetPageList", ["SubtleCrypto",11], "SVGAElement", "SVGAngle", "SVGAnimatedAngle", "SVGAnimatedBoolean", "SVGAnimatedEnumeration", - "SVGAnimatedInteger", "SVGAnimatedLength", "SVGAnimatedLengthList", "SVGAnimatedNumber", "SVGAnimatedNumberList", "SVGAnimatedPreserveAspectRatio", "SVGAnimatedRect", "SVGAnimatedString", - "SVGAnimatedTransformList", "SVGClipPathElement", ["SVGComponentTransferFunctionElement",10], "SVGDefsElement", "SVGDescElement", "SVGElementInstance", "SVGElementInstanceList", - "SVGEllipseElement", "SVGException", ["SVGFEBlendElement",10], ["SVGFEColorMatrixElement",10], ["SVGFEComponentTransferElement",10], ["SVGFECompositeElement",10], + "CSSMediaRule", "CSSNamespaceRule", "CSSPageRule", "CSSRuleList", "DataTransfer", ["DataView",9,9], "Debug", ["DeviceAcceleration",11], ["DeviceMotionEvent",11], ["DeviceOrientationEvent",11], + ["DeviceRotationRate",11], ["DOMError",10], "DOMException", ["DOMSettableTokenList",10], ["DOMStringList",10], ["DOMStringMap",11], "DragEvent", ["ErrorEvent",10], "EventException", + ["EXT_texture_filter_anisotropic",11], ["File",10], ["FileList",10], ["FileReader",10], ["Float32Array",10], ["Float64Array",10], "FocusEvent", ["FormData",10], "Geolocation", "GetObject", + ["HTMLAllCollection",11], "HTMLAppletElement", "HTMLAreasCollection", "HTMLAudioElement", "HTMLBaseElement", "HTMLBaseFontElement", "HTMLBGSoundElement", "HTMLBlockElement", "HTMLBRElement", + "HTMLCanvasElement", ["HTMLDataListElement",10], "HTMLDDElement", "HTMLDirectoryElement", "HTMLDivElement", "HTMLDListElement", "HTMLDTElement", "HTMLFieldSetElement", "HTMLFontElement", + "HTMLFrameSetElement", "HTMLHeadingElement", "HTMLHRElement", "HTMLIsIndexElement", "HTMLLegendElement", "HTMLLIElement", "HTMLMapElement", "HTMLMarqueeElement", "HTMLMediaElement", + "HTMLMenuElement", "HTMLModElement", "HTMLNextIdElement", "HTMLOListElement", "HTMLOptGroupElement", "HTMLParagraphElement", "HTMLParamElement", "HTMLPhraseElement", "HTMLPreElement", + ["HTMLProgressElement",10], "HTMLQuoteElement", "HTMLSourceElement", "HTMLSpanElement", "HTMLTableCaptionElement", "HTMLTableColElement", "HTMLTableHeaderCellElement", "HTMLTableSectionElement", + ["HTMLTrackElement",10], "HTMLUListElement", "HTMLVideoElement", ["IDBCursor",10], ["IDBCursorWithValue",10], ["IDBDatabase",10], ["IDBFactory",10], ["IDBIndex",10], ["IDBKeyRange",10], + ["IDBObjectStore",10], ["IDBOpenDBRequest",10], ["IDBRequest",10], ["IDBTransaction",10], ["IDBVersionChangeEvent",10], "ImageData", ["Int16Array",10], ["Int32Array",10], ["Int8Array",10], + ["Intl",11], ["Key",11], ["KeyOperation",11], ["KeyPair",11], "Location", "MediaError", "MediaList", ["MediaSource",11], ["MessageChannel",10], ["MessagePort",10], ["MimeType",11], + ["MimeTypeArray",9,10], "MouseWheelEvent", "MSBehaviorUrnsCollection", ["MSBlobBuilder",10], "MSCompatibleInfo", "MSCompatibleInfoCollection", ["MSCSSMatrix",10], ["MSGesture",10], + ["MSGestureEvent",10], ["MSGraphicsTrust",11], ["MSInputMethodContext",11], ["MSManipulationEvent",10], ["MSMediaKeyError",11], ["MSMediaKeyMessageEvent",11], ["MSMediaKeyNeededEvent",11], + ["MSMediaKeys",11], ["MSMediaKeySession",11], "MSMimeTypesCollection", ["MSNamespaceInfo",0,9], "MSPluginsCollection", ["MSPointerEvent",10], ["MSPopupWindow",0,10], ["MSRangeCollection",10], + "MSSiteModeEvent", ["MSStream",10], ["MSStreamReader",10], "MutationEvent", ["MutationRecord",11], "NodeFilter", "NodeIterator", ["OES_element_index_uint",11], ["OES_standard_derivatives",11], + ["OES_texture_float",11], ["OES_texture_float_linear",11], "PerformanceEntry", "PerformanceMark", "PerformanceMeasure", ["PerformanceNavigationTiming",11], "PerformanceResourceTiming", + ["Plugin",11], ["PluginArray",9,10], ["PointerEvent",11], ["PopStateEvent",10], "Position", "PositionError", "ProcessingInstruction", "RangeException", "RegExpError", "Selection", + ["SourceBuffer",11], ["SourceBufferList",11], "StyleMedia", "StyleSheetPageList", ["SubtleCrypto",11], "SVGAElement", "SVGAngle", "SVGAnimatedAngle", "SVGAnimatedBoolean", + "SVGAnimatedEnumeration", "SVGAnimatedInteger", "SVGAnimatedLength", "SVGAnimatedLengthList", "SVGAnimatedNumber", "SVGAnimatedNumberList", "SVGAnimatedPreserveAspectRatio", "SVGAnimatedRect", + "SVGAnimatedString", "SVGAnimatedTransformList", "SVGClipPathElement", ["SVGComponentTransferFunctionElement",10], "SVGDefsElement", "SVGDescElement", "SVGElementInstance", + "SVGElementInstanceList", "SVGEllipseElement", "SVGException", ["SVGFEBlendElement",10], ["SVGFEColorMatrixElement",10], ["SVGFEComponentTransferElement",10], ["SVGFECompositeElement",10], ["SVGFEConvolveMatrixElement",10], ["SVGFEDiffuseLightingElement",10], ["SVGFEDisplacementMapElement",10], ["SVGFEDistantLightElement",10], ["SVGFEFloodElement",10], ["SVGFEFuncAElement",10], ["SVGFEFuncBElement",10], ["SVGFEFuncGElement",10], ["SVGFEFuncRElement",10], ["SVGFEGaussianBlurElement",10], ["SVGFEImageElement",10], ["SVGFEMergeElement",10], ["SVGFEMergeNodeElement",10], ["SVGFEMorphologyElement",10], ["SVGFEOffsetElement",10], ["SVGFEPointLightElement",10], ["SVGFESpecularLightingElement",10], ["SVGFESpotLightElement",10], ["SVGFETileElement",10], ["SVGFETurbulenceElement",10], ["SVGFilterElement",10], "SVGGElement", "SVGGradientElement", "SVGImageElement", "SVGLength", "SVGLengthList", "SVGLinearGradientElement", "SVGLineElement", - "SVGMarkerElement", "SVGMaskElement", "SVGMatrix", "SVGMetadataElement", "SVGNumber", "SVGNumberList", "SVGPathElement", "SVGPathSeg", "SVGPathSegArcAbs", "SVGPathSegArcRel", - "SVGPathSegClosePath", "SVGPathSegCurvetoCubicAbs", "SVGPathSegCurvetoCubicRel", "SVGPathSegCurvetoCubicSmoothAbs", "SVGPathSegCurvetoCubicSmoothRel", "SVGPathSegCurvetoQuadraticAbs", - "SVGPathSegCurvetoQuadraticRel", "SVGPathSegCurvetoQuadraticSmoothAbs", "SVGPathSegCurvetoQuadraticSmoothRel", "SVGPathSegLinetoAbs", "SVGPathSegLinetoHorizontalAbs", - "SVGPathSegLinetoHorizontalRel", "SVGPathSegLinetoRel", "SVGPathSegLinetoVerticalAbs", "SVGPathSegLinetoVerticalRel", "SVGPathSegList", "SVGPathSegMovetoAbs", "SVGPathSegMovetoRel", - "SVGPatternElement", "SVGPoint", "SVGPointList", "SVGPolygonElement", "SVGPolylineElement", "SVGPreserveAspectRatio", "SVGRadialGradientElement", "SVGRect", "SVGRectElement", - "SVGScriptElement", "SVGStopElement", "SVGStringList", "SVGStyleElement", "SVGSwitchElement", "SVGSymbolElement", "SVGTextElement", "SVGTextPathElement", "SVGTitleElement", - "SVGTransform", "SVGTransformList", "SVGUnitTypes", "SVGUseElement", "SVGViewElement", "SVGZoomAndPan", "SVGZoomEvent", "TextEvent", "TextMetrics", "TextRangeCollection", ["TextTrack",10], - ["TextTrackCue",10], ["TextTrackCueList",10], ["TextTrackList",10], "TimeRanges", ["TrackEvent",10], ["TransitionEvent",10], "TreeWalker", ["Uint16Array",10], ["Uint32Array",10], - ["Uint8Array",10], ["Uint8ClampedArray",11], ["URL",10], ["ValidityState",10], ["VideoPlaybackQuality",11], ["WebGLActiveInfo",11], ["WebGLBuffer",11], ["WebGLContextEvent",11], - ["WebGLFramebuffer",11], ["WebGLObject",11], ["WebGLProgram",11], ["WebGLRenderbuffer",11], ["WebGLRenderingContext",11], ["WebGLShader",11], ["WebGLShaderPrecisionFormat",11], - ["WebGLTexture",11], ["WebGLUniformLocation",11], ["WEBGL_compressed_texture_s3tc",11], ["WEBGL_debug_renderer_info",11], ["WebSocket",10], "WheelEvent", ["Worker",10], - ["XDomainRequest",9,10], ["XMLDocument",11], ["XMLHttpRequestEventTarget",10], "XMLSerializer" + "SVGMarkerElement", "SVGMaskElement", "SVGMatrix", "SVGMetadataElement", "SVGNumber", "SVGNumberList", "SVGPathElement", "SVGPathSeg", "SVGPathSegArcAbs", "SVGPathSegArcRel", "SVGPathSegClosePath", + "SVGPathSegCurvetoCubicAbs", "SVGPathSegCurvetoCubicRel", "SVGPathSegCurvetoCubicSmoothAbs", "SVGPathSegCurvetoCubicSmoothRel", "SVGPathSegCurvetoQuadraticAbs", "SVGPathSegCurvetoQuadraticRel", + "SVGPathSegCurvetoQuadraticSmoothAbs", "SVGPathSegCurvetoQuadraticSmoothRel", "SVGPathSegLinetoAbs", "SVGPathSegLinetoHorizontalAbs", "SVGPathSegLinetoHorizontalRel", "SVGPathSegLinetoRel", + "SVGPathSegLinetoVerticalAbs", "SVGPathSegLinetoVerticalRel", "SVGPathSegList", "SVGPathSegMovetoAbs", "SVGPathSegMovetoRel", "SVGPatternElement", "SVGPoint", "SVGPointList", "SVGPolygonElement", + "SVGPolylineElement", "SVGPreserveAspectRatio", "SVGRadialGradientElement", "SVGRect", "SVGRectElement", "SVGScriptElement", "SVGStopElement", "SVGStringList", "SVGStyleElement", + "SVGSwitchElement", "SVGSymbolElement", "SVGTextElement", "SVGTextPathElement", "SVGTitleElement", "SVGTransform", "SVGTransformList", "SVGUnitTypes", "SVGUseElement", "SVGViewElement", + "SVGZoomAndPan", "SVGZoomEvent", "TextEvent", "TextMetrics", "TextRangeCollection", ["TextTrack",10], ["TextTrackCue",10], ["TextTrackCueList",10], ["TextTrackList",10], "TimeRanges", + ["TrackEvent",10], ["TransitionEvent",10], "TreeWalker", ["Uint16Array",10], ["Uint32Array",10], ["Uint8Array",10], ["Uint8ClampedArray",11], ["URL",10], ["ValidityState",10], + ["VideoPlaybackQuality",11], ["WebGLActiveInfo",11], ["WebGLBuffer",11], ["WebGLContextEvent",11], ["WebGLFramebuffer",11], ["WebGLObject",11], ["WebGLProgram",11], ["WebGLRenderbuffer",11], + ["WebGLRenderingContext",11], ["WebGLShader",11], ["WebGLShaderPrecisionFormat",11], ["WebGLTexture",11], ["WebGLUniformLocation",11], ["WEBGL_compressed_texture_s3tc",11], + ["WEBGL_debug_renderer_info",11], ["WebSocket",10], "WheelEvent", ["Worker",10], ["XDomainRequest",9,10], ["XMLDocument",11], ["XMLHttpRequestEventTarget",10], "XMLSerializer" ]); next_test(); } diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 1781df69ee3..67f974bbacf 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2814,6 +2814,17 @@ sync_test("screen", function() { ok(!check_enum(o, "prop2"), "prop2 enumerated"); });
+sync_test("DOMParser", function() { + var p, r = DOMParser.length; + ok(r === 0, "length = " + r); + + p = DOMParser(); + r = Object.getPrototypeOf(p); + ok(r === DOMParser.prototype, "prototype of instance created without new = " + r); + ok(p !== new DOMParser(), "DOMParser() == new DOMParser()"); + ok(new DOMParser() !== new DOMParser(), "new DOMParser() == new DOMParser()"); +}); + sync_test("builtin_func", function() { var o = document.implementation, r; var f = o.hasFeature;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Native modes IE10 and up implement XML documents as children of the DocumentPrototype, which have standard IHTMLDocument interfaces. But previous modes do not, but instead have the IXMLDOMDocument interface (which suggests it uses msxml like now).
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 47 ++++++++++++++++++++++++++++-- dlls/mshtml/mshtml_private.h | 11 +++++++ dlls/mshtml/tests/documentmode.js | 6 +++- dlls/mshtml/tests/xhr.js | 22 ++++++++++++++ dlls/mshtml/tests/xmlhttprequest.c | 15 ++++++++++ dlls/mshtml/xmlhttprequest.c | 14 +++++++++ 6 files changed, 112 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 7255e8d9ec3..542382bf4d0 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -39,8 +39,39 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static dispex_static_data_t *const dispex_from_document_type[] = { + [DOCTYPE_HTML] = &HTMLDocument_dispex, + [DOCTYPE_XHTML] = &XMLDocument_dispex, + [DOCTYPE_XML] = &XMLDocument_dispex, + [DOCTYPE_SVG] = &XMLDocument_dispex, +}; + static HRESULT create_document_fragment(nsIDOMNode *nsnode, HTMLDocumentNode *doc_node, HTMLDocumentNode **ret);
+static document_type_t get_doc_type(nsIDOMDocument *nsdoc) +{ + document_type_t doc_type; + const PRUnichar *str; + nsAString nsstr; + nsresult nsres; + + nsAString_Init(&nsstr, NULL); + nsres = nsIDOMDocument_GetContentType(nsdoc, &nsstr); + assert(nsres == NS_OK); + + nsAString_GetData(&nsstr, &str); + if(!wcscmp(str, L"text/html")) + doc_type = DOCTYPE_HTML; + else if(!wcscmp(str, L"application/xhtml+xml")) + doc_type = DOCTYPE_XHTML; + else if(!wcscmp(str, L"image/svg+xml")) + doc_type = DOCTYPE_SVG; + else + doc_type = DOCTYPE_XML; + nsAString_Finish(&nsstr); + return doc_type; +} + HRESULT get_doc_elem_by_id(HTMLDocumentNode *doc, const WCHAR *id, HTMLElement **ret) { nsIDOMNodeList *nsnode_list; @@ -5634,7 +5665,7 @@ static HTMLInnerWindow *HTMLDocumentNode_get_script_global(DispatchEx *dispex, d if(This->node.vtbl != &HTMLDocumentNodeImplVtbl) *dispex_data = &DocumentFragment_dispex; else - *dispex_data = This->document_mode < COMPAT_MODE_IE11 ? &Document_dispex : &HTMLDocument_dispex; + *dispex_data = This->document_mode < COMPAT_MODE_IE11 ? &Document_dispex : dispex_from_document_type[This->doc_type]; return This->script_global; }
@@ -5870,6 +5901,17 @@ dispex_static_data_t HTMLDocument_dispex = { .min_compat_mode = COMPAT_MODE_IE11, };
+dispex_static_data_t XMLDocument_dispex = { + .id = OBJID_XMLDocument, + .prototype_id = OBJID_Document, + .vtbl = &HTMLDocument_event_target_vtbl.dispex_vtbl, + .disp_tid = DispHTMLDocument_tid, + .iface_tids = HTMLDocumentNode_iface_tids, + .init_info = HTMLDocumentNode_init_dispex_info, + .js_flags = HOSTOBJ_VOLATILE_FILL, + .min_compat_mode = COMPAT_MODE_IE11, +}; + static HTMLDocumentNode *alloc_doc_node(HTMLDocumentObj *doc_obj, HTMLInnerWindow *window, HTMLInnerWindow *script_global) { HTMLDocumentNode *doc; @@ -5927,6 +5969,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI doc = alloc_doc_node(doc_obj, window, script_global); if(!doc) return E_OUTOFMEMORY; + doc->doc_type = get_doc_type(nsdoc);
if(parent_mode >= COMPAT_MODE_IE9) { TRACE("using parent mode %u\n", parent_mode); @@ -5946,7 +5989,7 @@ HRESULT create_document_node(nsIDOMDocument *nsdoc, GeckoBrowser *browser, HTMLI doc->html_document = NULL; }
- HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)doc->dom_document, &HTMLDocument_dispex); + HTMLDOMNode_Init(doc, &doc->node, (nsIDOMNode*)doc->dom_document, dispex_from_document_type[doc->doc_type]);
init_document_mutation(doc); doc_init_events(doc); diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 50f147531d1..6686772110a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -510,6 +510,7 @@ typedef struct { X(TextRange) \ X(UIEvent) \ X(Window) \ + X(XMLDocument) \ X(XMLHttpRequest)
typedef enum { @@ -1094,6 +1095,15 @@ struct HTMLFrameBase {
typedef struct nsDocumentEventListener nsDocumentEventListener;
+/* NOTE: Update arrays at top of htmldoc.c if you change this */ +typedef enum { + DOCTYPE_INVALID = -1, + DOCTYPE_HTML, + DOCTYPE_XHTML, + DOCTYPE_XML, + DOCTYPE_SVG, +} document_type_t; + struct HTMLDocumentNode { HTMLDOMNode node;
@@ -1149,6 +1159,7 @@ struct HTMLDocumentNode { unsigned int content_ready : 1; unsigned int unload_sent : 1;
+ document_type_t doc_type; IHTMLDOMImplementation *dom_implementation; IHTMLNamespaceCollection *namespaces;
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 6809b957b2f..17b4919457d 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -981,6 +981,7 @@ sync_test("window_props", function() { test_exposed("matchMedia", v >= 10); test_exposed("Document", v >= 9); test_exposed("HTMLDocument", v === 8 || v >= 11, v === 8); + test_exposed("XMLDocument", v >= 11); test_exposed("DOMParser", v >= 9); test_exposed("MutationObserver", v >= 11); test_exposed("PageTransitionEvent", v >= 11); @@ -3868,6 +3869,7 @@ sync_test("prototypes", function() { else { check(document, HTMLDocument.prototype, "html document"); check(HTMLDocument.prototype, Document.prototype, "html document prototype"); + check(XMLDocument.prototype, Document.prototype, "xml document prototype"); } check(Document.prototype, Node.prototype, "document prototype"); check(window, Window.prototype, "window"); @@ -4412,6 +4414,8 @@ sync_test("prototype props", function() { check(StyleSheet, [ "disabled", "href", "media", "ownerNode", "parentStyleSheet", "title", "type" ]); check(Text, [ "removeNode", "replaceNode", "replaceWholeText", "splitText", "swapNode", "wholeText" ], [ "replaceWholeText", "wholeText" ]); check(UIEvent, [ "detail", "initUIEvent", "view" ], null, [ "deviceSessionId" ]); + if(v >= 11) + check(XMLDocument, []); });
sync_test("constructors", function() { @@ -4585,7 +4589,7 @@ async_test("window own props", function() { ["TrackEvent",10], ["TransitionEvent",10], "TreeWalker", ["Uint16Array",10], ["Uint32Array",10], ["Uint8Array",10], ["Uint8ClampedArray",11], ["URL",10], ["ValidityState",10], ["VideoPlaybackQuality",11], ["WebGLActiveInfo",11], ["WebGLBuffer",11], ["WebGLContextEvent",11], ["WebGLFramebuffer",11], ["WebGLObject",11], ["WebGLProgram",11], ["WebGLRenderbuffer",11], ["WebGLRenderingContext",11], ["WebGLShader",11], ["WebGLShaderPrecisionFormat",11], ["WebGLTexture",11], ["WebGLUniformLocation",11], ["WEBGL_compressed_texture_s3tc",11], - ["WEBGL_debug_renderer_info",11], ["WebSocket",10], "WheelEvent", ["Worker",10], ["XDomainRequest",9,10], ["XMLDocument",11], ["XMLHttpRequestEventTarget",10], "XMLSerializer" + ["WEBGL_debug_renderer_info",11], ["WebSocket",10], "WheelEvent", ["Worker",10], ["XDomainRequest",9,10], ["XMLHttpRequestEventTarget",10], "XMLSerializer" ]); next_test(); } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index cc543e7cec8..46aed46624c 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -22,6 +22,7 @@ var xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<a name="test">wine</a> async_test("async_xhr", function() { var xhr = new XMLHttpRequest(); var complete_cnt = 0, loadstart = false; + var v = document.documentMode;
xhr.onreadystatechange = function() { if(xhr.readyState != 4) @@ -30,6 +31,26 @@ async_test("async_xhr", function() { ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText); ok(xhr.responseXML !== null, "unexpected null responseXML");
+ var x = xhr.responseXML, r = Object.prototype.toString.call(x); + ok(r === (v < 10 ? "[object Object]" : (v < 11 ? "[object Document]" : "[object XMLDocument]")), + "XML document Object.toString = " + r); + + r = Object.getPrototypeOf(x); + if(v < 10) + ok(r === null, "prototype of returned XML document = " + r); + else if(v < 11) + ok(r === window.Document.prototype, "prototype of returned XML document = " + r); + else + ok(r === window.XMLDocument.prototype, "prototype of returned XML document = " + r); + + if(v < 10) { + ok(!("anchors" in x), "anchors is in returned XML document"); + ok(Object.prototype.hasOwnProperty.call(x, "createElement"), "createElement not a prop of returned XML document"); + }else { + ok("anchors" in x, "anchors not in returned XML document"); + ok(!x.hasOwnProperty("createElement"), "createElement is a prop of returned XML document"); + } + if(complete_cnt++ && !("onloadend" in xhr)) next_test(); } @@ -229,6 +250,7 @@ async_test("content_types", function() { var xml_types = [ "text/xmL", "apPliCation/xml", + "application/xHtml+xml", "image/SvG+xml", "Wine/Test+xml", "++Xml", diff --git a/dlls/mshtml/tests/xmlhttprequest.c b/dlls/mshtml/tests/xmlhttprequest.c index 6226461a502..44132160520 100644 --- a/dlls/mshtml/tests/xmlhttprequest.c +++ b/dlls/mshtml/tests/xmlhttprequest.c @@ -519,10 +519,14 @@ static void _set_request_header(unsigned line, IHTMLXMLHttpRequest *xhr, const W static void test_responseXML(const WCHAR *expect_text) { IDispatch *disp; + IHTMLDocument2 *html_doc; IXMLDOMDocument *xmldom; IObjectSafety *safety; + IHTMLDOMNode *node; DWORD enabled = 0, supported = 0; + DISPID dispid; HRESULT hres; + BSTR str;
disp = NULL; hres = IHTMLXMLHttpRequest_get_responseXML(xhr, &disp); @@ -545,6 +549,17 @@ static void test_responseXML(const WCHAR *expect_text) "Expected enabled: (INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA | INTERFACE_USES_SECURITY_MANAGER), got 0x%08lx\n", enabled); IObjectSafety_Release(safety);
+ hres = IXMLDOMDocument_QueryInterface(xmldom, &IID_IHTMLDOMNode, (void**)&node); + ok(hres == E_NOINTERFACE, "QueryInterface(IHTMLDOMNode) returned: %08lx\n", hres); + + hres = IXMLDOMDocument_QueryInterface(xmldom, &IID_IHTMLDocument2, (void**)&html_doc); + ok(hres == E_NOINTERFACE, "QueryInterface(IHTMLDocument2) returned: %08lx\n", hres); + + str = SysAllocString(L"anchors"); + hres = IDispatch_GetIDsOfNames(disp, &IID_NULL, &str, 1, LOCALE_USER_DEFAULT, &dispid); + ok(hres == DISP_E_UNKNOWNNAME, "GetIDsOfNames("anchors") returned: %08lx\n", hres); + SysFreeString(str); + if(!expect_text) test_illegal_xml(xmldom);
diff --git a/dlls/mshtml/xmlhttprequest.c b/dlls/mshtml/xmlhttprequest.c index 3097792c620..61561d3a2b7 100644 --- a/dlls/mshtml/xmlhttprequest.c +++ b/dlls/mshtml/xmlhttprequest.c @@ -576,6 +576,7 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *if }
if(dispex_compat_mode(&This->event_target.dispex) >= COMPAT_MODE_IE10) { + HTMLDocumentNode *doc; nsIDOMDocument *nsdoc; nsresult nsres;
@@ -586,7 +587,20 @@ static HRESULT WINAPI HTMLXMLHttpRequest_get_responseXML(IHTMLXMLHttpRequest *if *p = NULL; return S_OK; } + + if(!This->window->base.outer_window || !This->window->base.outer_window->browser) + hres = E_UNEXPECTED; + else + hres = create_document_node(nsdoc, This->window->base.outer_window->browser, NULL, This->window, + dispex_compat_mode(&This->window->event_target.dispex), &doc); nsIDOMDocument_Release(nsdoc); + if(FAILED(hres)) + return hres; + + /* make sure dispex info is initialized */ + dispex_compat_mode(&doc->node.event_target.dispex); + *p = (IDispatch*)&doc->IHTMLDocument2_iface; + return S_OK; }
hres = CoCreateInstance(&CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void**)&xmldoc);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 12 +++++++++++- dlls/mshtml/tests/xhr.js | 11 +++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 542382bf4d0..547de31afe1 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -39,6 +39,13 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static const WCHAR *const content_type_from_document_type[] = { + [DOCTYPE_HTML] = L"text/html", + [DOCTYPE_XHTML] = L"application/xhtml+xml", + [DOCTYPE_XML] = L"text/xml", + [DOCTYPE_SVG] = L"image/svg+xml", +}; + static dispex_static_data_t *const dispex_from_document_type[] = { [DOCTYPE_HTML] = &HTMLDocument_dispex, [DOCTYPE_XHTML] = &XMLDocument_dispex, @@ -1305,7 +1312,10 @@ static HRESULT WINAPI HTMLDocument_get_mimeType(IHTMLDocument2 *iface, BSTR *p)
*p = NULL;
- if(This->window && !This->window->navigation_start_time) + if(!This->window) + return get_mime_type_display_name(content_type_from_document_type[This->doc_type], p); + + if(!This->window->navigation_start_time) return (*p = SysAllocString(L"")) ? S_OK : E_FAIL;
nsAString_InitDepend(&nsstr, NULL); diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 46aed46624c..7c553dc25ea 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -259,9 +259,16 @@ async_test("content_types", function() {
function onload() { ok(xhr.responseText === xml, "unexpected responseText " + xhr.responseText); - if(v < 10 || types === xml_types) + if(v < 10 || types === xml_types) { ok(xhr.responseXML !== null, "unexpected null responseXML for " + types[i]); - else + if(v >= 10) { + var r = xhr.responseXML.mimeType, e = "text/xml"; + if(types[i] === "application/xHtml+xml" || types[i] === "image/SvG+xml") + e = types[i].toLowerCase(); + e = external.getExpectedMimeType(e); + ok(r === e, "XML document mimeType for " + types[i] + " = " + r + ", expected " + e); + } + }else ok(xhr.responseXML === null, "unexpected non-null responseXML for " + (override ? "overridden " : "") + types[i]);
if(("overrideMimeType" in xhr) && !override) {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 21 ++++++++++----------- dlls/mshtml/tests/xhr.js | 2 ++ 2 files changed, 12 insertions(+), 11 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 547de31afe1..7c6b64a04e9 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -651,21 +651,20 @@ static HRESULT WINAPI HTMLDocument_get_anchors(IHTMLDocument2 *iface, IHTMLEleme return E_UNEXPECTED; }
- if(!This->html_document) { - FIXME("Not implemented for XML document\n"); - return E_NOTIMPL; - } + if(This->doc_type == DOCTYPE_XHTML) + FIXME("Not implemented for XHTML Document, returning empty list\n");
- nsres = nsIDOMHTMLDocument_GetAnchors(This->html_document, &nscoll); - if(NS_FAILED(nsres)) { - ERR("GetAnchors failed: %08lx\n", nsres); - return E_FAIL; + if(This->html_document) { + nsres = nsIDOMHTMLDocument_GetAnchors(This->html_document, &nscoll); + if(NS_FAILED(nsres)) { + ERR("GetAnchors failed: %08lx\n", nsres); + return E_FAIL; + } }
- if(nscoll) { - *p = create_collection_from_htmlcol(nscoll, &This->node.event_target.dispex); + *p = create_collection_from_htmlcol(nscoll, &This->node.event_target.dispex); + if(nscoll) nsIDOMHTMLCollection_Release(nscoll); - }
return S_OK; } diff --git a/dlls/mshtml/tests/xhr.js b/dlls/mshtml/tests/xhr.js index 7c553dc25ea..7685a5a8486 100644 --- a/dlls/mshtml/tests/xhr.js +++ b/dlls/mshtml/tests/xhr.js @@ -49,6 +49,8 @@ async_test("async_xhr", function() { }else { ok("anchors" in x, "anchors not in returned XML document"); ok(!x.hasOwnProperty("createElement"), "createElement is a prop of returned XML document"); + r = x.anchors; + ok(r.length === 0, "anchors.length of returned XML document = " + r.length); }
if(complete_cnt++ && !("onloadend" in xhr))
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/mshtml_private.h | 2 + dlls/mshtml/nsembed.c | 43 +++++++++++++ dlls/mshtml/nsiface.idl | 13 ++++ dlls/mshtml/omnavigator.c | 103 +++++++++++++++++++++++++++++- dlls/mshtml/tests/documentmode.js | 3 + dlls/mshtml/tests/es5.js | 96 +++++++++++++++++++++++++++- 6 files changed, 257 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 6686772110a..30802386291 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -76,6 +76,7 @@ #define MSHTML_E_INVALID_PROPERTY 0x800a01b6 #define MSHTML_E_INVALID_ACTION 0x800a01bd #define MSHTML_E_NODOC 0x800a025c +#define MSHTML_E_SYNTAX 0x800a03ea #define MSHTML_E_NOT_FUNC 0x800a138a
typedef struct HTMLWindow HTMLWindow; @@ -1294,6 +1295,7 @@ HRESULT nsnode_to_nsstring(nsIDOMNode*,nsAString*); void setup_editor_controller(GeckoBrowser*); nsresult get_nsinterface(nsISupports*,REFIID,void**); nsIWritableVariant *create_nsvariant(void); +nsIDOMParser *create_nsdomparser(HTMLDocumentNode*); nsIXMLHttpRequest *create_nsxhr(nsIDOMWindow *nswindow); nsresult create_nsfile(const PRUnichar*,nsIFile**); char *get_nscategory_entry(const char*,const char*); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 5480c4ed044..cbaf05e6345 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -42,6 +42,7 @@ WINE_DECLARE_DEBUG_CHANNEL(gecko); #define NS_WEBBROWSER_CONTRACTID "@mozilla.org/embedding/browser/nsWebBrowser;1" #define NS_COMMANDPARAMS_CONTRACTID "@mozilla.org/embedcomp/command-params;1" #define NS_HTMLSERIALIZER_CONTRACTID "@mozilla.org/layout/contentserializer;1?mimetype=text/html" +#define NS_DOMPARSER_CONTRACTID "@mozilla.org/xmlextras/domparser;1" #define NS_EDITORCONTROLLER_CONTRACTID "@mozilla.org/editor/editorcontroller;1" #define NS_PREFERENCES_CONTRACTID "@mozilla.org/preferences;1" #define NS_VARIANT_CONTRACTID "@mozilla.org/variant;1" @@ -2415,6 +2416,48 @@ __ASM_GLOBAL_FUNC(call_thiscall_func, #define nsIScriptObjectPrincipal_GetPrincipal(this) ((void* (WINAPI*)(void*,void*))&call_thiscall_func)((this)->lpVtbl->GetPrincipal,this) #endif
+nsIDOMParser *create_nsdomparser(HTMLDocumentNode *doc_node) +{ + nsIScriptObjectPrincipal *sop; + mozIDOMWindow *inner_window; + nsIGlobalObject *nsglo; + nsIDOMParser *nsparser; + nsIPrincipal *nspri; + nsresult nsres; + + nsres = nsIDOMWindow_GetInnerWindow(doc_node->window->dom_window, &inner_window); + if(NS_FAILED(nsres)) { + ERR("Could not get inner window: %08lx\n", nsres); + return NULL; + } + + nsres = mozIDOMWindow_QueryInterface(inner_window, &IID_nsIGlobalObject, (void**)&nsglo); + mozIDOMWindow_Release(inner_window); + assert(nsres == NS_OK); + + nsres = nsIGlobalObject_QueryInterface(nsglo, &IID_nsIScriptObjectPrincipal, (void**)&sop); + assert(nsres == NS_OK); + + /* The returned principal is *not* AddRef'd */ + nspri = nsIScriptObjectPrincipal_GetPrincipal(sop); + nsIScriptObjectPrincipal_Release(sop); + + nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, + NS_DOMPARSER_CONTRACTID, NULL, &IID_nsIDOMParser, (void**)&nsparser); + if(NS_SUCCEEDED(nsres)) { + nsres = nsIDOMParser_Init(nsparser, nspri, NULL, NULL, nsglo); + if(NS_FAILED(nsres)) + nsIDOMParser_Release(nsparser); + } + nsIGlobalObject_Release(nsglo); + if(NS_FAILED(nsres)) { + ERR("nsIDOMParser_Init failed: %08lx\n", nsres); + return NULL; + } + + return nsparser; +} + nsIXMLHttpRequest *create_nsxhr(nsIDOMWindow *nswindow) { nsIScriptObjectPrincipal *sop; diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 43786b490f5..1f2131dfb24 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -4369,6 +4369,19 @@ interface nsIScriptObjectPrincipal : nsISupports nsIPrincipal* /* thiscall */ GetPrincipal(); }
+[ + object, + uuid(70b9600e-8622-4c93-9ad8-22c28058dc44), + local +] +interface nsIDOMParser : nsISupports +{ + nsresult ParseFromString(const char16_t *str, const char *contentType, nsIDOMDocument **_retval); + nsresult ParseFromBuffer(const uint8_t *buf, uint32_t bufLen, const char *aContentType, nsIDOMDocument **_retval); + nsresult ParseFromStream(nsIInputStream *stream, const char *charset, int32_t contentLength, const char *contentType, nsIDOMDocument **_retval); + nsresult Init(nsIPrincipal *principal, nsIURI *documentURI, nsIURI *baseURI, nsIGlobalObject *scriptObject); +} + [ object, uuid(6f54214c-7175-498d-9d2d-0429e38c2869), diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index c65fb675372..d9189f7ef71 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -32,6 +32,38 @@
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static document_type_t document_type_from_content_type(const WCHAR *content_type) +{ + static const struct { + const WCHAR *content_type; + document_type_t doc_type; + } table[] = { + { L"application/xhtml+xml", DOCTYPE_XHTML }, + { L"application/xml", DOCTYPE_XML }, + { L"image/svg+xml", DOCTYPE_SVG }, + { L"text/html", DOCTYPE_HTML }, + { L"text/xml", DOCTYPE_XML }, + }; + unsigned int i, a = 0, b = ARRAY_SIZE(table); + int c; + + while(a < b) { + i = (a + b) / 2; + c = wcsicmp(table[i].content_type, content_type); + if(!c) return table[i].doc_type; + if(c > 0) b = i; + else a = i + 1; + } + return DOCTYPE_INVALID; +} + +static const char *const content_type_from_document_type[] = { + [DOCTYPE_HTML] = "text/html", + [DOCTYPE_XHTML] = "application/xhtml+xml", + [DOCTYPE_XML] = "text/xml", + [DOCTYPE_SVG] = "image/svg+xml", +}; + typedef struct HTMLPluginsCollection HTMLPluginsCollection; typedef struct HTMLMimeTypesCollection HTMLMimeTypesCollection;
@@ -272,6 +304,8 @@ void detach_dom_implementation(IHTMLDOMImplementation *iface) struct dom_parser { DispatchEx dispex; IDOMParser IDOMParser_iface; + + HTMLDocumentNode *doc; };
static inline struct dom_parser *impl_from_IDOMParser(IDOMParser *iface) @@ -284,10 +318,53 @@ DISPEX_IDISPATCH_IMPL(dom_parser, IDOMParser, impl_from_IDOMParser(iface)->dispe static HRESULT WINAPI dom_parser_parseFromString(IDOMParser *iface, BSTR string, BSTR mimeType, IHTMLDocument2 **ppNode) { struct dom_parser *This = impl_from_IDOMParser(iface); + nsIDOMDocument *nsdoc = NULL; + document_type_t doc_type; + nsAString errns, errtag; + HTMLDocumentNode *doc; + nsIDOMNodeList *nodes; + nsIDOMParser *parser; + nsresult nsres; + HRESULT hres;
- FIXME("(%p)->(%s %s %p)\n", This, debugstr_w(string), debugstr_w(mimeType), ppNode); + TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(string), debugstr_w(mimeType), ppNode);
- return E_NOTIMPL; + if(!string || !mimeType || (doc_type = document_type_from_content_type(mimeType)) == DOCTYPE_INVALID) + return E_INVALIDARG; + + if(!(parser = create_nsdomparser(This->doc))) + return E_FAIL; + nsres = nsIDOMParser_ParseFromString(parser, string ? string : L"", content_type_from_document_type[doc_type], &nsdoc); + nsIDOMParser_Release(parser); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("ParseFromString failed: 0x%08lx\n", nsres); + return NS_FAILED(nsres) ? map_nsresult(nsres) : E_FAIL; + } + + nsAString_InitDepend(&errns, L"http://www.mozilla.org/newlayout/xml/parsererror.xml"); + nsAString_InitDepend(&errtag, L"parsererror"); + nsres = nsIDOMDocument_GetElementsByTagNameNS(nsdoc, &errns, &errtag, &nodes); + nsAString_Finish(&errtag); + nsAString_Finish(&errns); + if(NS_SUCCEEDED(nsres)) { + UINT32 length; + nsres = nsIDOMNodeList_GetLength(nodes, &length); + nsIDOMNodeList_Release(nodes); + if(NS_SUCCEEDED(nsres) && length) { + nsIDOMDocument_Release(nsdoc); + return MSHTML_E_SYNTAX; + } + } + + hres = create_document_node(nsdoc, This->doc->browser, NULL, This->doc->script_global, This->doc->document_mode, &doc); + nsIDOMDocument_Release(nsdoc); + if(FAILED(hres)) + return hres; + + /* make sure dispex info is initialized */ + dispex_compat_mode(&doc->node.event_target.dispex); + *ppNode = &doc->IHTMLDocument2_iface; + return hres; }
static const IDOMParserVtbl dom_parser_vtbl = { @@ -316,6 +393,23 @@ static void *dom_parser_query_interface(DispatchEx *dispex, REFIID riid) return NULL; }
+static void dom_parser_traverse(DispatchEx *dispex, nsCycleCollectionTraversalCallback *cb) +{ + struct dom_parser *This = dom_parser_from_DispatchEx(dispex); + if(This->doc) + note_cc_edge((nsISupports*)&This->doc->node.IHTMLDOMNode_iface, "doc", cb); +} + +static void dom_parser_unlink(DispatchEx *dispex) +{ + struct dom_parser *This = dom_parser_from_DispatchEx(dispex); + if(This->doc) { + HTMLDocumentNode *doc = This->doc; + This->doc = NULL; + IHTMLDOMNode_Release(&doc->node.IHTMLDOMNode_iface); + } +} + static void dom_parser_destructor(DispatchEx *dispex) { struct dom_parser *This = dom_parser_from_DispatchEx(dispex); @@ -327,6 +421,8 @@ static HRESULT init_dom_parser_ctor(struct constructor*); static const dispex_static_data_vtbl_t dom_parser_dispex_vtbl = { .query_interface = dom_parser_query_interface, .destructor = dom_parser_destructor, + .traverse = dom_parser_traverse, + .unlink = dom_parser_unlink };
static const tid_t dom_parser_iface_tids[] = { @@ -367,6 +463,9 @@ static HRESULT dom_parser_ctor_value(DispatchEx *dispex, LCID lcid, WORD flags, return E_OUTOFMEMORY;
ret->IDOMParser_iface.lpVtbl = &dom_parser_vtbl; + ret->doc = This->window->doc; + IHTMLDOMNode_AddRef(&ret->doc->node.IHTMLDOMNode_iface); + init_dispatch(&ret->dispex, &DOMParser_dispex, This->window, dispex_compat_mode(&This->dispex));
V_VT(res) = VT_DISPATCH; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 17b4919457d..035d3b2ef31 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -334,6 +334,9 @@ sync_test("builtin_toString", function() { test("computedStyle", window.getComputedStyle(e), "CSSStyleDeclaration"); test("doctype", document.doctype, "DocumentType"); test("domParser", new DOMParser(), "DOMParser"); + test("svgDocument", new DOMParser().parseFromString("<tag>foobar</tag>", "image/svg+xml"), v < 11 ? "Document" : "XMLDocument"); + test("xhtmlDocument", new DOMParser().parseFromString("<tag>foobar</tag>", "application/xhtml+xml"), v < 11 ? "Document" : "XMLDocument"); + test("xmlDocument", new DOMParser().parseFromString("<tag>foobar</tag>", "text/xml"), v < 11 ? "Document" : "XMLDocument");
test("Event", document.createEvent("Event"), "Event"); test("CustomEvent", document.createEvent("CustomEvent"), "CustomEvent"); diff --git a/dlls/mshtml/tests/es5.js b/dlls/mshtml/tests/es5.js index 67f974bbacf..02f72586d26 100644 --- a/dlls/mshtml/tests/es5.js +++ b/dlls/mshtml/tests/es5.js @@ -2815,7 +2815,7 @@ sync_test("screen", function() { });
sync_test("DOMParser", function() { - var p, r = DOMParser.length; + var p, r = DOMParser.length, mimeType; ok(r === 0, "length = " + r);
p = DOMParser(); @@ -2823,6 +2823,100 @@ sync_test("DOMParser", function() { ok(r === DOMParser.prototype, "prototype of instance created without new = " + r); ok(p !== new DOMParser(), "DOMParser() == new DOMParser()"); ok(new DOMParser() !== new DOMParser(), "new DOMParser() == new DOMParser()"); + + var teststr = { toString: function() { return "<a name="test">wine</a>"; } }; + + // HTML mime types + mimeType = [ + "text/hTml" + ]; + for(var i = 0; i < mimeType.length; i++) { + var m = mimeType[i], html = p.parseFromString(teststr, m), e = external.getExpectedMimeType(m.toLowerCase()); + r = html.mimeType; + ok(r === e, "mimeType of HTML document with mime type " + m + " = " + r + ", expected " + e); + r = html.childNodes; + ok(r.length === 1 || r.length === 2, "childNodes.length of HTML document with mime type " + m + " = " + r.length); + var html_elem = r[r.length - 1]; + ok(html_elem.nodeName === "HTML", "child nodeName of HTML document with mime type " + m + " = " + html_elem.nodeName); + ok(html_elem.nodeValue === null, "child nodeValue of HTML document with mime type " + m + " = " + html_elem.nodeValue); + r = html.anchors; + ok(r.length === 1, "anchors.length of HTML document with mime type " + m + " = " + r.length); + r = r[0]; + ok(r.nodeName === "A", "anchor nodeName of HTML document with mime type " + m + " = " + r.nodeName); + ok(r.nodeValue === null, "anchor nodeValue of HTML document with mime type " + m + " = " + r.nodeValue); + r = r.parentNode; + ok(r.nodeName === "BODY", "anchor parent nodeName of HTML document with mime type " + m + " = " + r.nodeName); + ok(r.nodeValue === null, "anchor parent nodeValue of HTML document with mime type " + m + " = " + r.nodeValue); + r = r.parentNode; + ok(r === html_elem, "body parent of HTML document with mime type " + m + " = " + r); + } + + // XML mime types + mimeType = [ + "text/xmL", + "aPPlication/xml", + "application/xhtml+xml", + "image/svg+xml" + ]; + for(var i = 0; i < mimeType.length; i++) { + var m = mimeType[i], xml = p.parseFromString(teststr, m), e; + e = external.getExpectedMimeType(m === "aPPlication/xml" ? "text/xml" : m.toLowerCase()); + r = xml.mimeType; + ok(r === e, "mimeType of XML document with mime type " + m + " = " + r + ", expected " + e); + r = xml.childNodes; + ok(r.length === 1, "childNodes.length of XML document with mime type " + m + " = " + r.length); + r = r[0]; + ok(r.nodeName === "a", "child nodeName of XML document with mime type " + m + " = " + r.nodeName); + ok(r.nodeValue === null, "child nodeValue of XML document with mime type " + m + " = " + r.nodeValue); + r = r.childNodes; + ok(r.length === 1, "childNodes of child.length of XML document with mime type " + m + " = " + r.length); + r = r[0]; + ok(r.nodeName === "#text", "child of child nodeName of XML document with mime type " + m + " = " + r.nodeName); + ok(r.nodeValue === "wine", "child of child nodeValue of XML document with mime type " + m + " = " + r.nodeValue); + ok(!("test" in xml), "'test' in XML document with mime type " + m); + + // test HTMLDocument specific props, which are available in DocumentPrototype, + // so they are shared in XMLDocument since they both have the same prototype + r = xml.anchors; + if(m === "application/xhtml+xml") { + todo_wine. + ok(r.length === 1, "anchors.length of XML document with mime type " + m + " = " + r.length); + r = r[0]; + todo_wine. + ok(r === xml.childNodes[0], "anchor of XML document with mime type " + m + " = " + r); + }else { + ok(r.length === 0, "anchors.length of XML document with mime type " + m + " = " + r.length); + } + } + + // Invalid mime types + mimeType = [ + "application/html", + "wine/test+xml", + "image/jpeg", + "text/plain", + "html", + "+xml", + "xml", + 42 + ]; + for(var i = 0; i < mimeType.length; i++) { + try { + p.parseFromString(teststr, mimeType[i]); + ok(false, "expected exception calling parseFromString with mime type " + mimeType[i]); + }catch(ex) { + var n = ex.number >>> 0; + ok(n === E_INVALIDARG, "parseFromString with mime type " + mimeType[i] + " threw " + n); + } + } + + try { + r = p.parseFromString("<invalid>xml", "text/xml"); + ok(false, "expected exception calling parseFromString with invalid xml"); + }catch(ex) { + ok(ex.name === "SyntaxError", "parseFromString with invalid xml threw " + ex.name); + } + p.parseFromString("<parsererror></parsererror>", "text/xml"); });
sync_test("builtin_func", function() {
Jacek Caban (@jacek) commented about dlls/mshtml/tests/documentmode.js:
"HTMLFrameSetElement", "HTMLHeadingElement", "HTMLHRElement", "HTMLIsIndexElement", "HTMLLegendElement", "HTMLLIElement", "HTMLMapElement", "HTMLMarqueeElement", "HTMLMediaElement",
"HTMLMenuElement", "HTMLModElement", "HTMLNextIdElement", "HTMLOListElement", "HTMLOptGroupElement", "HTMLParagraphElement", "HTMLParamElement", "HTMLPhraseElement", "HTMLPreElement",
["HTMLProgressElement",10], "HTMLQuoteElement", "HTMLSourceElement", "HTMLSpanElement", "HTMLTableCaptionElement", "HTMLTableColElement", "HTMLTableHeaderCellElement", "HTMLTableSectionElement",
["HTMLTrackElement",10], "HTMLUListElement", "HTMLVideoElement", ["IDBCursor",10], ["IDBCursorWithValue",10], ["IDBDatabase",10], ["IDBFactory",10], ["IDBIndex",10], ["IDBKeyRange",10],
["IDBObjectStore",10], ["IDBOpenDBRequest",10], ["IDBRequest",10], ["IDBTransaction",10], ["IDBVersionChangeEvent",10], "ImageData", ["Int16Array",10], ["Int32Array",10], ["Int8Array",10],
["Intl",11], ["Key",11], ["KeyOperation",11], ["KeyPair",11], "Location", "MediaError", "MediaList", ["MediaSource",11], ["MessageChannel",10], ["MessagePort",10], ["MimeType",11],
["MimeTypeArray",9,10], "MouseWheelEvent", "MSBehaviorUrnsCollection", ["MSBlobBuilder",10], "MSCompatibleInfo", "MSCompatibleInfoCollection", ["MSCSSMatrix",10], ["MSGesture",10],
["MSGestureEvent",10], ["MSGraphicsTrust",11], ["MSInputMethodContext",11], ["MSManipulationEvent",10], ["MSMediaKeyError",11], ["MSMediaKeyMessageEvent",11], ["MSMediaKeyNeededEvent",11],
["MSMediaKeys",11], ["MSMediaKeySession",11], "MSMimeTypesCollection", ["MSNamespaceInfo",0,9], "MSPluginsCollection", ["MSPointerEvent",10], ["MSPopupWindow",0,10], ["MSRangeCollection",10],
"MSSiteModeEvent", ["MSStream",10], ["MSStreamReader",10], "MutationEvent", ["MutationRecord",11], "NodeFilter", "NodeIterator", ["OES_element_index_uint",11], ["OES_standard_derivatives",11],
["OES_texture_float",11], ["OES_texture_float_linear",11], "PerformanceEntry", "PerformanceMark", "PerformanceMeasure", ["PerformanceNavigationTiming",11], "PerformanceResourceTiming",
["Plugin",11], ["PluginArray",9,10], ["PointerEvent",11], ["PopStateEvent",10], "Position", "PositionError", "ProcessingInstruction", "RangeException", "RegExpError", "Selection",
["SourceBuffer",11], ["SourceBufferList",11], "StyleMedia", "StyleSheetPageList", ["SubtleCrypto",11], "SVGAElement", "SVGAngle", "SVGAnimatedAngle", "SVGAnimatedBoolean",
"SVGAnimatedEnumeration", "SVGAnimatedInteger", "SVGAnimatedLength", "SVGAnimatedLengthList", "SVGAnimatedNumber", "SVGAnimatedNumberList", "SVGAnimatedPreserveAspectRatio", "SVGAnimatedRect",
"SVGAnimatedString", "SVGAnimatedTransformList", "SVGClipPathElement", ["SVGComponentTransferFunctionElement",10], "SVGDefsElement", "SVGDescElement", "SVGElementInstance",
"SVGElementInstanceList", "SVGEllipseElement", "SVGException", ["SVGFEBlendElement",10], ["SVGFEColorMatrixElement",10], ["SVGFEComponentTransferElement",10], ["SVGFECompositeElement",10],
Please don't realign surrounding lines like this on every change. It makes it hard to see what you're changing.
Jacek Caban (@jacek) commented about dlls/mshtml/htmldoc.c:
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+static dispex_static_data_t *const dispex_from_document_type[] = {
- [DOCTYPE_HTML] = &HTMLDocument_dispex,
- [DOCTYPE_XHTML] = &XMLDocument_dispex,
- [DOCTYPE_XML] = &XMLDocument_dispex,
- [DOCTYPE_SVG] = &XMLDocument_dispex,
+};
While I'm not necessarily against those `DOCTYPE_*` enums, the current use does not seem convincing. For example, instead of this array that you need to keep in sync, we could simply use something like `doc_type == DOCTYPE_HTML ? &HTMLDocument_dispex : &XMLDocument_dispex`. In fact we don't need `doc_type` at all, we could just have something like a `is_xml` flag. That, in combination with `html_document != NULL` checks, should cover all use cases and would not require hardcoding all content types, unless I'm missing something.
Jacek Caban (@jacek) commented about dlls/mshtml/htmldoc.c:
- nsAString_Init(&nsstr, NULL);
- nsres = nsIDOMDocument_GetContentType(nsdoc, &nsstr);
- assert(nsres == NS_OK);
- nsAString_GetData(&nsstr, &str);
- if(!wcscmp(str, L"text/html"))
doc_type = DOCTYPE_HTML;
- else if(!wcscmp(str, L"application/xhtml+xml"))
doc_type = DOCTYPE_XHTML;
- else if(!wcscmp(str, L"image/svg+xml"))
doc_type = DOCTYPE_SVG;
- else
doc_type = DOCTYPE_XML;
- nsAString_Finish(&nsstr);
- return doc_type;
+}
The only user, `create_document_node` already knows if it's a HTML document from QI. I guess if we'd go with `is_xml`, we could just do something like `strstr(getContentType(), "xml")` in case of HTML document to know if it's XHTML.
Jacek Caban (@jacek) commented about dlls/mshtml/htmldoc.c:
*p = NULL;
- if(This->window && !This->window->navigation_start_time)
- if(!This->window)
return get_mime_type_display_name(content_type_from_document_type[This->doc_type], p);
Could we just callback to `getContentType()` then? We get `doc_type` from it anyway.
Jacek Caban (@jacek) commented about dlls/mshtml/htmldoc.c:
return E_UNEXPECTED; }
- if(!This->html_document) {
FIXME("Not implemented for XML document\n");
return E_NOTIMPL;
- }
- if(This->doc_type == DOCTYPE_XHTML)
FIXME("Not implemented for XHTML Document, returning empty list\n");
What's wrong with using HTML code path?
Jacek Caban (@jacek) commented about dlls/mshtml/omnavigator.c:
- while(a < b) {
i = (a + b) / 2;
c = wcsicmp(table[i].content_type, content_type);
if(!c) return table[i].doc_type;
if(c > 0) b = i;
else a = i + 1;
- }
- return DOCTYPE_INVALID;
+}
+static const char *const content_type_from_document_type[] = {
- [DOCTYPE_HTML] = "text/html",
- [DOCTYPE_XHTML] = "application/xhtml+xml",
- [DOCTYPE_XML] = "text/xml",
- [DOCTYPE_SVG] = "image/svg+xml",
+};
Why do we need all of that? Could we just lowercase `mimeType` string and pass that to Gecko?
On Wed Aug 27 14:48:19 2025 +0000, Jacek Caban wrote:
The only user, `create_document_node` already knows if it's a HTML document from QI. I guess if we'd go with `is_xml`, we could just do something like `strstr(getContentType(), "xml")` in case of HTML document to know if it's XHTML.
You mean in every method that needs to special case it? I think that's a bit overkill and might be slow, depending on the prop. I guess I can use a `is_xhtml` flag instead, since that's probably the only one that needs it.
i.e.
`html_document != NULL` means HTML.
`is_xhtml` means XHTML.
Otherwise, it's XML.
On Wed Aug 27 14:48:20 2025 +0000, Jacek Caban wrote:
Why do we need all of that? Could we just lowercase `mimeType` string and pass that to Gecko?
I was worried about returning proper error (`E_INVALIDARG` for instance) but it seems I can find that out because Gecko returns `NS_ERROR_NOT_IMPLEMENTED` so I can special case it. Though I'll also have to convert it to ASCII, shouldn't be a problem.
On Wed Aug 27 14:48:20 2025 +0000, Jacek Caban wrote:
What's wrong with using HTML code path?
HTML code path uses `This->html_document`, and this is technically an XML so doesn't have it. Anyway this part doesn't even special case it, just prints a FIXME, but since there's no html_document it just de-facto skips it. Not much I can do there.
On Wed Aug 27 14:48:19 2025 +0000, Jacek Caban wrote:
Could we just callback to `getContentType()` then? We get `doc_type` from it anyway.
Interesting, I looked into why it was needed to have the tests pass. It looks like the "default" is XML, and doc_type was reflecting that. I'll have to use something similar here, then.