Make GWT's Anchor CSP compatible.

The Anchor element uses "javascript:" as no-op URL. When used with
strict CSP, this causes a violation to be generated when the link is
clicked. As a fix, we add an click event listener to call
preventDefault() if the href equals "javascript:".

Change-Id: Ic0ed6a4e8ccbdaffe41fc5f336769ac78a02d9fd
Review-Link: https://gwt-review.googlesource.com/#/c/18820/
diff --git a/user/src/com/google/gwt/event/dom/client/DomEvent.java b/user/src/com/google/gwt/event/dom/client/DomEvent.java
index dbebdf3..d911fd4 100644
--- a/user/src/com/google/gwt/event/dom/client/DomEvent.java
+++ b/user/src/com/google/gwt/event/dom/client/DomEvent.java
@@ -164,7 +164,11 @@
    */
   public void preventDefault() {
     assertLive();
-    nativeEvent.preventDefault();
+    // If there is no native event object set, do nothing. There will be no
+    // default action anyway.
+    if (nativeEvent != null) {
+      nativeEvent.preventDefault();
+    }
   }
 
   /**
diff --git a/user/src/com/google/gwt/user/UI.gwt.xml b/user/src/com/google/gwt/user/UI.gwt.xml
index 1d4e980..1f2dc81 100644
--- a/user/src/com/google/gwt/user/UI.gwt.xml
+++ b/user/src/com/google/gwt/user/UI.gwt.xml
@@ -64,4 +64,14 @@
     <skip name="rpc/**" />
   </source>
   <public path="public" />
+
+  <!--
+    gwt.cspCompatModeEnabled ensures that GWT's widgets try to be compatible
+    with strict CSP (Content Security Policy) policies. For example, with this
+    config enabled, GWT's Anchor class will take care not trigger violations due
+    to inline JS execution when clicked. This config should be safe to enable
+    and should have no user-visible effects.
+  -->
+  <define-property name="gwt.cspCompatModeEnabled" values="true, false"/>
+  <set-property name="gwt.cspCompatModeEnabled" value="false"/>
 </module>
diff --git a/user/src/com/google/gwt/user/client/ui/Anchor.java b/user/src/com/google/gwt/user/client/ui/Anchor.java
index 3b38f69..02ecaef 100644
--- a/user/src/com/google/gwt/user/client/ui/Anchor.java
+++ b/user/src/com/google/gwt/user/client/ui/Anchor.java
@@ -19,6 +19,8 @@
 import com.google.gwt.dom.client.Document;
 import com.google.gwt.dom.client.Element;
 import com.google.gwt.dom.client.Style.WhiteSpace;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
 import com.google.gwt.i18n.client.BidiUtils;
 import com.google.gwt.i18n.client.HasDirection;
 import com.google.gwt.i18n.shared.DirectionEstimator;
@@ -125,6 +127,22 @@
     if (useDefaultHref) {
       setHref(DEFAULT_HREF);
     }
+
+    // The following click handler is used to support users of CSP (Content
+    // Security Policy). When a CSP policy is in place, clicking on a link with
+    // the DEFAULT_HREF as the href can trigger a CSP violation. As a
+    // work-around, we prevent execution using preventDefault() when the href is
+    // set to DEFAULT_HREF.
+    if ("true".equals(System.getProperty("gwt.cspCompatModeEnabled"))) {
+      addClickHandler(new ClickHandler() {
+        @Override
+        public void onClick(ClickEvent event) {
+          if (DEFAULT_HREF.equals(getAnchorElement().getHref())) {
+            event.preventDefault();
+          }
+        }
+      });
+    }
   }
 
   /**