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 | 11 ++- dlls/mshtml/tests/es5.js | 11 +++ 4 files changed, 148 insertions(+), 2 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..cd18193bd1c 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++) { @@ -4544,7 +4551,7 @@ async_test("window own props", function() { "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], + ["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", 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;