Rolls behavior from incubator's HyperlinkOverride into Hyperlink. Now Hyperlink
will let the default browser action happen in some cases, eg Ctrl-clicking on a
link. Particular behavior is specific per browser.
patch by: ajr
review by: rjrjr
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@4225 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/Hyperlink.gwt.xml b/user/src/com/google/gwt/user/Hyperlink.gwt.xml
new file mode 100644
index 0000000..e667c13
--- /dev/null
+++ b/user/src/com/google/gwt/user/Hyperlink.gwt.xml
@@ -0,0 +1,19 @@
+<module>
+ <inherits name="com.google.gwt.core.Core"/>
+ <inherits name="com.google.gwt.user.UserAgent"/>
+
+ <replace-with class="com.google.gwt.user.client.ui.impl.HyperlinkImplOpera">
+ <when-type-is class="com.google.gwt.user.client.ui.impl.HyperlinkImpl"/>
+ <when-property-is name="user.agent" value="opera"/>
+ </replace-with>
+
+ <replace-with class="com.google.gwt.user.client.ui.impl.HyperlinkImplSafari">
+ <when-type-is class="com.google.gwt.user.client.ui.impl.HyperlinkImpl"/>
+ <when-property-is name="user.agent" value="safari"/>
+ </replace-with>
+
+ <replace-with class="com.google.gwt.user.client.ui.impl.HyperlinkImplIE">
+ <when-type-is class="com.google.gwt.user.client.ui.impl.HyperlinkImpl"/>
+ <when-property-is name="user.agent" value="ie6"/>
+ </replace-with>
+</module>
diff --git a/user/src/com/google/gwt/user/User.gwt.xml b/user/src/com/google/gwt/user/User.gwt.xml
index 3010bef..17de395 100644
--- a/user/src/com/google/gwt/user/User.gwt.xml
+++ b/user/src/com/google/gwt/user/User.gwt.xml
@@ -39,6 +39,7 @@
<inherits name="com.google.gwt.user.CaptionPanel" />
<inherits name="com.google.gwt.user.Window" />
<inherits name="com.google.gwt.user.Tree"/>
+ <inherits name="com.google.gwt.user.Hyperlink"/>
<super-source path="translatable"/>
<source path="client"/>
diff --git a/user/src/com/google/gwt/user/client/ui/Hyperlink.java b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
index 981ed9e..789f855 100644
--- a/user/src/com/google/gwt/user/client/ui/Hyperlink.java
+++ b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.user.client.ui;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
@@ -23,6 +24,7 @@
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.History;
+import com.google.gwt.user.client.ui.impl.HyperlinkImpl;
/**
* A widget that serves as an "internal" hyperlink. That is, it is a link to
@@ -52,6 +54,8 @@
public class Hyperlink extends Widget implements HasHTML, SourcesClickEvents,
HasClickHandlers {
+ private static HyperlinkImpl impl = GWT.create(HyperlinkImpl.class);
+
private Element anchorElem;
private String targetHistoryToken;
@@ -126,8 +130,11 @@
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONCLICK) {
super.onBrowserEvent(event);
- History.newItem(targetHistoryToken);
- DOM.eventPreventDefault(event);
+
+ if (impl.handleAsClick(event)) {
+ History.newItem(getTargetHistoryToken());
+ DOM.eventPreventDefault(event);
+ }
}
}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImpl.java b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImpl.java
new file mode 100644
index 0000000..884042e
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImpl.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.user.client.ui.impl;
+
+import com.google.gwt.user.client.Event;
+
+/**
+ * Methods that need browser-specific implementations for Hyperlink.
+ * By default, we're very conservative and let the browser handle any clicks
+ * with non-left buttons or with modifier keys. This happens to be the correct
+ * behavior for Firefox.
+ */
+public class HyperlinkImpl {
+
+ /**
+ * Default version, useful for Firefox. Don't fire if it's a rightclick,
+ * middleclick, or if any modifiers are held down.
+ */
+ public boolean handleAsClick(Event event) {
+ int mouseButtons = event.getButton();
+ boolean alt = event.getAltKey();
+ boolean ctrl = event.getCtrlKey();
+ boolean meta = event.getMetaKey();
+ boolean shift = event.getShiftKey();
+ boolean modifiers = alt || ctrl || meta || shift;
+ boolean middle = mouseButtons == Event.BUTTON_MIDDLE;
+ boolean right = mouseButtons == Event.BUTTON_RIGHT;
+
+ return !modifiers && !middle && !right;
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplIE.java b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplIE.java
new file mode 100644
index 0000000..42e83a3
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplIE.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.user.client.ui.impl;
+
+import com.google.gwt.user.client.Event;
+
+/**
+ * IE version of HyperlinkImpl. IE6 and IE7 actually have different
+ * behavior; both have special behavior for shift-click, but IE7 also opens
+ * in a new tab on ctrl-click. IE6 treats ctrl-click as a standard click.
+ */
+public class HyperlinkImplIE extends HyperlinkImpl {
+
+ private static boolean ctrlisModifier = (getInternetExplorerVersion() >= 7);
+
+ /**
+ * Returns the version of Internet Explorer or a -1, (indicating the use of
+ * another browser). Based on code from MSDN.
+ * http://msdn2.microsoft.com/en-us/library/ms537509.aspx
+ */
+ private static native int getInternetExplorerVersion() /*-{
+ var rv = -1; // Assume that we're not IE.
+
+ if (navigator.appName == 'Microsoft Internet Explorer') {
+ var ua = navigator.userAgent;
+ var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
+ if (re.exec(ua) != null)
+ rv = parseFloat( RegExp.$1 );
+ }
+
+ return rv;
+ }-*/;
+
+ @Override
+ public boolean handleAsClick(Event event) {
+ int mouseButtons = event.getButton();
+ boolean ctrl = event.getCtrlKey();
+ boolean shift = event.getShiftKey();
+ boolean middle = mouseButtons == Event.BUTTON_MIDDLE;
+ boolean right = mouseButtons == Event.BUTTON_RIGHT;
+ boolean modifiers;
+
+ if (ctrlisModifier) {
+ modifiers = shift || ctrl;
+ } else {
+ modifiers = shift;
+ }
+
+ return !modifiers && !middle && !right;
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplOpera.java b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplOpera.java
new file mode 100644
index 0000000..00f46c3
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplOpera.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.user.client.ui.impl;
+
+import com.google.gwt.user.client.Event;
+
+/**
+ * Opera version of HyperlinkImpl. As of Opera 9, the only modifier key
+ * that changes click behavior on links is shift.
+ */
+public class HyperlinkImplOpera extends HyperlinkImpl {
+ @Override
+ public boolean handleAsClick(Event event) {
+ int mouseButtons = event.getButton();
+ boolean shift = event.getShiftKey();
+ boolean middle = mouseButtons == Event.BUTTON_MIDDLE;
+ boolean right = mouseButtons == Event.BUTTON_RIGHT;
+
+ return !shift && !middle && !right;
+ }
+}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplSafari.java b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplSafari.java
new file mode 100644
index 0000000..764ece1
--- /dev/null
+++ b/user/src/com/google/gwt/user/client/ui/impl/HyperlinkImplSafari.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.user.client.ui.impl;
+
+import com.google.gwt.user.client.Event;
+
+/**
+ * HyperlinkImpl for Safari and Google Chrome. Safari has special behavior for
+ * all the modifier keys except shift, which behaves like a regular click.
+ * Chrome, however, opens a new window on a shift-click.
+ */
+public class HyperlinkImplSafari extends HyperlinkImpl {
+
+ private static boolean shiftIsModifier = onChrome();
+
+ private static native boolean onChrome() /*-{
+ return navigator.userAgent.indexOf("Chrome") != -1;
+ }-*/;
+
+ @Override
+ public boolean handleAsClick(Event event) {
+ int mouseButtons = event.getButton();
+ boolean alt = event.getAltKey();
+ boolean ctrl = event.getCtrlKey();
+ boolean meta = event.getMetaKey();
+ boolean shift = event.getShiftKey();
+ boolean middle = mouseButtons == Event.BUTTON_MIDDLE;
+ boolean right = mouseButtons == Event.BUTTON_RIGHT;
+
+ boolean modifiers = alt || ctrl || meta;
+ if (shiftIsModifier) {
+ modifiers |= shift;
+ }
+
+ return !modifiers && !middle && !right;
+ }
+}