WebCore:
authorgdennis <gdennis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Nov 2006 22:44:23 +0000 (22:44 +0000)
committergdennis <gdennis@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 6 Nov 2006 22:44:23 +0000 (22:44 +0000)
        Reviewed by Tim Hatcher.

        Part of patch for http://bugs.webkit.org/show_bug.cgi?id=11323
        Link dragging behaviour does not obey WebKitEditableLinkBehavior WebPref

        No layout tests added as this must be tested manually by the test
        WebCore/manual-tests/contenteditable-link.html

        * WebCore.exp: Exported HitTestResult::isLiveLink().
        * html/HTMLAnchorElement.cpp:
        (WebCore::HTMLAnchorElement::HTMLAnchorElement):
        (WebCore::HTMLAnchorElement::defaultEventHandler):
        (WebCore::HTMLAnchorElement::isLiveLink):
        * html/HTMLAnchorElement.h: added m_wasShiftKeyDownOnMouseDown variable
        to track shift key status.
        * manual-tests/contenteditable-link.html: Added description about link
        dragging behaviour.
        * rendering/HitTestResult.cpp:
        (WebCore::HitTestResult::isLiveLink): Added.
        * rendering/HitTestResult.h:

WebKit:

        Reviewed by Tim Hatcher.

        Part of patch for http://bugs.webkit.org/show_bug.cgi?id=11323
        Link dragging behaviour does not obey WebKitEditableLinkBehavior WebPref

        * DefaultDelegates/WebDefaultUIDelegate.m:
        (-[NSApplication webView:dragSourceActionMaskForPoint:]): Logic moved to
        WebHTMLView's _mayStartDragAtEventLocation
        * Misc/WebElementDictionary.m: added isLiveLink
        (+[WebElementDictionary initializeLookupTable]):
        (-[WebElementDictionary _isLiveLink]):
        * WebView/WebHTMLView.m:
        (-[WebHTMLView _mayStartDragAtEventLocation:]): Editable links should
        only be followed if isLiveLink is true
        (-[WebHTMLView _isMoveDrag:]): A drag of a live editable link is not
        a move
        (-[WebHTMLView draggingUpdatedWithDraggingInfo:actionMask:]):
        (-[WebHTMLView concludeDragForDraggingInfo:actionMask:]):
        * WebView/WebView.mm: added WebElementLinkIsLiveKey
        * WebView/WebViewPrivate.h: ditto

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@17629 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
WebCore/ChangeLog
WebCore/WebCore.exp
WebCore/html/HTMLAnchorElement.cpp
WebCore/html/HTMLAnchorElement.h
WebCore/manual-tests/contenteditable-link.html
WebCore/rendering/HitTestResult.cpp
WebCore/rendering/HitTestResult.h
WebKit/ChangeLog
WebKit/DefaultDelegates/WebDefaultUIDelegate.m
WebKit/Misc/WebElementDictionary.m
WebKit/WebView/WebHTMLView.m
WebKit/WebView/WebView.mm
WebKit/WebView/WebViewPrivate.h

index 3c9baef3f05480255084019b843899905ebcb359..690e148e33904234780775a0a5ee5c0f73c1b171 100644 (file)
@@ -1,3 +1,26 @@
+2006-11-06  Graham Dennis  <graham.dennis@gmail.com>
+
+        Reviewed by Tim Hatcher.
+
+        Part of patch for http://bugs.webkit.org/show_bug.cgi?id=11323
+        Link dragging behaviour does not obey WebKitEditableLinkBehavior WebPref
+        
+        No layout tests added as this must be tested manually by the test
+        WebCore/manual-tests/contenteditable-link.html
+
+        * WebCore.exp: Exported HitTestResult::isLiveLink().
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::HTMLAnchorElement):
+        (WebCore::HTMLAnchorElement::defaultEventHandler):
+        (WebCore::HTMLAnchorElement::isLiveLink):
+        * html/HTMLAnchorElement.h: added m_wasShiftKeyDownOnMouseDown variable
+        to track shift key status.
+        * manual-tests/contenteditable-link.html: Added description about link
+        dragging behaviour.
+        * rendering/HitTestResult.cpp:
+        (WebCore::HitTestResult::isLiveLink): Added.
+        * rendering/HitTestResult.h:
+
 2006-11-06  Brady Eidson  <beidson@apple.com>
 
         Reviewed by Oliver
