2 * Copyright 2008 Jacek Caban for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
31 #include "wine/debug.h"
33 #include "mshtml_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
38 static HRESULT get_url(HTMLLocation *This, const WCHAR **ret)
40 if(!This->window || !This->window->url) {
41 FIXME("No current URL\n");
45 *ret = This->window->url;
49 static HRESULT get_url_components(HTMLLocation *This, URL_COMPONENTSW *url)
54 hres = get_url(This, &doc_url);
58 if(!InternetCrackUrlW(doc_url, 0, 0, url)) {
59 FIXME("InternetCrackUrlW failed: 0x%08x\n", GetLastError());
67 #define HTMLLOCATION_THIS(iface) DEFINE_THIS(HTMLLocation, HTMLLocation, iface)
69 static HRESULT WINAPI HTMLLocation_QueryInterface(IHTMLLocation *iface, REFIID riid, void **ppv)
71 HTMLLocation *This = HTMLLOCATION_THIS(iface);
75 if(IsEqualGUID(&IID_IUnknown, riid)) {
76 TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
77 *ppv = HTMLLOCATION(This);
78 }else if(IsEqualGUID(&IID_IHTMLLocation, riid)) {
79 TRACE("(%p)->(IID_IHTMLLocation %p)\n", This, ppv);
80 *ppv = HTMLLOCATION(This);
81 }else if(dispex_query_interface(&This->dispex, riid, ppv)) {
82 return *ppv ? S_OK : E_NOINTERFACE;
86 IUnknown_AddRef((IUnknown*)*ppv);
90 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
94 static ULONG WINAPI HTMLLocation_AddRef(IHTMLLocation *iface)
96 HTMLLocation *This = HTMLLOCATION_THIS(iface);
97 LONG ref = InterlockedIncrement(&This->ref);
99 TRACE("(%p) ref=%d\n", This, ref);
104 static ULONG WINAPI HTMLLocation_Release(IHTMLLocation *iface)
106 HTMLLocation *This = HTMLLOCATION_THIS(iface);
107 LONG ref = InterlockedDecrement(&This->ref);
109 TRACE("(%p) ref=%d\n", This, ref);
113 This->window->location = NULL;
114 release_dispex(&This->dispex);
121 static HRESULT WINAPI HTMLLocation_GetTypeInfoCount(IHTMLLocation *iface, UINT *pctinfo)
123 HTMLLocation *This = HTMLLOCATION_THIS(iface);
124 return IDispatchEx_GetTypeInfoCount(&This->dispex.IDispatchEx_iface, pctinfo);
127 static HRESULT WINAPI HTMLLocation_GetTypeInfo(IHTMLLocation *iface, UINT iTInfo,
128 LCID lcid, ITypeInfo **ppTInfo)
130 HTMLLocation *This = HTMLLOCATION_THIS(iface);
131 return IDispatchEx_GetTypeInfo(&This->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
134 static HRESULT WINAPI HTMLLocation_GetIDsOfNames(IHTMLLocation *iface, REFIID riid,
135 LPOLESTR *rgszNames, UINT cNames,
136 LCID lcid, DISPID *rgDispId)
138 HTMLLocation *This = HTMLLOCATION_THIS(iface);
139 return IDispatchEx_GetIDsOfNames(&This->dispex.IDispatchEx_iface, riid, rgszNames, cNames,
143 static HRESULT WINAPI HTMLLocation_Invoke(IHTMLLocation *iface, DISPID dispIdMember,
144 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
145 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
147 HTMLLocation *This = HTMLLOCATION_THIS(iface);
148 return IDispatchEx_Invoke(&This->dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
149 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
152 static HRESULT WINAPI HTMLLocation_put_href(IHTMLLocation *iface, BSTR v)
154 HTMLLocation *This = HTMLLOCATION_THIS(iface);
156 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
159 FIXME("No window available\n");
163 return navigate_url(This->window, v, This->window->url);
166 static HRESULT WINAPI HTMLLocation_get_href(IHTMLLocation *iface, BSTR *p)
168 HTMLLocation *This = HTMLLOCATION_THIS(iface);
169 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
170 WCHAR *buf = NULL, *url_path = NULL;
175 TRACE("(%p)->(%p)\n", This, p);
180 url.dwSchemeLength = 1;
181 url.dwHostNameLength = 1;
182 url.dwUrlPathLength = 1;
183 url.dwExtraInfoLength = 1;
184 hres = get_url_components(This, &url);
188 switch(url.nScheme) {
189 case INTERNET_SCHEME_FILE:
191 /* prepend a slash */
192 url_path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR));
194 return E_OUTOFMEMORY;
196 memcpy(url_path + 1, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
197 url.lpszUrlPath = url_path;
198 url.dwUrlPathLength = url.dwUrlPathLength + 1;
202 case INTERNET_SCHEME_HTTP:
203 case INTERNET_SCHEME_HTTPS:
204 case INTERNET_SCHEME_FTP:
205 if(!url.dwUrlPathLength) {
206 /* add a slash if it's blank */
207 url_path = url.lpszUrlPath = HeapAlloc(GetProcessHeap(), 0, 1 * sizeof(WCHAR));
209 return E_OUTOFMEMORY;
210 url.lpszUrlPath[0] = '/';
211 url.dwUrlPathLength = 1;
219 /* replace \ with / */
220 for(i = 0; i < url.dwUrlPathLength; ++i)
221 if(url.lpszUrlPath[i] == '\\')
222 url.lpszUrlPath[i] = '/';
224 if(InternetCreateUrlW(&url, ICU_ESCAPE, NULL, &len)) {
225 FIXME("InternetCreateUrl succeeded with NULL buffer?\n");
230 if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
231 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
238 buf = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
244 if(!InternetCreateUrlW(&url, ICU_ESCAPE, buf, &len)) {
245 FIXME("InternetCreateUrl failed with error: %08x\n", GetLastError());
251 *p = SysAllocStringLen(buf, len);
260 HeapFree(GetProcessHeap(), 0, buf);
261 HeapFree(GetProcessHeap(), 0, url_path);
266 static HRESULT WINAPI HTMLLocation_put_protocol(IHTMLLocation *iface, BSTR v)
268 HTMLLocation *This = HTMLLOCATION_THIS(iface);
269 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
273 static HRESULT WINAPI HTMLLocation_get_protocol(IHTMLLocation *iface, BSTR *p)
275 HTMLLocation *This = HTMLLOCATION_THIS(iface);
276 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
279 TRACE("(%p)->(%p)\n", This, p);
284 url.dwSchemeLength = 1;
285 hres = get_url_components(This, &url);
289 if(!url.dwSchemeLength) {
290 FIXME("Unexpected blank protocol\n");
293 WCHAR buf[url.dwSchemeLength + 1];
294 memcpy(buf, url.lpszScheme, url.dwSchemeLength * sizeof(WCHAR));
295 buf[url.dwSchemeLength] = ':';
296 *p = SysAllocStringLen(buf, url.dwSchemeLength + 1);
299 return E_OUTOFMEMORY;
303 static HRESULT WINAPI HTMLLocation_put_host(IHTMLLocation *iface, BSTR v)
305 HTMLLocation *This = HTMLLOCATION_THIS(iface);
306 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
310 static HRESULT WINAPI HTMLLocation_get_host(IHTMLLocation *iface, BSTR *p)
312 HTMLLocation *This = HTMLLOCATION_THIS(iface);
313 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
316 TRACE("(%p)->(%p)\n", This, p);
321 url.dwHostNameLength = 1;
322 hres = get_url_components(This, &url);
326 if(!url.dwHostNameLength){
332 /* <hostname>:<port> */
333 const WCHAR format[] = {'%','d',0};
334 DWORD len = url.dwHostNameLength + 1 + 5 + 1;
337 memcpy(buf, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
338 buf[url.dwHostNameLength] = ':';
339 snprintfW(buf + url.dwHostNameLength + 1, 6, format, url.nPort);
340 *p = SysAllocString(buf);
342 *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength);
345 return E_OUTOFMEMORY;
349 static HRESULT WINAPI HTMLLocation_put_hostname(IHTMLLocation *iface, BSTR v)
351 HTMLLocation *This = HTMLLOCATION_THIS(iface);
352 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
356 static HRESULT WINAPI HTMLLocation_get_hostname(IHTMLLocation *iface, BSTR *p)
358 HTMLLocation *This = HTMLLOCATION_THIS(iface);
359 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
362 TRACE("(%p)->(%p)\n", This, p);
367 url.dwHostNameLength = 1;
368 hres = get_url_components(This, &url);
372 if(!url.dwHostNameLength){
377 *p = SysAllocStringLen(url.lpszHostName, url.dwHostNameLength);
379 return E_OUTOFMEMORY;
383 static HRESULT WINAPI HTMLLocation_put_port(IHTMLLocation *iface, BSTR v)
385 HTMLLocation *This = HTMLLOCATION_THIS(iface);
386 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
390 static HRESULT WINAPI HTMLLocation_get_port(IHTMLLocation *iface, BSTR *p)
392 HTMLLocation *This = HTMLLOCATION_THIS(iface);
393 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
396 TRACE("(%p)->(%p)\n", This, p);
401 hres = get_url_components(This, &url);
406 const WCHAR format[] = {'%','d',0};
408 snprintfW(buf, 6, format, url.nPort);
409 *p = SysAllocString(buf);
411 const WCHAR empty[] = {0};
412 *p = SysAllocString(empty);
416 return E_OUTOFMEMORY;
420 static HRESULT WINAPI HTMLLocation_put_pathname(IHTMLLocation *iface, BSTR v)
422 HTMLLocation *This = HTMLLOCATION_THIS(iface);
423 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
427 static HRESULT WINAPI HTMLLocation_get_pathname(IHTMLLocation *iface, BSTR *p)
429 HTMLLocation *This = HTMLLOCATION_THIS(iface);
430 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
433 TRACE("(%p)->(%p)\n", This, p);
438 url.dwUrlPathLength = 1;
439 url.dwExtraInfoLength = 1;
440 hres = get_url_components(This, &url);
444 if(url.dwUrlPathLength && url.lpszUrlPath[0] == '/')
445 *p = SysAllocStringLen(url.lpszUrlPath + 1, url.dwUrlPathLength - 1);
447 *p = SysAllocStringLen(url.lpszUrlPath, url.dwUrlPathLength);
450 return E_OUTOFMEMORY;
454 static HRESULT WINAPI HTMLLocation_put_search(IHTMLLocation *iface, BSTR v)
456 HTMLLocation *This = HTMLLOCATION_THIS(iface);
457 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
461 static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p)
463 HTMLLocation *This = HTMLLOCATION_THIS(iface);
464 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
466 const WCHAR hash[] = {'#',0};
468 TRACE("(%p)->(%p)\n", This, p);
473 url.dwExtraInfoLength = 1;
474 hres = get_url_components(This, &url);
478 if(!url.dwExtraInfoLength){
483 url.dwExtraInfoLength = strcspnW(url.lpszExtraInfo, hash);
485 *p = SysAllocStringLen(url.lpszExtraInfo, url.dwExtraInfoLength);
488 return E_OUTOFMEMORY;
492 static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v)
494 HTMLLocation *This = HTMLLOCATION_THIS(iface);
495 FIXME("(%p)->(%s)\n", This, debugstr_w(v));
499 static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p)
501 HTMLLocation *This = HTMLLOCATION_THIS(iface);
502 URL_COMPONENTSW url = {sizeof(URL_COMPONENTSW)};
503 const WCHAR hash[] = {'#',0};
507 TRACE("(%p)->(%p)\n", This, p);
512 url.dwExtraInfoLength = 1;
513 hres = get_url_components(This, &url);
517 if(!url.dwExtraInfoLength){
522 hash_pos = strcspnW(url.lpszExtraInfo, hash);
523 url.dwExtraInfoLength -= hash_pos;
525 *p = SysAllocStringLen(url.lpszExtraInfo + hash_pos, url.dwExtraInfoLength);
528 return E_OUTOFMEMORY;
532 static HRESULT WINAPI HTMLLocation_reload(IHTMLLocation *iface, VARIANT_BOOL flag)
534 HTMLLocation *This = HTMLLOCATION_THIS(iface);
535 FIXME("(%p)->(%x)\n", This, flag);
539 static HRESULT WINAPI HTMLLocation_replace(IHTMLLocation *iface, BSTR bstr)
541 HTMLLocation *This = HTMLLOCATION_THIS(iface);
542 FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
546 static HRESULT WINAPI HTMLLocation_assign(IHTMLLocation *iface, BSTR bstr)
548 HTMLLocation *This = HTMLLOCATION_THIS(iface);
549 FIXME("(%p)->(%s)\n", This, debugstr_w(bstr));
553 static HRESULT WINAPI HTMLLocation_toString(IHTMLLocation *iface, BSTR *String)
555 HTMLLocation *This = HTMLLOCATION_THIS(iface);
556 FIXME("(%p)->(%p)\n", This, String);
560 #undef HTMLLOCATION_THIS
562 static const IHTMLLocationVtbl HTMLLocationVtbl = {
563 HTMLLocation_QueryInterface,
565 HTMLLocation_Release,
566 HTMLLocation_GetTypeInfoCount,
567 HTMLLocation_GetTypeInfo,
568 HTMLLocation_GetIDsOfNames,
570 HTMLLocation_put_href,
571 HTMLLocation_get_href,
572 HTMLLocation_put_protocol,
573 HTMLLocation_get_protocol,
574 HTMLLocation_put_host,
575 HTMLLocation_get_host,
576 HTMLLocation_put_hostname,
577 HTMLLocation_get_hostname,
578 HTMLLocation_put_port,
579 HTMLLocation_get_port,
580 HTMLLocation_put_pathname,
581 HTMLLocation_get_pathname,
582 HTMLLocation_put_search,
583 HTMLLocation_get_search,
584 HTMLLocation_put_hash,
585 HTMLLocation_get_hash,
587 HTMLLocation_replace,
589 HTMLLocation_toString
592 static const tid_t HTMLLocation_iface_tids[] = {
596 static dispex_static_data_t HTMLLocation_dispex = {
598 DispHTMLLocation_tid,
600 HTMLLocation_iface_tids
604 HRESULT HTMLLocation_Create(HTMLWindow *window, HTMLLocation **ret)
606 HTMLLocation *location;
608 location = heap_alloc(sizeof(*location));
610 return E_OUTOFMEMORY;
612 location->lpHTMLLocationVtbl = &HTMLLocationVtbl;
614 location->window = window;
616 init_dispex(&location->dispex, (IUnknown*)HTMLLOCATION(location), &HTMLLocation_dispex);