| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
| (...skipping 16 matching lines...) Expand all Loading... |
| 27 */ | 27 */ |
| 28 | 28 |
| 29 #include "core/frame/Location.h" | 29 #include "core/frame/Location.h" |
| 30 | 30 |
| 31 #include "bindings/core/v8/BindingSecurity.h" | 31 #include "bindings/core/v8/BindingSecurity.h" |
| 32 #include "bindings/core/v8/ExceptionState.h" | 32 #include "bindings/core/v8/ExceptionState.h" |
| 33 #include "bindings/core/v8/V8DOMActivityLogger.h" | 33 #include "bindings/core/v8/V8DOMActivityLogger.h" |
| 34 #include "core/dom/DOMURLUtilsReadOnly.h" | 34 #include "core/dom/DOMURLUtilsReadOnly.h" |
| 35 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 36 #include "core/dom/ExceptionCode.h" | 36 #include "core/dom/ExceptionCode.h" |
| 37 #include "core/frame/DOMWindow.h" |
| 37 #include "core/frame/LocalDOMWindow.h" | 38 #include "core/frame/LocalDOMWindow.h" |
| 38 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
| 39 #include "core/loader/FrameLoader.h" | 40 #include "core/loader/FrameLoader.h" |
| 40 #include "platform/instrumentation/tracing/TraceEvent.h" | 41 #include "platform/instrumentation/tracing/TraceEvent.h" |
| 41 #include "platform/weborigin/KURL.h" | 42 #include "platform/weborigin/KURL.h" |
| 42 #include "platform/weborigin/SecurityOrigin.h" | 43 #include "platform/weborigin/SecurityOrigin.h" |
| 43 | 44 |
| 44 namespace blink { | 45 namespace blink { |
| 45 | 46 |
| 46 Location::Location(Frame* frame) : m_frame(frame) {} | 47 Location::Location(DOMWindow* domWindow) : m_domWindow(domWindow) {} |
| 47 | 48 |
| 48 DEFINE_TRACE(Location) { | 49 DEFINE_TRACE(Location) { |
| 49 visitor->trace(m_frame); | 50 visitor->trace(m_domWindow); |
| 50 } | 51 } |
| 51 | 52 |
| 52 inline const KURL& Location::url() const { | 53 inline const KURL& Location::url() const { |
| 53 const KURL& url = toLocalFrame(m_frame)->document()->url(); | 54 const KURL& url = document()->url(); |
| 54 if (!url.isValid()) { | 55 if (!url.isValid()) { |
| 55 // Use "about:blank" while the page is still loading (before we have a | 56 // Use "about:blank" while the page is still loading (before we have a |
| 56 // frame). | 57 // frame). |
| 57 return blankURL(); | 58 return blankURL(); |
| 58 } | 59 } |
| 59 | 60 |
| 60 return url; | 61 return url; |
| 61 } | 62 } |
| 62 | 63 |
| 63 String Location::href() const { | 64 String Location::href() const { |
| 64 if (!m_frame) | |
| 65 return String(); | |
| 66 | |
| 67 return url().strippedForUseAsHref(); | 65 return url().strippedForUseAsHref(); |
| 68 } | 66 } |
| 69 | 67 |
| 70 String Location::protocol() const { | 68 String Location::protocol() const { |
| 71 if (!m_frame) | |
| 72 return String(); | |
| 73 return DOMURLUtilsReadOnly::protocol(url()); | 69 return DOMURLUtilsReadOnly::protocol(url()); |
| 74 } | 70 } |
| 75 | 71 |
| 76 String Location::host() const { | 72 String Location::host() const { |
| 77 if (!m_frame) | |
| 78 return String(); | |
| 79 return DOMURLUtilsReadOnly::host(url()); | 73 return DOMURLUtilsReadOnly::host(url()); |
| 80 } | 74 } |
| 81 | 75 |
| 82 String Location::hostname() const { | 76 String Location::hostname() const { |
| 83 if (!m_frame) | |
| 84 return String(); | |
| 85 return DOMURLUtilsReadOnly::hostname(url()); | 77 return DOMURLUtilsReadOnly::hostname(url()); |
| 86 } | 78 } |
| 87 | 79 |
| 88 String Location::port() const { | 80 String Location::port() const { |
| 89 if (!m_frame) | |
| 90 return String(); | |
| 91 return DOMURLUtilsReadOnly::port(url()); | 81 return DOMURLUtilsReadOnly::port(url()); |
| 92 } | 82 } |
| 93 | 83 |
| 94 String Location::pathname() const { | 84 String Location::pathname() const { |
| 95 if (!m_frame) | |
| 96 return String(); | |
| 97 return DOMURLUtilsReadOnly::pathname(url()); | 85 return DOMURLUtilsReadOnly::pathname(url()); |
| 98 } | 86 } |
| 99 | 87 |
| 100 String Location::search() const { | 88 String Location::search() const { |
| 101 if (!m_frame) | |
| 102 return String(); | |
| 103 return DOMURLUtilsReadOnly::search(url()); | 89 return DOMURLUtilsReadOnly::search(url()); |
| 104 } | 90 } |
| 105 | 91 |
| 106 String Location::origin() const { | 92 String Location::origin() const { |
| 107 if (!m_frame) | |
| 108 return String(); | |
| 109 return DOMURLUtilsReadOnly::origin(url()); | 93 return DOMURLUtilsReadOnly::origin(url()); |
| 110 } | 94 } |
| 111 | 95 |
| 112 DOMStringList* Location::ancestorOrigins() const { | 96 DOMStringList* Location::ancestorOrigins() const { |
| 113 DOMStringList* origins = DOMStringList::create(); | 97 DOMStringList* origins = DOMStringList::create(); |
| 114 if (!m_frame) | 98 if (!isAttached()) |
| 115 return origins; | 99 return origins; |
| 116 for (Frame* frame = m_frame->tree().parent(); frame; | 100 for (Frame* frame = m_domWindow->frame()->tree().parent(); frame; |
| 117 frame = frame->tree().parent()) { | 101 frame = frame->tree().parent()) { |
| 118 origins->append(frame->securityContext()->getSecurityOrigin()->toString()); | 102 origins->append(frame->securityContext()->getSecurityOrigin()->toString()); |
| 119 } | 103 } |
| 120 return origins; | 104 return origins; |
| 121 } | 105 } |
| 122 | 106 |
| 123 String Location::hash() const { | 107 String Location::hash() const { |
| 124 if (!m_frame) | |
| 125 return String(); | |
| 126 | |
| 127 return DOMURLUtilsReadOnly::hash(url()); | 108 return DOMURLUtilsReadOnly::hash(url()); |
| 128 } | 109 } |
| 129 | 110 |
| 130 void Location::setHref(LocalDOMWindow* currentWindow, | 111 void Location::setHref(LocalDOMWindow* currentWindow, |
| 131 LocalDOMWindow* enteredWindow, | 112 LocalDOMWindow* enteredWindow, |
| 132 const String& url, | 113 const String& url, |
| 133 ExceptionState& exceptionState) { | 114 ExceptionState& exceptionState) { |
| 134 if (!m_frame) | |
| 135 return; | |
| 136 setLocation(url, currentWindow, enteredWindow, &exceptionState); | 115 setLocation(url, currentWindow, enteredWindow, &exceptionState); |
| 137 } | 116 } |
| 138 | 117 |
| 139 void Location::setProtocol(LocalDOMWindow* currentWindow, | 118 void Location::setProtocol(LocalDOMWindow* currentWindow, |
| 140 LocalDOMWindow* enteredWindow, | 119 LocalDOMWindow* enteredWindow, |
| 141 const String& protocol, | 120 const String& protocol, |
| 142 ExceptionState& exceptionState) { | 121 ExceptionState& exceptionState) { |
| 143 if (!m_frame) | 122 KURL url = document()->url(); |
| 144 return; | |
| 145 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 146 if (!url.setProtocol(protocol)) { | 123 if (!url.setProtocol(protocol)) { |
| 147 exceptionState.throwDOMException( | 124 exceptionState.throwDOMException( |
| 148 SyntaxError, "'" + protocol + "' is an invalid protocol."); | 125 SyntaxError, "'" + protocol + "' is an invalid protocol."); |
| 149 return; | 126 return; |
| 150 } | 127 } |
| 151 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 128 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 152 } | 129 } |
| 153 | 130 |
| 154 void Location::setHost(LocalDOMWindow* currentWindow, | 131 void Location::setHost(LocalDOMWindow* currentWindow, |
| 155 LocalDOMWindow* enteredWindow, | 132 LocalDOMWindow* enteredWindow, |
| 156 const String& host, | 133 const String& host, |
| 157 ExceptionState& exceptionState) { | 134 ExceptionState& exceptionState) { |
| 158 if (!m_frame) | 135 KURL url = document()->url(); |
| 159 return; | |
| 160 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 161 url.setHostAndPort(host); | 136 url.setHostAndPort(host); |
| 162 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 137 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 163 } | 138 } |
| 164 | 139 |
| 165 void Location::setHostname(LocalDOMWindow* currentWindow, | 140 void Location::setHostname(LocalDOMWindow* currentWindow, |
| 166 LocalDOMWindow* enteredWindow, | 141 LocalDOMWindow* enteredWindow, |
| 167 const String& hostname, | 142 const String& hostname, |
| 168 ExceptionState& exceptionState) { | 143 ExceptionState& exceptionState) { |
| 169 if (!m_frame) | 144 KURL url = document()->url(); |
| 170 return; | |
| 171 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 172 url.setHost(hostname); | 145 url.setHost(hostname); |
| 173 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 146 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 174 } | 147 } |
| 175 | 148 |
| 176 void Location::setPort(LocalDOMWindow* currentWindow, | 149 void Location::setPort(LocalDOMWindow* currentWindow, |
| 177 LocalDOMWindow* enteredWindow, | 150 LocalDOMWindow* enteredWindow, |
| 178 const String& portString, | 151 const String& portString, |
| 179 ExceptionState& exceptionState) { | 152 ExceptionState& exceptionState) { |
| 180 if (!m_frame) | 153 KURL url = document()->url(); |
| 181 return; | |
| 182 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 183 url.setPort(portString); | 154 url.setPort(portString); |
| 184 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 155 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 185 } | 156 } |
| 186 | 157 |
| 187 void Location::setPathname(LocalDOMWindow* currentWindow, | 158 void Location::setPathname(LocalDOMWindow* currentWindow, |
| 188 LocalDOMWindow* enteredWindow, | 159 LocalDOMWindow* enteredWindow, |
| 189 const String& pathname, | 160 const String& pathname, |
| 190 ExceptionState& exceptionState) { | 161 ExceptionState& exceptionState) { |
| 191 if (!m_frame) | 162 KURL url = document()->url(); |
| 192 return; | |
| 193 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 194 url.setPath(pathname); | 163 url.setPath(pathname); |
| 195 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 164 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 196 } | 165 } |
| 197 | 166 |
| 198 void Location::setSearch(LocalDOMWindow* currentWindow, | 167 void Location::setSearch(LocalDOMWindow* currentWindow, |
| 199 LocalDOMWindow* enteredWindow, | 168 LocalDOMWindow* enteredWindow, |
| 200 const String& search, | 169 const String& search, |
| 201 ExceptionState& exceptionState) { | 170 ExceptionState& exceptionState) { |
| 202 if (!m_frame) | 171 KURL url = document()->url(); |
| 203 return; | |
| 204 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 205 url.setQuery(search); | 172 url.setQuery(search); |
| 206 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 173 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 207 } | 174 } |
| 208 | 175 |
| 209 void Location::setHash(LocalDOMWindow* currentWindow, | 176 void Location::setHash(LocalDOMWindow* currentWindow, |
| 210 LocalDOMWindow* enteredWindow, | 177 LocalDOMWindow* enteredWindow, |
| 211 const String& hash, | 178 const String& hash, |
| 212 ExceptionState& exceptionState) { | 179 ExceptionState& exceptionState) { |
| 213 TRACE_EVENT0("blink", "Location::setHash"); | 180 TRACE_EVENT0("blink", "Location::setHash"); |
| 214 if (!m_frame) | 181 KURL url = document()->url(); |
| 215 return; | |
| 216 KURL url = toLocalFrame(m_frame)->document()->url(); | |
| 217 String oldFragmentIdentifier = url.fragmentIdentifier(); | 182 String oldFragmentIdentifier = url.fragmentIdentifier(); |
| 218 String newFragmentIdentifier = hash; | 183 String newFragmentIdentifier = hash; |
| 219 if (hash[0] == '#') | 184 if (hash[0] == '#') |
| 220 newFragmentIdentifier = hash.substring(1); | 185 newFragmentIdentifier = hash.substring(1); |
| 221 url.setFragmentIdentifier(newFragmentIdentifier); | 186 url.setFragmentIdentifier(newFragmentIdentifier); |
| 222 // Note that by parsing the URL and *then* comparing fragments, we are | 187 // Note that by parsing the URL and *then* comparing fragments, we are |
| 223 // comparing fragments post-canonicalization, and so this handles the | 188 // comparing fragments post-canonicalization, and so this handles the |
| 224 // cases where fragment identifiers are ignored or invalid. | 189 // cases where fragment identifiers are ignored or invalid. |
| 225 if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier())) | 190 if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier())) |
| 226 return; | 191 return; |
| 227 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); | 192 setLocation(url.getString(), currentWindow, enteredWindow, &exceptionState); |
| 228 } | 193 } |
| 229 | 194 |
| 230 void Location::assign(LocalDOMWindow* currentWindow, | 195 void Location::assign(LocalDOMWindow* currentWindow, |
| 231 LocalDOMWindow* enteredWindow, | 196 LocalDOMWindow* enteredWindow, |
| 232 const String& url, | 197 const String& url, |
| 233 ExceptionState& exceptionState) { | 198 ExceptionState& exceptionState) { |
| 234 // TODO(yukishiino): Remove this check once we remove [CrossOrigin] from | 199 // TODO(yukishiino): Remove this check once we remove [CrossOrigin] from |
| 235 // the |assign| DOM operation's definition in Location.idl. See the comment | 200 // the |assign| DOM operation's definition in Location.idl. See the comment |
| 236 // in Location.idl for details. | 201 // in Location.idl for details. |
| 237 if (!BindingSecurity::shouldAllowAccessTo(currentWindow, this, | 202 if (!BindingSecurity::shouldAllowAccessTo(currentWindow, this, |
| 238 exceptionState)) { | 203 exceptionState)) { |
| 239 return; | 204 return; |
| 240 } | 205 } |
| 241 | 206 |
| 242 if (!m_frame) | |
| 243 return; | |
| 244 setLocation(url, currentWindow, enteredWindow, &exceptionState); | 207 setLocation(url, currentWindow, enteredWindow, &exceptionState); |
| 245 } | 208 } |
| 246 | 209 |
| 247 void Location::replace(LocalDOMWindow* currentWindow, | 210 void Location::replace(LocalDOMWindow* currentWindow, |
| 248 LocalDOMWindow* enteredWindow, | 211 LocalDOMWindow* enteredWindow, |
| 249 const String& url, | 212 const String& url, |
| 250 ExceptionState& exceptionState) { | 213 ExceptionState& exceptionState) { |
| 251 if (!m_frame) | |
| 252 return; | |
| 253 setLocation(url, currentWindow, enteredWindow, &exceptionState, | 214 setLocation(url, currentWindow, enteredWindow, &exceptionState, |
| 254 SetLocationPolicy::ReplaceThisFrame); | 215 SetLocationPolicy::ReplaceThisFrame); |
| 255 } | 216 } |
| 256 | 217 |
| 257 void Location::reload(LocalDOMWindow* currentWindow) { | 218 void Location::reload(LocalDOMWindow* currentWindow) { |
| 258 if (!m_frame) | 219 if (!isAttached()) |
| 259 return; | 220 return; |
| 260 if (toLocalFrame(m_frame)->document()->url().protocolIsJavaScript()) | 221 if (document()->url().protocolIsJavaScript()) |
| 261 return; | 222 return; |
| 262 FrameLoadType reloadType = | 223 FrameLoadType reloadType = |
| 263 RuntimeEnabledFeatures::fasterLocationReloadEnabled() | 224 RuntimeEnabledFeatures::fasterLocationReloadEnabled() |
| 264 ? FrameLoadTypeReloadMainResource | 225 ? FrameLoadTypeReloadMainResource |
| 265 : FrameLoadTypeReload; | 226 : FrameLoadTypeReload; |
| 266 m_frame->reload(reloadType, ClientRedirectPolicy::ClientRedirect); | 227 m_domWindow->frame()->reload(reloadType, |
| 228 ClientRedirectPolicy::ClientRedirect); |
| 267 } | 229 } |
| 268 | 230 |
| 269 void Location::setLocation(const String& url, | 231 void Location::setLocation(const String& url, |
| 270 LocalDOMWindow* currentWindow, | 232 LocalDOMWindow* currentWindow, |
| 271 LocalDOMWindow* enteredWindow, | 233 LocalDOMWindow* enteredWindow, |
| 272 ExceptionState* exceptionState, | 234 ExceptionState* exceptionState, |
| 273 SetLocationPolicy setLocationPolicy) { | 235 SetLocationPolicy setLocationPolicy) { |
| 274 DCHECK(m_frame); | 236 if (!isAttached()) |
| 275 if (!m_frame || !m_frame->host()) | |
| 276 return; | 237 return; |
| 277 | 238 |
| 278 if (!currentWindow->frame()) | 239 if (!currentWindow->frame()) |
| 279 return; | 240 return; |
| 280 | 241 |
| 281 if (!currentWindow->frame()->canNavigate(*m_frame)) { | 242 if (!currentWindow->frame()->canNavigate(*m_domWindow->frame())) { |
| 282 if (exceptionState) { | 243 if (exceptionState) { |
| 283 exceptionState->throwSecurityError( | 244 exceptionState->throwSecurityError( |
| 284 "The current window does not have permission to navigate the target " | 245 "The current window does not have permission to navigate the target " |
| 285 "frame to '" + | 246 "frame to '" + |
| 286 url + "'."); | 247 url + "'."); |
| 287 } | 248 } |
| 288 return; | 249 return; |
| 289 } | 250 } |
| 290 | 251 |
| 291 Document* enteredDocument = enteredWindow->document(); | 252 Document* enteredDocument = enteredWindow->document(); |
| 292 if (!enteredDocument) | 253 if (!enteredDocument) |
| 293 return; | 254 return; |
| 294 | 255 |
| 295 KURL completedURL = enteredDocument->completeURL(url); | 256 KURL completedURL = enteredDocument->completeURL(url); |
| 296 if (completedURL.isNull()) | 257 if (completedURL.isNull()) |
| 297 return; | 258 return; |
| 298 if (exceptionState && !completedURL.isValid()) { | 259 if (exceptionState && !completedURL.isValid()) { |
| 299 exceptionState->throwDOMException(SyntaxError, | 260 exceptionState->throwDOMException(SyntaxError, |
| 300 "'" + url + "' is not a valid URL."); | 261 "'" + url + "' is not a valid URL."); |
| 301 return; | 262 return; |
| 302 } | 263 } |
| 303 | 264 |
| 304 if (m_frame->domWindow()->isInsecureScriptAccess(*currentWindow, | 265 if (m_domWindow->isInsecureScriptAccess(*currentWindow, completedURL)) |
| 305 completedURL)) | |
| 306 return; | 266 return; |
| 307 | 267 |
| 308 V8DOMActivityLogger* activityLogger = | 268 V8DOMActivityLogger* activityLogger = |
| 309 V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld(); | 269 V8DOMActivityLogger::currentActivityLoggerIfIsolatedWorld(); |
| 310 if (activityLogger) { | 270 if (activityLogger) { |
| 311 Vector<String> argv; | 271 Vector<String> argv; |
| 312 argv.push_back("LocalDOMWindow"); | 272 argv.push_back("LocalDOMWindow"); |
| 313 argv.push_back("url"); | 273 argv.push_back("url"); |
| 314 argv.push_back(enteredDocument->url()); | 274 argv.push_back(enteredDocument->url()); |
| 315 argv.push_back(completedURL); | 275 argv.push_back(completedURL); |
| 316 activityLogger->logEvent("blinkSetAttribute", argv.size(), argv.data()); | 276 activityLogger->logEvent("blinkSetAttribute", argv.size(), argv.data()); |
| 317 } | 277 } |
| 318 m_frame->navigate(*currentWindow->document(), completedURL, | 278 m_domWindow->frame()->navigate( |
| 319 setLocationPolicy == SetLocationPolicy::ReplaceThisFrame, | 279 *currentWindow->document(), completedURL, |
| 320 UserGestureStatus::None); | 280 setLocationPolicy == SetLocationPolicy::ReplaceThisFrame, |
| 281 UserGestureStatus::None); |
| 282 } |
| 283 |
| 284 Document* Location::document() const { |
| 285 return toLocalDOMWindow(m_domWindow)->document(); |
| 286 } |
| 287 |
| 288 bool Location::isAttached() const { |
| 289 return m_domWindow->frame() && m_domWindow->frame()->host(); |
| 321 } | 290 } |
| 322 | 291 |
| 323 } // namespace blink | 292 } // namespace blink |
| OLD | NEW |