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/eclipse/plugins/DevModeOptions/.classpath b/eclipse/plugins/DevModeOptions/.classpath new file mode 100644 index 0000000..26f2949 --- /dev/null +++ b/eclipse/plugins/DevModeOptions/.classpath
@@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="core/src"/> + <classpathentry kind="src" output="war" path="core/war"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry combineaccessrules="false" kind="src" path="/gwt-user"/> + <classpathentry kind="output" path="war/WEB-INF/classes"/> +</classpath>
diff --git a/eclipse/plugins/DevModeOptions/.project b/eclipse/plugins/DevModeOptions/.project new file mode 100644 index 0000000..35eeaec --- /dev/null +++ b/eclipse/plugins/DevModeOptions/.project
@@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>DevModeOptions</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>com.google.gwt.eclipse.core.gwtProjectValidator</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>com.google.gwt.eclipse.core.gwtNature</nature> + </natures> + <linkedResources> + <link> + <name>core</name> + <type>2</type> + <locationURI>GWT_ROOT/plugins/npapi/DevModeOptions</locationURI> + </link> + </linkedResources> +</projectDescription>
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
diff --git a/plugins/platform/Win/AllowDialog.cpp b/plugins/platform/Win/AllowDialog.cpp deleted file mode 100644 index 6e5672b..0000000 --- a/plugins/platform/Win/AllowDialog.cpp +++ /dev/null
@@ -1,54 +0,0 @@ -/* - * Copyright 2009 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. - */ - -#include "AllowDialog.h" -#include "Debug.h" -#include "resource.h" - -HINSTANCE AllowDialog::hInstance; - -static BOOL CALLBACK allowDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) { - if (message != WM_COMMAND) { - return false; - } - bool allowed; - switch (LOWORD(wParam)) { - case IDCANCEL: - allowed = false; - break; - case IDC_ALLOW_BUTTON: - allowed = true; - break; - default: - // ignore anything but buttons which close the dialog - return false; - } - bool remember = IsDlgButtonChecked(hwndDlg, IDC_REMEMBER_CHECKBOX) == BST_CHECKED; - int returnVal = (allowed ? 1 : 0) + (remember ? 2 : 0); - EndDialog(hwndDlg, (INT_PTR) returnVal); - return true; -} - -void AllowDialog::setHInstance(HINSTANCE hInstance) { - AllowDialog::hInstance = hInstance; -} - -bool AllowDialog::askUserToAllow(bool* remember) { - int result = (int) DialogBox(hInstance, MAKEINTRESOURCE(IDD_ALLOW_DIALOG), - NULL, (DLGPROC) allowDialogProc); - *remember = (result & 2) != 0; - return (result & 1) != 0; -}
diff --git a/plugins/platform/Win/AllowDialog.h b/plugins/platform/Win/AllowDialog.h deleted file mode 100644 index 93f9438..0000000 --- a/plugins/platform/Win/AllowDialog.h +++ /dev/null
@@ -1,42 +0,0 @@ -#ifndef _H_AllowDialog -#define _H_AllowDialog -/* - * Copyright 2009 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. - */ - -#ifdef _WINDOWS -#include <windows.h> -#include <winnt.h> -#include <windef.h> - -class AllowDialog { -public: - static void setHInstance(HINSTANCE hInstance); - - /** - * Ask the user if a connection should be allowed. - * - * @param remember *remember is set to true if the user asked us to remember this decision, - * false otherwise - * @return return true if this connection should be allowed - */ - static bool askUserToAllow(bool* remember); - -private: - static HINSTANCE hInstance; -}; -#endif - -#endif
diff --git a/plugins/platform/Win/Preferences.cpp b/plugins/platform/Win/Preferences.cpp deleted file mode 100644 index 7eeb381..0000000 --- a/plugins/platform/Win/Preferences.cpp +++ /dev/null
@@ -1,100 +0,0 @@ -/* - * Copyright 2009 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. - */ - -#include <windows.h> -#include <winnt.h> -#include <winreg.h> -#include "Debug.h" -#include "Preferences.h" -#include "AllowedConnections.h" - -#define REG_ACCESS_LIST "SOFTWARE\\Google\\Google Web Toolkit\\gwt-dev-plugin.accessList" - -/** - * Return a null-terminated string containing the access list. - * - * @param HKEY registry key for the access list value - * @return null-terminated string containing the access list (an empty string - * if the value does not exist) -- caller is responsible for freeing with - * delete[] - */ -static char* getAccessList(HKEY keyHandle) { - char *buf; - DWORD len = 512; - while(true) { - buf = new char[len]; - int cc = RegQueryValueExA(keyHandle, NULL, 0, NULL, (LPBYTE) buf, &len); - if (cc == ERROR_SUCCESS) { - break; - } else if (cc == ERROR_FILE_NOT_FOUND) { - // special handling if the value doesn't exist - len = 0; - break; - } else if (cc != ERROR_MORE_DATA) { - // log unexpected errors - Debug::log(Debug::Error) << "Unable to load access list from registry: " - << cc << Debug::flush; - len = 0; - break; - } - // Buffer wasn't big enough, so make it bigger and try again - delete [] buf; - len *= 2; - } - buf[len] = 0; - return buf; -} - -void Preferences::addNewRule(const std::string& pattern, bool exclude) { - HKEY keyHandle; - if (RegCreateKeyExA(HKEY_CURRENT_USER, REG_ACCESS_LIST, 0, 0, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL) - != ERROR_SUCCESS) { - return; - } - char *buf = getAccessList(keyHandle); - std::string pref(buf); - delete [] buf; - if (pref.length() > 0) { - pref += ','; - } - if (exclude) { - pref += '!'; - } - pref += pattern; - int cc = RegSetValueExA(keyHandle, NULL, 0, REG_SZ, (LPBYTE) pref.c_str(), - pref.length() + 1); - if (cc != ERROR_SUCCESS) { - Debug::log(Debug::Error) << "Unable to store access list in registry: " - << cc << Debug::flush; - } - RegCloseKey(keyHandle); -} - -void Preferences::loadAccessList() { - // TODO(jat): can Reg* routines throw exceptions? If so, we need to make - // this exception safe about closing the key hendle and freeing the buffer. - HKEY keyHandle; - if (RegCreateKeyExA(HKEY_CURRENT_USER, REG_ACCESS_LIST, 0, 0, - REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL) - != ERROR_SUCCESS) { - return; - } - char *buf = getAccessList(keyHandle); - AllowedConnections::initFromAccessList(buf); - delete [] buf; - RegCloseKey(keyHandle); -}
diff --git a/plugins/platform/Win/Preferences.h b/plugins/platform/Win/Preferences.h deleted file mode 100644 index f4fc49b..0000000 --- a/plugins/platform/Win/Preferences.h +++ /dev/null
@@ -1,34 +0,0 @@ -#ifndef _H_Preferences -#define _H_Preferences -/* - * Copyright 2009 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. - */ - -#include <string> - -/** - * Deal with getting/storing/updating preferences in the Windows registry. - */ -class Preferences { -private: - // prevent instantiation - Preferences() {} - -public: - static void loadAccessList(); - static void addNewRule(const std::string& pattern, bool exclude); -}; - -#endif