Changeset 28620 in webkit


Ignore:
Timestamp:
Dec 11, 2007 11:11:46 AM (16 years ago)
Author:
ap@webkit.org
Message:

Reviewed by Darin.

<rdar://problem/5535636>
Have to press 4 times instead of 2 times to get the expected result of with german keyboard.

http://bugs.webkit.org/show_bug.cgi?id=13916
JavaScript detects Tab as a character input on a textfield validation

Location:
trunk
Files:
7 added
75 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r28612 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * platform/win/fast/events: Added.
     12        * platform/win/fast/events/double-dead-char-expected.txt: Added.
     13        * platform/win/fast/events/double-dead-char.html: Added.
     14        * fast/events/key-events-in-input-button.html: Added
     15        * fast/events/key-events-in-input-button-expected.txt: Added
     16        * fast/events/key-events-in-input-text.html: Added
     17        * fast/events/key-events-in-input-text-expected.txt: Added
     18
     19        * fast/events/access-key-self-destruct.html:
     20        * fast/forms/listbox-onchange.html:
     21        * fast/forms/listbox-selection.html:
     22        * fast/forms/access-key.html:
     23        * fast/forms/legend-access-key.html:
     24        * fast/forms/enter-clicks-buttons.html:
     25        * fast/forms/check-box-enter-key.html:
     26        * fast/forms/button-enter-click.html:
     27        * fast/events/onsearch-enter.html:
     28        * fast/events/onchange-passwordfield.html:
     29        * fast/events/onchange-searchfield.html:
     30        * fast/events/onchange-textfield.html:
     31        Use eventSender instead of DOM events, because it emulates the real user action much better,
     32        and we weren't getting cross-browser compatibility for the tests anyway.
     33
     34        * fast/events/frame-tab-focus.html:
     35        * fast/html/tab-order.html:
     36        * fast/forms/select-enter-key.html:
     37        * fast/forms/focus2-expected.txt:
     38        * fast/forms/focus2.html:
     39        * fast/events/option-tab.html:
     40        Dispatch a keydown instead of keypress, as this is when default processing is now done.
     41        Possibly, it would be better stiull to use eventSender here, as well.
     42
     43        * fast/forms/onchange-enter-submit.html:
     44        * fast/forms/select-double-onchange.html:
     45        * fast/forms/textfield-onchange-deletion.html:
     46        The correct code is '\r', not '\n' - previously, the difference was lost while converting
     47        events back and forth.
     48
     49        * fast/forms/search-event-delay.html: Use a new named key to dispatch backspace - the
     50        character code for it is cross-platform, but key code is not.
     51        Also changed the test to call notifyDone() from a timer - otherwise, DRT would hang as
     52        WM_KEYUP was dispatched after WM_QUIT. I tried and couldn't make DRT work, but I'm
     53        fairly confident that this issue doesn't affect Safari.
     54
     55        * fast/events/keydown-keypress-preventDefault-expected.txt:
     56        * fast/events/keydown-keypress-preventDefault.html:
     57        This test claimed that its expacted behavior matched both IE and Firefox, but it did not.
     58        We now match IE.
     59
     60        * fast/events/js-keyboard-event-creation-expected.txt:
     61        * fast/events/js-keyboard-event-creation.html:
     62        This test was problematic, because it was tabbing out to chrome, and that doesn't work
     63        well in DRT. I have added another input for it to have a nicer target.
     64
     65        * platform/mac/fast/events/objc-event-api-expected.txt:
     66        Updated for new behavior:
     67          - eventSender.keyDown() now dispatches a keyUp, too;
     68          - raw events do not have charCode;
     69          - keypresses do not have keyIdentifiers.
     70
    1712007-12-10  Oliver Hunt  <oliver@apple.com>
    272
  • trunk/LayoutTests/fast/events/access-key-self-destruct.html

    r26721 r28620  
    66function test()
    77{
    8     if (window.layoutTestController)
     8    if (window.layoutTestController) {
    99        layoutTestController.dumpAsText();
    10    
    11     var event = document.createEvent("KeyboardEvent");
    12     if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
    13         event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, true, false, false, false, false);
    14     else
    15         event.initKeyboardEvent("keydown", true, true, document.defaultView, "a", 0, false, true, false, false, false);
    16     document.dispatchEvent(event);
     10        if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
     11            modifier = "ctrlKey";
     12        else
     13            modifier = "altKey";
     14        eventSender.keyDown("a", [modifier]);
     15    }
    1716}
    1817</script>
  • trunk/LayoutTests/fast/events/frame-tab-focus.html

    r21445 r28620  
    9090    var event = document.createEvent('KeyboardEvents');
    9191    var tabKeyIdentifier = 'U+0009';
    92     event.initKeyboardEvent('keypress', true, true, document.defaultView, tabKeyIdentifier, 0, false, altKey, shiftKey, false, false);
     92    event.initKeyboardEvent('keydown', true, true, document.defaultView, tabKeyIdentifier, 0, false, altKey, shiftKey, false, false);
    9393    element.dispatchEvent(event);
    9494}
  • trunk/LayoutTests/fast/events/js-keyboard-event-creation-expected.txt

    r21687 r28620  
    1 
     1 
    22This tests that DOMKeyboardEvents are created correctly in the JavaScript API.
    33
    4 keydown - key: U+0009@0 (keyCode/charCode: 9/9) modifiers: false,false,false,false
     4keydown - key: U+0009@0 (keyCode/charCode: 9/0) modifiers: false,false,false,false
    55
    6 keypress - key: U+0009@0 (keyCode/charCode: 9/9) modifiers: false,false,false,false
    7 
    8 keydown - key: U+0009@0 (keyCode/charCode: 9/9) modifiers: false,false,true,false
    9 
    10 keypress - key: U+0009@0 (keyCode/charCode: 9/9) modifiers: false,false,true,false
     6keyup - key: U+0009@0 (keyCode/charCode: 9/0) modifiers: false,false,true,false
  • trunk/LayoutTests/fast/events/js-keyboard-event-creation.html

    r17124 r28620  
    1515    input.addEventListener("keyup", keyevent, true);
    1616   
    17     if (layoutTestController)
     17    if (window.layoutTestController)
    1818        layoutTestController.dumpAsText();
    1919   
     
    2929    <form>
    3030        <input type="text" size="50" id="testinput" />
     31        <input type="text" size="50" />
    3132    </form>
    3233   
  • trunk/LayoutTests/fast/events/keydown-keypress-preventDefault-expected.txt

    r24542 r28620  
    1 This tests that preventing the default behavior for a keydown event will not prevent the keypress event from firing, but will prevent text from being inserted.
    2 This matches IE7 and Firefox.
     1This tests that preventing the default behavior for a keydown event will prevent the keypress event from firing, and will prevent text from being inserted.
     2This matches IE7, but not Firefox, which still dispatches a keypress.
    33 
    44key down
    5 key press
    65key down
    7 key press
    86key down
    9 key press
    107key down
    11 key press
    128
    139
  • trunk/LayoutTests/fast/events/keydown-keypress-preventDefault.html

    r24542 r28620  
    2020</script>
    2121<body onload="test()">
    22     This tests that preventing the default behavior for a keydown event will not prevent the keypress event from firing, but will prevent text from being inserted.<br>
    23     This matches IE7 and Firefox.<br>
    24     <input id="tf" onkeydown="log('key down'); event.preventDefault();" onkeypress="log('key press')">
     22    This tests that preventing the default behavior for a keydown event will prevent the keypress event from firing, and will prevent text from being inserted.<br>
     23    This matches IE7, but not Firefox, which still dispatches a keypress.<br>
     24    <input id="tf" onkeydown="log('key down'); return false" onkeypress="log('key press')">
    2525    <br>
    2626    <div id="res"></div>
  • trunk/LayoutTests/fast/events/onchange-passwordfield.html

    r21045 r28620  
    2828
    2929// hit enter
    30 var enterEvent = document.createEvent("KeyboardEvents");
    31 enterEvent.initKeyboardEvent("keypress", true, false, window, "Enter", 0, false, false, false, false, false); // This is not at all like pulling teeth
    32 input.dispatchEvent(enterEvent);
     30input.focus();
     31if (window.eventSender)
     32    eventSender.keyDown("\r", []);
    3333
    3434</script>
  • trunk/LayoutTests/fast/events/onchange-searchfield.html

    r21045 r28620  
    2828
    2929// hit enter
    30 var enterEvent = document.createEvent("KeyboardEvents");
    31 enterEvent.initKeyboardEvent("keypress", true, false, window, "Enter", 0, false, false, false, false, false); // This is not at all like pulling teeth
    32 input.dispatchEvent(enterEvent);
     30input.focus();
     31if (window.eventSender)
     32    eventSender.keyDown("\r", []);
    3333
    3434</script>
  • trunk/LayoutTests/fast/events/onchange-textfield.html

    r21045 r28620  
    2828
    2929// hit enter
    30 var enterEvent = document.createEvent("KeyboardEvents");
    31 enterEvent.initKeyboardEvent("keypress", true, false, window, "Enter", 0, false, false, false, false, false); // This is not at all like pulling teeth
    32 input.dispatchEvent(enterEvent);
     30input.focus();
     31if (window.eventSender)
     32    eventSender.keyDown("\r", []);
    3333
    3434</script>
  • trunk/LayoutTests/fast/events/onsearch-enter.html

    r18384 r28620  
    66            var sf = document.getElementById('sf');
    77            sf.focus();
    8             var enterEvent = document.createEvent("KeyboardEvents");
    9             enterEvent.initKeyboardEvent("keypress", true, false, window, "Enter", 0, false, false, false, false, false);
    10             sf.dispatchEvent(enterEvent);
    11             if (window.layoutTestController)
     8            if (window.layoutTestController) {
    129                layoutTestController.dumpAsText();
     10                eventSender.keyDown("\r", []);
     11            }
    1312        }
    1413        function log(msg)
  • trunk/LayoutTests/fast/events/option-tab.html

    r21445 r28620  
    1515    document.getElementById(fieldId).focus();
    1616    var event = document.createEvent("KeyboardEvents");
    17     event.initKeyboardEvent("keypress", true, true, document.defaultView, "U+0009", 0, false, true, false, false, false);
     17    event.initKeyboardEvent("keydown", true, true, document.defaultView, "U+0009", 0, false, true, false, false, false);
    1818    document.getElementById(fieldId).dispatchEvent(event);
    1919    if (window.linkFocused)
     
    2525    document.getElementById(fieldId).focus();
    2626    event = document.createEvent("KeyboardEvents");
    27     event.initKeyboardEvent("keypress", true, true, document.defaultView, "U+0009", 0, false, false, false, false, false);
     27    event.initKeyboardEvent("keydown", true, true, document.defaultView, "U+0009", 0, false, false, false, false, false);
    2828    document.getElementById(fieldId).dispatchEvent(event);
    2929    if (window.linkFocused)
  • trunk/LayoutTests/fast/forms/access-key.html

    r27599 r28620  
    1010function pressKey(key)
    1111{
    12     var event = document.createEvent("KeyboardEvent");
    1312    if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
    14         event.initKeyboardEvent("keydown", true, true, document.defaultView, key, 0, true, false, false, false, false);
     13        modifier = "ctrlKey";
    1514    else
    16         event.initKeyboardEvent("keydown", true, true, document.defaultView, key, 0, false, true, false, false, false);
    17     document.dispatchEvent(event);
     15        modifier = "altKey";
     16    eventSender.keyDown(key, [modifier]);
    1817}
    1918function test()
    2019{
    21     if (window.layoutTestController)
     20    if (window.layoutTestController) {
    2221        layoutTestController.dumpAsText();
    2322
    24     for (i = 1; i <= 9; i++)
    25         pressKey(i);
    26     pressKey("a");
    27     pressKey("b");
    28     pressKey("c");
     23        for (i = 1; i <= 9; i++)
     24            pressKey(i.toString());
     25        pressKey("a");
     26        pressKey("b");
     27        pressKey("c");
     28    }
    2929}
    3030</script>
  • trunk/LayoutTests/fast/forms/button-enter-click.html

    r21174 r28620  
    55        var bt = document.getElementById('bt');
    66        bt.focus();
    7         if (window.layoutTestController)
     7        if (window.layoutTestController) {
    88            layoutTestController.dumpAsText();
    9         var keyEvent = document.createEvent("KeyboardEvents");
    10         keyEvent.initKeyboardEvent("keypress", true, true, window, "Enter", 0, false, false, false, false, false);
    11         bt.dispatchEvent(keyEvent);
     9            eventSender.keyDown("\r", []);
     10        }
    1211    }
    1312    function log(msg) {
  • trunk/LayoutTests/fast/forms/check-box-enter-key.html

    r11995 r28620  
    1919function test()
    2020{
    21     if (window.layoutTestController)
     21    document.getElementById("form").onsubmit = submitHandler;
     22    document.getElementById("check").focus();
     23    if (window.layoutTestController) {
    2224        layoutTestController.dumpAsText();
    23 
    24     document.getElementById("form").onsubmit = submitHandler;
    25     var event = document.createEvent("KeyboardEvents");
    26     event.initKeyboardEvent("keypress", true, true, document.defaultView, "Enter", 0, false, false, false, false, false);
    27     document.getElementById("check").dispatchEvent(event);
     25        eventSender.keyDown("\r", []);
     26    }
    2827}
    2928</script>
  • trunk/LayoutTests/fast/forms/enter-clicks-buttons.html

    r27652 r28620  
    2626        layoutTestController.dumpAsText();
    2727
    28     var keys = ['Enter', 'U+0020'];
     28    var keys = ['\r', ' '];
     29    var keyNames = ['Enter', 'U+0020'];
    2930    var tagNames = ['button', 'input'];
    3031
    3132    for (var i in keys) {
    32         log('\n\nSending ' + keys[i] + ' keypresses...\n');
     33        log('\n\nSending ' + keyNames[i] + ' keypresses...\n');
    3334        for (var j in tagNames) {
    3435            var elements = document.getElementsByTagName(tagNames[j]);
    3536            log('\nLooping over ' + elements.length + ' ' + tagNames[j] + ' elements...\n');
    3637            for (var k = 0; k < elements.length; ++k) {
    37                 var event = elements[k].ownerDocument.createEvent("KeyboardEvent");
    38                 event.initKeyboardEvent("keypress", true, true, elements[k].ownerDocument.defaultView, keys[i], 0, false, false, false, false, false);
    39                 elements[k].dispatchEvent(event);
     38                elements[k].focus();
     39                eventSender.keyDown(keys[i], []);
    4040            }
    4141        }
  • trunk/LayoutTests/fast/forms/focus2-expected.txt

    r19636 r28620  
    66PARENT DOCUMENT:
    77focus event: [to] BUTTON
    8 keypress event: [to] BUTTON
     8keydown event: [to] BUTTON
    99blur event: [to] BUTTON
    1010focus event: [to] CHECKBOX
    11 keypress event: [to] CHECKBOX
     11keydown event: [to] CHECKBOX
    1212blur event: [to] CHECKBOX
    1313focus event: [to] FILE
    14 keypress event: [to] FILE
     14keydown event: [to] FILE
    1515blur event: [to] FILE
    1616focus event: [to] IMAGE
    17 keypress event: [to] IMAGE
     17keydown event: [to] IMAGE
    1818blur event: [to] IMAGE
    1919focus event: [to] ISINDEX
    20 keypress event: [to] ISINDEX
     20keydown event: [to] ISINDEX
    2121blur event: [to] ISINDEX
    2222focus event: [to] PASSWORD
    23 keypress event: [to] PASSWORD
     23keydown event: [to] PASSWORD
    2424blur event: [to] PASSWORD
    2525focus event: [to] RANGE
    26 keypress event: [to] RANGE
     26keydown event: [to] RANGE
    2727blur event: [to] RANGE
    2828focus event: [to] RESET
    29 keypress event: [to] RESET
     29keydown event: [to] RESET
    3030blur event: [to] RESET
    3131focus event: [to] SEARCH
    32 keypress event: [to] SEARCH
     32keydown event: [to] SEARCH
    3333blur event: [to] SEARCH
    3434focus event: [to] SUBMIT
    35 keypress event: [to] SUBMIT
     35keydown event: [to] SUBMIT
    3636blur event: [to] SUBMIT
    3737focus event: [to] TEXT
    38 keypress event: [to] TEXT
     38keydown event: [to] TEXT
    3939blur event: [to] TEXT
    4040focus event: [to] TEXTAREA
    41 keypress event: [to] TEXTAREA
     41keydown event: [to] TEXTAREA
    4242blur event: [to] TEXTAREA
    4343focus event: [to] DIV
    44 keypress event: [to] DIV
     44keydown event: [to] DIV
    4545blur event: [to] DIV
    4646focus event: [to] ANCHOR
     
    4949IFRAME DOCUMENT:
    5050focus event: [to] BUTTON
    51 keypress event: [to] BUTTON
     51keydown event: [to] BUTTON
    5252blur event: [to] BUTTON
    5353focus event: [to] CHECKBOX
    54 keypress event: [to] CHECKBOX
     54keydown event: [to] CHECKBOX
    5555blur event: [to] CHECKBOX
    5656focus event: [to] FILE
    57 keypress event: [to] FILE
     57keydown event: [to] FILE
    5858blur event: [to] FILE
    5959focus event: [to] IMAGE
    60 keypress event: [to] IMAGE
     60keydown event: [to] IMAGE
    6161blur event: [to] IMAGE
    6262focus event: [to] ISINDEX
    63 keypress event: [to] ISINDEX
     63keydown event: [to] ISINDEX
    6464blur event: [to] ISINDEX
    6565focus event: [to] PASSWORD
    66 keypress event: [to] PASSWORD
     66keydown event: [to] PASSWORD
    6767blur event: [to] PASSWORD
    6868focus event: [to] RANGE
    69 keypress event: [to] RANGE
     69keydown event: [to] RANGE
    7070blur event: [to] RANGE
    7171focus event: [to] RESET
    72 keypress event: [to] RESET
     72keydown event: [to] RESET
    7373blur event: [to] RESET
    7474focus event: [to] SEARCH
    75 keypress event: [to] SEARCH
     75keydown event: [to] SEARCH
    7676blur event: [to] SEARCH
    7777focus event: [to] SUBMIT
    78 keypress event: [to] SUBMIT
     78keydown event: [to] SUBMIT
    7979blur event: [to] SUBMIT
    8080focus event: [to] TEXT
    81 keypress event: [to] TEXT
     81keydown event: [to] TEXT
    8282blur event: [to] TEXT
    8383focus event: [to] TEXTAREA
    84 keypress event: [to] TEXTAREA
     84keydown event: [to] TEXTAREA
    8585blur event: [to] TEXTAREA
    8686focus event: [to] DIV
    87 keypress event: [to] DIV
     87keydown event: [to] DIV
    8888blur event: [to] DIV
    8989focus event: [to] ANCHOR
  • trunk/LayoutTests/fast/forms/focus2.html

    r21651 r28620  
    3636}
    3737
    38 function keypressListener(event)
     38function keydownListener(event)
    3939{
    40     log("keypress event: [to] " + description(event.target)  + "\n");
     40    log("keydown event: [to] " + description(event.target)  + "\n");
    4141}
    4242
     
    5555function addEventListeners(element)
    5656{
    57     element.addEventListener('keypress', keypressListener, false);
     57    element.addEventListener('keydown', keydownListener, false);
    5858    element.addEventListener('focus', focusListener, false);
    5959    element.addEventListener('blur', blurListener, false);
     
    110110    var event = document.createEvent("KeyboardEvents");
    111111    var tabKeyIdentifier = "U+0009";
    112     event.initKeyboardEvent("keypress", true, true, document.defaultView, tabKeyIdentifier, 0, false, true, shiftKey, false, false);
     112    event.initKeyboardEvent("keydown", true, true, document.defaultView, tabKeyIdentifier, 0, false, true, shiftKey, false, false);
    113113    element.dispatchEvent(event);
    114114}
  • trunk/LayoutTests/fast/forms/legend-access-key.html

    r26721 r28620  
    1010function test()
    1111{
    12     if (window.layoutTestController)
     12    if (window.layoutTestController) {
    1313        layoutTestController.dumpAsText();
    1414
    15     var event = document.createEvent("KeyboardEvent");
    16     if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
    17         event.initKeyboardEvent("keydown", true, true, document.defaultView, "f", 0, true, false, false, false, false);
    18     else
    19         event.initKeyboardEvent("keydown", true, true, document.defaultView, "f", 0, false, true, false, false, false);
    20     document.dispatchEvent(event);
     15        if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
     16            modifier = "ctrlKey";
     17        else
     18            modifier = "altKey";
     19        eventSender.keyDown("f", [modifier]);
     20    }
    2121}
    2222</script>
  • trunk/LayoutTests/fast/forms/listbox-onchange.html

    r26687 r28620  
    5252
    5353                log("6) Make sure onChange fires when changing the selection with the keyboard");
    54                 keyPressOnSelect("sl1", "Down", true, false);
     54                keyDownOnSelect("sl1", "downArrow", true, false);
    5555                checkSelection("0,1");
    5656
     
    148148            }
    149149
    150             function keyPressOnSelect(selId, identifier, shift, metaOrCtrl)
     150            function keyDownOnSelect(selId, identifier, shift, metaOrCtrl)
    151151            {
    152                 var meta = false;
    153                 var ctrl = false;
     152                modifiers = [];
     153                if (shift)
     154                    modifiers[0] = "shiftKey";
    154155                if (metaOrCtrl) {
    155156                    if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
    156                         meta = true;
     157                        modifiers[modifiers.length] = "metaKey";
    157158                    else
    158                         ctrl = true;
     159                        modifiers[modifiers.length] = "controlKey";
    159160                }
    160                 var sl = document.getElementById(selId);
    161                 var event = document.createEvent("KeyboardEvents");
    162                 event.initKeyboardEvent("keypress", true, true, document.defaultView, identifier, 0, ctrl, false, shift, meta, false);
    163                 sl.dispatchEvent(event);
     161
     162                document.getElementById(selId).focus();
     163                eventSender.keyDown(identifier, modifiers);
    164164            }
    165165           
  • trunk/LayoutTests/fast/forms/listbox-selection.html

    r26687 r28620  
    4545                               
    4646                // 3) Select one item with the keyboard (no previous selection)
    47                 keyPressOnSelect("sl3", "Up", false, false);               
     47                keyDownOnSelect("sl3", "upArrow", false, false);               
    4848                expectedSelectionResults = new Array(false, false, false, false, true);
    4949                testResults(expectedSelectionResults, 3);
    5050
    5151                // 4) Select one item with the keyboard (with previous selection)
    52                 keyPressOnSelect("sl4", "Down", false, false);
     52                keyDownOnSelect("sl4", "downArrow", false, false);
    5353                expectedSelectionResults = new Array(false, false, true, false, false);
    5454                testResults(expectedSelectionResults, 4);
     
    6565               
    6666                // 7) Attempt to select a range with the keyboard
    67                 keyPressOnSelect("sl7", "Down", true, false);
     67                keyDownOnSelect("sl7", "downArrow", true, false);
    6868                expectedSelectionResults = new Array(false, false, true, false, false);
    6969                testResults(expectedSelectionResults, 7);
     
    8383               
    8484                // 10) Select one item with the keyboard (no previous selection)
    85                 keyPressOnSelect("sl10", "Up", false, false);
     85                keyDownOnSelect("sl10", "upArrow", false, false);
    8686                expectedSelectionResults = new Array(false, false, false, false, true);
    8787                testResults(expectedSelectionResults, 10);
    8888                               
    8989                // 11) Select one item with the keyboard (with previous selection)
    90                 keyPressOnSelect("sl11", "Down", false, false);
     90                keyDownOnSelect("sl11", "downArrow", false, false);
    9191                expectedSelectionResults = new Array(false, false, true, false, false);
    9292                testResults(expectedSelectionResults, 11);
     
    103103                               
    104104                // 14) Select a range with the keyboard
    105                 keyPressOnSelect("sl14", "Down", true, false);
     105                keyDownOnSelect("sl14", "downArrow", true, false);
    106106                expectedSelectionResults = new Array(false, true, true, false, false);
    107107                testResults(expectedSelectionResults, 14);
     
    131131            }
    132132           
    133             function keyPressOnSelect(selId, identifier, shift, metaOrCtrl)
    134             {
    135                 var meta = false;
    136                 var ctrl = false;
     133            function keyDownOnSelect(selId, identifier, shift, metaOrCtrl)
     134            {
     135                modifiers = [];
     136                if (shift)
     137                    modifiers[0] = "shiftKey";
    137138                if (metaOrCtrl) {
    138139                    if (navigator.userAgent.search(/\bMac OS X\b/) != -1)
    139                         meta = true;
     140                        modifiers[modifiers.length] = "metaKey";
    140141                    else
    141                         ctrl = true;
    142                 }
    143                 var sl = document.getElementById(selId);
    144                 sl.focus();
    145                 var event = document.createEvent("KeyboardEvents");
    146                 event.initKeyboardEvent("keypress", true, true, document.defaultView, identifier, 0, ctrl, false, shift, meta, false);
    147                 sl.dispatchEvent(event);
     142                        modifiers[modifiers.length] = "controlKey";
     143                }
     144
     145                document.getElementById(selId).focus();
     146                eventSender.keyDown(identifier, modifiers);
    148147            }
    149148           
  • trunk/LayoutTests/fast/forms/onchange-enter-submit.html

    r15720 r28620  
    1717        if (window.layoutTestController) {
    1818            eventSender.keyDown('a');
    19             eventSender.keyDown('\n');
     19            eventSender.keyDown('\r');
    2020        }
    2121
  • trunk/LayoutTests/fast/forms/search-event-delay.html

    r19336 r28620  
    1313{
    1414    if (window.eventSender)
    15         eventSender.keyDown("\x7F");
     15        eventSender.keyDown("delete");
    1616}
    1717
     
    3434    } else {
    3535        if (window.layoutTestController)
    36             layoutTestController.notifyDone();
     36            setTimeout("layoutTestController.notifyDone()", 0); // Do it on a timer to avoid Windows DRT hanging.
    3737    }
    3838}
     
    5656<p>As of this writing we can't use DOM events to type into a search field, so the test uses the event sender and only runs under DumpRenderTree.</p>
    5757
    58 <p><input id="search" type="search" incremental onkeypress="keyEvent(event)" onsearch="searchEvent(event)"></p>
     58<p><input id="search" type="search" incremental onkeydown="keyEvent(event)" onsearch="searchEvent(event)"></p>
    5959
    6060<div>The two rows below should match.</div>
  • trunk/LayoutTests/fast/forms/select-double-onchange.html

    r21734 r28620  
    1616
    1717                eventSender.keyDown("t", null);
    18                 eventSender.keyDown("\n", null);
     18                eventSender.keyDown("\r", null);
    1919            }
    2020
  • trunk/LayoutTests/fast/forms/select-enter-key.html

    r19633 r28620  
    1414function test()
    1515{
    16     if (window.layoutTestController)
     16    document.getElementById("form").onsubmit = submitHandler;
     17    document.getElementById("select").focus();
     18    if (window.layoutTestController) {
    1719        layoutTestController.dumpAsText();
    18 
    19     document.getElementById("form").onsubmit = submitHandler;
    20     var event = document.createEvent("KeyboardEvents");
    21     event.initKeyboardEvent("keypress", true, true, document.defaultView, "Enter", 0, false, false, false, false, false);
    22     document.getElementById("select").dispatchEvent(event);
     20        eventSender.keyDown("\r", []);
     21    }
    2322}
    2423</script>
  • trunk/LayoutTests/fast/forms/textfield-onchange-deletion.html

    r26934 r28620  
    1111        document.getElementById('tf').focus();
    1212        eventSender.keyDown('a');
    13         eventSender.keyDown("\n", null);
     13        eventSender.keyDown("\r", null);
    1414        if (window.layoutTestController)
    1515            layoutTestController.notifyDone();
  • trunk/LayoutTests/fast/html/tab-order.html

    r21445 r28620  
    2020            var event = document.createEvent('KeyboardEvents');
    2121            var tabKeyIdentifier = 'U+0009';
    22             event.initKeyboardEvent('keypress', true, true, document.defaultView, tabKeyIdentifier, 0, false, false, shiftKey, false, false);
     22            event.initKeyboardEvent('keydown', true, true, document.defaultView, tabKeyIdentifier, 0, false, false, shiftKey, false, false);
    2323            element.dispatchEvent(event);
    2424        }
  • trunk/LayoutTests/platform/mac/fast/events/objc-event-api-expected.txt

    r28203 r28620  
    8080  modifier keys: c:0 s:0 a:0 m:0
    8181  keyCode:       65
    82   charCode:      97
     82  charCode:      0
    8383event type:      keypress
    8484  target:        <body>
     
    8888  detail:        0
    8989  view:          OK (document: OK)
    90   keyIdentifier: U+0041
     90  keyIdentifier:
    9191  keyLocation:   0
    9292  modifier keys: c:0 s:0 a:0 m:0
    9393  keyCode:       97
    9494  charCode:      97
     95event type:      keyup
     96  target:        <body>
     97  eventPhase:    3
     98  bubbles:       1
     99  cancelable:    1
     100  detail:        0
     101  view:          OK (document: OK)
     102  keyIdentifier: U+0041
     103  keyLocation:   0
     104  modifier keys: c:0 s:0 a:0 m:0
     105  keyCode:       65
     106  charCode:      0
    95107event type:      keydown
    96108  target:        <body>
     
    104116  modifier keys: c:1 s:0 a:0 m:0
    105117  keyCode:       66
    106   charCode:      98
     118  charCode:      0
    107119event type:      keypress
    108120  target:        <body>
     
    112124  detail:        0
    113125  view:          OK (document: OK)
    114   keyIdentifier: U+0042
     126  keyIdentifier:
    115127  keyLocation:   0
    116128  modifier keys: c:1 s:0 a:0 m:0
    117129  keyCode:       98
    118130  charCode:      98
     131event type:      keyup
     132  target:        <body>
     133  eventPhase:    3
     134  bubbles:       1
     135  cancelable:    1
     136  detail:        0
     137  view:          OK (document: OK)
     138  keyIdentifier: U+0042
     139  keyLocation:   0
     140  modifier keys: c:1 s:0 a:0 m:0
     141  keyCode:       66
     142  charCode:      0
    119143event type:      keydown
    120144  target:        <body>
     
    128152  modifier keys: c:0 s:1 a:0 m:0
    129153  keyCode:       68
    130   charCode:      100
     154  charCode:      0
    131155event type:      keypress
    132156  target:        <body>
     
    136160  detail:        0
    137161  view:          OK (document: OK)
    138   keyIdentifier: U+0044
     162  keyIdentifier:
    139163  keyLocation:   0
    140164  modifier keys: c:0 s:1 a:0 m:0
    141165  keyCode:       100
    142166  charCode:      100
     167event type:      keyup
     168  target:        <body>
     169  eventPhase:    3
     170  bubbles:       1
     171  cancelable:    1
     172  detail:        0
     173  view:          OK (document: OK)
     174  keyIdentifier: U+0044
     175  keyLocation:   0
     176  modifier keys: c:0 s:1 a:0 m:0
     177  keyCode:       68
     178  charCode:      0
    143179event type:      keydown
    144180  target:        <body>
     
    152188  modifier keys: c:0 s:0 a:1 m:1
    153189  keyCode:       69
    154   charCode:      101
     190  charCode:      0
    155191event type:      keypress
    156192  target:        <body>
     
    160196  detail:        0
    161197  view:          OK (document: OK)
    162   keyIdentifier: U+0045
     198  keyIdentifier:
    163199  keyLocation:   0
    164200  modifier keys: c:0 s:0 a:1 m:1
    165201  keyCode:       101
    166202  charCode:      101
     203event type:      keyup
     204  target:        <body>
     205  eventPhase:    3
     206  bubbles:       1
     207  cancelable:    1
     208  detail:        0
     209  view:          OK (document: OK)
     210  keyIdentifier: U+0045
     211  keyLocation:   0
     212  modifier keys: c:0 s:0 a:1 m:1
     213  keyCode:       69
     214  charCode:      0
    167215event type:      mousemove
    168216  target:        <div>
  • trunk/WebCore/ChangeLog

    r28616 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        Test: platform/win/fast/events/double-dead-char.html
     12
     13        * platform/PlatformKeyboardEvent.h:
     14        (WebCore::PlatformKeyboardEvent::):
     15        (WebCore::PlatformKeyboardEvent::type):
     16        (WebCore::PlatformKeyboardEvent::windowsVirtualKeyCode):
     17        (WebCore::PlatformKeyboardEvent::setWindowsVirtualKeyCode):
     18        (WebCore::PlatformKeyboardEvent::keyIdentifier):
     19        (WebCore::PlatformKeyboardEvent::setIsAutoRepeat):
     20        Added an explicit type member to differentiate different kinds of events:
     21          RawKeyDown == keydown == WM_KEYDOWN
     22          KeyUp == keyup == WM_KEYUP
     23          Char == keypress == WM_CHAR
     24          KeyDown == e.g. NSKeyDown or NSFlagsChanged, used on platforms that have a different model for
     25          event processing, and needs to be converted to RawKeyDown (+ Char) for processing in DOM.
     26
     27        * platform/mac/KeyEventMac.mm:
     28        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent): Updated for changed data members.
     29        Fix Enter (numeric keypad) charCode to match Return, as we check for it from keypress default handlers.
     30        (WebCore::windowsKeyCodeForKeyEvent):
     31        (WebCore::isKeyUpEvent): Made it do something closer to what it claims; added a FIXME explaining
     32        that it still fails.
     33        (WebCore::disambiguateKeyDownEvent): Downgrade from KeyDown to RawKeyDown or Char, removing information that
     34        should not be available in those (because it cannot be provided on Windows).
     35
     36        * platform/win/KeyEventWin.cpp:
     37        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent): Updated for changed data members.
     38        Used standard Windows constants for bit masks instead of our own ones.
     39        (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent): Should never be called on Windows.
     40
     41        * platform/gtk/KeyEventGtk.cpp:
     42        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
     43        (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent):
     44        * platform/qt/PlatformKeyboardEventQt.cpp:
     45        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
     46        (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent):
     47        * platform/wx/KeyboardEventWx.cpp:
     48        (WebCore::PlatformKeyboardEvent::PlatformKeyboardEvent):
     49        (WebCore::PlatformKeyboardEvent::disambiguateKeyDownEvent):
     50        Updated for cross-platform changes as much as it was possible without appropriate build
     51        environments.
     52
     53        * WebCore.base.exp: Export PlatformKeyboardEvent::disambiguateKeyDownEvent(), used by platforms that need to
     54        convert their fancy key events to RawKeyDown/Char pairs. Export Editor::isTextInsertionCommand().
     55
     56        * bridge/EditorClient.h:
     57        Renamed handleKeypress() to handleKeyboardEvent(), as it gets both keydowns and keypresses.
     58        Renamed handleInputMethodKeypress() to handleInputMethodKeydown(), as IMs work with raw keydowns.
     59
     60        * dom/Document.h:
     61        * dom/Document.cpp:
     62        (WebCore::Document::defaultEventHandler): Moved accesskey processing to EventHandler.
     63
     64        * dom/KeyboardEvent.h: Added comments describing keyCode/charCode behavior.
     65
     66        * dom/KeyboardEvent.cpp:
     67        (WebCore::eventTypeForKeyboardEventType):
     68        (WebCore::KeyboardEvent::KeyboardEvent): Conversion between platform and DOM event types is
     69        now straightforward, so scary hacks such as using autorepeat to distinguish types are
     70        not needed.
     71        (WebCore::KeyboardEvent::keyCode): Added a comment describing other browsers' behavior.
     72        (WebCore::KeyboardEvent::charCode): Added a comment describing other browsers' behavior.
     73        Changed to a more compatible behavior: raw keydown/keyup events do not and can not have
     74        character codes.
     75
     76        * editing/Editor.h:
     77        * editing/Editor.cpp:
     78        (WebCore::Editor::isTextInsertionCommand): Is this command actually text input in disguise?
     79        (WebCore::Editor::handleKeyboardEvent): Updated for new function names.
     80        (WebCore::Editor::handleInputMethodKeydown): Ditto.
     81
     82        * html/HTMLButtonElement.cpp:
     83        (WebCore::HTMLButtonElement::defaultEventHandler): Perform the default action when handling an
     84        appropriate event. Enter is processed on keypress (and thus should be checked for via charCode,
     85        not keyIdentifier), Space is processed on keydown+keyup! We now match IE in that a button is
     86        highlighted when Space is pressed.
     87
     88        * html/HTMLInputElement.cpp:
     89        (WebCore::HTMLInputElement::defaultEventHandler):
     90        * html/HTMLSelectElement.cpp:
     91        (WebCore::HTMLSelectElement::menuListDefaultEventHandler):
     92        (WebCore::HTMLSelectElement::listBoxDefaultEventHandler):
     93        Made a number of fixes to when default actions take place, similar to HTMLButtonElement ones
     94        described above.
     95
     96        * page/EventHandler.cpp:
     97        (WebCore::EventHandler::keyEvent): Unless we have a combined KeyDown, just forward the event
     98        to the target. Call accesskey handling directly, as it doesn't seem to be part of normal event
     99        handling in IE. Also streamlined the code in KeyDown case, thanks to handleInputMethodKeypress()
     100        now being handleInputMethodKeydown().
     101        (WebCore::EventHandler::handleTextInputEvent): Check that we were not called from keydown.
     102        (WebCore::EventHandler::defaultTextInputEventHandler): Removed a call to defaultTabEventHandler,
     103        as default tab handling happens when processing keydown.
     104        (WebCore::handleAccessKey): Moved from Document, as access keys are processed outside normal
     105        event handling. Fixed accesskey processing to use information that's available in a raw keydown
     106        event.
     107
     108        (WebCore::EventHandler::defaultKeyboardEventHandler): Do not ignore keydown; in particular,
     109        handle tabs during keydown processing.
     110
     111        * page/mac/EventHandlerMac.mm:
     112        (WebCore::EventHandler::currentKeyboardEvent): Disambiguate KeyDown as RawKeyDown, as this is
     113        what callers want.
     114
     115        * platform/text/PlatformString.h:
     116        * platform/text/String.cpp:
     117        (WebCore::String::characterStartingAt):
     118        * platform/text/StringImpl.cpp:
     119        (WebCore::StringImpl::characterStartingAt):
     120        * platform/text/StringImpl.h:
     121        Added a UChar32 accessor.
     122
     123        * svg/graphics/SVGImageEmptyClients.h:
     124        (WebCore::SVGEmptyEditorClient::handleKeyboardEvent):
     125        (WebCore::SVGEmptyEditorClient::handleInputMethodKeydown):
     126        Updated for new function names.
     127
    11282007-12-11  John Sullivan  <sullivan@apple.com>
    2129
  • trunk/WebCore/WebCore.base.exp

    r28468 r28620  
    355355__ZN7WebCore20ResourceResponseBase24setExpectedContentLengthEx
    356356__ZN7WebCore21ContextMenuController16clearContextMenuEv
    357 __ZN7WebCore21PlatformKeyboardEventC1EP7NSEventb
     357__ZN7WebCore21PlatformKeyboardEventC1EP7NSEvent
     358__ZN7WebCore21PlatformKeyboardEvent24disambiguateKeyDownEventENS0_4TypeEb
    358359__ZN7WebCore21WindowsLatin1EncodingEv
    359360__ZN7WebCore21findEventWithKeyStateEPNS_5EventE
     
    415416__ZN7WebCore6Editor10insertTextERKNS_6StringEPNS_5EventE
    416417__ZN7WebCore6Editor11canDHTMLCutEv
     418__ZN7WebCore6Editor22isTextInsertionCommandERKNS_12AtomicStringE
    417419__ZN7WebCore6Editor11execCommandERKNS_12AtomicStringEPNS_5EventE
    418420__ZN7WebCore6Editor11tryDHTMLCutEv
  • trunk/WebCore/bridge/EditorClient.h

    r25547 r28620  
    109109    virtual void redo() = 0;
    110110
    111     virtual void handleKeypress(KeyboardEvent*) = 0;
    112     virtual void handleInputMethodKeypress(KeyboardEvent*) = 0;
     111    virtual void handleKeyboardEvent(KeyboardEvent*) = 0;
     112    virtual void handleInputMethodKeydown(KeyboardEvent*) = 0;
    113113   
    114114    virtual void textFieldDidBeginEditing(Element*) = 0;
  • trunk/WebCore/dom/Document.cpp

    r28555 r28620  
    24432443}
    24442444
    2445 
    2446 void Document::defaultEventHandler(Event *evt)
    2447 {
    2448     // handle accesskey
    2449     if (evt->type() == keydownEvent) {
    2450         KeyboardEvent* kevt = static_cast<KeyboardEvent *>(evt);
    2451 #if PLATFORM(MAC)
    2452         if (kevt->ctrlKey())
    2453 #else
    2454         if (kevt->altKey())
    2455 #endif
    2456         {
    2457             const PlatformKeyboardEvent* ev = kevt->keyEvent();
    2458             String key = (ev ? ev->unmodifiedText() : kevt->keyIdentifier()).lower();
    2459             Element* elem = getElementByAccessKey(key);
    2460             if (elem) {
    2461                 elem->accessKeyAction(false);
    2462                 evt->setDefaultHandled();
    2463                 return;
    2464             }
    2465         }
    2466     }
    2467 
    2468     ContainerNode::defaultEventHandler(evt);
    2469 }
    2470 
    24712445void Document::setHTMLWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener> listener)
    24722446{
  • trunk/WebCore/dom/Document.h

    r28327 r28620  
    484484    CSSStyleDeclaration* getOverrideStyle(Element*, const String& pseudoElt);
    485485
    486     virtual void defaultEventHandler(Event*);
    487486    void handleWindowEvent(Event*, bool useCapture);
    488487    void setHTMLWindowEventListener(const AtomicString &eventType, PassRefPtr<EventListener>);
  • trunk/WebCore/dom/KeyboardEvent.cpp

    r25754 r28620  
    2424#include "KeyboardEvent.h"
    2525
     26#include "Document.h"
     27#include "DOMWindow.h"
    2628#include "EventNames.h"
    2729#include "PlatformKeyboardEvent.h"
     30#include "Settings.h"
    2831
    2932namespace WebCore {
    3033
    3134using namespace EventNames;
     35
     36static inline const AtomicString& eventTypeForKeyboardEventType(PlatformKeyboardEvent::Type type)
     37{
     38    switch (type) {
     39        case PlatformKeyboardEvent::KeyUp:
     40            return keyupEvent;
     41        case PlatformKeyboardEvent::RawKeyDown:
     42            return keydownEvent;
     43        case PlatformKeyboardEvent::Char:
     44            return keypressEvent;
     45        case PlatformKeyboardEvent::KeyDown:
     46            // The caller should disambiguate the combined event into RawKeyDown or Char events.
     47            break;
     48    }
     49    ASSERT_NOT_REACHED();
     50    return keydownEvent;
     51}
    3252
    3353KeyboardEvent::KeyboardEvent()
     
    3959
    4060KeyboardEvent::KeyboardEvent(const PlatformKeyboardEvent& key, AbstractView* view)
    41     : UIEventWithKeyState(key.isKeyUp() ? keyupEvent : key.isAutoRepeat() ? keypressEvent : keydownEvent,
     61    : UIEventWithKeyState(eventTypeForKeyboardEventType(key.type()),
    4262                          true, true, view, 0, key.ctrlKey(), key.altKey(), key.shiftKey(), key.metaKey())
    4363    , m_keyEvent(new PlatformKeyboardEvent(key))
    4464    , m_keyIdentifier(key.keyIdentifier())
    45     , m_keyLocation(key.isKeypad() ? DOM_KEY_LOCATION_NUMPAD : DOM_KEY_LOCATION_STANDARD)
     65    , m_keyLocation(key.isKeypad() ? DOM_KEY_LOCATION_NUMPAD : DOM_KEY_LOCATION_STANDARD) // FIXME: differentiate right/left, too
    4666    , m_altGraphKey(false)
    4767{
     
    97117int KeyboardEvent::keyCode() const
    98118{
     119    // IE: virtual key code for keyup/keydown, character code for keypress
     120    // Firefox: virtual key code for keyup/keydown, zero for keypress
     121    // We match IE.
    99122    if (!m_keyEvent)
    100123        return 0;
    101124    if (type() == keydownEvent || type() == keyupEvent)
    102         return m_keyEvent->WindowsKeyCode();
     125        return m_keyEvent->windowsVirtualKeyCode();
    103126    return charCode();
    104127}
     
    106129int KeyboardEvent::charCode() const
    107130{
    108     if (!m_keyEvent)
     131    // IE: not supported
     132    // Firefox: 0 for keydown/keyup events, character code for keypress
     133    // We match Firefox, unless in Dashboard compatibility mode, where we always return the character code.
     134    bool dashboardCompatibilityMode = false;
     135    if (view())
     136        if (Settings* settings = view()->document()->settings())
     137            dashboardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
     138
     139    if (!m_keyEvent || (type() != keypressEvent && !dashboardCompatibilityMode))
    109140        return 0;
    110141    String text = m_keyEvent->text();
    111     if (text.length() != 1)
    112         return 0;
    113     return text[0];
     142    return static_cast<int>(text.characterStartingAt(0));
    114143}
    115144
  • trunk/WebCore/dom/KeyboardEvent.h

    r25754 r28620  
    7171        const PlatformKeyboardEvent* keyEvent() const { return m_keyEvent; }
    7272
    73         int keyCode() const; // key code for keydown and keyup, character for other events
    74         int charCode() const;
     73        int keyCode() const; // key code for keydown and keyup, character for keypress
     74        int charCode() const; // character code for keypress, 0 for keydown and keyup
    7575   
    7676        virtual bool isKeyboardEvent() const;
  • trunk/WebCore/editing/Editor.cpp

    r28126 r28620  
    112112}
    113113
    114 void Editor::handleKeypress(KeyboardEvent* event)
     114void Editor::handleKeyboardEvent(KeyboardEvent* event)
    115115{
    116116    if (EditorClient* c = client())
    117117        if (selectionForEvent(m_frame, event).isContentEditable())
    118             c->handleKeypress(event);
    119 }
    120 
    121 void Editor::handleInputMethodKeypress(KeyboardEvent* event)
     118            c->handleKeyboardEvent(event);
     119}
     120
     121void Editor::handleInputMethodKeydown(KeyboardEvent* event)
    122122{
    123123    if (EditorClient* c = client())
    124124        if (selectionForEvent(m_frame, event).isContentEditable())
    125             c->handleInputMethodKeypress(event);
     125            c->handleInputMethodKeydown(event);
    126126}
    127127
     
    13271327}
    13281328
     1329bool Editor::isTextInsertionCommand(const AtomicString& command)
     1330{
     1331    return command == "InsertBacktab"
     1332        || command == "InsertTab"
     1333        || command == "InsertLineBreak"
     1334        || command == "InsertNewline";
     1335}
     1336
    13291337bool Editor::execCommand(const AtomicString& command, Event* triggeringEvent)
    13301338{
  • trunk/WebCore/editing/Editor.h

    r27874 r28620  
    7878    EditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
    7979
    80     void handleKeypress(KeyboardEvent*);
    81     void handleInputMethodKeypress(KeyboardEvent*);
     80    void handleKeyboardEvent(KeyboardEvent*);
     81    void handleInputMethodKeydown(KeyboardEvent*);
    8282
    8383    bool canEdit() const;
     
    157157
    158158    bool clientIsEditable() const;
    159    
     159
     160    static bool isTextInsertionCommand(const AtomicString&);
     161
    160162    bool execCommand(const AtomicString&, Event* triggeringEvent = 0);
    161163   
  • trunk/WebCore/html/HTMLButtonElement.cpp

    r27652 r28620  
    9292    }
    9393
    94     if (evt->type() == keypressEvent && evt->isKeyboardEvent()) {
    95         String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
    96 
    97         if (key == "Enter" || key == "U+0020") {
    98             dispatchSimulatedClick(evt);
     94    if (evt->isKeyboardEvent()) {
     95        if (evt->type() == keydownEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
     96            setActive(true, true);
     97            // No setDefaultHandled() - IE dispatches a keypress in this case.
     98            return;
     99        }
     100        if (evt->type() == keypressEvent) {
     101            switch (static_cast<KeyboardEvent*>(evt)->charCode()) {
     102                case '\r':
     103                    dispatchSimulatedClick(evt);
     104                    evt->setDefaultHandled();
     105                    return;
     106                case ' ':
     107                    // Prevent scrolling down the page.
     108                    evt->setDefaultHandled();
     109                    return;
     110                default:
     111                    break;
     112            }
     113        }
     114        if (evt->type() == keyupEvent && static_cast<KeyboardEvent*>(evt)->keyIdentifier() == "U+0020") {
     115            if (active())
     116                dispatchSimulatedClick(evt);
    99117            evt->setDefaultHandled();
    100118            return;
  • trunk/WebCore/html/HTMLInputElement.cpp

    r28212 r28620  
    11231123    }
    11241124
    1125     // Before calling the base class defaultEventHandler, which will call handleKeypress, call doTextFieldCommandFromEvent.
    1126     if (isTextField() && evt->type() == keypressEvent && evt->isKeyboardEvent() && focused() && document()->frame()
     1125    if (isTextField() && evt->type() == keydownEvent && evt->isKeyboardEvent() && focused() && document()->frame()
    11271126                && document()->frame()->doTextFieldCommandFromEvent(this, static_cast<KeyboardEvent*>(evt))) {
    11281127        evt->setDefaultHandled();
     
    11741173        bool clickElement = false;
    11751174
    1176         String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
    1177 
    1178         if (key == "U+0020") {
    1179             switch (inputType()) {
    1180                 case BUTTON:
    1181                 case CHECKBOX:
    1182                 case FILE:
    1183                 case IMAGE:
    1184                 case RESET:
    1185                 case SUBMIT:
    1186                     // Simulate mouse click for spacebar for these types of elements.
    1187                     // The AppKit already does this for some, but not all, of them.
    1188                     clickElement = true;
    1189                     break;
    1190                 case RADIO:
    1191                     // If an unselected radio is tabbed into (because the entire group has nothing
    1192                     // checked, or because of some explicit .focus() call), then allow space to check it.
    1193                     if (!checked())
    1194                         clickElement = true;
    1195                     break;
    1196                 case HIDDEN:
    1197                 case ISINDEX:
    1198                 case PASSWORD:
    1199                 case RANGE:
    1200                 case SEARCH:
    1201                 case TEXT:
    1202                     break;
    1203             }
    1204         }
    1205 
    1206         if (key == "Enter") {
     1175        int charCode = static_cast<KeyboardEvent*>(evt)->charCode();
     1176
     1177        if (charCode == '\r') {
    12071178            switch (inputType()) {
    12081179                case CHECKBOX:
     
    12261197                case RADIO:
    12271198                    break; // Don't do anything for enter on a radio button.
     1199            }
     1200        } else if (charCode == ' ') {
     1201            switch (inputType()) {
     1202                case BUTTON:
     1203                case CHECKBOX:
     1204                case FILE:
     1205                case IMAGE:
     1206                case RESET:
     1207                case SUBMIT:
     1208                case RADIO:
     1209                    // Prevent scrolling down the page.
     1210                    evt->setDefaultHandled();
     1211                    return;
     1212                default:
     1213                    break;
     1214            }
     1215        }
     1216
     1217        if (clickElement) {
     1218            dispatchSimulatedClick(evt);
     1219            evt->setDefaultHandled();
     1220            return;
     1221        }
     1222    }
     1223
     1224    if (evt->type() == keydownEvent && evt->isKeyboardEvent()) {
     1225        String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
     1226
     1227        if (key == "U+0020") {
     1228            switch (inputType()) {
     1229                case BUTTON:
     1230                case CHECKBOX:
     1231                case FILE:
     1232                case IMAGE:
     1233                case RESET:
     1234                case SUBMIT:
     1235                case RADIO:
     1236                    setActive(true, true);
     1237                    // No setDefaultHandled() - IE dispatches a keypress in this case.
     1238                    return;
     1239                default:
     1240                    break;
    12281241            }
    12291242        }
     
    12631276            }
    12641277        }
     1278    }
     1279
     1280    if (evt->type() == keyupEvent && evt->isKeyboardEvent()) {
     1281        bool clickElement = false;
     1282
     1283        String key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
     1284
     1285        if (key == "U+0020") {
     1286            switch (inputType()) {
     1287                case BUTTON:
     1288                case CHECKBOX:
     1289                case FILE:
     1290                case IMAGE:
     1291                case RESET:
     1292                case SUBMIT:
     1293                    // Simulate mouse click for spacebar for these types of elements.
     1294                    // The AppKit already does this for some, but not all, of them.
     1295                    clickElement = true;
     1296                    break;
     1297                case RADIO:
     1298                    // If an unselected radio is tabbed into (because the entire group has nothing
     1299                    // checked, or because of some explicit .focus() call), then allow space to check it.
     1300                    if (!checked())
     1301                        clickElement = true;
     1302                    break;
     1303                case HIDDEN:
     1304                case ISINDEX:
     1305                case PASSWORD:
     1306                case RANGE:
     1307                case SEARCH:
     1308                case TEXT:
     1309                    break;
     1310            }
     1311        }
    12651312
    12661313        if (clickElement) {
    1267             dispatchSimulatedClick(evt);
     1314            if (active())
     1315                dispatchSimulatedClick(evt);
    12681316            evt->setDefaultHandled();
    12691317            return;
  • trunk/WebCore/html/HTMLSelectElement.cpp

    r28524 r28620  
    620620    RenderMenuList* menuList = static_cast<RenderMenuList*>(renderer());
    621621
    622     // Use key press event here since sending simulated mouse events
    623     // on key down blocks the proper sending of the key press event.
    624     if (evt->type() == keypressEvent) {
     622    if (evt->type() == keydownEvent) {
    625623        if (!renderer() || !evt->isKeyboardEvent())
    626624            return;
     
    628626        bool handled = false;
    629627#if ARROW_KEYS_POP_MENU
    630         if (keyIdentifier == "Enter") {
    631             menuListOnChange();
    632             if (form())
    633                 form()->submitClick(evt);
    634             handled = true;
    635         }
    636         if (keyIdentifier == "Down" || keyIdentifier == "Up" || keyIdentifier == "U+0020") {
     628        if (keyIdentifier == "Down" || keyIdentifier == "Up") {
    637629            focus();
    638630            // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
     
    662654                setSelectedIndex(listToOptionIndex(listIndex));
    663655            handled = true;
    664         } else if (keyIdentifier == "Enter") {
     656        }
     657#endif
     658        if (handled)
     659            evt->setDefaultHandled();
     660    }
     661
     662    // Use key press event here since sending simulated mouse events
     663    // on key down blocks the proper sending of the key press event.
     664    if (evt->type() == keypressEvent) {
     665        if (!renderer() || !evt->isKeyboardEvent())
     666            return;
     667        int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
     668        bool handled = false;
     669#if ARROW_KEYS_POP_MENU
     670        if (keyCode == ' ') {
     671            focus();
     672            // Save the selection so it can be compared to the new selection when we call onChange during setSelectedIndex,
     673            // which gets called from RenderMenuList::valueChanged, which gets called after the user makes a selection from the menu.
     674            saveLastSelection();
     675            menuList->showPopup();
     676            handled = true;
     677        }
     678        if (keyCode == '\r') {
     679            menuListOnChange();
     680            if (form())
     681                form()->submitClick(evt);
     682            handled = true;
     683        }
     684#else
     685        int listIndex = optionToListIndex(selectedIndex());
     686        if (keyCode == '\r') {
    665687            // listIndex should already be selected, but this will fire the onchange handler.
    666688            setSelectedIndex(listToOptionIndex(listIndex), true, true);
     
    670692        if (handled)
    671693            evt->setDefaultHandled();
    672 
    673     }
     694    }
     695
    674696    if (evt->type() == mousedownEvent && evt->isMouseEvent() && static_cast<MouseEvent*>(evt)->button() == LeftButton) {
    675697        focus();
     
    751773        // This makes sure we fire onChange for a single click.  For drag selection, onChange will fire when the autoscroll timer stops.
    752774        listBoxOnChange();
    753     else if (evt->type() == keypressEvent) {
     775    else if (evt->type() == keydownEvent) {
    754776        if (!evt->isKeyboardEvent())
    755777            return;
    756778        String keyIdentifier = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
    757 
    758         if (keyIdentifier == "Enter") {
    759             if (form())
    760                 form()->submitClick(evt);
    761             evt->setDefaultHandled();
    762             return;
    763         }
    764779
    765780        int endIndex = 0;       
     
    799814            evt->setDefaultHandled();
    800815        }
     816    } else if (evt->type() == keypressEvent) {
     817        if (!evt->isKeyboardEvent())
     818            return;
     819        int keyCode = static_cast<KeyboardEvent*>(evt)->keyCode();
     820
     821        if (keyCode == '\r') {
     822            if (form())
     823                form()->submitClick(evt);
     824            evt->setDefaultHandled();
     825            return;
     826        }
    801827    }
    802828}
  • trunk/WebCore/page/EventHandler.cpp

    r28233 r28620  
    14651465}
    14661466
     1467static bool handleAccessKey(Document* document, const PlatformKeyboardEvent& evt)
     1468{
     1469#if PLATFORM(MAC)
     1470    if (evt.ctrlKey())
     1471#else
     1472    if (evt.altKey())
     1473#endif
     1474    {
     1475        String key = evt.unmodifiedText();
     1476        Element* elem = document->getElementByAccessKey(key.lower());
     1477        if (elem) {
     1478            elem->accessKeyAction(false);
     1479            return true;
     1480        }
     1481    }
     1482
     1483    return false;
     1484}
    14671485
    14681486bool EventHandler::keyEvent(const PlatformKeyboardEvent& initialKeyEvent)
     
    14701488    // Check for cases where we are too early for events -- possible unmatched key up
    14711489    // from pressing return in the location bar.
    1472     EventTargetNode* node = eventTargetNodeForDocument(m_frame->document());
     1490    RefPtr<EventTargetNode> node = eventTargetNodeForDocument(m_frame->document());
    14731491    if (!node)
    14741492        return false;
    1475        
    1476     if (initialKeyEvent.isKeyUp())
     1493
     1494    // FIXME: what is this doing here, in keyboard event handler?
     1495    m_frame->loader()->resetMultipleFormSubmissionProtection();
     1496
     1497    // In IE, access keys are special, they are handled after default keydown processing, but cannot be canceled - this is hard to match.
     1498    // On Windows, we process them before dispatching keypress event (and rely on WebKit to not drop WM_SYSCHAR events when a keydown representing WM_SYSKEYDOWN is canceled).
     1499    // On Mac OS X, we process them before dispatching keydown, as the default keydown handler implements Emacs key bindings, which may conflict with access keys.
     1500    // Other platforms currently match either Mac or Windows behavior, depending on whether they send combined KeyDown events.
     1501    bool matchedAnAccessKey = false;
     1502    if (initialKeyEvent.type() == PlatformKeyboardEvent::Char) {
     1503        if (handleAccessKey(m_frame->document(), initialKeyEvent))
     1504            return true;
     1505    } else if (initialKeyEvent.type() == PlatformKeyboardEvent::KeyDown)
     1506        matchedAnAccessKey = handleAccessKey(m_frame->document(), initialKeyEvent);
     1507
     1508    // FIXME: it would be fair to let an input method handle KeyUp events before DOM dispatch.
     1509    if (initialKeyEvent.type() == PlatformKeyboardEvent::KeyUp || initialKeyEvent.type() == PlatformKeyboardEvent::Char)
    14771510        return !node->dispatchKeyEvent(initialKeyEvent);
    1478        
    1479     m_frame->loader()->resetMultipleFormSubmissionProtection();
    1480    
    1481     // Prepare the keyPress in advance of the keyDown so we can fire the input method
    1482     // in advance of keyDown
    1483     PlatformKeyboardEvent keyPressEvent = initialKeyEvent;   
    1484     keyPressEvent.setIsAutoRepeat(true);
     1511
     1512    bool dashboardCompatibilityMode = false;
     1513    if (Settings* settings = node->document()->settings())
     1514        dashboardCompatibilityMode = settings->usesDashboardBackwardCompatibilityMode();
     1515
     1516    ExceptionCode ec;
     1517    PlatformKeyboardEvent keyDownEvent = initialKeyEvent;   
     1518    if (keyDownEvent.type() != PlatformKeyboardEvent::RawKeyDown)
     1519        keyDownEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown, dashboardCompatibilityMode);
     1520    RefPtr<KeyboardEvent> keydown = new KeyboardEvent(keyDownEvent, m_frame->document()->defaultView());
     1521    if (matchedAnAccessKey)
     1522        keydown->setDefaultPrevented(true);
     1523    keydown->setTarget(node);
     1524
     1525    if (initialKeyEvent.type() == PlatformKeyboardEvent::RawKeyDown) {
     1526        node->dispatchEvent(keydown, ec, true);
     1527        return keydown->defaultHandled() || keydown->defaultPrevented();
     1528    }
     1529
     1530    // Run input method in advance of DOM event handling.  This may result in the IM
     1531    // modifying the page prior the keydown event, but this behaviour is necessary
     1532    // in order to match IE:
     1533    // 1. preventing default handling of keydown and keypress events has no effect on IM input;
     1534    // 2. if an input method handles the event, its keyCode is set to 229 in keydown event.
     1535    m_frame->editor()->handleInputMethodKeydown(keydown.get());
     1536   
     1537    bool handledByInputMethod = keydown->defaultHandled();
     1538   
     1539    if (handledByInputMethod) {
     1540        keyDownEvent.setWindowsVirtualKeyCode(CompositionEventKeyCode);
     1541        keydown = new KeyboardEvent(keyDownEvent, m_frame->document()->defaultView());
     1542        keydown->setTarget(node);
     1543        keydown->setDefaultHandled();
     1544    }
     1545
     1546    node->dispatchEvent(keydown, ec, true);
     1547    bool keydownResult = keydown->defaultHandled() || keydown->defaultPrevented();
     1548    if (handledByInputMethod || (keydownResult && !dashboardCompatibilityMode) || initialKeyEvent.text().isEmpty())
     1549        return keydownResult;
     1550   
     1551    // Focus may have changed during keydown handling, so refetch node.
     1552    // But if we are dispatching a fake Dashboard compatibility keypress, then we pretend that the keypress happened on the original node.
     1553    if (!keydownResult) {
     1554        node = eventTargetNodeForDocument(m_frame->document());
     1555        if (!node)
     1556            return false;
     1557    }
     1558
     1559    PlatformKeyboardEvent keyPressEvent = initialKeyEvent;
     1560    keyPressEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::Char, dashboardCompatibilityMode);
    14851561    RefPtr<KeyboardEvent> keypress = new KeyboardEvent(keyPressEvent, m_frame->document()->defaultView());
    14861562    keypress->setTarget(node);
    1487    
    1488     // Run input method in advance of DOM event handling.  This may result in the IM
    1489     // modifying the page prior the keydown event, however this behaviour is necessary
    1490     // in order to match IE
    1491     m_frame->editor()->handleInputMethodKeypress(keypress.get());
    1492    
    1493     bool handledByInputMethod = keypress->defaultHandled();
    1494    
    1495     PlatformKeyboardEvent keyDownEvent = initialKeyEvent;
    1496    
    1497     if (handledByInputMethod)
    1498         keyDownEvent.setWindowsKeyCode(CompositionEventKeyCode);
    1499        
    1500     // We always send keyDown and keyPress for all events, including autorepeat keys
    1501     keyDownEvent.setIsAutoRepeat(false);
    1502    
    1503     bool result = !node->dispatchKeyEvent(keyDownEvent);
    1504    
    1505     // Focus may have change during the keyDown handling, so refetch node
    1506     node = eventTargetNodeForDocument(m_frame->document());
    1507     if (!node)
    1508         return result;
    1509    
    1510     if (keypress->defaultHandled())
    1511         return true;
    1512    
    1513     if (handledByInputMethod || initialKeyEvent.isModifierKeyPress())
    1514         return result;
    1515    
    1516     // If the default handling has been prevented on the keydown, we prevent it on
    1517     // the keypress as well
    1518     if (result)
    1519         keypress->setDefaultHandled();
    1520    
    1521     ExceptionCode ec;
     1563    if (keydownResult)
     1564        keypress->setDefaultPrevented(true);
    15221565    node->dispatchEvent(keypress, ec, true);
    1523    
    1524     return result || keypress->defaultHandled() || keypress->defaultPrevented();
     1566
     1567    return keydownResult || keypress->defaultPrevented() || keypress->defaultHandled();
    15251568}
    15261569
    15271570void EventHandler::defaultKeyboardEventHandler(KeyboardEvent* event)
    15281571{
    1529    if (event->type() == keypressEvent) {
    1530         m_frame->editor()->handleKeypress(event);
     1572   if (event->type() == keydownEvent) {
     1573        m_frame->editor()->handleKeyboardEvent(event);
    15311574        if (event->defaultHandled())
    15321575            return;
    15331576        if (event->keyIdentifier() == "U+0009")
    15341577            defaultTabEventHandler(event, false);
    1535     }
     1578   }
     1579   if (event->type() == keypressEvent) {
     1580        m_frame->editor()->handleKeyboardEvent(event);
     1581        if (event->defaultHandled())
     1582            return;
     1583   }
    15361584}
    15371585
     
    17251773    if (!m_frame)
    17261774        return false;
     1775#ifndef NDEBUG
     1776    // Platforms should differentiate real commands like selectAll from text input in disguise (like insertNewline),
     1777    // and avoid dispatching text input events from keydown default handlers.
     1778    if (underlyingEvent && underlyingEvent->isKeyboardEvent())
     1779        ASSERT(static_cast<KeyboardEvent*>(underlyingEvent)->type() == keypressEvent);
     1780#endif
    17271781    EventTarget* target;
    17281782    if (underlyingEvent)
     
    17631817{
    17641818    String data = event->data();
    1765     if (data == "\t") {
    1766         defaultTabEventHandler(event, event->isBackTab());
    1767         if (event->defaultHandled())
    1768             return;
    1769     }
    17701819    if (data == "\n") {
    17711820        if (event->isLineBreak()) {
  • trunk/WebCore/page/mac/EventHandlerMac.mm

    r24098 r28620  
    8888        return 0;
    8989    switch ([event type]) {
    90         case NSKeyDown:
     90        case NSKeyDown: {
     91            PlatformKeyboardEvent platformEvent(event);
     92            platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
     93            return new KeyboardEvent(platformEvent, m_frame->document() ? m_frame->document()->defaultView() : 0);
     94        }
    9195        case NSKeyUp:
    9296            return new KeyboardEvent(event, m_frame->document() ? m_frame->document()->defaultView() : 0);
  • trunk/WebCore/platform/PlatformKeyboardEvent.h

    r27459 r28620  
    6161    class PlatformKeyboardEvent {
    6262    public:
     63        enum Type {
     64            // KeyDown is sent by platforms such as Mac OS X, gtk and Qt, and has information about both physical pressed key, and its translation.
     65            // For DOM processing, it needs to be disambiguated as RawKeyDown or Char event.
     66            KeyDown,
     67
     68            // KeyUp is sent by all platforms.
     69            KeyUp,
     70
     71            // These events are sent by platforms such as Windows and wxWidgets. RawKeyDown only has information about a physical key, and Char
     72            // only has information about a character it was translated into.
     73            RawKeyDown,
     74            Char
     75        };
     76
     77        Type type() const { return m_type; }
     78        void disambiguateKeyDownEvent(Type, bool dashboardCompatibilityMode = false); // Only used on platforms that need it, i.e. those that generate KeyDown events.
     79
     80        // Text as as generated by processing a virtual key code with a keyboard layout
     81        // (in most cases, just a character code, but the layout can emit several
     82        // characters in a single keypress event on some platforms).
     83        // This may bear no resemblance to the ultimately inserted text if an input method
     84        // processes the input.
     85        // Will be null for KeyUp and RawKeyDown events.
    6386        String text() const { return m_text; }
     87
     88        // Text that would have been generated by the keyboard if no modifiers were pressed
     89        // (except for Shift); useful for shortcut (accelerator) key handling.
     90        // Otherwise, same as text().
    6491        String unmodifiedText() const { return m_unmodifiedText; }
     92
     93        // Most compatible Windows virtual key code associated with the event.
     94        // Zero for Char events.
     95        int windowsVirtualKeyCode() const { return m_windowsVirtualKeyCode; }
     96        void setWindowsVirtualKeyCode(int code) { m_windowsVirtualKeyCode = code; }
     97
    6598        String keyIdentifier() const { return m_keyIdentifier; }
    66         bool isKeyUp() const { return m_isKeyUp; }
    6799        bool isAutoRepeat() const { return m_autoRepeat; }
    68100        void setIsAutoRepeat(bool in) { m_autoRepeat = in; }
    69         int WindowsKeyCode() const { return m_WindowsKeyCode; }
    70         void setWindowsKeyCode(int code) { m_WindowsKeyCode = code; }
    71101        bool isKeypad() const { return m_isKeypad; }
    72102        bool shiftKey() const { return m_shiftKey; }
     
    74104        bool altKey() const { return m_altKey; }
    75105        bool metaKey() const { return m_metaKey; }
    76         bool isModifierKeyPress() const { return m_isModifierKeyPress; }
    77106
    78107        static bool currentCapsLockState();
    79108
    80109#if PLATFORM(MAC)
    81         PlatformKeyboardEvent(NSEvent*, bool forceAutoRepeat = false);
     110        PlatformKeyboardEvent(NSEvent*);
    82111        NSEvent* macEvent() const { return m_macEvent.get(); }
    83112#endif
    84113
    85114#if PLATFORM(WIN)
    86         PlatformKeyboardEvent(HWND, WPARAM, LPARAM, UChar, bool);
     115        PlatformKeyboardEvent(HWND, WPARAM, LPARAM, Type, bool);
    87116        bool isSystemKey() const { return m_isSystemKey; }
    88117#endif
     
    98127#if PLATFORM(WX)
    99128        PlatformKeyboardEvent(wxKeyEvent&);
    100         bool isWxCharEvent() const { return m_isWxCharEvent; }
    101129#endif
    102130
    103131    private:
     132        Type m_type;
    104133        String m_text;
    105134        String m_unmodifiedText;
    106135        String m_keyIdentifier;
    107         bool m_isKeyUp;
    108136        bool m_autoRepeat;
    109         int m_WindowsKeyCode;
     137        int m_windowsVirtualKeyCode;
    110138        bool m_isKeypad;
    111139        bool m_shiftKey;
     
    113141        bool m_altKey;
    114142        bool m_metaKey;
    115        
    116         // A control key event -- eg. keydown/up for shift, ctrl, alt, and meta -- needs
    117         // a flag to indicate that we should not generate a keyPress event.
    118         bool m_isModifierKeyPress;
    119 #if PLATFORM(WX)
    120         bool m_isWxCharEvent;
    121 #endif
     143
    122144#if PLATFORM(MAC)
    123145        RetainPtr<NSEvent> m_macEvent;
  • trunk/WebCore/platform/gtk/KeyEventGtk.cpp

    r27932 r28620  
    475475
    476476PlatformKeyboardEvent::PlatformKeyboardEvent(GdkEventKey* event)
    477     : m_text(singleCharacterString(event->keyval))
     477    : m_type((event->type == GDK_KEY_RELEASE) ? KeyUp : KeyDown)
     478    , m_text(singleCharacterString(event->keyval))
    478479    , m_unmodifiedText(singleCharacterString(event->keyval))
    479480    , m_keyIdentifier(keyIdentifierForGdkKeyCode(event->keyval))
    480     , m_isKeyUp(event->type == GDK_KEY_RELEASE)
    481481    , m_autoRepeat(false)
    482     , m_WindowsKeyCode(windowsKeyCodeForKeyEvent(event->keyval))
     482    , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event->keyval))
    483483    , m_isKeypad(false)
    484484    , m_shiftKey((event->state & GDK_SHIFT_MASK) || (event->keyval == GDK_3270_BackTab))
     
    486486    , m_altKey(event->state & GDK_MOD1_MASK)
    487487    , m_metaKey(event->state & GDK_MOD2_MASK)
    488     , m_isModifierKeyPress(false)
    489488{
     489}
     490
     491void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool)
     492{
     493    // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
     494    ASSERT(m_type == KeyDown);
     495    m_type = type;
     496
     497    if (type == RawKeyDown) {
     498        m_text = String();
     499        m_unmodifiedText = String();
     500    } else {
     501        m_keyIdentifier = String();
     502        m_windowsVirtualKeyCode = 0;
     503    }
    490504}
    491505
  • trunk/WebCore/platform/mac/KeyEventMac.mm

    r27372 r28620  
    394394}
    395395
    396 static int WindowsKeyCodeForKeyEvent(NSEvent* event)
     396static int windowsKeyCodeForKeyEvent(NSEvent* event)
    397397{
    398398    switch ([event keyCode]) {
     
    765765{
    766766    if ([event type] != NSFlagsChanged)
    767         return false;
     767        return [event type] == NSKeyUp;
     768    // FIXME: This logic fails if the user presses both Shift keys at once, for example:
     769    // we treat releasing one of them as keyDown.
    768770    switch ([event keyCode]) {
    769771        case 54: // Right Command
     
    806808    return [event charactersIgnoringModifiers];
    807809}
    808    
    809 PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event, bool forceAutoRepeat)
    810     : m_text(textFromEvent(event))
     810
     811PlatformKeyboardEvent::PlatformKeyboardEvent(NSEvent *event)
     812    : m_type(isKeyUpEvent(event) ? PlatformKeyboardEvent::KeyUp : PlatformKeyboardEvent::KeyDown)
     813    , m_text(textFromEvent(event))
    811814    , m_unmodifiedText(unmodifiedTextFromEvent(event))
    812815    , m_keyIdentifier(keyIdentifierForKeyEvent(event))
    813     , m_isKeyUp([event type] == NSKeyUp || isKeyUpEvent(event))
    814     , m_autoRepeat(([event type] != NSFlagsChanged) && (forceAutoRepeat || [event isARepeat]))
    815     , m_WindowsKeyCode(WindowsKeyCodeForKeyEvent(event))
     816    , m_autoRepeat(([event type] != NSFlagsChanged) && [event isARepeat])
     817    , m_windowsVirtualKeyCode(windowsKeyCodeForKeyEvent(event))
    816818    , m_isKeypad(isKeypadEvent(event))
    817819    , m_shiftKey([event modifierFlags] & NSShiftKeyMask)
     
    819821    , m_altKey([event modifierFlags] & NSAlternateKeyMask)
    820822    , m_metaKey([event modifierFlags] & NSCommandKeyMask)
    821     , m_isModifierKeyPress([event type] == NSFlagsChanged)
    822823    , m_macEvent(event)
    823824{
     825    // Always use 13 for Enter/Return -- we don't want to use AppKit's different character for Enter.
     826    if (m_windowsVirtualKeyCode == '\r') {
     827        m_text = "\r";
     828        m_unmodifiedText = "\r";
     829    }
     830
     831    // The adjustments below are only needed in Dashboard compatibility mode, but we cannot tell what mode we are in from here.
     832
    824833    // Turn 0x7F into 8, because backspace needs to always be 8.
    825834    if (m_text == "\x7F")
     
    828837        m_unmodifiedText = "\x8";
    829838    // Always use 9 for tab -- we don't want to use AppKit's different character for shift-tab.
    830     if (m_WindowsKeyCode == 9) {
     839    if (m_windowsVirtualKeyCode == 9) {
    831840        m_text = "\x9";
    832841        m_unmodifiedText = "\x9";
     
    834843}
    835844
     845void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool dashboardCompatibilityMode)
     846{
     847    // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
     848    ASSERT(m_type == KeyDown);
     849    ASSERT(type == RawKeyDown || type == Char);
     850    m_type = type;
     851    if (dashboardCompatibilityMode)
     852        return;
     853
     854    if (type == RawKeyDown) {
     855        m_text = String();
     856        m_unmodifiedText = String();
     857    } else {
     858        m_keyIdentifier = String();
     859        m_windowsVirtualKeyCode = 0;
     860    }
     861}
     862
    836863bool PlatformKeyboardEvent::currentCapsLockState()
    837864{
  • trunk/WebCore/platform/qt/PlatformKeyboardEventQt.cpp

    r27306 r28620  
    436436{
    437437    const int state = event->modifiers();
     438    m_type = (event->type() == QEvent::KeyRelease) ? KeyUp : KeyDown;
    438439    m_text = event->text();
    439440    m_unmodifiedText = event->text(); // FIXME: not correct
    440441    m_keyIdentifier = keyIdentifierForQtKeyCode(event->key());
    441     m_isKeyUp = (event->type() == QEvent::KeyRelease);
    442442    m_autoRepeat = event->isAutoRepeat();
    443443    m_ctrlKey = (state & Qt::ControlModifier) != 0;
    444444    m_altKey = (state & Qt::AltModifier) != 0;
    445445    m_metaKey = (state & Qt::MetaModifier) != 0;   
    446     m_WindowsKeyCode = windowsKeyCodeForKeyEvent(event->key());
     446    m_windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event->key());
    447447    m_isKeypad = (state & Qt::KeypadModifier) != 0;
    448448    m_shiftKey = (state & Qt::ShiftModifier) != 0 || event->key() == Qt::Key_Backtab; // Simulate Shift+Tab with Key_Backtab
     449}
     450
     451void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool)
     452{
     453    // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
     454    ASSERT(m_type == KeyDown);
     455    m_type = type;
     456
     457    if (type == RawKeyDown) {
     458        m_text = String();
     459        m_unmodifiedText = String();
     460    } else {
     461        m_keyIdentifier = String();
     462        m_windowsVirtualKeyCode = 0;
     463    }
    449464}
    450465
  • trunk/WebCore/platform/text/PlatformString.h

    r28234 r28620  
    7575    const UChar* charactersWithNullTermination();
    7676   
    77     UChar operator[](unsigned i) const; // if i >= length(), returns 0
     77    UChar operator[](unsigned i) const; // if i >= length(), returns 0   
     78    UChar32 characterStartingAt(unsigned) const; // Ditto.
    7879   
    7980    bool contains(UChar c) const { return find(c) != -1; }
  • trunk/WebCore/platform/text/String.cpp

    r28234 r28620  
    176176}
    177177
     178UChar32 String::characterStartingAt(unsigned i) const
     179{
     180    if (!m_impl || i >= m_impl->length())
     181        return 0;
     182    return m_impl->characterStartingAt(i);
     183}
    178184unsigned String::length() const
    179185{
  • trunk/WebCore/platform/text/StringImpl.cpp

    r28234 r28620  
    270270        len = m_length - pos;
    271271    return new StringImpl(m_data + pos, len);
     272}
     273
     274UChar32 StringImpl::characterStartingAt(unsigned i) const
     275{
     276    if (U16_IS_SINGLE(m_data[i]))
     277        return m_data[i];
     278    if (i + 1 < m_length && U16_IS_LEAD(m_data[i]) && U16_IS_TRAIL(m_data[i + 1]))
     279        return U16_GET_SUPPLEMENTARY(m_data[i], m_data[i + 1]);
     280    return 0;
    272281}
    273282
  • trunk/WebCore/platform/text/StringImpl.h

    r28234 r28620  
    9494
    9595    UChar operator[](int pos) const { return m_data[pos]; }
     96    UChar32 characterStartingAt(unsigned) const;
    9697
    9798    Length toLength() const;
  • trunk/WebCore/platform/win/KeyEventWin.cpp

    r27459 r28620  
    3333
    3434namespace WebCore {
    35 
    36 static const unsigned REPEAT_COUNT_MASK = 0x0000FFFF;
    37 static const unsigned NEW_RELEASE_STATE_MASK = 0x80000000;
    38 static const unsigned PREVIOUS_DOWN_STATE_MASK = 0x40000000;
    3935
    4036static const unsigned short HIGH_BIT_MASK_SHORT = 0x8000;
     
    149145static inline String singleCharacterString(UChar c) { return String(&c, 1); }
    150146
    151 PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM virtualKeyCode, LPARAM keyData, UChar characterCode, bool systemKey)
    152     : m_text(singleCharacterString(characterCode))
    153     , m_unmodifiedText(singleCharacterString(characterCode))
    154     , m_keyIdentifier(keyIdentifierForWindowsKeyCode(virtualKeyCode))
    155     , m_isKeyUp((keyData & NEW_RELEASE_STATE_MASK))
    156     , m_autoRepeat((keyData & REPEAT_COUNT_MASK) > 1)
    157     , m_WindowsKeyCode(virtualKeyCode)
     147PlatformKeyboardEvent::PlatformKeyboardEvent(HWND, WPARAM code, LPARAM keyData, Type type, bool systemKey)
     148    : m_type(type)
     149    , m_text((type == Char) ? singleCharacterString(code) : String())
     150    , m_unmodifiedText((type == Char) ? singleCharacterString(code) : String())
     151    , m_keyIdentifier((type == Char) ? String() : keyIdentifierForWindowsKeyCode(code))
     152    , m_autoRepeat(keyData & KF_REPEAT)
     153    , m_windowsVirtualKeyCode((type == RawKeyDown || type == KeyUp) ? code : 0)
    158154    , m_isKeypad(false) // FIXME: Need to implement this.
    159155    , m_shiftKey(GetKeyState(VK_SHIFT) & HIGH_BIT_MASK_SHORT)
     
    161157    , m_altKey(GetKeyState(VK_MENU) & HIGH_BIT_MASK_SHORT)
    162158    , m_metaKey(m_altKey)
    163     , m_isModifierKeyPress(virtualKeyCode == VK_SHIFT || virtualKeyCode == VK_CONTROL || virtualKeyCode == VK_MENU || virtualKeyCode == VK_CAPITAL)
    164159    , m_isSystemKey(systemKey)
    165160{
     161}
     162
     163void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type, bool)
     164{
     165    // No KeyDown events here to change.
     166    ASSERT_NOT_REACHED();
    166167}
    167168
  • trunk/WebCore/platform/wx/KeyboardEventWx.cpp

    r27466 r28620  
    326326PlatformKeyboardEvent::PlatformKeyboardEvent(wxKeyEvent& event)
    327327{
    328     m_text = wxString(event.GetUnicodeKey());
    329     m_unmodifiedText = m_text;
    330     m_keyIdentifier = keyIdentifierForWxKeyCode(event.GetKeyCode());
    331     m_isKeyUp = event.GetEventType() == wxEVT_KEY_UP;
     328    switch (event.GetEventType()) {
     329        case wxEVT_KEY_UP:
     330            m_type = KeyUp;
     331            break;
     332        case wxEVT_KEY_DOWN:
     333            m_type = KeyDown;
     334            break;
     335        case wxEVT_CHAR:
     336            m_type = Char;
     337            break;
     338        default:
     339            ASSERT_NOT_REACHED();
     340    }
     341    m_text = (type == Char) ? wxString(event.GetUnicodeKey()) : String();
     342    m_unmodifiedText = (type == Char) ? m_text : String();
     343    m_keyIdentifier = (type == Char) ? String() : keyIdentifierForWxKeyCode(event.GetKeyCode());
    332344    m_autoRepeat = false; // FIXME: not correct.
    333     m_WindowsKeyCode = windowsKeyCodeForKeyEvent(event.GetKeyCode());
     345    m_windowsVirtualKeyCode = windowsKeyCodeForKeyEvent(event.GetKeyCode());
    334346    m_isKeypad = (event.GetKeyCode() >= WXK_NUMPAD_SPACE) && (event.GetKeyCode() <= WXK_NUMPAD_DIVIDE);
    335347    m_shiftKey = event.ShiftDown();
     
    337349    m_altKey = event.AltDown();
    338350    m_metaKey = event.MetaDown();
    339     m_isModifierKeyPress = false;
    340     m_isWxCharEvent = event.GetEventType() == wxEVT_CHAR;
     351}
     352
     353void PlatformKeyboardEvent::disambiguateKeyDownEvent(Type type, bool)
     354{
     355    // Can only change type from KeyDown to RawKeyDown or Char, as we lack information for other conversions.
     356    ASSERT(m_type == KeyDown);
     357    m_type = type;
     358    if (type == RawKeyDown) {
     359        m_text = String();
     360        m_unmodifiedText = String();
     361    } else {
     362        m_keyIdentifier = String();
     363        m_windowsVirtualKeyCode = 0;
     364    }
    341365}
    342366
  • trunk/WebCore/svg/graphics/SVGImageEmptyClients.h

    r28399 r28620  
    323323    virtual void redo() { }
    324324
    325     virtual void handleKeypress(KeyboardEvent*) { }
    326     virtual void handleInputMethodKeypress(KeyboardEvent*) { }
     325    virtual void handleKeyboardEvent(KeyboardEvent*) { }
     326    virtual void handleInputMethodKeydown(KeyboardEvent*) { }
    327327
    328328    virtual void textFieldDidBeginEditing(Element*) { }
  • trunk/WebKit/gtk/ChangeLog

    r28564 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * WebCoreSupport/EditorClientGtk.cpp:
     12        (WebKit::EditorClient::handleKeyboardEvent):
     13        (WebKit::EditorClient::handleInputMethodKeydown):
     14        * WebCoreSupport/EditorClientGtk.h:
     15        Updated for cross-platform changes as much as it was possible without a gtk build environment.
     16
    1172007-12-08  Luca Bruno  <lethalman88@gmail.com>
    218
  • trunk/WebKit/gtk/WebCoreSupport/EditorClientGtk.cpp

    r28564 r28620  
    213213}
    214214
    215 void EditorClient::handleKeypress(KeyboardEvent* event)
     215void EditorClient::handleKeyboardEvent(KeyboardEvent* event)
    216216{
    217217    Frame* frame = core(m_page)->focusController()->focusedOrMainFrame();
     
    220220
    221221    const PlatformKeyboardEvent* kevent = event->keyEvent();
    222     if (!kevent || kevent->isKeyUp())
     222    if (!kevent || kevent->type() == PlatformKeyboardEvent::KeyUp)
    223223        return;
    224224
     
    231231
    232232    if (start->isContentEditable()) {
    233         switch(kevent->WindowsKeyCode()) {
     233        switch (kevent->windowsVirtualKeyCode()) {
    234234            case VK_BACK:
    235235                frame->editor()->deleteWithDirection(SelectionController::BACKWARD,
     
    305305                    frame->editor()->insertText(kevent->text(), event);
    306306                } else if (kevent->ctrlKey()) {
    307                     switch (kevent->WindowsKeyCode()) {
     307                    switch (kevent->windowsVirtualKeyCode()) {
    308308                        case VK_B:
    309309                            frame->editor()->execCommand("ToggleBold");
     
    324324        }
    325325    } else {
    326         switch (kevent->WindowsKeyCode()) {
     326        switch (kevent->windowsVirtualKeyCode()) {
    327327            case VK_UP:
    328328                frame->editor()->execCommand("MoveUp");
     
    353353
    354354
    355 void EditorClient::handleInputMethodKeypress(KeyboardEvent*)
     355void EditorClient::handleInputMethodKeydown(KeyboardEvent*)
    356356{
    357357    notImplemented();
  • trunk/WebKit/gtk/WebCoreSupport/EditorClientGtk.h

    r28273 r28620  
    8888        virtual void redo();
    8989
    90         virtual void handleKeypress(WebCore::KeyboardEvent*);
    91         virtual void handleInputMethodKeypress(WebCore::KeyboardEvent*);
     90        virtual void handleKeyboardEvent(WebCore::KeyboardEvent*);
     91        virtual void handleInputMethodKeydown(WebCore::KeyboardEvent*);
    9292
    9393        virtual void textFieldDidBeginEditing(WebCore::Element*);
  • trunk/WebKit/mac/ChangeLog

    r28597 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * WebCoreSupport/WebEditorClient.h:
     12        Renamed handleKeypress() to handleKeyboardEvent(), as it gets both keydowns and keypresses.
     13        Renamed handleInputMethodKeypress() to handleInputMethodKeydown().
     14        * WebCoreSupport/WebEditorClient.mm:
     15        (WebEditorClient::handleKeyboardEvent): This change makes sense only remotely, but it helped
     16        to get tests working. I guess Mac keyboard event handling needs further refactoring.
     17
     18        * WebView/WebHTMLView.mm:
     19        (selectorToCommandName): Convert AppKit editing selector name to Editor command name - extracted
     20        from callWebCoreCommand:.
     21        (_interceptEditingKeyEvent:shouldSaveCommand:): Insert text from keypress.
     22
     23        * WebView/WebPDFView.mm:
     24        (-[WebPDFView PDFViewWillClickOnLink:withURL:]):
     25        Convert incoming platform KeyDown into RawKeyDown, as this is what the view is interested in.
     26
    1272007-12-10  Brady Eidson  <beidson@apple.com>
    228
  • trunk/WebKit/mac/WebCoreSupport/WebEditorClient.h

    r25547 r28620  
    8888    virtual void redo();
    8989   
    90     virtual void handleKeypress(WebCore::KeyboardEvent*);
    91     virtual void handleInputMethodKeypress(WebCore::KeyboardEvent*);
     90    virtual void handleKeyboardEvent(WebCore::KeyboardEvent*);
     91    virtual void handleInputMethodKeydown(WebCore::KeyboardEvent*);
    9292
    9393    virtual void textFieldDidBeginEditing(WebCore::Element*);
  • trunk/WebKit/mac/WebCoreSupport/WebEditorClient.mm

    r27753 r28620  
    431431}
    432432
    433 void WebEditorClient::handleKeypress(KeyboardEvent* event)
     433void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
    434434{
    435435    Frame* frame = event->target()->toNode()->document()->frame();
     
    439439}
    440440
    441 void WebEditorClient::handleInputMethodKeypress(KeyboardEvent* event)
     441void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* event)
    442442{
    443443    Frame* frame = event->target()->toNode()->document()->frame();
  • trunk/WebKit/mac/WebView/WebHTMLView.mm

    r28585 r28620  
    20482048}
    20492049
    2050 - (void)callWebCoreCommand:(SEL)selector
    2051 {
    2052     if ([self callDelegateDoCommandBySelectorIfNeeded:selector])
    2053         return;
    2054 
    2055     Frame* coreFrame = core([self _frame]);
    2056     if (!coreFrame)
    2057         return;
    2058 
     2050static AtomicString selectorToCommandName(SEL selector)
     2051{
    20592052    // Capitalize the first letter of the selector, since we use capitalized command
    20602053    // names in the Editor object (why?). And remove the trailing colon.
     2054    // And change a few command names into ones supported by WebCore::Editor.
     2055
     2056    if (selector == @selector(insertParagraphSeparator:) || selector == @selector(insertNewlineIgnoringFieldEditor:))
     2057        return "InsertNewline";
     2058    if (selector == @selector(insertTabIgnoringFieldEditor:))
     2059        return "InsertTab";
     2060
    20612061    const char* selectorName = sel_getName(selector);
    20622062    size_t selectorNameLength = strlen(selectorName);
     
    20682068    commandName[selectorNameLength - 1] = 0;
    20692069
    2070     coreFrame->editor()->execCommand(commandName.data());
     2070    return AtomicString(commandName.data());
     2071}
     2072
     2073- (void)callWebCoreCommand:(SEL)selector
     2074{
     2075    if ([self callDelegateDoCommandBySelectorIfNeeded:selector])
     2076        return;
     2077
     2078    Frame* coreFrame = core([self _frame]);
     2079    if (!coreFrame)
     2080        return;
     2081
     2082    coreFrame->editor()->execCommand(selectorToCommandName(selector));
    20712083}
    20722084
     
    51865198    // We assume the IM will *not* consume hotkey sequences
    51875199    parameters.consumedByIM = !event->metaKey() && shouldSave;
    5188        
     5200
    51895201    if (const PlatformKeyboardEvent* platformEvent = event->keyEvent()) {
    51905202        NSEvent *macEvent = platformEvent->macEvent();
     
    52015213        bool hasKeypressCommand = !command.commandNames.isEmpty() || !command.text.isEmpty();
    52025214
     5215        // FIXME: interpretKeyEvents doesn't match application key equivalents (such as Cmd+A),
     5216        // and sends noop: for those. As a result, we don't handle those from within WebCore,
     5217        // but send a full sequence of DOM events, including an unneeded keypress.
    52035218        if (parameters.shouldSaveCommand || !hasKeypressCommand)
    52045219            [self interpretKeyEvents:[NSArray arrayWithObject:macEvent]];
    52055220        else {
    5206             if (!command.text.isEmpty())
    5207                 [self insertText:command.text];
    5208             else {
    5209                 size_t size = command.commandNames.size();
     5221            ASSERT(platformEvent->type() == PlatformKeyboardEvent::RawKeyDown);
     5222            size_t size = command.commandNames.size();
     5223            // Are there commands that would just cause text insertion if executed via Editor?
     5224            // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
     5225            // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
     5226            // (e.g. Tab that inserts a Tab character, or Enter).
     5227            bool haveTextInsertionCommands = false;
     5228            for (size_t i = 0; i < size; ++i) {
     5229                if (Editor::isTextInsertionCommand(selectorToCommandName(NSSelectorFromString(command.commandNames[i]))))
     5230                    haveTextInsertionCommands = true;
     5231            }
     5232            if (!haveTextInsertionCommands)
    52105233                for (size_t i = 0; i < size; ++i)
    52115234                    [self doCommandBySelector:NSSelectorFromString(command.commandNames[i])];
    5212             }
    52135235        }
    52145236        _private->interpretKeyEventsParameters = 0;
     
    55485570        Frame* coreFrame = core([self _frame]);
    55495571        if (![[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector] && coreFrame) {
    5550             if (selector == @selector(insertNewline:) || selector == @selector(insertParagraphSeparator:) || selector == @selector(insertNewlineIgnoringFieldEditor:))
    5551                 eventWasHandled = coreFrame->editor()->execCommand("InsertNewline", event);
    5552             else if (selector == @selector(insertLineBreak:))
    5553                 eventWasHandled = coreFrame->editor()->execCommand("InsertLineBreak", event);
    5554             else if (selector == @selector(insertTab:) || selector == @selector(insertTabIgnoringFieldEditor:))
    5555                 eventWasHandled = coreFrame->editor()->execCommand("InsertTab", event);
    5556             else if (selector == @selector(insertBacktab:))
    5557                 eventWasHandled = coreFrame->editor()->execCommand("InsertBacktab", event);
     5572            AtomicString commandName = selectorToCommandName(selector);
     5573            if (Editor::isTextInsertionCommand(commandName))
     5574                eventWasHandled = coreFrame->editor()->execCommand(commandName, event);
    55585575            else {
    55595576                _private->selectorForDoCommandBySelector = selector;
  • trunk/WebKit/mac/WebView/WebPDFView.mm

    r27718 r28620  
    948948        case NSKeyDown: {
    949949            PlatformKeyboardEvent pe(nsEvent);
     950            pe.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
    950951            event = new KeyboardEvent(keydownEvent, true, true, 0,
    951                 pe.keyIdentifier(), pe.WindowsKeyCode(),
     952                pe.keyIdentifier(), pe.windowsVirtualKeyCode(),
    952953                pe.ctrlKey(), pe.altKey(), pe.shiftKey(), pe.metaKey(), false);
    953954        }
  • trunk/WebKit/qt/ChangeLog

    r28550 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * WebCoreSupport/EditorClientQt.cpp:
     12        (WebCore::EditorClientQt::handleKeyboardEvent):
     13        (WebCore::EditorClientQt::handleInputMethodKeydown):
     14        * WebCoreSupport/EditorClientQt.h:
     15        Updated for cross-platform changes as much as it was possible without a Qt build environment.
     16
    1172007-12-07  Darin Adler  <darin@apple.com>
    218
  • trunk/WebKit/qt/WebCoreSupport/EditorClientQt.cpp

    r28230 r28620  
    326326}
    327327
    328 void EditorClientQt::handleKeypress(KeyboardEvent* event)
     328void EditorClientQt::handleKeyboardEvent(KeyboardEvent* event)
    329329{
    330330    Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame();
     
    333333
    334334    const PlatformKeyboardEvent* kevent = event->keyEvent();
    335     if (!kevent || kevent->isKeyUp())
     335    if (!kevent || kevent->type() == PlatformKeyboardEvent::KeyUp)
    336336        return;
    337337
     
    342342    // FIXME: refactor all of this to use Actions or something like them
    343343    if (start->isContentEditable()) {
    344         switch(kevent->WindowsKeyCode()) {
     344        switch (kevent->windowsVirtualKeyCode()) {
    345345            case VK_RETURN:
    346346                frame->editor()->execCommand("InsertLineBreak");
     
    386386                    frame->editor()->insertText(kevent->text(), event);
    387387                } else if (kevent->ctrlKey()) {
    388                     switch (kevent->WindowsKeyCode()) {
     388                    switch (kevent->windowsVirtualKeyCode()) {
    389389                        case VK_A:
    390390                            frame->editor()->execCommand("SelectAll");
     
    417417        }
    418418    } else {
    419         switch (kevent->WindowsKeyCode()) {
     419        switch (kevent->windowsVirtualKeyCode()) {
    420420            case VK_UP:
    421421                frame->editor()->execCommand("MoveUp");
     
    440440            default:
    441441                if (kevent->ctrlKey()) {
    442                     switch(kevent->WindowsKeyCode()) {
     442                    switch(kevent->windowsVirtualKeyCode()) {
    443443                        case VK_A:
    444444                            frame->editor()->execCommand("SelectAll");
     
    456456}
    457457
    458 void EditorClientQt::handleInputMethodKeypress(KeyboardEvent*)
     458void EditorClientQt::handleInputMethodKeydown(KeyboardEvent*)
    459459{
    460460}
  • trunk/WebKit/qt/WebCoreSupport/EditorClientQt.h

    r27780 r28620  
    8585    virtual void redo();
    8686
    87     virtual void handleKeypress(KeyboardEvent*);
    88     virtual void handleInputMethodKeypress(KeyboardEvent*);
     87    virtual void handleKeyboardEvent(KeyboardEvent*);
     88    virtual void handleInputMethodKeydown(KeyboardEvent*);
    8989
    9090    virtual void textFieldDidBeginEditing(Element*);
  • trunk/WebKit/win/ChangeLog

    r28608 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        Listen to WM_CHAR messages, and actually pass the type of message received down to WebCore.
     12        Since WM_KEYDOWN == keydown and WM_CHAR == keypress, this allows for much better IE compatibility
     13        than layering Windows keyboard event handling on top of Mac one.
     14
     15        * WebView.cpp:
     16        (WebView::keyUp): Do not special case Alt+F4 and Alt+Space - we don't get keyups for those anyway!
     17        (WebView::interpretKeyEvent): Renamed WindowsKeyCode() to windowsVirtualKeyCode().
     18        (WebView::handleEditingKeyboardEvent): Use the additional information about event type that
     19        we now pass with PlatformKeyboardEvent.
     20        (WebView::keyDown): (WebView::keyPress): Split WM_KEYDOWN and WM_CHAR handling in separate
     21        functions, pass them down as is, without trying to guess what WM_CHAR Windows would have sent
     22        for a given WM_KEYDOWN.
     23
     24        (WebViewWndProc): Handle WM_CHAR and WM_SYSCHAR.
     25
     26        * WebView.h: Removed inIMEKeyDown() - it doesn't look like we need it at all. At least, I didn't
     27        notice any regressions after removing the only call to it in WebEditorClient.
     28
     29        * WebEditorClient.cpp:
     30        (WebEditorClient::handleKeyboardEvent):
     31        (WebEditorClient::handleInputMethodKeydown):
     32        * WebEditorClient.h:
     33        Renamed handleKeypress() to handleKeyboardEvent(), as it gets both keydowns and keypresses.
     34        Renamed handleInputMethodKeypress() to handleInputMethodKeydown() and removed
     35        inIMEKeyDown()-related code.
     36
    1372007-12-10  Geoffrey Garen  <ggaren@apple.com>
    238
  • trunk/WebKit/win/WebEditorClient.cpp

    r27368 r28620  
    595595}
    596596
    597 void WebEditorClient::handleKeypress(KeyboardEvent* evt)
     597void WebEditorClient::handleKeyboardEvent(KeyboardEvent* evt)
    598598{
    599599    if (m_webView->handleEditingKeyboardEvent(evt))
     
    601601}
    602602
    603 void WebEditorClient::handleInputMethodKeypress(KeyboardEvent* evt)
    604 {
    605     if (m_webView->inIMEKeyDown())
    606         evt->setDefaultHandled();
     603void WebEditorClient::handleInputMethodKeydown(KeyboardEvent* )
     604{
    607605}
    608606
  • trunk/WebKit/win/WebEditorClient.h

    r25345 r28620  
    9595    virtual void textDidChangeInTextArea(WebCore::Element*);
    9696
    97     void handleKeypress(WebCore::KeyboardEvent*);
    98     void handleInputMethodKeypress(WebCore::KeyboardEvent*);
     97    void handleKeyboardEvent(WebCore::KeyboardEvent*);
     98    void handleInputMethodKeydown(WebCore::KeyboardEvent*);
    9999
    100100    virtual void ignoreWordInSpellDocument(const WebCore::String&);
  • trunk/WebKit/win/WebView.cpp

    r28505 r28620  
    12401240bool WebView::keyUp(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
    12411241{
    1242     PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, m_currentCharacterCode, systemKeyDown);
    1243 
    1244     // Don't send key events for alt+space and alt+f4.
    1245     if (keyEvent.altKey() && (virtualKeyCode == VK_SPACE || virtualKeyCode == VK_F4))
    1246         return false;
     1242    PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, PlatformKeyboardEvent::KeyUp, systemKeyDown);
    12471243
    12481244    Frame* frame = m_page->focusController()->focusedOrMainFrame();
     
    12571253
    12581254
    1259 struct KeyEntry {
     1255struct KeyDownEntry {
    12601256    unsigned virtualKey;
    12611257    unsigned modifiers;
     
    12631259};
    12641260
    1265 static const KeyEntry keyEntries[] = {
     1261struct KeyPressEntry {
     1262    unsigned charCode;
     1263    unsigned modifiers;
     1264    const char* name;
     1265};
     1266
     1267static const KeyDownEntry keyDownEntries[] = {
    12661268    { VK_LEFT,   0,                  "MoveLeft"                                    },
    12671269    { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
     
    13171319};
    13181320
     1321static const KeyPressEntry keyPressEntries[] = {
     1322    { '\t',   0,                  "InsertTab"                                   },
     1323    { '\t',   ShiftKey,           "InsertBacktab"                               },
     1324    { '\r',   0,                  "InsertNewline"                               },
     1325    { '\r',   CtrlKey,            "InsertNewline"                               },
     1326    { '\r',   AltKey,             "InsertNewline"                               },
     1327    { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
     1328};
     1329
    13191330const char* WebView::interpretKeyEvent(const KeyboardEvent* evt)
    13201331{
    1321     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
    1322     if (!keyEvent)
    1323         return "";
    1324 
    1325     static HashMap<int, const char*>* commandsMap = 0;
    1326 
    1327     if (!commandsMap) {
    1328         commandsMap = new HashMap<int, const char*>;
    1329 
    1330         for (unsigned i = 0; i < _countof(keyEntries); i++)
    1331             commandsMap->set(keyEntries[i].modifiers << 16 | keyEntries[i].virtualKey, keyEntries[i].name);
     1332    ASSERT(evt->type() == keydownEvent || evt->type() == keypressEvent);
     1333
     1334    static HashMap<int, const char*>* keyDownCommandsMap = 0;
     1335    static HashMap<int, const char*>* keyPressCommandsMap = 0;
     1336
     1337    if (!keyDownCommandsMap) {
     1338        keyDownCommandsMap = new HashMap<int, const char*>;
     1339        keyPressCommandsMap = new HashMap<int, const char*>;
     1340
     1341        for (unsigned i = 0; i < _countof(keyDownEntries); i++)
     1342            keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
     1343
     1344        for (unsigned i = 0; i < _countof(keyPressEntries); i++)
     1345            keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].virtualKey, keyPressEntries[i].name);
    13321346    }
    13331347
    13341348    unsigned modifiers = 0;
    1335     if (keyEvent->shiftKey())
     1349    if (evt->shiftKey())
    13361350        modifiers |= ShiftKey;
    1337     if (keyEvent->altKey())
     1351    if (evt->altKey())
    13381352        modifiers |= AltKey;
    1339     if (keyEvent->ctrlKey())
     1353    if (evt->ctrlKey())
    13401354        modifiers |= CtrlKey;
    13411355
    1342     return commandsMap->get(modifiers << 16 | keyEvent->WindowsKeyCode());
     1356    return evt->type() == keydownEvent ?
     1357        keyDownCommandsMap->get(modifiers << 16 | evt->keyCode()) :
     1358        keyPressCommandsMap->get(modifiers << 16 | evt->charCode());
    13431359}
    13441360
    13451361bool WebView::handleEditingKeyboardEvent(KeyboardEvent* evt)
    13461362{
    1347     String command(interpretKeyEvent(evt));
    1348 
    13491363    Node* node = evt->target()->toNode();
    13501364    ASSERT(node);
     
    13521366    ASSERT(frame);
    13531367
    1354     if (!command.isEmpty())
     1368    const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
     1369    if (!keyEvent || keyEvent->isSystemKey())  // do not treat this as text input if it's a system key event
     1370        return false;
     1371
     1372    if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
     1373        String command = interpretKeyEvent(evt);
     1374
     1375        // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
     1376        // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
     1377        // (e.g. Tab that inserts a Tab character, or Enter).
     1378        if (!command.isEmpty() && !Editor::isTextInsertionCommand(command))
     1379            if (frame->editor()->execCommand(command, evt))
     1380                return true;
     1381        return false;
     1382    }
     1383
     1384    String command = interpretKeyEvent(evt);
     1385     if (!command.isEmpty())
    13551386        if (frame->editor()->execCommand(command, evt))
    13561387            return true;
    13571388
    1358     if (!evt->keyEvent() || evt->keyEvent()->isSystemKey())  // do not treat this as text input if it's a system key event
     1389    // Don't insert null or control characters as they can result in unexpected behaviour
     1390    if (evt->charCode() < ' ')
    13591391        return false;
    1360 
    1361     if (evt->keyEvent()->text().length() == 1) {
    1362         UChar ch = evt->keyEvent()->text()[0];
    1363         // Don't insert null or control characters as they can reslt in unexpected behaviour
    1364         if (ch < ' ')
    1365             return false;
    1366     }
    13671392
    13681393    return frame->editor()->insertText(evt->keyEvent()->text(), evt);
     
    13751400        frame->eventHandler()->capsLockStateMayHaveChanged();
    13761401
    1377     // Don't send key events for alt+space and alt+f4, since the OS needs to handle that.
    1378     if (systemKeyDown && (virtualKeyCode == VK_SPACE || virtualKeyCode == VK_F4))
    1379         return false;
    1380 
    1381     MSG msg;
    1382     // If the next message is a WM_CHAR message, then take it out of the queue, and use
    1383     // the message parameters to get the character code to construct the PlatformKeyboardEvent.
    1384     if (systemKeyDown) {
    1385         if (::PeekMessage(&msg, m_viewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_NOREMOVE))     // don't remove sys key message from the windows message queue until we know we can handle it
    1386             m_currentCharacterCode = (UChar)msg.wParam;
    1387     } else if (::PeekMessage(&msg, m_viewWindow, WM_CHAR, WM_CHAR, PM_REMOVE))
    1388         m_currentCharacterCode = (UChar)msg.wParam;
    1389 
    1390     // FIXME: We need to check WM_UNICHAR to support supplementary characters.
    1391     // FIXME: We may need to handle other messages for international text.
    1392 
    1393     m_inIMEKeyDown = virtualKeyCode == VK_PROCESSKEY;
    1394     if (virtualKeyCode == VK_PROCESSKEY && !m_inIMEComposition)
    1395         virtualKeyCode = MapVirtualKey(LOBYTE(HIWORD(keyData)), 1);
    1396 
    1397     PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, m_currentCharacterCode, systemKeyDown);
     1402    PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, PlatformKeyboardEvent::RawKeyDown, systemKeyDown);
    13981403    bool handled = frame->eventHandler()->keyEvent(keyEvent);
    1399     m_inIMEKeyDown = false;
    1400     if (handled)
    1401         goto exit;
     1404
     1405    // These events cannot be canceled.
     1406    // FIXME: match IE list more closely, see <http://msdn2.microsoft.com/en-us/library/ms536938.aspx>.
     1407    if (systemKeyDown)
     1408        handled = false;
     1409
     1410    if (handled) {
     1411        // FIXME: remove WM_UNICHAR, too
     1412        MSG msg;
     1413        // WM_SYSCHAR events should not be removed, because access keys are implemented in WebCore in WM_SYSCHAR handler.
     1414        if (!systemKeyDown)
     1415            ::PeekMessage(&msg, m_viewWindow, WM_CHAR, WM_CHAR, PM_REMOVE);
     1416        return true;
     1417    }
    14021418
    14031419    // We need to handle back/forward using either Backspace(+Shift) or Ctrl+Left/Right Arrow keys.
    1404     int windowsKeyCode = keyEvent.WindowsKeyCode();
    1405     if ((windowsKeyCode == VK_BACK && keyEvent.shiftKey()) || (windowsKeyCode == VK_RIGHT && keyEvent.ctrlKey()))
     1420    if ((virtualKeyCode == VK_BACK && keyEvent.shiftKey()) || (virtualKeyCode == VK_RIGHT && keyEvent.ctrlKey()))
    14061421        m_page->goForward();
    1407     else if (windowsKeyCode == VK_BACK || (windowsKeyCode == VK_LEFT && keyEvent.ctrlKey()))
     1422    else if (virtualKeyCode == VK_BACK || (virtualKeyCode == VK_LEFT && keyEvent.ctrlKey()))
    14081423        m_page->goBack();
    14091424   
     
    14111426    ScrollDirection direction;
    14121427    ScrollGranularity granularity;
    1413     switch (windowsKeyCode) {
     1428    switch (virtualKeyCode) {
    14141429        case VK_LEFT:
    14151430            granularity = ScrollByLine;
     
    14511466            // We want to let Windows handle the WM_SYSCHAR event if we can't handle it
    14521467            // We do want to return true for regular key down case so the WM_CHAR handler won't pick up unhandled messages
    1453             return !systemKeyDown;
     1468            return false;
    14541469    }
    14551470
    14561471    if (!frame->eventHandler()->scrollOverflow(direction, granularity))
    14571472        frame->view()->scroll(direction, granularity);
    1458 
    1459 exit:
    1460     if (systemKeyDown)  // remove sys key message if we have handled it
    1461         ::PeekMessage(&msg, m_viewWindow, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE);
    1462 
    14631473    return true;
     1474}
     1475
     1476bool WebView::keyPress(WPARAM charCode, LPARAM keyData, bool systemKeyDown)
     1477{
     1478    Frame* frame = m_page->focusController()->focusedOrMainFrame();
     1479
     1480    PlatformKeyboardEvent keyEvent(m_viewWindow, charCode, keyData, PlatformKeyboardEvent::Char, systemKeyDown);
     1481    return frame->eventHandler()->keyEvent(keyEvent);
    14641482}
    14651483
     
    15771595            handled = webView->keyUp(wParam, lParam);
    15781596            break;
     1597        case WM_SYSCHAR:
     1598            handled = webView->keyPress(wParam, lParam, true);
     1599            break;
     1600        case WM_CHAR:
     1601            handled = webView->keyPress(wParam, lParam);
     1602            break;
     1603        // FIXME: We need to check WM_UNICHAR to support supplementary characters (that don't fit in 16 bits).
    15791604        case WM_SIZE:
    15801605            if (webView->isBeingDestroyed())
  • trunk/WebKit/win/WebView.h

    r28505 r28620  
    640640    bool keyDown(WPARAM, LPARAM, bool systemKeyDown = false);
    641641    bool keyUp(WPARAM, LPARAM, bool systemKeyDown = false);
     642    bool keyPress(WPARAM, LPARAM, bool systemKeyDown = false);
    642643    bool inResizer(LPARAM lParam);
    643644    void paint(HDC, LPARAM);
     
    666667    void selectionChanged();
    667668    void resetIME(WebCore::Frame*);
    668     bool inIMEKeyDown() const { return m_inIMEKeyDown; }
    669669    void setInputMethodState(bool);
    670670
     
    760760    bool m_hasCustomDropTarget;
    761761    unsigned m_inIMEComposition;
    762     bool m_inIMEKeyDown;
    763762    HWND m_toolTipHwnd;
    764763    WebCore::String m_toolTip;
  • trunk/WebKit/wx/ChangeLog

    r28518 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * WebKitSupport/EditorClientWx.cpp:
     12        (WebCore::EditorClientWx::handleInputMethodKeydown):
     13        (WebCore::EditorClientWx::handleKeyboardEvent):
     14        * WebKitSupport/EditorClientWx.h:
     15        Updated for cross-platform changes as much as it was possible without a wx build environment.
     16        The keyboard event model of wx is similar to Windows one, so further fixes can be modeled
     17        after the Windows port.
     18
    1192007-12-06  Kevin Ollivier  <kevino@theolliviers.com>
    220
  • trunk/WebKit/wx/WebKitSupport/EditorClientWx.cpp

    r27631 r28620  
    233233}
    234234
    235 void EditorClientWx::handleInputMethodKeypress(KeyboardEvent* event)
     235void EditorClientWx::handleInputMethodKeydown(KeyboardEvent* event)
    236236{
    237237// NOTE: we don't currently need to handle this. When key events occur,
    238 // both this method and handleKeypress get a chance at handling them.
     238// both this method and handleKeyboardEvent get a chance at handling them.
    239239// We might use this method later on for IME-specific handling.
    240240}
    241241
    242 void EditorClientWx::handleKeypress(KeyboardEvent* event)
     242void EditorClientWx::handleKeyboardEvent(KeyboardEvent* event)
    243243{
    244244    Frame* frame = m_page->focusController()->focusedOrMainFrame();
     
    247247
    248248    const PlatformKeyboardEvent* kevent = event->keyEvent();
    249     if (!kevent->isKeyUp()) {
     249    if (!kevent->type() == PlatformKeyboardEvent::KeyUp) {
    250250        Node* start = frame->selectionController()->start().node();
    251251        if (!start || !start->isContentEditable())
    252252            return;
    253253       
    254         if (kevent->isWxCharEvent() && !kevent->ctrlKey() && !kevent->altKey()) {
    255             switch(kevent->WindowsKeyCode()) {
     254        if (kevent->type() == PlatformKeyboardEvent::Char && !kevent->ctrlKey() && !kevent->altKey()) {
     255            switch (kevent->windowsVirtualKeyCode()) {
    256256                // we handled these on key down, ignore them for char events
    257257                case VK_BACK:
     
    270270        }
    271271       
    272         switch(kevent->WindowsKeyCode()) {
     272        switch (kevent->windowsVirtualKeyCode()) {
    273273            case VK_BACK:
    274274                frame->editor()->deleteWithDirection(SelectionController::BACKWARD,
  • trunk/WebKit/wx/WebKitSupport/EditorClientWx.h

    r27631 r28620  
    8181    virtual void redo();
    8282   
    83     virtual void handleKeypress(KeyboardEvent*);
    84     virtual void handleInputMethodKeypress(KeyboardEvent*);
     83    virtual void handleKeyboardEvent(KeyboardEvent*);
     84    virtual void handleInputMethodKeydown(KeyboardEvent*);
    8585   
    8686    virtual void textFieldDidBeginEditing(Element*);
  • trunk/WebKitTools/ChangeLog

    r28615 r28620  
     12007-12-07  Alexey Proskuryakov  <ap@webkit.org>
     2
     3        Reviewed by Darin.
     4
     5        <rdar://problem/5535636>
     6        Have to press 4 times instead of 2 times to get the expected result of ^^ with german keyboard.
     7
     8        http://bugs.webkit.org/show_bug.cgi?id=13916
     9        JavaScript detects Tab as a character input on a textfield validation
     10
     11        * DumpRenderTree/mac/EventSendingController.mm:
     12        (-[EventSendingController keyDown:withModifiers:]): Added a few more named keys.
     13        Dispatch a keyup to better match what happens when a key is physically pressed.
     14
     15        * DumpRenderTree/win/EventSender.cpp:
     16        (keyDownCallback): Ditto. Also make sure that WM_CHAR is consistently dispatched before
     17        returning from keyDown().
     18        (getConstantCallback): Fixed a couple copy/paste mistakes.
     19
    1202007-12-07  Kevin McCullough  <kmccullough@apple.com>
    221
  • trunk/WebKitTools/DumpRenderTree/mac/EventSendingController.mm

    r28124 r28620  
    351351{
    352352    NSString *eventCharacter = character;
    353     if ([character isEqualToString:@"rightArrow"]) {
    354         const unichar rightArrowCharacter = NSRightArrowFunctionKey;
    355         eventCharacter = [NSString stringWithCharacters:&rightArrowCharacter length:1];
     353    if ([character isEqualToString:@"leftArrow"]) {
     354        const unichar ch = NSLeftArrowFunctionKey;
     355        eventCharacter = [NSString stringWithCharacters:&ch length:1];
     356    } else if ([character isEqualToString:@"rightArrow"]) {
     357        const unichar ch = NSRightArrowFunctionKey;
     358        eventCharacter = [NSString stringWithCharacters:&ch length:1];
     359    } else if ([character isEqualToString:@"upArrow"]) {
     360        const unichar ch = NSUpArrowFunctionKey;
     361        eventCharacter = [NSString stringWithCharacters:&ch length:1];
     362    } else if ([character isEqualToString:@"downArrow"]) {
     363        const unichar ch = NSDownArrowFunctionKey;
     364        eventCharacter = [NSString stringWithCharacters:&ch length:1];
     365    } else if ([character isEqualToString:@"delete"]) {
     366        const unichar ch = 0x7f;
     367        eventCharacter = [NSString stringWithCharacters:&ch length:1];
    356368    }
    357369
     
    392404
    393405    [[[[mainFrame webView] window] firstResponder] keyDown:event];
     406
     407    event = [NSEvent keyEventWithType:NSKeyUp
     408                        location:NSMakePoint(5, 5)
     409                        modifierFlags:modifierFlags
     410                        timestamp:[self currentEventTime]
     411                        windowNumber:[[[mainFrame webView] window] windowNumber]
     412                        context:[NSGraphicsContext currentContext]
     413                        characters:eventCharacter
     414                        charactersIgnoringModifiers:charactersIgnoringModifiers
     415                        isARepeat:NO
     416                        keyCode:0];
     417
     418    [[[[mainFrame webView] window] firstResponder] keyUp:event];
    394419}
    395420
  • trunk/WebKitTools/DumpRenderTree/win/EventSender.cpp

    r28453 r28620  
    7171        return JSValueMakeNumber(context, WM_KEYUP);
    7272    if (JSStringIsEqualToUTF8CString(propertyName, "WM_CHAR"))
    73         return JSValueMakeNumber(context, WM_KEYDOWN);
     73        return JSValueMakeNumber(context, WM_CHAR);
    7474    if (JSStringIsEqualToUTF8CString(propertyName, "WM_DEADCHAR"))
    75         return JSValueMakeNumber(context, WM_CHAR);
     75        return JSValueMakeNumber(context, WM_DEADCHAR);
    7676    if (JSStringIsEqualToUTF8CString(propertyName, "WM_SYSKEYDOWN"))
    7777        return JSValueMakeNumber(context, WM_SYSKEYDOWN);
     
    293293    int charCode = 0;
    294294    bool needsShiftKeyModifier = false;
    295     if (JSStringIsEqualToUTF8CString(character, "rightArrow")) {
     295    if (JSStringIsEqualToUTF8CString(character, "leftArrow"))
     296        virtualKeyCode = VK_LEFT;
     297    else if (JSStringIsEqualToUTF8CString(character, "rightArrow"))
    296298        virtualKeyCode = VK_RIGHT;
    297     } else {
     299    else if (JSStringIsEqualToUTF8CString(character, "upArrow"))
     300        virtualKeyCode = VK_UP;
     301    else if (JSStringIsEqualToUTF8CString(character, "downArrow"))
     302        virtualKeyCode = VK_DOWN;
     303    else if (JSStringIsEqualToUTF8CString(character, "delete"))
     304        virtualKeyCode = VK_BACK;
     305    else {
    298306        charCode = JSStringGetCharactersPtr(character)[0];
    299307        virtualKeyCode = LOBYTE(VkKeyScan(charCode));
     
    344352        // ::Translate will not work, so we post an WM_CHAR event ourselves.
    345353        ::PostMessage(webViewWindow, WM_CHAR, charCode, 0);
     354    }
     355
     356    // Tests expect that all messages are processed by the time keyDown() returns.
     357    if (::PeekMessage(&msg, webViewWindow, WM_CHAR, WM_CHAR, PM_REMOVE))
    346358        ::DispatchMessage(&msg);
    347     }
     359
     360    MSG msgUp = makeMsg(webViewWindow, WM_KEYUP, virtualKeyCode, 0);
     361    ::DispatchMessage(&msgUp);
    348362
    349363    if (argumentCount > 1 || needsShiftKeyModifier)
     
    385399        msg.pt = lastMousePosition;
    386400
    387     dispatchMessage(&msg);
     401    ::DispatchMessage(&msg);
    388402
    389403    return JSValueMakeUndefined(context);
Note: See TracChangeset for help on using the changeset viewer.