summaryrefslogtreecommitdiffstats
path: root/gerrit-prettify
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2010-07-14 15:31:06 -0700
committerShawn O. Pearce <sop@google.com>2010-07-14 16:12:35 -0700
commit56d8f8824aafae43db1af03cb0f0f7c4f72d6fb5 (patch)
tree7f6f059e0269b9ac220b4be7ae5b11e8f8827d17 /gerrit-prettify
parent077b2c5dd09304ab41fa898b1054b788c8653ec5 (diff)
Fix prettify private scope in IE6, IE8
On IE6 or IE8 we can't abuse an IFrame quite the same way as we do on Mozilla, WebKit and Opera. IE requires us to initialize the iframe by running a script that exports the iframe window back to the parent before we can use its eval method. Change-Id: Ia5e01a611ed9685a5fc5341a3f8a2446f7dcb9f4 Signed-off-by: Shawn O. Pearce <sop@google.com>
Diffstat (limited to 'gerrit-prettify')
-rw-r--r--gerrit-prettify/src/main/java/com/google/gerrit/prettify/PrettyFormatter.gwt.xml12
-rw-r--r--gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/ClientSideFormatter.java51
-rw-r--r--gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImpl.java67
-rw-r--r--gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImplIE6.java46
4 files changed, 144 insertions, 32 deletions
diff --git a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/PrettyFormatter.gwt.xml b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/PrettyFormatter.gwt.xml
index 93ce272151..48591f8239 100644
--- a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/PrettyFormatter.gwt.xml
+++ b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/PrettyFormatter.gwt.xml
@@ -1,19 +1,27 @@
<!--
Copyright (C) 2008 The Android Open Source Project
- Licensed under the Apache License, Version 2.0 (the "License");
+ 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,
+ 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.
-->
<module>
+ <replace-with class='com.google.gerrit.prettify.client.PrivateScopeImplIE6'>
+ <when-type-is class='com.google.gerrit.prettify.client.PrivateScopeImpl'/>
+ <any>
+ <when-property-is name="user.agent" value="ie6" />
+ <when-property-is name="user.agent" value="ie8" />
+ </any>
+ </replace-with>
+
<inherits name='com.google.gwt.resources.Resources'/>
<inherits name='com.google.gwtexpui.safehtml.SafeHtml'/>
<source path='common' />
diff --git a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/ClientSideFormatter.java b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/ClientSideFormatter.java
index 49811f9e41..1b03c625b9 100644
--- a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/ClientSideFormatter.java
+++ b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/ClientSideFormatter.java
@@ -16,8 +16,8 @@ package com.google.gerrit.prettify.client;
import com.google.gerrit.prettify.common.PrettyFactory;
import com.google.gerrit.prettify.common.PrettyFormatter;
-import com.google.gwt.resources.client.TextResource;
-import com.google.gwt.user.client.ui.NamedFrame;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.user.client.ui.RootPanel;
/** Evaluates prettify using the host browser's JavaScript engine. */
@@ -29,45 +29,36 @@ public class ClientSideFormatter extends PrettyFormatter {
}
};
+ private static final PrivateScopeImpl prettify;
+
static {
Resources.I.prettify_css().ensureInjected();
Resources.I.gerrit_css().ensureInjected();
- createFrame();
- compile(Resources.I.core());
- compile(Resources.I.lang_css());
- compile(Resources.I.lang_hs());
- compile(Resources.I.lang_lisp());
- compile(Resources.I.lang_lua());
- compile(Resources.I.lang_ml());
- compile(Resources.I.lang_proto());
- compile(Resources.I.lang_sql());
- compile(Resources.I.lang_vb());
- compile(Resources.I.lang_wiki());
- }
+ prettify = GWT.create(PrivateScopeImpl.class);
+ RootPanel.get().add(prettify);
- private static void createFrame() {
- NamedFrame frame = new NamedFrame("_prettify");
- frame.setUrl("javascript:");
- frame.setVisible(false);
- RootPanel.get().add(frame);
+ prettify.compile(Resources.I.core());
+ prettify.compile(Resources.I.lang_css());
+ prettify.compile(Resources.I.lang_hs());
+ prettify.compile(Resources.I.lang_lisp());
+ prettify.compile(Resources.I.lang_lua());
+ prettify.compile(Resources.I.lang_ml());
+ prettify.compile(Resources.I.lang_proto());
+ prettify.compile(Resources.I.lang_sql());
+ prettify.compile(Resources.I.lang_vb());
+ prettify.compile(Resources.I.lang_wiki());
}
- private static void compile(TextResource core) {
- eval(core.getText());
- }
-
- private static native void eval(String js)
- /*-{ $wnd._prettify.eval(js); }-*/;
-
@Override
protected String prettify(String html, String type) {
- return go(html, type, settings.getTabSize());
+ return go(prettify.getContext(), html, type, settings.getTabSize());
}
- private static native String go(String srcText, String srcType, int tabSize)
+ private static native String go(JavaScriptObject ctx, String srcText,
+ String srcType, int tabSize)
/*-{
- $wnd._prettify.PR_TAB_WIDTH = tabSize;
- return $wnd._prettify.prettyPrintOne(srcText, srcType);
+ ctx.PR_TAB_WIDTH = tabSize;
+ return ctx.prettyPrintOne(srcText, srcType);
}-*/;
}
diff --git a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImpl.java b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImpl.java
new file mode 100644
index 0000000000..65ee2127cc
--- /dev/null
+++ b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImpl.java
@@ -0,0 +1,67 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// 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.gerrit.prettify.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.resources.client.TextResource;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.NamedFrame;
+
+/**
+ * Creates a private JavaScript environment, typically inside an IFrame.
+ * <p>
+ * Instances must be created through {@code GWT.create(PrivateScopeImpl.class)}.
+ * A scope must remain attached to the primary document for its entire life.
+ * Behavior is undefined if a scope is detached and attached again later. It is
+ * best to attach the scope with {@code RootPanel.get().add(scope)} as soon as
+ * it has been created.
+ */
+public class PrivateScopeImpl extends Composite {
+ private static int scopeId;
+
+ protected final String scopeName;
+
+ public PrivateScopeImpl() {
+ scopeName = nextScopeName();
+
+ NamedFrame frame = new NamedFrame(scopeName);
+ frame.setUrl("javascript:''");
+ initWidget(frame);
+
+ setVisible(false);
+ }
+
+ public void compile(TextResource js) {
+ eval(js.getText());
+ }
+
+ public void eval(String js) {
+ nativeEval(getContext(), js);
+ }
+
+ public JavaScriptObject getContext() {
+ return nativeGetContext(scopeName);
+ }
+
+ private static String nextScopeName() {
+ return "_PrivateScope" + (++scopeId);
+ }
+
+ private static native void nativeEval(JavaScriptObject ctx, String js)
+ /*-{ ctx.eval(js); }-*/;
+
+ private static native JavaScriptObject nativeGetContext(String scopeName)
+ /*-{ return $wnd[scopeName]; }-*/;
+}
diff --git a/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImplIE6.java b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImplIE6.java
new file mode 100644
index 0000000000..abb4e15812
--- /dev/null
+++ b/gerrit-prettify/src/main/java/com/google/gerrit/prettify/client/PrivateScopeImplIE6.java
@@ -0,0 +1,46 @@
+// Copyright (C) 2010 The Android Open Source Project
+//
+// 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.gerrit.prettify.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/** IE6 requires us to initialize the document before we can use it. */
+public class PrivateScopeImplIE6 extends PrivateScopeImpl {
+ private JavaScriptObject context;
+
+ @Override
+ protected void onAttach() {
+ super.onAttach();
+ context = nativeInitContext(scopeName);
+ }
+
+ @Override
+ public JavaScriptObject getContext() {
+ return context;
+ }
+
+ private static native JavaScriptObject nativeInitContext(String scopeName)
+ /*-{
+ var fe = $wnd[scopeName];
+ fe.document.write(
+ '<script>'
+ + 'parent._PrivateScopeNewChild = this;'
+ + '</' + 'script>'
+ );
+ var ctx = $wnd._PrivateScopeNewChild;
+ $wnd._PrivateScopeNewChild = undefined;
+ return ctx;
+ }-*/;
+}