index d53fe571a4959884c8478f02aaff8214335be1a1..abc0db55a3b0b65d8c48e92c5506e25726825849 100644 (file)
@@ -307,6 +307,7 @@ __ZNK7WebCore13HitTestResult16altDisplayStringEv
 __ZNK7WebCore13HitTestResult18titleDisplayStringEv
 __ZNK7WebCore13HitTestResult5imageEv
 __ZNK7WebCore13HitTestResult5titleEv
+__ZNK7WebCore13HitTestResult10isLiveLinkEv
 __ZNK7WebCore14DocumentLoader10isStoppingEv
 __ZNK7WebCore14DocumentLoader11frameLoaderEv
 __ZNK7WebCore14DocumentLoader11isCommittedEv
index bcdab65beefefdfa728989e9dc711b162dac3859..1be1b21cffc38afb4989c1cc93a58893ae76202d 100644 (file)
@@ -50,12 +50,14 @@ using namespace EventNames;
 HTMLAnchorElement::HTMLAnchorElement(Document* doc)
     : HTMLElement(aTag, doc)
     , m_rootEditableElementForSelectionOnMouseDown(0)
+    , m_wasShiftKeyDownOnMouseDown(false)
 {
 }
 
 HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* doc)
     : HTMLElement(tagName, doc)
     , m_rootEditableElementForSelectionOnMouseDown(0)
+    , m_wasShiftKeyDownOnMouseDown(false)
 {
 }
 
@@ -212,10 +214,17 @@ void HTMLAnchorElement::defaultEventHandler(Event* evt)
     } else if (m_isLink && isContentEditable()) {
     // This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
     // for the LiveWhenNotFocused editable link behavior
-        if (evt->type() == mousedownEvent && document()->frame() && document()->frame()->selectionController())
+        if (evt->type() == mousedownEvent && document()->frame() && document()->frame()->selectionController()) {
+            MouseEvent* e = static_cast<MouseEvent*>(evt);
+
             m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selectionController()->rootEditableElement();
-        else if (evt->type() == mouseoutEvent)
+            m_wasShiftKeyDownOnMouseDown = e && e->shiftKey();
+        } else if (evt->type() == mouseoverEvent) {
+        // These are cleared on mouseover and not mouseout because their values are needed for drag events, but these happen
+        // after mouse out events.
             m_rootEditableElementForSelectionOnMouseDown = 0;
+            m_wasShiftKeyDownOnMouseDown = false;
+        }
     }
 
     HTMLElement::defaultEventHandler(evt);
@@ -446,5 +455,34 @@ String HTMLAnchorElement::text() const
     return innerText();
 }
 
+bool HTMLAnchorElement::isLiveLink() const
+{
+    if (!m_isLink)
+        return false;
+    if (!isContentEditable())
+        return true;
+    
+    Settings::EditableLinkBehavior editableLinkBehavior = Settings::EditableLinkDefaultBehavior;
+    if (document() && document()->frame() && document()->frame()->settings())
+        editableLinkBehavior = document()->frame()->settings()->editableLinkBehavior();
+        
+    switch(editableLinkBehavior) {
+        default:
+        case Settings::EditableLinkDefaultBehavior:
+        case Settings::EditableLinkAlwaysLive:
+            return true;
+            
+        // Don't set the link to be live if the current selection is in the same editable block as
+        // this link or if the shift key is down
+        case Settings::EditableLinkLiveWhenNotFocused:
+            return m_wasShiftKeyDownOnMouseDown || m_rootEditableElementForSelectionOnMouseDown != rootEditableElement();
+            
+        case Settings::EditableLinkOnlyLiveWithShiftKey:
+            return m_wasShiftKeyDownOnMouseDown;
+    }
+    // not reached
+    ASSERT(0);
+    return false;
+}
 
 }
