Add a permissions model to the Chrome NPAPI plugin.
Permissions are stored in localstorage of the background page.
They can be changed by navigating to the extension's options page.
A page action indicates if the plugin permissions are good or bad for the current host.
Review at http://gwt-code-reviews.appspot.com/1084801
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9283 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/npapi/DevModeOptions/build.xml b/plugins/npapi/DevModeOptions/build.xml
new file mode 100644
index 0000000..da11701
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/build.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<project name="DevModeOptions" default="prebuilt" basedir=".">
+ <!-- Arguments to gwtc and devmode targets -->
+ <property name="gwt.args" value="" />
+
+ <!-- Configure path to GWT SDK -->
+ <property name="gwt.sdk" location="../../../build/staging/gwt-0.0.0" />
+
+ <path id="project.class.path">
+ <pathelement location="war/WEB-INF/classes"/>
+ <pathelement location="${gwt.sdk}/gwt-user.jar"/>
+ <fileset dir="${gwt.sdk}" includes="gwt-dev*.jar"/>
+ <!-- Add any additional non-server libs (such as JUnit) -->
+ <fileset dir="war/WEB-INF/lib" includes="**/*.jar"/>
+ </path>
+
+ <target name="javac" description="Compile java source to bytecode">
+ <mkdir dir="war/WEB-INF/classes"/>
+ <javac srcdir="src" includes="**" encoding="utf-8"
+ destdir="war/WEB-INF/classes"
+ source="1.5" target="1.5" nowarn="true"
+ debug="true" debuglevel="lines,vars,source">
+ <classpath refid="project.class.path"/>
+ </javac>
+ <copy todir="war/WEB-INF/classes">
+ <fileset dir="src" excludes="**/*.java"/>
+ </copy>
+ </target>
+
+ <target name="gwtc" depends="javac" description="GWT compile to JavaScript (production mode)">
+ <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
+ <classpath>
+ <pathelement location="src"/>
+ <path refid="project.class.path"/>
+ </classpath>
+ <!-- add jvmarg -Xss16M or similar if you see a StackOverflowError -->
+ <jvmarg value="-Xmx256M"/>
+ <arg line="-war"/>
+ <arg value="war"/>
+ <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
+ <arg line="${gwt.args}"/>
+ <arg value="com.google.gwt.devmodeoptions.DevModeOptions"/>
+ </java>
+ </target>
+
+ <target name="devmode" depends="javac" description="Run development mode">
+ <java failonerror="true" fork="true" classname="com.google.gwt.dev.DevMode">
+ <classpath>
+ <pathelement location="src"/>
+ <path refid="project.class.path"/>
+ </classpath>
+ <jvmarg value="-Xmx256M"/>
+ <arg value="-startupUrl"/>
+ <arg value="DevModeOptions.html"/>
+ <arg line="-war"/>
+ <arg value="war"/>
+ <!-- Additional arguments like -style PRETTY or -logLevel DEBUG -->
+ <arg line="${gwt.args}"/>
+ <arg value="com.google.devmodeoptions"/>
+ </java>
+ </target>
+
+ <target name="build" depends="gwtc" description="Build this project">
+ </target>
+
+ <target name="war" depends="build" description="Create a war file">
+ <zip destfile="DevModeOptions.war" basedir="war"/>
+ </target>
+
+ <target name="clean" depends="clean-prebuilt" description="Cleans this project">
+ <delete dir="war/WEB-INF/classes" failonerror="false" />
+ <delete dir="war/DevModeOptions" failonerror="false" />
+ </target>
+
+ <target name="clean-prebuilt" description="Clean the prebuilt copy">
+ <delete file="../prebuilt/gwt-dev-plugin/DevModeOptions.html" />
+ <delete dir="../prebuilt/gwt-dev-plugin/DevModeOptions" />
+ </target>
+
+ <target name="prebuilt" depends="build,clean-prebuilt" description="Copy compiled files into
+ the prebuilt crx directory">
+ <copy todir="../prebuilt/gwt-dev-plugin/DevModeOptions">
+ <fileset dir="war/DevModeOptions" excludes="**/*.java"/>
+ </copy>
+ <copy todir="../prebuilt/gwt-dev-plugin/">
+ <fileset dir="war/">
+ <include name="DevModeOptions.html" />
+ </fileset>
+ </copy>
+ </target>
+</project>
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/DevModeOptions.gwt.xml b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/DevModeOptions.gwt.xml
new file mode 100644
index 0000000..32a4aa4
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/DevModeOptions.gwt.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC "-//Google Inc.//DTD Google Web Toolkit 0.0.999//EN" "http://google-web-toolkit.googlecode.com/svn/tags/0.0.999/distro-source/core/src/gwt-module.dtd">
+<module rename-to='DevModeOptions'>
+ <!-- Inherit the core Web Toolkit stuff. -->
+ <inherits name='com.google.gwt.user.User' />
+
+ <!-- Specify the app entry point class. -->
+ <entry-point class='com.google.gwt.devmodeoptions.client.DevModeOptions'/>
+
+ <!-- TARGETING WEBKIT ONLY -->
+ <set-property name='user.agent' value='safari' />
+
+ <!-- Specify the paths for translatable code -->
+ <source path='client'/>
+</module>
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.java b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.java
new file mode 100644
index 0000000..6ec7ae8
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2010 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.devmodeoptions.client;
+
+import com.google.gwt.core.client.EntryPoint;
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.dom.client.StyleInjector;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
+import com.google.gwt.event.dom.client.KeyCodes;
+import com.google.gwt.event.dom.client.KeyPressEvent;
+import com.google.gwt.event.dom.client.KeyPressHandler;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.uibinder.client.UiField;
+import com.google.gwt.user.client.Window.Location;
+import com.google.gwt.user.client.ui.Button;
+import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.Label;
+import com.google.gwt.user.client.ui.RadioButton;
+import com.google.gwt.user.client.ui.RootLayoutPanel;
+import com.google.gwt.user.client.ui.TextBox;
+import com.google.gwt.user.client.ui.Widget;
+
+/**
+ * The options page for configuring the set of hosts permitted to use the GWT
+ * Developer Plugin.
+ */
+public class DevModeOptions implements EntryPoint {
+
+ interface Binder extends UiBinder<Widget, DevModeOptions> {
+ }
+
+ private static final DevModeOptionsResources bundle = GWT.create(DevModeOptionsResources.class);
+
+ @UiField
+ Button addBtn;
+
+ @UiField
+ Label errorMessage;
+
+ @UiField
+ TextBox hostname;
+
+ JsArray<HostEntry> hosts;
+
+ @UiField
+ RadioButton includeNo;
+
+ @UiField
+ RadioButton includeYes;
+
+ @UiField
+ FlexTable savedHosts;
+
+ public void onModuleLoad() {
+ StyleInjector.inject(bundle.css().getText(), true);
+ RootLayoutPanel.get().add(
+ GWT.<Binder> create(Binder.class).createAndBindUi(this));
+
+ hosts = HostEntryStorage.get().getHostEntries();
+
+ addBtn.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ addHost(HostEntry.create(hostname.getText(), includeYes.getValue()));
+ }
+ });
+
+ hostname.setFocus(true);
+ String host = Location.getParameter("host");
+ if (host != null) {
+ hostname.setText(host);
+ }
+
+ hostname.addKeyPressHandler(new KeyPressHandler() {
+ public void onKeyPress(KeyPressEvent event) {
+ if (event.getCharCode() == KeyCodes.KEY_ENTER) {
+ addHost(HostEntry.create(hostname.getText(), includeYes.getValue()));
+ }
+ }
+ });
+
+ savedHosts.setText(0, 0, "Host");
+ savedHosts.setText(0, 1, "Include/Exclude");
+ savedHosts.setText(0, 2, "Remove");
+ savedHosts.getCellFormatter().addStyleName(0, 0,
+ bundle.css().savedHostsHeading());
+ savedHosts.getCellFormatter().addStyleName(0, 0, bundle.css().textCol());
+
+ savedHosts.getCellFormatter().addStyleName(0, 1,
+ bundle.css().savedHostsHeading());
+
+ savedHosts.getCellFormatter().addStyleName(0, 2,
+ bundle.css().savedHostsHeading());
+
+ for (int i = 0; i < hosts.length(); i++) {
+ displayHost(hosts.get(i));
+ }
+ }
+
+ private void addHost(final HostEntry newHost) {
+ if (newHost.getUrl().length() == 0) {
+ return;
+ }
+
+ boolean alreadyExists = false;
+ for (int i = 0; i < hosts.length() && !alreadyExists; i++) {
+ if (hosts.get(i).isEqual(newHost)) {
+ alreadyExists = true;
+ }
+ }
+
+ if (alreadyExists) {
+ error("Cannot add duplicate host entry for " + newHost.getUrl());
+ return;
+ } else {
+ hosts.push(newHost);
+ clearError();
+ }
+ HostEntryStorage.get().saveEntries(hosts);
+
+ displayHost(newHost);
+
+ hostname.setText("");
+ hostname.setFocus(true);
+ }
+
+ private void clearError() {
+ errorMessage.setText("");
+ }
+
+ private void displayHost(final HostEntry newHost) {
+ int numRows = savedHosts.getRowCount();
+ int col = 0;
+ savedHosts.insertRow(numRows);
+ savedHosts.setText(numRows, col++, newHost.getUrl());
+ savedHosts.setText(numRows, col++, newHost.include() ? "Include"
+ : "Exclude");
+ if (newHost.include()) {
+ savedHosts.getCellFormatter().addStyleName(numRows, 0,
+ bundle.css().include());
+ savedHosts.getCellFormatter().addStyleName(numRows, 1,
+ bundle.css().include());
+ } else {
+ savedHosts.getCellFormatter().addStyleName(numRows, 0,
+ bundle.css().exclude());
+ savedHosts.getCellFormatter().addStyleName(numRows, 1,
+ bundle.css().exclude());
+ }
+
+ Button removeHostButton = new Button("x");
+ removeHostButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ removeHost(newHost);
+ }
+ });
+ savedHosts.setWidget(numRows, col, removeHostButton);
+ }
+
+ private void error(String text) {
+ errorMessage.setText(text);
+ }
+
+ private void removeHost(HostEntry host) {
+ JsArray<HostEntry> newHosts = JavaScriptObject.createArray().cast();
+ for (int index = 0; index < hosts.length(); index++) {
+ if (hosts.get(index).isEqual(host)) {
+ savedHosts.removeRow(index + 1);
+ } else {
+ newHosts.push(hosts.get(index));
+ }
+ }
+
+ hosts = newHosts;
+ HostEntryStorage.get().saveEntries(hosts);
+ }
+
+}
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.ui.xml b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.ui.xml
new file mode 100644
index 0000000..555ce15
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptions.ui.xml
@@ -0,0 +1,52 @@
+<!-- Copyright 2010 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 -->
+<!-- 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. License for the specific language governing permissions and -->
+<!-- limitations under the License. -->
+
+<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
+<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
+ xmlns:g="urn:import:com.google.gwt.user.client.ui">
+ <ui:with field='res'
+ type='com.google.gwt.devmodeoptions.client.DevModeOptionsResources' />
+ <g:HTMLPanel styleName="{res.css.mainPanel}">
+ <g:VerticalPanel>
+ <g:HorizontalPanel>
+ <g:Image resource='{res.gwt64}' styleName="{res.css.logo}" />
+ <g:HTML>
+ <h1> GWT Developer Plugin Options </h1>
+ </g:HTML>
+ </g:HorizontalPanel>
+
+ <g:Label styleName="{res.css.explanation}">
+ The GWT Developer Plugin will open a TCP/IP connection to an arbitrary
+ host/port at the request of a web page. To minimize security risks,
+ by default it will only connect to the local machine. To allow
+ cross-machine debugging, you can add exceptions here -- include the
+ exact host name of the web servers you will use for debugging, but
+ do not include any you do not trust.</g:Label>
+
+ <g:Label ui:field="errorMessage" styleName="{res.css.errorMessage}"/>
+ <g:HorizontalPanel>
+ <g:TextBox ui:field="hostname" styleName="{res.css.textBox}" />
+ <g:Button styleName="{res.css.important}" ui:field="addBtn">Add</g:Button>
+ <g:VerticalPanel>
+ <g:RadioButton name="include" ui:field="includeYes"
+ checked="true">Include</g:RadioButton>
+ <g:RadioButton name="include" ui:field="includeNo">Exclude</g:RadioButton>
+ </g:VerticalPanel>
+ </g:HorizontalPanel>
+
+ <g:FlexTable ui:field="savedHosts" styleName="{res.css.savedHosts}">
+ </g:FlexTable>
+ </g:VerticalPanel>
+ </g:HTMLPanel>
+
+</ui:UiBinder>
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptionsResources.java b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptionsResources.java
new file mode 100644
index 0000000..3f17ced
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/DevModeOptionsResources.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2010 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.devmodeoptions.client;
+
+import com.google.gwt.resources.client.ClientBundle;
+import com.google.gwt.resources.client.CssResource;
+import com.google.gwt.resources.client.ImageResource;
+
+public interface DevModeOptionsResources extends ClientBundle {
+
+ public interface Css extends CssResource {
+ String errorMessage();
+
+ String exclude();
+
+ String explanation();
+
+ String header();
+
+ String important();
+
+ String include();
+
+ String logo();
+
+ String mainPanel();
+
+ String savedHosts();
+
+ String savedHostsHeading();
+
+ String textBox();
+
+ String textCol();
+ }
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/DevModeOptions.css")
+ Css css();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/gwt128.png")
+ ImageResource gwt128();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/gwt16.png")
+ ImageResource gwt16();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/gwt32.png")
+ ImageResource gwt32();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/gwt48.png")
+ ImageResource gwt48();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/gwt64.png")
+ ImageResource gwt64();
+
+ @Source("com/google/gwt/devmodeoptions/client/resources/warning.png")
+ ImageResource warning();
+}
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntry.java b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntry.java
new file mode 100644
index 0000000..672a783
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntry.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2010 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.devmodeoptions.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+
+public class HostEntry extends JavaScriptObject{
+
+ protected HostEntry() {}
+
+ public static HostEntry create(String url, boolean include) {
+ HostEntry entry = JavaScriptObject.createObject().cast();
+ entry.setUrl(url);
+ entry.setInclude(include);
+ return entry;
+ }
+
+ public final native String getUrl() /*-{
+ return this.url;
+ }-*/;
+
+ public final native void setUrl(String url) /*-{
+ this.url = url;
+ }-*/;
+
+ public final native void setInclude(boolean include) /*-{
+ this.include = include;
+ }-*/;
+
+ public final native boolean include() /*-{
+ return this.include;
+ }-*/;
+
+ public final boolean isEqual(HostEntry host) {
+ return this.getUrl().equals(host.getUrl());
+ }
+}
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntryStorage.java b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntryStorage.java
new file mode 100644
index 0000000..6a7ddc0
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/HostEntryStorage.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2010 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.devmodeoptions.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+
+public class HostEntryStorage {
+ private static HostEntryStorage singleton = new HostEntryStorage();
+ private static final String HOST_ENTRY_KEY = "GWT_DEV_HOSTENTRY";
+
+ public static HostEntryStorage get() {
+ return singleton;
+ }
+
+ private final LocalStorage localStorage;
+
+ private HostEntryStorage() {
+ localStorage = getLocalStorage();
+ }
+
+ private static native LocalStorage getLocalStorage() /*-{
+ return $wnd.localStorage;
+ }-*/;
+
+ public JsArray<HostEntry> getHostEntries() {
+ JsArray<HostEntry> entries = localStorage.getItem(HOST_ENTRY_KEY).cast();
+ if (entries == null) {
+ return JavaScriptObject.createArray().cast();
+ } else {
+ return entries;
+ }
+ }
+
+ public void saveEntries(JsArray<HostEntry> entries) {
+ localStorage.setItem(HOST_ENTRY_KEY, entries.cast());
+ }
+
+}
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/LocalStorage.java b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/LocalStorage.java
new file mode 100644
index 0000000..9e6a6c2
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/LocalStorage.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2010 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.devmodeoptions.client;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * Simple wrapper around HTML5 <a
+ * href="http://dev.w3.org/html5/webstorage/#the-localstorage-attribute">local
+ * storage</a> API.
+ */
+public class LocalStorage extends JavaScriptObject {
+ protected LocalStorage() {
+ }
+
+ public final native void clear() /*-{
+ this.clear();
+ }-*/;
+
+ public final native JavaScriptObject getItem(String key) /*-{
+ return JSON.parse(this.getItem(key));
+ }-*/;
+
+ public final native String getKey(int index) /*-{
+ return this.key(index);
+ }-*/;
+
+ public final native int getLength() /*-{
+ return this.length;
+ }-*/;
+
+ public final native String getStringItem(String key) /*-{
+ return this.getItem(key);
+ }-*/;
+
+ public final native void removeItem(String key) /*-{
+ this.removeItem(key);
+ }-*/;
+
+ public final native void setItem(String key, JavaScriptObject dataObject) /*-{
+ // Note, as of FF3.6, gecko does not support storing an object (only strings).
+ this.setItem(key, JSON.stringify(dataObject));
+ }-*/;
+
+ public final native void setStringItem(String key, String dataString) /*-{
+ this.setItem(key, dataString);
+ }-*/;
+}
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/DevModeOptions.css b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/DevModeOptions.css
new file mode 100644
index 0000000..f42e7ad
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/DevModeOptions.css
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2010 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.
+ */
+@def TEXTWIDTH 30em;
+.savedHostsHeading {
+ font-weight: bold;
+}
+
+.savedHosts {
+ border: 2px solid silver;
+ padding: 2px;
+ margin-top: 1.5em;
+}
+
+.include {
+ color: blue;
+}
+
+.exclude {
+ color: IndianRed;
+}
+
+.errorMessage {
+ color: red;
+ font-weight: bold;
+}
+
+.important {
+ font-weight: bold;
+}
+
+.header {
+ font-size: large;
+ font-weight: bold;
+}
+
+.textBox {
+ width: TEXTWIDTH;
+}
+
+.textCol {
+ width: TEXTWIDTH;
+}
+
+.logo {
+ margin-right: 1em;
+}
+
+.mainPanel {
+ margin-left: 2em;
+ margin-top: 2em;
+ font-family: sans-serif;
+ font-size: small;
+ max-width: 50em;
+}
+
+.explanation {
+ margin-top: 1.5em;
+ margin-bottom: 1.5em;
+}
\ No newline at end of file
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt128.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt128.png
new file mode 100644
index 0000000..57e8e01
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt128.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt16.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt16.png
new file mode 100644
index 0000000..f26096e
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt16.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt32.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt32.png
new file mode 100644
index 0000000..7ba8270
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt32.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt48.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt48.png
new file mode 100644
index 0000000..e8a4172
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt48.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt64.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt64.png
new file mode 100644
index 0000000..922cc88
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/gwt64.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/warning.png b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/warning.png
new file mode 100644
index 0000000..55a203b
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/src/com/google/gwt/devmodeoptions/client/resources/warning.png
Binary files differ
diff --git a/plugins/npapi/DevModeOptions/war/DevModeOptions.html b/plugins/npapi/DevModeOptions/war/DevModeOptions.html
new file mode 100644
index 0000000..d2132e8
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/war/DevModeOptions.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<html>
+ <head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+
+ <title>GWT DevMode Options</title>
+ <script type="text/javascript" language="javascript" src="DevModeOptions/DevModeOptions.nocache.js"></script>
+ </head>
+
+ <body>
+ </body>
+</html>
diff --git a/plugins/npapi/DevModeOptions/war/WEB-INF/classes/marker b/plugins/npapi/DevModeOptions/war/WEB-INF/classes/marker
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/war/WEB-INF/classes/marker
diff --git a/plugins/npapi/DevModeOptions/war/WEB-INF/lib/marker b/plugins/npapi/DevModeOptions/war/WEB-INF/lib/marker
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/war/WEB-INF/lib/marker
diff --git a/plugins/npapi/DevModeOptions/war/WEB-INF/web.xml b/plugins/npapi/DevModeOptions/war/WEB-INF/web.xml
new file mode 100644
index 0000000..bd4f348
--- /dev/null
+++ b/plugins/npapi/DevModeOptions/war/WEB-INF/web.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+xmlns="http://java.sun.com/xml/ns/javaee"
+xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
+http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
+</web-app>
diff --git a/plugins/npapi/Makefile b/plugins/npapi/Makefile
index 0a482f0..4aedc18 100644
--- a/plugins/npapi/Makefile
+++ b/plugins/npapi/Makefile
@@ -23,6 +23,7 @@
# Mac puts multiple architectures into the same files
TARGET_PLATFORM = Darwin-gcc3
CHROME_PATH ?= /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome
+PLATFORM_DIR_SUFFIX = gwtDev.plugin/Contents/MacOS/
else
ifeq ($(OS),linux)
RUN_PATH_FLAG = -rpath-link
@@ -49,6 +50,7 @@
OBJ_OUTDIR = build/$(TARGET_PLATFORM)
EXTENSION_OUTDIR = prebuilt/gwt-dev-plugin
PLATFORM_DIR = $(EXTENSION_OUTDIR)/$(TARGET_PLATFORM)
+PLATFORM_DIR_SUFFIX ?= ""
INSTALLER_CRX = prebuilt/gwt-dev-plugin.crx
DLL = $(OBJ_OUTDIR)/libGwtDevPlugin$(DLL_SUFFIX)
@@ -63,9 +65,9 @@
endif
.PHONY: default all crx lib common clean depend install install-platform \
- versioned-files
+ versioned-files devmodeoptions
-default:: lib versioned-files
+default:: lib versioned-files devmodeoptions
all:: common lib install-platform crx
@@ -112,7 +114,7 @@
$(DLL): $(OBJS) $(COMMON)
$(CXX) -m$(FLAG32BIT) -o $@ $(OBJS) $(COMMON) $(DLLFLAGS)
@mkdir -p $(PLATFORM_DIR)
- cp $(DLL) $(PLATFORM_DIR)/
+ cp $(DLL) $(PLATFORM_DIR)/$(PLATFORM_DIR_SUFFIX)
$(OBJ_OUTDIR)/%.o: %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ -I. -I../common $<
@@ -123,6 +125,9 @@
clean:
rm -rf build
+devmodeoptions:
+ (ant -f DevModeOptions/build.xml prebuilt)
+
depend: $(OBJ_OUTDIR)
($(foreach src,$(SRCS),$(DEPEND)) true) >>Makefile
# makedepend -- $(CFLAGS) -- $(SRCS)
diff --git a/plugins/npapi/NPVariantWrapper.h b/plugins/npapi/NPVariantWrapper.h
index 91bcaaf..4e039e1 100644
--- a/plugins/npapi/NPVariantWrapper.h
+++ b/plugins/npapi/NPVariantWrapper.h
@@ -61,6 +61,22 @@
return &variant;
}
+ int isBoolean() const {
+ return isBoolean(variant);
+ }
+
+ static int isBoolean(const NPVariant& variant) {
+ return NPVARIANT_IS_BOOLEAN(variant);
+ }
+
+ bool getAsBoolean() const {
+ return getAsBoolean(variant);
+ }
+
+ static bool getAsBoolean(const NPVariant& variant) {
+ return NPVARIANT_TO_BOOLEAN(variant);
+ }
+
int isInt() const {
return isInt(variant);
}
@@ -429,6 +445,10 @@
NPVariantProxy::retain(variant); // does nothing, present for consistency
return &variant;
}
+
+ bool isBoolean() const {
+ return NPVariantProxy::isBoolean(variant);
+ }
int isInt() const {
return NPVariantProxy::isInt(variant);
@@ -442,6 +462,10 @@
return NPVariantProxy::isString(variant);
}
+ bool getAsBoolean() const {
+ return NPVariantProxy::getAsBoolean(variant);
+ }
+
int getAsInt() const {
return NPVariantProxy::getAsInt(variant);
}
diff --git a/plugins/npapi/ScriptableInstance.cpp b/plugins/npapi/ScriptableInstance.cpp
index 8b85d75..1e74d4d 100644
--- a/plugins/npapi/ScriptableInstance.cpp
+++ b/plugins/npapi/ScriptableInstance.cpp
@@ -21,10 +21,6 @@
#include "ReturnMessage.h"
#include "ServerMethods.h"
#include "AllowedConnections.h"
-#ifdef _WINDOWS
-#include "Preferences.h"
-#include "AllowDialog.h"
-#endif
#include "mozincludes.h"
#include "scoped_ptr/scoped_ptr.h"
@@ -32,6 +28,10 @@
using std::string;
using std::endl;
+const static string BACKGROUND_PAGE_STR = "chrome-extension://jpjpnpmbddbjkfaccnmhnkdgjideieim/background.html";
+const static string UNKNOWN_STR = "unknown";
+const static string INCLUDE_STR = "include";
+const static string EXCLUDE_STR = "exclude";
static inline string convertToString(const NPString& str) {
return string(GetNPStringUTF8Characters(str), GetNPStringUTF8Length(str));
@@ -62,6 +62,12 @@
_connectId(NPN_GetStringIdentifier("connect")),
initID(NPN_GetStringIdentifier("init")),
toStringID(NPN_GetStringIdentifier("toString")),
+ loadHostEntriesID(NPN_GetStringIdentifier("loadHostEntries")),
+ locationID(NPN_GetStringIdentifier("location")),
+ hrefID(NPN_GetStringIdentifier("href")),
+ urlID(NPN_GetStringIdentifier("url")),
+ includeID(NPN_GetStringIdentifier("include")),
+ getHostPermissionID(NPN_GetStringIdentifier("getHostPermission")),
connectedID(NPN_GetStringIdentifier("connected")),
statsID(NPN_GetStringIdentifier("stats")),
gwtId(NPN_GetStringIdentifier("__gwt_ObjectId")),
@@ -178,7 +184,11 @@
bool ScriptableInstance::hasMethod(NPIdentifier name) {
Debug::log(Debug::Debugging) << "ScriptableInstance::hasMethod(name=" << NPN_UTF8FromIdentifier(name) << ")"
<< Debug::flush;
- if (name == _connectId || name == initID || name == toStringID) {
+ if (name == _connectId ||
+ name == initID ||
+ name == toStringID ||
+ name == loadHostEntriesID ||
+ name == getHostPermissionID) {
return true;
}
return false;
@@ -200,6 +210,10 @@
val += _channel->isConnected() ? 'Y' : 'N';
val += ']';
NPVariantProxy::assignFrom(*result, val);
+ } else if (name == loadHostEntriesID) {
+ loadHostEntries(args, argCount, result);
+ } else if (name == getHostPermissionID) {
+ getHostPermission(args, argCount, result);
}
return true;
}
@@ -248,6 +262,81 @@
result->type = NPVariantType_Bool;
}
+string ScriptableInstance::getLocationHref() {
+ NPVariantWrapper locationVariant(*this);
+ NPVariantWrapper hrefVariant(*this);
+
+ // window.location
+ NPN_GetProperty(getNPP(), window, locationID, locationVariant.addressForReturn());
+ //window.location.href
+ NPN_GetProperty(getNPP(), locationVariant.getAsObject(), hrefID, hrefVariant.addressForReturn());
+
+ const NPString* locationHref = NPVariantProxy::getAsNPString(hrefVariant);
+ return convertToString(*locationHref);
+}
+
+
+void ScriptableInstance::loadHostEntries(const NPVariant* args, unsigned argCount, NPVariant* result) {
+ string locationHref = getLocationHref();
+ if (locationHref.compare(BACKGROUND_PAGE_STR) == 0) {
+ AllowedConnections::clearRules();
+ for (unsigned i = 0; i < argCount; ++i) {
+ //Get the host entry object {url: "somehost.net", include: true/false}
+ NPObject* hostEntry = NPVariantProxy::getAsObject(args[i]);
+ if (!hostEntry) {
+ Debug::log(Debug::Error) << "Got a host entry that is not an object.\n";
+ break;
+ }
+
+ //Get the url
+ NPVariantWrapper urlVariant(*this);
+ if (!NPN_GetProperty(getNPP(), hostEntry, urlID, urlVariant.addressForReturn()) ||
+ !urlVariant.isString()) {
+ Debug::log(Debug::Error) << "Got a host.url entry that is not a string.\n";
+ break;
+ }
+ const NPString* urlNPString = urlVariant.getAsNPString();
+ string urlString = convertToString(*urlNPString);
+
+ //Include/Exclude?
+ NPVariantWrapper includeVariant(*this);
+ if (!NPN_GetProperty(getNPP(), hostEntry, includeID, includeVariant.addressForReturn()) ||
+ !includeVariant.isBoolean()) {
+ Debug::log(Debug::Error) << "Got a host.include entry that is not a boolean.\n";
+ break;
+ }
+ bool include = includeVariant.getAsBoolean();
+ Debug::log(Debug::Info) << "Adding " << urlString << "(" << (include ? "include" : "exclude") << ")\n";
+ AllowedConnections::addRule(urlString, !include);
+ }
+ } else {
+ Debug::log(Debug::Error) << "ScriptableInstance::loadHostEntries called from outside the background page: " <<
+ locationHref << "\n";
+ }
+}
+
+void ScriptableInstance::getHostPermission(const NPVariant* args, unsigned argCount, NPVariant* result) {
+ if (argCount != 1 || !NPVariantProxy::isString(args[0])) {
+ Debug::log(Debug::Error) << "ScriptableInstance::getHostPermission called with incorrect arguments.\n";
+ }
+
+ const NPString url = args[0].value.stringValue;
+ const string urlStr = convertToString(url);
+ bool allowed = false;
+ bool matches = AllowedConnections::matchesRule(urlStr, &allowed);
+ string retStr;
+
+ if (!matches) {
+ retStr = UNKNOWN_STR;
+ } else if (allowed) {
+ retStr = INCLUDE_STR;
+ } else {
+ retStr = EXCLUDE_STR;
+ }
+
+ NPVariantProxy(*this, *result) = retStr;
+}
+
void ScriptableInstance::connect(const NPVariant* args, unsigned argCount, NPVariant* result) {
if (argCount != 5 || !NPVariantProxy::isString(args[0])
|| !NPVariantProxy::isString(args[1])
@@ -263,7 +352,8 @@
result->type = NPVariantType_Void;
return;
}
- const NPString url = args[0].value.stringValue;
+ //ignore args[0]. Get the URL from window.location.href instead.
+ const string urlStr = getLocationHref();
const NPString sessionKey = args[1].value.stringValue;
const NPString hostAddr = args[2].value.stringValue;
const NPString moduleName = args[3].value.stringValue;
@@ -272,27 +362,9 @@
<< ",sessionKey=" << NPVariantProxy::toString(args[1]) << ",host=" << NPVariantProxy::toString(args[2])
<< ",module=" << NPVariantProxy::toString(args[3]) << ",hostedHtmlVers=" << NPVariantProxy::toString(args[4])
<< ")" << Debug::flush;
- const std::string urlStr = convertToString(url);
-#ifdef _WINDOWS
- // TODO: platform-independent preferences storage
- Preferences::loadAccessList();
-#endif
bool allowed = false;
- if (!AllowedConnections::matchesRule(urlStr, &allowed)) {
-#ifdef _WINDOWS
- // TODO: platform-independent allow-connection dialog
- bool remember = false;
- allowed = AllowDialog::askUserToAllow(&remember);
- if (remember) {
- std::string host = AllowedConnections::getHostFromUrl(urlStr);
- Preferences::addNewRule(host, !allowed);
- }
-#elif 0
- // WARNING: BIG SECURITY HOLE IF ENABLED!
- allowed = true;
-#endif
- }
+ AllowedConnections::matchesRule(urlStr, &allowed);
if (!allowed) {
BOOLEAN_TO_NPVARIANT(false, *result);
result->type = NPVariantType_Bool;
@@ -356,7 +428,7 @@
return id;
}
-void ScriptableInstance::fatalError(HostChannel& channel, const std::string& message) {
+void ScriptableInstance::fatalError(HostChannel& channel, const string& message) {
// TODO(jat): better error handling
Debug::log(Debug::Error) << "Fatal error: " << message << Debug::flush;
}
@@ -382,7 +454,7 @@
}
}
-void ScriptableInstance::loadJsni(HostChannel& channel, const std::string& js) {
+void ScriptableInstance::loadJsni(HostChannel& channel, const string& js) {
NPString npScript;
dupString(js.c_str(), npScript);
NPVariantWrapper npResult(*this);
@@ -405,7 +477,7 @@
NPObject* obj = localObjects.get(id);
NPIdentifier propID;
if (args[1].isString()) {
- std::string propName = args[1].getString();
+ string propName = args[1].getString();
propID = NPN_GetStringIdentifier(propName.c_str());
} else {
int propNum = args[1].getInt();
@@ -434,7 +506,7 @@
NPObject* obj = localObjects.get(id);
NPIdentifier propID;
if (args[1].isString()) {
- std::string propName = args[1].getString();
+ string propName = args[1].getString();
propID = NPN_GetStringIdentifier(propName.c_str());
} else {
int propNum = args[1].getInt();
@@ -477,7 +549,7 @@
}
Debug::log(Debug::Error) << Debug::flush;
// TODO(jat): should we create a real exception object?
- std::string buf("unexpected invokeSpecial(");
+ string buf("unexpected invokeSpecial(");
buf += static_cast<int>(dispatchId);
buf += ")";
returnValue->setString(buf);
@@ -485,7 +557,7 @@
}
bool ScriptableInstance::invoke(HostChannel& channel, const Value& thisRef,
- const std::string& methodName, int numArgs, const Value* const args,
+ const string& methodName, int numArgs, const Value* const args,
Value* returnValue) {
Debug::log(Debug::Debugging) << "invokeJS(" << methodName << ", this="
<< thisRef.toString() << ", numArgs=" << numArgs << ")" << Debug::flush;
diff --git a/plugins/npapi/ScriptableInstance.h b/plugins/npapi/ScriptableInstance.h
index 2d03a67..a24e085 100644
--- a/plugins/npapi/ScriptableInstance.h
+++ b/plugins/npapi/ScriptableInstance.h
@@ -93,6 +93,13 @@
const NPIdentifier _connectId;
const NPIdentifier initID;
const NPIdentifier toStringID;
+
+ const NPIdentifier loadHostEntriesID;
+ const NPIdentifier locationID;
+ const NPIdentifier hrefID;
+ const NPIdentifier urlID;
+ const NPIdentifier includeID;
+ const NPIdentifier getHostPermissionID;
const NPIdentifier connectedID;
const NPIdentifier statsID;
@@ -124,6 +131,8 @@
void connect(const NPVariant* args, unsigned argCount, NPVariant* result);
void init(const NPVariant* args, unsigned argCount, NPVariant* result);
+ void loadHostEntries(const NPVariant* args, unsigned argCount, NPVariant* result);
+ void getHostPermission(const NPVariant* args, unsigned argCount, NPVariant* result);
Value clientMethod_getProperty(HostChannel& channel, int numArgs, const Value* const args);
Value clientMethod_setProperty(HostChannel& channel, int numArgs, const Value* const args);
@@ -137,6 +146,7 @@
private:
std::string computeTabIdentity();
+ std::string getLocationHref();
};
#endif
diff --git a/plugins/npapi/VisualStudio/npapi-plugin.sln b/plugins/npapi/VisualStudio/npapi-plugin.sln
index 8b8af37..8d6e04a 100755
--- a/plugins/npapi/VisualStudio/npapi-plugin.sln
+++ b/plugins/npapi/VisualStudio/npapi-plugin.sln
@@ -1,6 +1,6 @@
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual C++ Express 2005
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "npapi-plugin", "npapi-plugin.vcproj", "{6BF0C2CE-CB0C-421B-A67C-1E448371D24A}"
EndProject
Global
diff --git a/plugins/npapi/VisualStudio/npapi-plugin.vcproj b/plugins/npapi/VisualStudio/npapi-plugin.vcproj
index 74b9075..bb53d97 100755
--- a/plugins/npapi/VisualStudio/npapi-plugin.vcproj
+++ b/plugins/npapi/VisualStudio/npapi-plugin.vcproj
@@ -1,11 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<VisualStudioProject
ProjectType="Visual C++"
- Version="8.00"
+ Version="9.00"
Name="npapi-plugin"
ProjectGUID="{6BF0C2CE-CB0C-421B-A67C-1E448371D24A}"
RootNamespace="npapi-plugin"
Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
>
<Platforms>
<Platform
@@ -39,7 +40,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
- AdditionalIncludeDirectories=""$(ProjectDir)\..\..\platform\Win";"$(ProjectDir)\..";"$(ProjectDir)\..\..\common""
+ AdditionalIncludeDirectories=""$(ProjectDir)\..";"$(ProjectDir)\..\..\common""
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FIREFOXPLUGIN_EXPORTS"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@@ -69,6 +70,8 @@
GenerateDebugInformation="true"
ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb"
SubSystem="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
ImportLibrary="$(IntDir)\$(TargetName).lib"
TargetMachine="1"
/>
@@ -91,9 +94,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
@@ -122,12 +122,14 @@
Name="VCCLCompilerTool"
Optimization="3"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories=""$(ProjectDir)\..\..\platform\Win";"$(ProjectDir)\..";"$(ProjectDir)\..\..\common""
+ FavorSizeOrSpeed="1"
+ AdditionalIncludeDirectories=""$(ProjectDir)\..";"$(ProjectDir)\..\..\common""
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FIREFOXPLUGIN_EXPORTS"
ExceptionHandling="1"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
+ WarnAsError="false"
Detect64BitPortabilityProblems="false"
DebugInformationFormat="3"
/>
@@ -153,6 +155,8 @@
SubSystem="2"
OptimizeReferences="2"
EnableCOMDATFolding="2"
+ RandomizedBaseAddress="1"
+ DataExecutionPrevention="0"
ImportLibrary="$(IntDir)\$(TargetName).lib"
TargetMachine="1"
/>
@@ -175,9 +179,6 @@
Name="VCAppVerifierTool"
/>
<Tool
- Name="VCWebDeploymentTool"
- />
- <Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
@@ -327,18 +328,6 @@
</File>
</Filter>
<Filter
- Name="win"
- >
- <File
- RelativePath="..\..\platform\Win\AllowDialog.h"
- >
- </File>
- <File
- RelativePath="..\..\platform\Win\Preferences.h"
- >
- </File>
- </Filter>
- <Filter
Name="npapi"
>
<File
@@ -466,18 +455,6 @@
>
</File>
</Filter>
- <Filter
- Name="win"
- >
- <File
- RelativePath="..\..\platform\Win\AllowDialog.cpp"
- >
- </File>
- <File
- RelativePath="..\..\platform\Win\Preferences.cpp"
- >
- </File>
- </Filter>
</Filter>
</Files>
<Globals>
diff --git a/plugins/npapi/main.cpp b/plugins/npapi/main.cpp
index 557fe62..1e44452 100644
--- a/plugins/npapi/main.cpp
+++ b/plugins/npapi/main.cpp
@@ -19,15 +19,12 @@
#include "scoped_ptr/scoped_ptr.h"
#ifdef _WINDOWS
-// TODO: add platform-independent permission dialog
-#include "AllowDialog.h"
-
#include <windows.h>
-
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ulReasonForCall, LPVOID lpReserved) {
- AllowDialog::setHInstance(hModule);
switch (ulReasonForCall) {
case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(hModule);
+ break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
@@ -36,7 +33,6 @@
return TRUE;
}
#endif
-
extern "C" {
static const NPNetscapeFuncs* browser;
@@ -242,8 +238,8 @@
}
int16 NPP_HandleEvent(NPP instance, void* event) {
- Debug::log(Debug::Info) << "NPP_HandleEvent(instance=" << instance << ")" << Debug::flush;
- return 1 ;
+ Debug::log(Debug::Spam) << "NPP_HandleEvent(instance=" << instance << ")" << Debug::flush;
+ return 0 ;
}
void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData) {
diff --git a/plugins/npapi/manifest-template.json b/plugins/npapi/manifest-template.json
index ecf565f..9c6a1b8 100644
--- a/plugins/npapi/manifest-template.json
+++ b/plugins/npapi/manifest-template.json
@@ -10,12 +10,16 @@
"64": "gwt64.png",
"128": "gwt128.png"
},
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi6RrEy9YllRLM8bGBcIEk5ECAG2z+8ngTz7wwzRAQJpOzDp1Alq8fQFjH0+dzxok4RFLrWKHjxGqvXzWyWyTEo2nY3ScHLN/RoANMs8pl9X6TygRyO+3naqZOtLCrYHfV49JKXnYoFVbY5eBVYxHYY3BHAOKJj9onyAM4UPmMzQIDAQAB",
"background_page": "background.html",
- "content_scripts": [
- {
- "matches": ["http://*/*", "https://*/*", "file:///*"],
- "js": ["record_tab_id.js"]
- }
+ "options_page" : "DevModeOptions.html",
+ "page_action" : {
+ "default_icon" : "gwt32.png",
+ "default_title" : "GWT Development Mode",
+ "default_popup" : "page_action.html"
+ },
+ "permissions" : [
+ "tabs"
],
"plugins": [
{ "path": "WINNT_x86-msvc/npGwtDevPlugin.dll", "public": true },
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin.crx b/plugins/npapi/prebuilt/gwt-dev-plugin.crx
index 0a33eba..0852c4b 100644
--- a/plugins/npapi/prebuilt/gwt-dev-plugin.crx
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin.crx
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/gwtDev.plugin/Contents/MacOS/libGwtDevPlugin.dylib b/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/gwtDev.plugin/Contents/MacOS/libGwtDevPlugin.dylib
index 6e17d7b..3523020 100755
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/gwtDev.plugin/Contents/MacOS/libGwtDevPlugin.dylib
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/gwtDev.plugin/Contents/MacOS/libGwtDevPlugin.dylib
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/libGwtDevPlugin.dylib b/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/libGwtDevPlugin.dylib
deleted file mode 100755
index 98f3d3f..0000000
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/Darwin-gcc3/libGwtDevPlugin.dylib
+++ /dev/null
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86-gcc3/libGwtDevPlugin.so b/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86-gcc3/libGwtDevPlugin.so
index 2aec960..1294ca9 100755
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86-gcc3/libGwtDevPlugin.so
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86-gcc3/libGwtDevPlugin.so
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86_64-gcc3/libGwtDevPlugin.so b/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86_64-gcc3/libGwtDevPlugin.so
index 1f7949b..ce762bb 100755
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86_64-gcc3/libGwtDevPlugin.so
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/Linux_x86_64-gcc3/libGwtDevPlugin.so
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/WINNT_x86-msvc/npGwtDevPlugin.dll b/plugins/npapi/prebuilt/gwt-dev-plugin/WINNT_x86-msvc/npGwtDevPlugin.dll
index 2631415..dd1522a 100755
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/WINNT_x86-msvc/npGwtDevPlugin.dll
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/WINNT_x86-msvc/npGwtDevPlugin.dll
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/background.html b/plugins/npapi/prebuilt/gwt-dev-plugin/background.html
index 0bca1a5..2569678 100644
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/background.html
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/background.html
@@ -1,10 +1,65 @@
<html>
<head>
-<script>
- chrome.extension.onConnect.addListener(function(port) {
- // Tell my caller his tabId
- port.postMessage( { name:"tabId", tabId:port.tab.id } );
- });
-</script>
</head>
+
+<embed id="pluginEmbed" type="application/x-gwt-hosted-mode" width="10"
+height="10">
+</embed>
+
+
+<script>
+var plugin = document.getElementById('pluginEmbed');
+var disabledIcon = 'gwt32-gray.png';
+var enabledIcon = 'gwt32.png';
+
+
+function getHostFromUrl(url) {
+ var hostname = '';
+ var idx = url.indexOf('://');
+ if (idx >= 0) {
+ idx += 3;
+ hostname = url.substring(idx);
+ }
+ idx = hostname.indexOf('/');
+ if (idx >= 0) {
+ hostname = hostname.split('/')[0];
+ }
+ idx = hostname.indexOf(':');
+ if (idx >= 0) {
+ hostname = hostname.split(':')[0];
+ }
+ return hostname;
+}
+
+function devModeTabListener(tabId, changeInfo, tab) {
+ var search = tab.url.slice(tab.url.indexOf('?'));
+ if (search.indexOf('gwt.codesvr=') >= 0 || search.indexOf('gwt.hosted=') >= 0) {
+ var permission = plugin.getHostPermission(tab.url);
+ var host = getHostFromUrl(tab.url);
+ var popup = 'page_action.html';
+ var icon = null;
+ console.log("got permission " + permission + " for host " + host);
+
+ if (permission == 'include') {
+ icon = enabledIcon;
+ } else if (permission == 'exclude') {
+ icon = disabledIcon;
+ } else if (permission == 'unknown') {
+ icon = disabledIcon;
+ }
+ popup += "?permission=" + permission + "&host=" + host;
+ chrome.pageAction.setIcon({'tabId' : tabId, 'path' : icon});
+ chrome.pageAction.setPopup({'tabId' : tabId, 'popup' : popup});
+ chrome.pageAction.show(tabId);
+
+ var hostEntries = window.localStorage.getItem('GWT_DEV_HOSTENTRY') || [];
+ console.log("loading hostentries: " + hostEntries);
+ plugin.loadHostEntries.apply(plugin, JSON.parse(hostEntries));
+ } else {
+ chrome.pageAction.hide(tabId);
+ }
+};
+
+chrome.tabs.onUpdated.addListener(devModeTabListener);
+</script>
</html>
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/gwt32-gray.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt32-gray.png
new file mode 100644
index 0000000..d02689e
--- /dev/null
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt32-gray.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json b/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
index 0f1cdf0..f425fc2 100644
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
@@ -1,6 +1,6 @@
{
"name": "GWT Developer Plugin",
- "version": "1.0.9119",
+ "version": "1.0.9274",
"description": "A plugin to enable debugging with GWT's Development Mode",
"update_url": "https://dl-ssl.google.com/gwt/plugins/chrome/updates.xml",
"icons": {
@@ -10,12 +10,16 @@
"64": "gwt64.png",
"128": "gwt128.png"
},
+ "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDi6RrEy9YllRLM8bGBcIEk5ECAG2z+8ngTz7wwzRAQJpOzDp1Alq8fQFjH0+dzxok4RFLrWKHjxGqvXzWyWyTEo2nY3ScHLN/RoANMs8pl9X6TygRyO+3naqZOtLCrYHfV49JKXnYoFVbY5eBVYxHYY3BHAOKJj9onyAM4UPmMzQIDAQAB",
"background_page": "background.html",
- "content_scripts": [
- {
- "matches": ["http://*/*", "https://*/*", "file:///*"],
- "js": ["record_tab_id.js"]
- }
+ "options_page" : "DevModeOptions.html",
+ "page_action" : {
+ "default_icon" : "gwt32.png",
+ "default_title" : "GWT Development Mode",
+ "default_popup" : "page_action.html"
+ },
+ "permissions" : [
+ "tabs"
],
"plugins": [
{ "path": "WINNT_x86-msvc/npGwtDevPlugin.dll", "public": true },
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/page_action.html b/plugins/npapi/prebuilt/gwt-dev-plugin/page_action.html
new file mode 100644
index 0000000..f891515
--- /dev/null
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/page_action.html
@@ -0,0 +1,47 @@
+<head>
+ <style>
+ body {
+ width: 20em;
+ }
+ </style>
+ <script>
+ function getParam(key) {
+ var idx = window.location.search.indexOf(key + "=");
+ var value = '';
+ if (idx >= 0) {
+ idx += key.length + 1;
+ value = window.location.search.substring(idx).split('&')[0];
+ }
+ return value;
+ }
+
+ function init() {
+ var permission = getParam('permission');
+ var host = getParam('host');
+ var message='';
+
+ if (permission == 'include') {
+ message = 'The host at ' + host + ' is allowed to use the plugin';
+ } else if (permission == 'exclude') {
+ message = 'The host at ' + host + ' has been been blacklisted.';
+ } else if (permission == 'unknown') {
+ message = 'The host at ' + host + ' is unknown to the plugin.';
+ }
+
+ document.getElementById('message').innerText = message;
+ }
+
+ function updateConfiguration() {
+ var url = 'DevModeOptions.html?host=' + getParam('host');
+ url = chrome.extension.getURL(url);
+ chrome.tabs.create({'url' : url});
+ }
+ </script>
+</head>
+<body onload='javascript:init()'>
+ <h3>GWT Developer Plugin</h3>
+ <div id='message'></div>
+ <br/>
+ <button onclick= "updateConfiguration()">Update Your Configuration</button>
+ </p>
+</body>
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/record_tab_id.js b/plugins/npapi/prebuilt/gwt-dev-plugin/record_tab_id.js
deleted file mode 100644
index 78c9e73..0000000
--- a/plugins/npapi/prebuilt/gwt-dev-plugin/record_tab_id.js
+++ /dev/null
@@ -1,13 +0,0 @@
-if (window != top && location.href.indexOf("hosted.html") >= 0) {
- var port = chrome.extension.connect();
- port.onMessage.addListener(function(msg) {
- if (msg.name == "tabId") {
- var doc = window.document;
- var div = document.createElement("div");
- div.id = "$__gwt_tab_id";
- div.textContent = "" + msg.tabId;
- doc.body.appendChild(div);
- // console.log("record_tab_id.js " + msg.tabId);
- }
- });
-}
diff --git a/plugins/npapi/prebuilt/gwt-dev-plugin/warning.png b/plugins/npapi/prebuilt/gwt-dev-plugin/warning.png
new file mode 100644
index 0000000..55a203b
--- /dev/null
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/warning.png
Binary files differ