OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
3 * (C) 1999 Antti Koivisto (koivisto@kde.org) | 3 * (C) 1999 Antti Koivisto (koivisto@kde.org) |
4 * (C) 2001 Dirk Mueller (mueller@kde.org) | 4 * (C) 2001 Dirk Mueller (mueller@kde.org) |
5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) | 5 * (C) 2006 Alexey Proskuryakov (ap@webkit.org) |
6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. | 6 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2011, 2012 Apple Inc. All r
ights reserved. |
7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) | 7 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.t
orchmobile.com/) |
8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. | 8 * Copyright (C) 2008, 2009, 2011, 2012 Google Inc. All rights reserved. |
9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) | 9 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies) |
10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. | 10 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved. |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 // | 280 // |
281 // If a Document has the address "about:blank" | 281 // If a Document has the address "about:blank" |
282 // The origin of the Document is the origin it was assigned when its bro
wsing context was created. | 282 // The origin of the Document is the origin it was assigned when its bro
wsing context was created. |
283 // | 283 // |
284 // Note: We generalize this to all "blank" URLs and invalid URLs because we | 284 // Note: We generalize this to all "blank" URLs and invalid URLs because we |
285 // treat all of these URLs as about:blank. | 285 // treat all of these URLs as about:blank. |
286 // | 286 // |
287 return url.isEmpty() || url.isBlankURL(); | 287 return url.isEmpty() || url.isBlankURL(); |
288 } | 288 } |
289 | 289 |
290 static Widget* widgetForElement(Element* focusedElement) | 290 static Widget* widgetForElement(const Element& focusedElement) |
291 { | 291 { |
292 if (!focusedElement) | 292 RenderObject* renderer = focusedElement.renderer(); |
293 return 0; | |
294 RenderObject* renderer = focusedElement->renderer(); | |
295 if (!renderer || !renderer->isWidget()) | 293 if (!renderer || !renderer->isWidget()) |
296 return 0; | 294 return 0; |
297 return toRenderWidget(renderer)->widget(); | 295 return toRenderWidget(renderer)->widget(); |
298 } | 296 } |
299 | 297 |
300 static bool acceptsEditingFocus(Element* element) | 298 static bool acceptsEditingFocus(const Element& element) |
301 { | 299 { |
302 ASSERT(element); | 300 ASSERT(element.rendererIsEditable()); |
303 ASSERT(element->rendererIsEditable()); | |
304 | 301 |
305 return element->document().frame() && element->rootEditableElement(); | 302 return element.document().frame() && element.rootEditableElement(); |
306 } | 303 } |
307 | 304 |
308 static bool canAccessAncestor(const SecurityOrigin* activeSecurityOrigin, Frame*
targetFrame) | 305 static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame*
targetFrame) |
309 { | 306 { |
310 // targetFrame can be 0 when we're trying to navigate a top-level frame | 307 // targetFrame can be 0 when we're trying to navigate a top-level frame |
311 // that has a 0 opener. | 308 // that has a 0 opener. |
312 if (!targetFrame) | 309 if (!targetFrame) |
313 return false; | 310 return false; |
314 | 311 |
315 const bool isLocalActiveOrigin = activeSecurityOrigin->isLocal(); | 312 const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal(); |
316 for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ance
storFrame->tree().parent()) { | 313 for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ance
storFrame->tree().parent()) { |
317 Document* ancestorDocument = ancestorFrame->document(); | 314 Document* ancestorDocument = ancestorFrame->document(); |
318 // FIXME: Should be an ASSERT? Frames should alway have documents. | 315 // FIXME: Should be an ASSERT? Frames should alway have documents. |
319 if (!ancestorDocument) | 316 if (!ancestorDocument) |
320 return true; | 317 return true; |
321 | 318 |
322 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit
yOrigin(); | 319 const SecurityOrigin* ancestorSecurityOrigin = ancestorDocument->securit
yOrigin(); |
323 if (activeSecurityOrigin->canAccess(ancestorSecurityOrigin)) | 320 if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin)) |
324 return true; | 321 return true; |
325 | 322 |
326 // Allow file URL descendant navigation even when allowFileAccessFromFil
eURLs is false. | 323 // Allow file URL descendant navigation even when allowFileAccessFromFil
eURLs is false. |
327 // FIXME: It's a bit strange to special-case local origins here. Should
we be doing | 324 // FIXME: It's a bit strange to special-case local origins here. Should
we be doing |
328 // something more general instead? | 325 // something more general instead? |
329 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal()) | 326 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal()) |
330 return true; | 327 return true; |
331 } | 328 } |
332 | 329 |
333 return false; | 330 return false; |
334 } | 331 } |
335 | 332 |
336 static void printNavigationErrorMessage(Frame* frame, const KURL& activeURL, con
st char* reason) | 333 static void printNavigationErrorMessage(const Frame& frame, const KURL& activeUR
L, const char* reason) |
337 { | 334 { |
338 String message = "Unsafe JavaScript attempt to initiate navigation for frame
with URL '" + frame->document()->url().string() + "' from frame with URL '" + a
ctiveURL.string() + "'. " + reason + "\n"; | 335 String message = "Unsafe JavaScript attempt to initiate navigation for frame
with URL '" + frame.document()->url().string() + "' from frame with URL '" + ac
tiveURL.string() + "'. " + reason + "\n"; |
339 | 336 |
340 // FIXME: should we print to the console of the document performing the navi
gation instead? | 337 // FIXME: should we print to the console of the document performing the navi
gation instead? |
341 frame->domWindow()->printErrorMessage(message); | 338 frame.domWindow()->printErrorMessage(message); |
342 } | 339 } |
343 | 340 |
344 uint64_t Document::s_globalTreeVersion = 0; | 341 uint64_t Document::s_globalTreeVersion = 0; |
345 | 342 |
346 // This class should be passed only to Document::postTask. | 343 // This class should be passed only to Document::postTask. |
347 class CheckFocusedElementTask FINAL : public ExecutionContextTask { | 344 class CheckFocusedElementTask FINAL : public ExecutionContextTask { |
348 public: | 345 public: |
349 static PassOwnPtr<CheckFocusedElementTask> create() | 346 static PassOwnPtr<CheckFocusedElementTask> create() |
350 { | 347 { |
351 return adoptPtr(new CheckFocusedElementTask()); | 348 return adoptPtr(new CheckFocusedElementTask()); |
(...skipping 2375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2727 return true; | 2724 return true; |
2728 | 2725 |
2729 if (isSandboxed(SandboxNavigation)) { | 2726 if (isSandboxed(SandboxNavigation)) { |
2730 if (targetFrame->tree().isDescendantOf(m_frame)) | 2727 if (targetFrame->tree().isDescendantOf(m_frame)) |
2731 return true; | 2728 return true; |
2732 | 2729 |
2733 const char* reason = "The frame attempting navigation is sandboxed, and
is therefore disallowed from navigating its ancestors."; | 2730 const char* reason = "The frame attempting navigation is sandboxed, and
is therefore disallowed from navigating its ancestors."; |
2734 if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().
top()) | 2731 if (isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().
top()) |
2735 reason = "The frame attempting navigation of the top-level window is
sandboxed, but the 'allow-top-navigation' flag is not set."; | 2732 reason = "The frame attempting navigation of the top-level window is
sandboxed, but the 'allow-top-navigation' flag is not set."; |
2736 | 2733 |
2737 printNavigationErrorMessage(targetFrame, url(), reason); | 2734 printNavigationErrorMessage(*targetFrame, url(), reason); |
2738 return false; | 2735 return false; |
2739 } | 2736 } |
2740 | 2737 |
| 2738 ASSERT(securityOrigin()); |
| 2739 SecurityOrigin& origin = *securityOrigin(); |
| 2740 |
2741 // This is the normal case. A document can navigate its decendant frames, | 2741 // This is the normal case. A document can navigate its decendant frames, |
2742 // or, more generally, a document can navigate a frame if the document is | 2742 // or, more generally, a document can navigate a frame if the document is |
2743 // in the same origin as any of that frame's ancestors (in the frame | 2743 // in the same origin as any of that frame's ancestors (in the frame |
2744 // hierarchy). | 2744 // hierarchy). |
2745 // | 2745 // |
2746 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for | 2746 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for |
2747 // historical information about this security check. | 2747 // historical information about this security check. |
2748 if (canAccessAncestor(securityOrigin(), targetFrame)) | 2748 if (canAccessAncestor(origin, targetFrame)) |
2749 return true; | 2749 return true; |
2750 | 2750 |
2751 // Top-level frames are easier to navigate than other frames because they | 2751 // Top-level frames are easier to navigate than other frames because they |
2752 // display their URLs in the address bar (in most browsers). However, there | 2752 // display their URLs in the address bar (in most browsers). However, there |
2753 // are still some restrictions on navigation to avoid nuisance attacks. | 2753 // are still some restrictions on navigation to avoid nuisance attacks. |
2754 // Specifically, a document can navigate a top-level frame if that frame | 2754 // Specifically, a document can navigate a top-level frame if that frame |
2755 // opened the document or if the document is the same-origin with any of | 2755 // opened the document or if the document is the same-origin with any of |
2756 // the top-level frame's opener's ancestors (in the frame hierarchy). | 2756 // the top-level frame's opener's ancestors (in the frame hierarchy). |
2757 // | 2757 // |
2758 // In both of these cases, the document performing the navigation is in | 2758 // In both of these cases, the document performing the navigation is in |
2759 // some way related to the frame being navigate (e.g., by the "opener" | 2759 // some way related to the frame being navigate (e.g., by the "opener" |
2760 // and/or "parent" relation). Requiring some sort of relation prevents a | 2760 // and/or "parent" relation). Requiring some sort of relation prevents a |
2761 // document from navigating arbitrary, unrelated top-level frames. | 2761 // document from navigating arbitrary, unrelated top-level frames. |
2762 if (!targetFrame->tree().parent()) { | 2762 if (!targetFrame->tree().parent()) { |
2763 if (targetFrame == m_frame->loader().opener()) | 2763 if (targetFrame == m_frame->loader().opener()) |
2764 return true; | 2764 return true; |
2765 | 2765 |
2766 if (canAccessAncestor(securityOrigin(), targetFrame->loader().opener())) | 2766 if (canAccessAncestor(origin, targetFrame->loader().opener())) |
2767 return true; | 2767 return true; |
2768 } | 2768 } |
2769 | 2769 |
2770 printNavigationErrorMessage(targetFrame, url(), "The frame attempting naviga
tion is neither same-origin with the target, nor is it the target's parent or op
ener."); | 2770 printNavigationErrorMessage(*targetFrame, url(), "The frame attempting navig
ation is neither same-origin with the target, nor is it the target's parent or o
pener."); |
2771 return false; | 2771 return false; |
2772 } | 2772 } |
2773 | 2773 |
2774 Frame* Document::findUnsafeParentScrollPropagationBoundary() | 2774 Frame* Document::findUnsafeParentScrollPropagationBoundary() |
2775 { | 2775 { |
2776 Frame* currentFrame = m_frame; | 2776 Frame* currentFrame = m_frame; |
2777 Frame* ancestorFrame = currentFrame->tree().parent(); | 2777 Frame* ancestorFrame = currentFrame->tree().parent(); |
2778 | 2778 |
2779 while (ancestorFrame) { | 2779 while (ancestorFrame) { |
2780 if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrig
in())) | 2780 if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrig
in())) |
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3342 // on it, probably when <rdar://problem/8503958> is resolved. | 3342 // on it, probably when <rdar://problem/8503958> is resolved. |
3343 oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, ne
wFocusedElement.get()); // DOM level 2 name for compatibility. | 3343 oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::DOMFocusOut, ne
wFocusedElement.get()); // DOM level 2 name for compatibility. |
3344 | 3344 |
3345 if (m_focusedElement) { | 3345 if (m_focusedElement) { |
3346 // handler shifted focus | 3346 // handler shifted focus |
3347 focusChangeBlocked = true; | 3347 focusChangeBlocked = true; |
3348 newFocusedElement = 0; | 3348 newFocusedElement = 0; |
3349 } | 3349 } |
3350 | 3350 |
3351 if (view()) { | 3351 if (view()) { |
3352 Widget* oldWidget = widgetForElement(oldFocusedElement.get()); | 3352 Widget* oldWidget = widgetForElement(*oldFocusedElement); |
3353 if (oldWidget) | 3353 if (oldWidget) |
3354 oldWidget->setFocus(false); | 3354 oldWidget->setFocus(false); |
3355 else | 3355 else |
3356 view()->setFocus(false); | 3356 view()->setFocus(false); |
3357 } | 3357 } |
3358 | 3358 |
3359 // Autofill client may have modified the value of newFocusedElement, thu
s require | 3359 // Autofill client may have modified the value of newFocusedElement, thu
s require |
3360 // a layout update here, otherwise it will assert at newFocusedElement->
isFocusable(). | 3360 // a layout update here, otherwise it will assert at newFocusedElement->
isFocusable(). |
3361 // See crbug.com/251163. | 3361 // See crbug.com/251163. |
3362 updateLayoutIgnorePendingStylesheets(); | 3362 updateLayoutIgnorePendingStylesheets(); |
3363 } | 3363 } |
3364 | 3364 |
3365 if (newFocusedElement && newFocusedElement->isFocusable()) { | 3365 if (newFocusedElement && newFocusedElement->isFocusable()) { |
3366 if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(n
ewFocusedElement.get())) { | 3366 if (newFocusedElement->isRootEditableElement() && !acceptsEditingFocus(*
newFocusedElement)) { |
3367 // delegate blocks focus change | 3367 // delegate blocks focus change |
3368 focusChangeBlocked = true; | 3368 focusChangeBlocked = true; |
3369 goto SetFocusedElementDone; | 3369 goto SetFocusedElementDone; |
3370 } | 3370 } |
3371 // Set focus on the new node | 3371 // Set focus on the new node |
3372 m_focusedElement = newFocusedElement; | 3372 m_focusedElement = newFocusedElement; |
3373 | 3373 |
3374 // Dispatch the focus event and let the node do any other focus related
activities (important for text fields) | 3374 // Dispatch the focus event and let the node do any other focus related
activities (important for text fields) |
3375 m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), direction)
; | 3375 m_focusedElement->dispatchFocusEvent(oldFocusedElement.get(), direction)
; |
3376 | 3376 |
(...skipping 21 matching lines...) Expand all Loading... |
3398 goto SetFocusedElementDone; | 3398 goto SetFocusedElementDone; |
3399 } | 3399 } |
3400 m_focusedElement->setFocus(true); | 3400 m_focusedElement->setFocus(true); |
3401 | 3401 |
3402 if (m_focusedElement->isRootEditableElement()) | 3402 if (m_focusedElement->isRootEditableElement()) |
3403 frame()->editor().didBeginEditing(m_focusedElement.get()); | 3403 frame()->editor().didBeginEditing(m_focusedElement.get()); |
3404 | 3404 |
3405 // eww, I suck. set the qt focus correctly | 3405 // eww, I suck. set the qt focus correctly |
3406 // ### find a better place in the code for this | 3406 // ### find a better place in the code for this |
3407 if (view()) { | 3407 if (view()) { |
3408 Widget* focusWidget = widgetForElement(m_focusedElement.get()); | 3408 Widget* focusWidget = widgetForElement(*m_focusedElement); |
3409 if (focusWidget) { | 3409 if (focusWidget) { |
3410 // Make sure a widget has the right size before giving it focus. | 3410 // Make sure a widget has the right size before giving it focus. |
3411 // Otherwise, we are testing edge cases of the Widget code. | 3411 // Otherwise, we are testing edge cases of the Widget code. |
3412 // Specifically, in WebCore this does not work well for text fie
lds. | 3412 // Specifically, in WebCore this does not work well for text fie
lds. |
3413 updateLayout(); | 3413 updateLayout(); |
3414 // Re-get the widget in case updating the layout changed things. | 3414 // Re-get the widget in case updating the layout changed things. |
3415 focusWidget = widgetForElement(m_focusedElement.get()); | 3415 focusWidget = widgetForElement(*m_focusedElement); |
3416 } | 3416 } |
3417 if (focusWidget) | 3417 if (focusWidget) |
3418 focusWidget->setFocus(true); | 3418 focusWidget->setFocus(true); |
3419 else | 3419 else |
3420 view()->setFocus(true); | 3420 view()->setFocus(true); |
3421 } | 3421 } |
3422 } | 3422 } |
3423 | 3423 |
3424 if (!focusChangeBlocked && m_focusedElement) { | 3424 if (!focusChangeBlocked && m_focusedElement) { |
3425 // Create the AXObject cache in a focus change because Chromium relies o
n it. | 3425 // Create the AXObject cache in a focus change because Chromium relies o
n it. |
(...skipping 1854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5280 void Document::modifiedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, Style
ResolverUpdateMode updateMode) | 5280 void Document::modifiedStyleSheet(StyleSheet* sheet, RecalcStyleTime when, Style
ResolverUpdateMode updateMode) |
5281 { | 5281 { |
5282 if (!isActive()) | 5282 if (!isActive()) |
5283 return; | 5283 return; |
5284 | 5284 |
5285 styleEngine()->modifiedStyleSheet(sheet); | 5285 styleEngine()->modifiedStyleSheet(sheet); |
5286 styleResolverChanged(when, updateMode); | 5286 styleResolverChanged(when, updateMode); |
5287 } | 5287 } |
5288 | 5288 |
5289 } // namespace WebCore | 5289 } // namespace WebCore |
OLD | NEW |