index 0184fb5530c632d821ebf8b9773b08158e2aac3a..08796f33cd5bcb09e08b0e79c9060e213dcb1619 100644 (file)
@@ -95,8 +95,11 @@ public:
     String search() const;
     String text() const;
     
+    bool isLiveLink() const;
+    
 private:
     Element *m_rootEditableElementForSelectionOnMouseDown;
+    bool m_wasShiftKeyDownOnMouseDown;
 };
 
 } //namespace
index 1612fbf93123abb0494b16afcf720cc8e9a35583..cc41e786e867654d75bd9b363b3df1f969d3fece 100644 (file)
@@ -17,6 +17,9 @@
 
 <div>The behaviour of editable links is controlled by the user default WebKitEditableLinkBehavior. This can be set via a private WebPreference. If the preference is OnlyLiveWithShiftKey, then the link will only be active when the shift key is pressed (WinIE/Firefox behaviour). If the preference is WebKitEditableLinkAlwaysLive or WebKitEditableLinkDefaultBehavior, then the link is always active (Safari 2.0 behaviour). Finally, if the preference is WebKitEditableLinkLiveWhenNotFocused, the link will only be live if the selection before clicking on the link is not in the same editable block as the link.</div>
 
+<div>Also, when a link is 'live' it can be dragged as a link, and when the link isn't 'live', dragging a link just performs a normal text selection.
+</div>
+
 <div id="editable" contentEditable="true">
   <p>Test content</p>
   <p><a href="about:blank">Test link</a></p>
index 2168aa753ae3eb360e426c0cfdeacc6b53a8976a..b8550b2124fab585586daec9d1bf37015d8865e7 100644 (file)
@@ -27,6 +27,7 @@
 #include "Document.h"
 #include "Frame.h"
 #include "FrameTree.h"
+#include "HTMLAnchorElement.h"
 #include "HTMLElement.h"
 #include "HTMLImageElement.h"
 #include "HTMLInputElement.h"
@@ -228,6 +229,17 @@ KURL HitTestResult::absoluteLinkURL() const
         static_cast<Element*>(m_innerURLElement.get())->getAttribute("href")).deprecatedString()));
 }
 
