mshtml: Added handling of right and left arrow keys in editing mode.
This commit is contained in:
parent
93c909a3ad
commit
bc71685676
|
@ -36,6 +36,11 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
||||
|
||||
#define DOM_VK_LEFT VK_LEFT
|
||||
#define DOM_VK_UP VK_UP
|
||||
#define DOM_VK_RIGHT VK_RIGHT
|
||||
#define DOM_VK_DOWN VK_DOWN
|
||||
|
||||
static const WCHAR wszFont[] = {'f','o','n','t',0};
|
||||
static const WCHAR wszSize[] = {'s','i','z','e',0};
|
||||
|
||||
|
@ -231,3 +236,202 @@ void set_font_size(HTMLDocument *This, LPCWSTR size)
|
|||
nsISelection_Release(nsselection);
|
||||
nsIDOMDocument_Release(nsdoc);
|
||||
}
|
||||
|
||||
static BOOL is_visible_text_node(nsIDOMNode *node)
|
||||
{
|
||||
nsIDOMCharacterData *char_data;
|
||||
nsAString data_str;
|
||||
LPCWSTR data, ptr;
|
||||
PRUint32 len;
|
||||
|
||||
nsIDOMNode_QueryInterface(node, &IID_nsIDOMCharacterData, (void**)&char_data);
|
||||
|
||||
nsIDOMCharacterData_GetLength(char_data, &len);
|
||||
|
||||
nsAString_Init(&data_str, NULL);
|
||||
nsIDOMCharacterData_GetData(char_data, &data_str);
|
||||
nsAString_GetData(&data_str, &data, NULL);
|
||||
|
||||
if(*data == '\n') {
|
||||
len--;
|
||||
for(ptr=data+1; ptr && isspaceW(*ptr); ptr++)
|
||||
len--;
|
||||
}
|
||||
|
||||
nsAString_Finish(&data_str);
|
||||
|
||||
nsIDOMCharacterData_Release(char_data);
|
||||
|
||||
return len != 0;
|
||||
}
|
||||
|
||||
static nsIDOMNode *get_child_text_node(nsIDOMNode *node, BOOL first)
|
||||
{
|
||||
nsIDOMNode *iter, *iter2;
|
||||
|
||||
if(first)
|
||||
nsIDOMNode_GetFirstChild(node, &iter);
|
||||
else
|
||||
nsIDOMNode_GetLastChild(node, &iter);
|
||||
|
||||
while(iter) {
|
||||
PRUint16 node_type;
|
||||
|
||||
nsIDOMNode_GetNodeType(iter, &node_type);
|
||||
switch(node_type) {
|
||||
case TEXT_NODE:
|
||||
if(is_visible_text_node(iter))
|
||||
return iter;
|
||||
case ELEMENT_NODE:
|
||||
iter2 = get_child_text_node(iter, first);
|
||||
if(iter2) {
|
||||
nsIDOMNode_Release(iter);
|
||||
return iter2;
|
||||
}
|
||||
}
|
||||
|
||||
if(first)
|
||||
nsIDOMNode_GetNextSibling(iter, &iter2);
|
||||
else
|
||||
nsIDOMNode_GetPreviousSibling(iter, &iter2);
|
||||
|
||||
nsIDOMNode_Release(iter);
|
||||
iter = iter2;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static nsIDOMNode *get_next_text_node(nsIDOMNode *node, BOOL next)
|
||||
{
|
||||
nsIDOMNode *iter, *iter2 = NULL, *parent = NULL;
|
||||
PRUint16 node_type;
|
||||
|
||||
iter = node;
|
||||
nsIDOMNode_AddRef(iter);
|
||||
|
||||
while(1) {
|
||||
if(next)
|
||||
nsIDOMNode_GetNextSibling(iter, &iter2);
|
||||
else
|
||||
nsIDOMNode_GetPreviousSibling(iter, &iter2);
|
||||
|
||||
while(!iter2) {
|
||||
nsIDOMNode_GetParentNode(iter, &parent);
|
||||
nsIDOMNode_Release(iter);
|
||||
if(!parent)
|
||||
return NULL;
|
||||
|
||||
iter = parent;
|
||||
|
||||
if(next)
|
||||
nsIDOMNode_GetNextSibling(iter, &iter2);
|
||||
else
|
||||
nsIDOMNode_GetPreviousSibling(iter, &iter2);
|
||||
}
|
||||
|
||||
nsIDOMNode_Release(iter);
|
||||
iter = iter2;
|
||||
|
||||
nsIDOMNode_GetNodeType(iter, &node_type);
|
||||
|
||||
switch(node_type) {
|
||||
case TEXT_NODE:
|
||||
if(is_visible_text_node(iter))
|
||||
return iter;
|
||||
case ELEMENT_NODE:
|
||||
iter2 = get_child_text_node(iter, next);
|
||||
if(iter2) {
|
||||
nsIDOMNode_Release(iter);
|
||||
return iter2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void collapse_end_node(nsISelection *selection, nsIDOMNode *node)
|
||||
{
|
||||
nsIDOMCharacterData *char_data;
|
||||
PRUint32 len;
|
||||
|
||||
nsIDOMNode_QueryInterface(node, &IID_nsIDOMCharacterData, (void**)&char_data);
|
||||
nsIDOMCharacterData_GetLength(char_data, &len);
|
||||
nsIDOMCharacterData_Release(char_data);
|
||||
|
||||
nsISelection_Collapse(selection, node, len);
|
||||
}
|
||||
|
||||
static void collapse_next_char(HTMLDocument *doc, nsIDOMKeyEvent *event, BOOL next)
|
||||
{
|
||||
nsISelection *selection = get_ns_selection(doc);
|
||||
nsIDOMNode *node;
|
||||
PRBool collapsed, b;
|
||||
PRUint16 node_type;
|
||||
nsIDOMNode *text_node;
|
||||
|
||||
nsIDOMKeyEvent_GetCtrlKey(event, &b);
|
||||
if(b) return;
|
||||
|
||||
nsIDOMKeyEvent_GetShiftKey(event, &b);
|
||||
if(b) return;
|
||||
|
||||
nsISelection_GetIsCollapsed(selection, &collapsed);
|
||||
if(!collapsed)
|
||||
nsISelection_CollapseToEnd(selection);
|
||||
|
||||
nsISelection_GetFocusNode(selection, &node);
|
||||
nsIDOMNode_GetNodeType(node, &node_type);
|
||||
|
||||
if(node_type == TEXT_NODE) {
|
||||
nsIDOMCharacterData *char_data;
|
||||
PRInt32 offset;
|
||||
PRUint32 len;
|
||||
|
||||
nsISelection_GetFocusOffset(selection, &offset);
|
||||
|
||||
nsIDOMNode_QueryInterface(node, &IID_nsIDOMCharacterData, (void**)&char_data);
|
||||
nsIDOMCharacterData_GetLength(char_data, &len);
|
||||
nsIDOMCharacterData_Release(char_data);
|
||||
|
||||
if(next ? offset != len : offset) {
|
||||
nsISelection_Collapse(selection, node, offset + (next?1:-1));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
text_node = get_next_text_node(node, next);
|
||||
if(text_node) {
|
||||
if(next)
|
||||
nsISelection_Collapse(selection, text_node, 1);
|
||||
else
|
||||
collapse_end_node(selection, text_node);
|
||||
nsIDOMNode_Release(text_node);
|
||||
}
|
||||
|
||||
nsIDOMNode_Release(node);
|
||||
nsISelection_Release(selection);
|
||||
}
|
||||
|
||||
void handle_edit_event(HTMLDocument *This, nsIDOMEvent *event)
|
||||
{
|
||||
nsIDOMKeyEvent *key_event;
|
||||
PRUint32 code;
|
||||
|
||||
nsIDOMEvent_QueryInterface(event, &IID_nsIDOMKeyEvent, (void**)&key_event);
|
||||
|
||||
nsIDOMKeyEvent_GetKeyCode(key_event, &code);
|
||||
|
||||
switch(code) {
|
||||
case DOM_VK_LEFT:
|
||||
TRACE("left");
|
||||
collapse_next_char(This, key_event, FALSE);
|
||||
break;
|
||||
case DOM_VK_RIGHT:
|
||||
TRACE("right\n");
|
||||
collapse_next_char(This, key_event, TRUE);
|
||||
};
|
||||
|
||||
nsIDOMKeyEvent_Release(key_event);
|
||||
}
|
||||
|
|
|
@ -117,6 +117,7 @@ struct NSContainer {
|
|||
const nsIInterfaceRequestorVtbl *lpInterfaceRequestorVtbl;
|
||||
const nsIWeakReferenceVtbl *lpWeakReferenceVtbl;
|
||||
const nsISupportsWeakReferenceVtbl *lpSupportsWeakReferenceVtbl;
|
||||
const nsIDOMEventListenerVtbl *lpDOMEventListenerVtbl;
|
||||
|
||||
nsIWebBrowser *webbrowser;
|
||||
nsIWebNavigation *navigation;
|
||||
|
@ -253,6 +254,7 @@ typedef struct {
|
|||
#define NSEMBWNDS(x) ((nsIEmbeddingSiteWindow*) &(x)->lpEmbeddingSiteWindowVtbl)
|
||||
#define NSIFACEREQ(x) ((nsIInterfaceRequestor*) &(x)->lpInterfaceRequestorVtbl)
|
||||
#define NSTOOLTIP(x) ((nsITooltipListener*) &(x)->lpTooltipListenerVtbl)
|
||||
#define NSEVENTLIST(x) ((nsIDOMEventListener*) &(x)->lpDOMEventListenerVtbl)
|
||||
#define NSWEAKREF(x) ((nsIWeakReference*) &(x)->lpWeakReferenceVtbl)
|
||||
#define NSSUPWEAKREF(x) ((nsISupportsWeakReference*) &(x)->lpSupportsWeakReferenceVtbl)
|
||||
|
||||
|
@ -351,6 +353,8 @@ void release_nodes(HTMLDocument*);
|
|||
void install_wine_gecko(void);
|
||||
|
||||
/* editor */
|
||||
void handle_edit_event(HTMLDocument*,nsIDOMEvent*);
|
||||
|
||||
void get_font_size(HTMLDocument*,WCHAR*);
|
||||
void set_font_size(HTMLDocument*,LPCWSTR);
|
||||
|
||||
|
|
|
@ -640,6 +640,9 @@ static nsresult NSAPI nsWebBrowserChrome_QueryInterface(nsIWebBrowserChrome *ifa
|
|||
}else if(IsEqualGUID(&IID_nsITooltipListener, riid)) {
|
||||
TRACE("(%p)->(IID_nsITooltipListener %p)\n", This, result);
|
||||
*result = NSTOOLTIP(This);
|
||||
}else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
|
||||
TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
|
||||
*result = NSEVENTLIST(This);
|
||||
}else if(IsEqualGUID(&IID_nsIInterfaceRequestor, riid)) {
|
||||
TRACE("(%p)->(IID_nsIInterfaceRequestor %p)\n", This, result);
|
||||
*result = NSIFACEREQ(This);
|
||||
|
@ -1227,6 +1230,48 @@ static const nsITooltipListenerVtbl nsTooltipListenerVtbl = {
|
|||
nsTooltipListener_OnHideTooltip
|
||||
};
|
||||
|
||||
#define NSEVENTLIST_THIS(iface) DEFINE_THIS(NSContainer, DOMEventListener, iface)
|
||||
|
||||
static nsresult NSAPI nsDOMEventListener_QueryInterface(nsIDOMEventListener *iface,
|
||||
nsIIDRef riid, nsQIResult result)
|
||||
{
|
||||
NSContainer *This = NSEVENTLIST_THIS(iface);
|
||||
return nsIWebBrowserChrome_QueryInterface(NSWBCHROME(This), riid, result);
|
||||
}
|
||||
|
||||
static nsrefcnt NSAPI nsDOMEventListener_AddRef(nsIDOMEventListener *iface)
|
||||
{
|
||||
NSContainer *This = NSEVENTLIST_THIS(iface);
|
||||
return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
|
||||
}
|
||||
|
||||
static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface)
|
||||
{
|
||||
NSContainer *This = NSEVENTLIST_THIS(iface);
|
||||
return nsIWebBrowserChrome_Release(NSWBCHROME(This));
|
||||
}
|
||||
|
||||
static nsresult NSAPI nsDOMEventListener_HandleEvent(nsIDOMEventListener *iface, nsIDOMEvent *event)
|
||||
{
|
||||
NSContainer *This = NSEVENTLIST_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, event);
|
||||
|
||||
if(This->doc->usermode == EDITMODE)
|
||||
handle_edit_event(This->doc, event);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#undef NSEVENTLIST_THIS
|
||||
|
||||
static const nsIDOMEventListenerVtbl nsDOMEventListenerVtbl = {
|
||||
nsDOMEventListener_QueryInterface,
|
||||
nsDOMEventListener_AddRef,
|
||||
nsDOMEventListener_Release,
|
||||
nsDOMEventListener_HandleEvent
|
||||
};
|
||||
|
||||
#define NSIFACEREQ_THIS(iface) DEFINE_THIS(NSContainer, InterfaceRequestor, iface)
|
||||
|
||||
static nsresult NSAPI nsInterfaceRequestor_QueryInterface(nsIInterfaceRequestor *iface,
|
||||
|
@ -1352,6 +1397,7 @@ const nsISupportsWeakReferenceVtbl nsSupportsWeakReferenceVtbl = {
|
|||
|
||||
NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
|
||||
{
|
||||
nsIDOMWindow *dom_window;
|
||||
nsIWebBrowserSetup *wbsetup;
|
||||
NSContainer *ret;
|
||||
nsresult nsres;
|
||||
|
@ -1369,7 +1415,7 @@ NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
|
|||
ret->lpInterfaceRequestorVtbl = &nsInterfaceRequestorVtbl;
|
||||
ret->lpWeakReferenceVtbl = &nsWeakReferenceVtbl;
|
||||
ret->lpSupportsWeakReferenceVtbl = &nsSupportsWeakReferenceVtbl;
|
||||
|
||||
ret->lpDOMEventListenerVtbl = &nsDOMEventListenerVtbl;
|
||||
|
||||
ret->doc = doc;
|
||||
ret->ref = 1;
|
||||
|
@ -1438,6 +1484,28 @@ NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
|
|||
if(NS_FAILED(nsres))
|
||||
ERR("SetParentURIContentListener failed: %08x\n", nsres);
|
||||
|
||||
nsres = nsIWebBrowser_GetContentDOMWindow(ret->webbrowser, &dom_window);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
nsIDOMEventTarget *target;
|
||||
nsres = nsIDOMWindow_QueryInterface(dom_window, &IID_nsIDOMEventTarget, (void**)&target);
|
||||
nsIDOMWindow_Release(dom_window);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
nsAString keypress_str;
|
||||
static const PRUnichar wsz_keypress[] = {'k','e','y','p','r','e','s','s',0};
|
||||
nsAString_Init(&keypress_str, wsz_keypress);
|
||||
nsres = nsIDOMEventTarget_AddEventListener(target, &keypress_str, NSEVENTLIST(ret), TRUE);
|
||||
nsAString_Finish(&keypress_str);
|
||||
nsIDOMEventTarget_Release(target);
|
||||
if(NS_FAILED(nsres))
|
||||
ERR("AddEventTarget failed: %08x\n", nsres);
|
||||
}else {
|
||||
ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
|
||||
}
|
||||
}else {
|
||||
ERR("GetContentDOMWindow failed: %08x\n", nsres);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ interface nsIWebBrowserChrome;
|
|||
interface nsILoadGroup;
|
||||
interface nsIDOMNode;
|
||||
interface nsIDOMDocument;
|
||||
interface nsIDOMEvent;
|
||||
|
||||
interface IMoniker;
|
||||
|
||||
|
@ -86,7 +87,6 @@ typedef nsISupports nsISHistory;
|
|||
typedef nsISupports nsISimpleEnumerator;
|
||||
typedef nsISupports nsIWidget;
|
||||
typedef nsISupports nsIProtocolHandler;
|
||||
typedef nsISupports nsIDOMEventTarget;
|
||||
typedef nsISupports nsIDOMAbstractView;
|
||||
typedef nsISupports nsIHttpHeaderVisitor;
|
||||
typedef nsISupports nsIDOMBarProp;
|
||||
|
@ -1045,6 +1045,26 @@ interface nsIWebBrowserChrome : nsISupports
|
|||
nsresult ExitModalEventLoop(nsresult aStatus);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(df31c120-ded6-11d1-bd85-00805f8ae3f4)
|
||||
]
|
||||
interface nsIDOMEventListener : nsISupports
|
||||
{
|
||||
nsresult HandleEvent(nsIDOMEvent *event);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(1c773b30-d1cf-11d2-bd95-00805f8ae3f4)
|
||||
]
|
||||
interface nsIDOMEventTarget : nsISupports
|
||||
{
|
||||
nsresult AddEventListener(const nsAString *type, nsIDOMEventListener *listener, PRBool useCapture);
|
||||
nsresult RemoveEventListener(const nsAString *type, nsIDOMEventListener *listener, PRBool useCapture);
|
||||
nsresult DispatchEvent(nsIDOMEvent *evt, PRBool *_retval);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(a66b7b80-ff46-bd97-0080-5f8ae38add32)
|
||||
|
@ -1115,6 +1135,24 @@ interface nsIDOMMouseEvent : nsIDOMUIEvent
|
|||
nsIDOMEventTarget *relatedTargetArg);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(028e0e6e-8b01-11d3-aae7-0010838a3123)
|
||||
]
|
||||
interface nsIDOMKeyEvent : nsIDOMUIEvent
|
||||
{
|
||||
nsresult GetCharCode(PRUint32 *aCharCode);
|
||||
nsresult GetKeyCode(PRUint32 *aKeyCode);
|
||||
nsresult GetAltKey(PRBool *aAltKey);
|
||||
nsresult GetCtrlKey(PRBool *aCtrlKey);
|
||||
nsresult GetShiftKey(PRBool *aShiftKey);
|
||||
nsresult GetMetaKey(PRBool *aMetaKey);
|
||||
nsresult InitKeyEvent(const nsAString *typeArg, PRBool canBubbleArg,
|
||||
PRBool cancelableArg, nsIDOMAbstractView *viewArg, PRBool ctrlKeyArg,
|
||||
PRBool altKeyArg, PRBool shiftKeyArg, PRBool metaKeyArg, PRUint32 keyCodeArg,
|
||||
PRUint32 charCodeArg);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(3e5432cd-9568-4bd1-8cbe-d50aba110743)
|
||||
|
|
Loading…
Reference in New Issue