/* virtual */ ES_GetState JS_Location::GetName(OpAtom property_name, ES_Value* value, ES_Runtime* origining_runtime) { TempBuffer *buffer = GetEmptyTempBuf(); URL url; if (fakewindow) url = fakewindow->GetURL(); #ifdef SELFTEST else if (!do_navigation) url = current_url; #endif // SELFTEST else if (FramesDocument *frames_doc = GetFramesDocument()) { url = frames_doc->GetURL(); // The anchors (hash) might be better in DocumentManager URL doc_man_url = frames_doc->GetDocManager()->GetCurrentURL(); if (doc_man_url == url) // Doesn't compare anchors url = doc_man_url; } #ifdef DOM_WEBWORKERS_SUPPORT /* No FramesDocument to query, so consult the origin DocumentManager for the Worker */ if (!GetFramesDocument()) { DOM_WebWorkerController *web_workers = GetEnvironment()->GetWorkerController(); if (DOM_WebWorker *ww = web_workers->GetWorkerObject()) url = ww->GetLocationURL(); else if (DocumentManager *doc = web_workers->GetWorkerDocManager()) url = doc->GetCurrentURL(); OP_ASSERT(!url.IsEmpty()); } #endif // DOM_WEBWORKERS_SUPPORT switch (property_name) { case OP_ATOM_href: DOMSetString(value, url.GetAttribute(URL::KUniName_With_Fragment_Escaped).CStr()); return GET_SUCCESS; case OP_ATOM_protocol: if (value) { const char *protocol = url.GetAttribute(URL::KProtocolName).CStr(); if (protocol) { GET_FAILED_IF_ERROR(buffer->Append(protocol)); GET_FAILED_IF_ERROR(buffer->Append(":")); } DOMSetString(value, buffer); } return GET_SUCCESS; case OP_ATOM_host: case OP_ATOM_hostname: if (value) { const uni_char *name = url.GetServerName() ? url.GetServerName()->UniName() : NULL; if (property_name == OP_ATOM_host) { unsigned short port = url.GetServerPort(); if (port) { GET_FAILED_IF_ERROR(buffer->Append(name)); GET_FAILED_IF_ERROR(buffer->Append(":")); GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port)); name = buffer->GetStorage(); } } DOMSetString(value, name); } return GET_SUCCESS; case OP_ATOM_port: if (value) { unsigned short port = url.GetServerPort(); if (port) GET_FAILED_IF_ERROR(buffer->AppendUnsignedLong(port)); DOMSetString(value, buffer); } return GET_SUCCESS; case OP_ATOM_pathname: if (value) { const uni_char *path = url.GetAttribute(URL::KUniPath).CStr(); if (path) { GET_FAILED_IF_ERROR(buffer->Append(path)); uni_char *path_tmp = buffer->GetStorage(); /* It isn't obvious from the JS spec and the relevant RFC, but in Javascript the 'pathname' excludes any arguments passed to the page. */ if (uni_char *query_start = uni_strchr(path_tmp, '?')) { path = path_tmp; *query_start = 0; } } DOMSetString(value, path); } return GET_SUCCESS; case OP_ATOM_search: if (value) { const uni_char *name = url.GetAttribute(URL::KUniName).CStr(); if (name) name = uni_strchr(name, '?'); DOMSetString(value, name); } return GET_SUCCESS; case OP_ATOM_hash: if (value) { const uni_char *fragment = url.UniRelName(); // MSIE emits "#" for the empty fragment (as in http://www.opera.com/# ) but no other // browser does that and neither will we. if (fragment && *fragment) { GET_FAILED_IF_ERROR(buffer->Append('#')); GET_FAILED_IF_ERROR(buffer->Append(fragment)); fragment = buffer->GetStorage(); } DOMSetString(value, fragment); } return GET_SUCCESS; } return GET_FAILED; }