+bool HitTestResult::isLiveLink() const
+{
+    if (!(m_innerURLElement && m_innerURLElement->document()))
+        return false;
+
+    if (!m_innerURLElement->hasTagName(aTag))
+        return false;
+
+    return static_cast<HTMLAnchorElement*>(m_innerURLElement.get())->isLiveLink();
+}
+
 String HitTestResult::titleDisplayString() const
 {
     if (!(m_innerURLElement && m_innerURLElement->isHTMLElement()))
index a68526c3854abcab90ff3de34d2837a708ca29ff..270287d76fd52d19bf54433d593659e1ad61f25a 100644 (file)
@@ -66,6 +66,7 @@ public:
     KURL absoluteLinkURL() const;
     String titleDisplayString() const;
     String textContent() const;
+    bool isLiveLink() const;
 
 private:
     RefPtr<Node> m_innerNode;
index fbd8bb7ef993ed234eb10ffacd6d29e4d6f4a345..cfc644369c85034540f0ea7e2b2aebd631c18465 100644 (file)
@@ -1,3 +1,26 @@
+2006-11-06  Graham Dennis  <graham.dennis@gmail.com>
+
+        Reviewed by Tim Hatcher.
+
+        Part of patch for http://bugs.webkit.org/show_bug.cgi?id=11323
+        Link dragging behaviour does not obey WebKitEditableLinkBehavior WebPref
+
+        * DefaultDelegates/WebDefaultUIDelegate.m:
+        (-[NSApplication webView:dragSourceActionMaskForPoint:]): Logic moved to 
+        WebHTMLView's _mayStartDragAtEventLocation
+        * Misc/WebElementDictionary.m: added isLiveLink
+        (+[WebElementDictionary initializeLookupTable]):
+        (-[WebElementDictionary _isLiveLink]):
+        * WebView/WebHTMLView.m: 
+        (-[WebHTMLView _mayStartDragAtEventLocation:]): Editable links should
+        only be followed if isLiveLink is true
+        (-[WebHTMLView _isMoveDrag:]): A drag of a live editable link is not
+        a move
+        (-[WebHTMLView draggingUpdatedWithDraggingInfo:actionMask:]):
+        (-[WebHTMLView concludeDragForDraggingInfo:actionMask:]):
+        * WebView/WebView.mm: added WebElementLinkIsLiveKey
+        * WebView/WebViewPrivate.h: ditto
+
 2006-11-04  Maciej Stachowiak  <mjs@apple.com>
 
         Reviewed by Oliver.
index 740b2209d88128d00ab017de65406e17da85c745..5f2c1887e31289817660fca654096349553071cd 100644 (file)
@@ -203,10 +203,6 @@ static WebDefaultUIDelegate *sharedDelegate = nil;
 
 - (unsigned)webView:(WebView *)webView dragSourceActionMaskForPoint:(NSPoint)point;
 {
-    DOMElement *elementAtPoint = [[webView elementAtPoint:point] objectForKey:WebElementDOMNodeKey];
-    if ([elementAtPoint respondsToSelector:@selector(isContentEditable)] && [(id)elementAtPoint isContentEditable])
-        return (WebDragSourceActionAny & ~WebDragSourceActionLink);
-
     return WebDragSourceActionAny;
 }
 
index e2d0c0a77d06b0b070245b7f7e3795d9d4116374..f8089837613b86a502a471a492950088e5a2c10a 100644 (file)
@@ -79,6 +79,7 @@ static void cacheValueForKey(const void *key, const void *value, void *self)
     addLookupKey(WebElementLinkTargetFrameKey, @selector(_targetWebFrame));
     addLookupKey(WebElementLinkTitleKey, @selector(_titleDisplayString));
     addLookupKey(WebElementLinkLabelKey, @selector(_textContent));
+    addLookupKey(WebElementLinkIsLiveKey, @selector(_isLiveLink));
 }
 
 - (id)initWithHitTestResult:(const HitTestResult&)result
@@ -218,4 +219,9 @@ static void cacheValueForKey(const void *key, const void *value, void *self)
     return _result->textContent();
 }
 
+- (NSNumber *)_isLiveLink
+{
+    return [NSNumber numberWithBool:_result->isLiveLink()];
+}
+
 @end
index 7fa4dcb1252e288e62a6fed1426c491f4e362d9f..0ea7dbd195b9860e13ee806a29b3c67d166668f4 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
+ *           (C) 2006 Graham Dennis (graham.dennis@gmail.com)
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1512,7 +1513,8 @@ static WebHTMLView *lastHitView = nil;
         return YES;
     
     if ([mouseDownElement objectForKey:WebElementLinkURLKey]
-            && (_private->dragSourceActionMask & WebDragSourceActionLink))
+            && (_private->dragSourceActionMask & WebDragSourceActionLink)
+            && [[mouseDownElement objectForKey:WebElementLinkIsLiveKey] boolValue])
         return YES;
     
     if ([[mouseDownElement objectForKey:WebElementIsSelectedKey] boolValue]
@@ -5972,13 +5974,14 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     return NO;
 }
 
-- (BOOL)_isMoveDrag
+- (BOOL)_isMoveDrag:(id <NSDraggingInfo>)draggingInfo
 {
     FrameMac* coreFrame = core([self _frame]);
     return _private->initiatedDrag
         && coreFrame
         && coreFrame->selectionController()->isContentEditable()
-        && !([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask);
+        && !([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)
+        && ![[[draggingInfo draggingPasteboard] types] containsObject:NSURLPboardType];
 }
 
 - (BOOL)_isNSColorDrag:(id <NSDraggingInfo>)draggingInfo
@@ -6008,7 +6011,7 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
             ASSERT(innerFrame);
             ASSERT([innerFrame isKindOfClass:[WebFrame class]]);
             WebHTMLView* innerView = (WebHTMLView *)[[innerFrame frameView] documentView];
-            operation = [innerView _isMoveDrag] ? NSDragOperationMove : NSDragOperationCopy;
+            operation = [innerView _isMoveDrag:draggingInfo] ? NSDragOperationMove : NSDragOperationCopy;
         }
     } else
         [[self _webView] removeDragCaret];
@@ -6072,14 +6075,14 @@ static DOMRange *unionDOMRanges(DOMRange *a, DOMRange *b)
     BOOL didInsert = NO;
     if ([self _canProcessDragWithDraggingInfo:draggingInfo]) {
         NSPasteboard *pasteboard = [draggingInfo draggingPasteboard];
-        if ([innerView _isMoveDrag] || [innerBridge isDragCaretRichlyEditable]) { 
+        if ([innerView _isMoveDrag:draggingInfo] || [innerBridge isDragCaretRichlyEditable]) { 
             DOMRange *range = [innerBridge dragCaretDOMRange];
             BOOL chosePlainText;
             DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard
                 inContext:range allowPlainText:YES chosePlainText:&chosePlainText];
             if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionDropped]) {
                 [[webView _UIDelegateForwarder] webView:webView willPerformDragDestinationAction:WebDragDestinationActionEdit forDraggingInfo:draggingInfo];
-                if ([innerView _isMoveDrag]) {
+                if ([innerView _isMoveDrag:draggingInfo]) {
                     BOOL smartMove = [innerBridge selectionGranularity] == WebBridgeSelectByWord && [self _canSmartReplaceWithPasteboard:pasteboard];
                     [innerBridge moveSelectionToDragCaret:fragment smartMove:smartMove];
                 } else {
index 8ad859c538004ab4824e0c24c6043cdae1e1fd15..6c79cf4cc96af06c3163836dfe0059fc7064665f 100644 (file)
@@ -342,6 +342,7 @@ NSString *WebElementLinkTitleKey =          @"WebElementLinkTitle";
 NSString *WebElementLinkURLKey =            @"WebElementLinkURL";
 NSString *WebElementSpellingToolTipKey =    @"WebElementSpellingToolTip";
 NSString *WebElementTitleKey =              @"WebElementTitle";
+NSString *WebElementLinkIsLiveKey =         @"WebElementLinkIsLive";
 
 NSString *WebViewProgressStartedNotification =          @"WebProgressStartedNotification";
 NSString *WebViewProgressEstimateChangedNotification =  @"WebProgressEstimateChangedNotification";
index 1c6801a664b7c1cc03ecf0706f1b9219c98222ea..7a0e202a84c27c7bc36f7b46fcb7daf569c92736 100644 (file)
@@ -84,6 +84,9 @@ extern NSString *_WebMainFrameDocumentKey;
 extern NSString *WebElementTitleKey;             // NSString of the title of the element (used by Safari)
 extern NSString *WebElementSpellingToolTipKey;   // NSString of a tooltip representing misspelling or bad grammar (used internally)
 
+// other WebElementDictionary keys
+extern NSString *WebElementLinkIsLiveKey;        // NSNumber of BOOL indictating whether the link is live or not
+
 typedef enum {
     WebDashboardBehaviorAlwaysSendMouseEventsToAllWindows,
     WebDashboardBehaviorAlwaysSendActiveNullEventsToPlugIns,