From 63dc030e321b05faf02248ca266a90dec2aff067 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Fri, 4 May 2012 13:13:11 +0000 Subject: Add new CSS class to the base theme enabling (touch) scrolling of the element (#8716 #8720 #8721 #8722 #8723 #8724 #8725) svn changeset:23677/svn branch:6.8 --- WebContent/VAADIN/themes/base/common/common.css | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'WebContent') diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index 27bc57dd00..adf84ac3b7 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -229,4 +229,9 @@ div.v-app-loading { opacity: 0.5; filter: alpha(opacity=50); cursor: default; +} + +.v-scrollable { + overflow: auto; + -webkit-overflow-scrolling: touch; } \ No newline at end of file -- cgit v1.2.3 From 0bcee7fad275880d2acf5ed4cca34ace42c7481b Mon Sep 17 00:00:00 2001 From: Automerge Date: Wed, 9 May 2012 17:06:15 +0000 Subject: [merge from 6.7] Test case for #8781 svn changeset:23699/svn branch:6.8 --- WebContent/statictestfiles/dummy.zip | Bin 0 -> 138 bytes .../tests/components/window/DownloadAndUpdate.java | 45 +++++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 WebContent/statictestfiles/dummy.zip create mode 100644 tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java (limited to 'WebContent') diff --git a/WebContent/statictestfiles/dummy.zip b/WebContent/statictestfiles/dummy.zip new file mode 100644 index 0000000000..e6e34282fe Binary files /dev/null and b/WebContent/statictestfiles/dummy.zip differ diff --git a/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java b/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java new file mode 100644 index 0000000000..ca9c31513f --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/window/DownloadAndUpdate.java @@ -0,0 +1,45 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.terminal.ExternalResource; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Table; + +public class DownloadAndUpdate extends TestBase { + + @Override + protected void setup() { + addComponent(new Button("Download and update", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + downloadAndUpdate(); + } + })); + } + + protected void downloadAndUpdate() { + getMainWindow().open( + new ExternalResource("/statictestfiles/dummy.zip", "_new")); + + // Any component sending an UIDL request when rendered will likely do + Table table = new Table(); + table.addContainerProperty("A", String.class, ""); + for (int i = 0; i < 100; i++) { + table.addItem(new Object[] { Integer.toString(i) }, + Integer.valueOf(i)); + } + addComponent(table); + } + + @Override + protected String getDescription() { + return "There should be no problems downloading a file from the same request that triggers another request, even in webkit browsers."; + } + + @Override + protected Integer getTicketNumber() { + return Integer.valueOf(8781); + } + +} -- cgit v1.2.3 From 239aad4885931b6e7913ca4c86409b7b6997642f Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Fri, 11 May 2012 14:04:26 +0000 Subject: #8763 Removed overflow: auto from v-panel-content, v-accordion-item-content, and v-view classes; use v-scrollable class in elements that should scroll instead svn changeset:23718/svn branch:6.8 --- WebContent/VAADIN/themes/base/accordion/accordion.css | 1 - WebContent/VAADIN/themes/base/common/common.css | 1 - WebContent/VAADIN/themes/base/panel/panel.css | 1 - 3 files changed, 3 deletions(-) (limited to 'WebContent') diff --git a/WebContent/VAADIN/themes/base/accordion/accordion.css b/WebContent/VAADIN/themes/base/accordion/accordion.css index 10c205ae24..ad762ee0ac 100644 --- a/WebContent/VAADIN/themes/base/accordion/accordion.css +++ b/WebContent/VAADIN/themes/base/accordion/accordion.css @@ -22,6 +22,5 @@ } .v-accordion-item-content { position: absolute; - overflow: auto; width: 100%; } \ No newline at end of file diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index adf84ac3b7..f0b0f8e7be 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -29,7 +29,6 @@ div.v-app-loading { .v-view { height: 100%; width: 100%; - overflow: auto; /* avoid scrollbars with margins in root layout */ outline: none; margin-top: -1px; diff --git a/WebContent/VAADIN/themes/base/panel/panel.css b/WebContent/VAADIN/themes/base/panel/panel.css index 126d3da91c..74d7b67a35 100644 --- a/WebContent/VAADIN/themes/base/panel/panel.css +++ b/WebContent/VAADIN/themes/base/panel/panel.css @@ -29,7 +29,6 @@ overflow: hidden; } .v-panel-content { - overflow: auto; } .v-panel-deco { } \ No newline at end of file -- cgit v1.2.3 From e716b16b6162a90946a926eff3bfd2593f092b69 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Mon, 21 May 2012 12:26:20 +0000 Subject: Remove -webkit-overflow-scrolling from .v-scrollable for now - caused a weird iOS 5 bug in Accordion touch support (#8723 #8792) svn changeset:23770/svn branch:6.8 --- WebContent/VAADIN/themes/base/common/common.css | 1 - 1 file changed, 1 deletion(-) (limited to 'WebContent') diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index f0b0f8e7be..8734aee63f 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -232,5 +232,4 @@ div.v-app-loading { .v-scrollable { overflow: auto; - -webkit-overflow-scrolling: touch; } \ No newline at end of file -- cgit v1.2.3 From 6e960199f98fda0745dd846e786e0e3b625cfcbb Mon Sep 17 00:00:00 2001 From: Marko Grönroos Date: Wed, 30 May 2012 13:30:53 +0000 Subject: Updated Release Notes for Vaadin 6.8 RC1. Cleanup of the invalid HTML formatting. svn changeset:23853/svn branch:6.8 --- WebContent/release-notes.html | 756 ++++++++++++++++++++++++------------------ 1 file changed, 437 insertions(+), 319 deletions(-) (limited to 'WebContent') diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 4574766ea9..3f3cc30a3d 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -1,14 +1,14 @@ - - -Vaadin Framework @version@ - + + + Vaadin Framework @version@ + - - - - - - - + + -
+ -

Version @version@ built on @builddate@.

- -

Release Notes for Vaadin Framework - @version@

- -

Package Contents

-

- Vaadin is a Java framework for building modern web - applications that look great, perform well and make you and your - users happy. Vaadin is available under the Apache 2 license - (see license.html). -

-

- Vaadin is distributed as a single JAR file. Inside the JAR you - will find: -

    -
  • Vaadin server and client side classes (/com)
  • -
  • Vaadin server and client side sources (/com)
  • -
  • The default widget set (/VAADIN/widgetsets)
  • -
  • Themes: Runo, Reindeer and Chameleon (/VAADIN/themes)
  • -
  • Release notes (/release-notes.html)
  • -
  • Licensing information (/license.html)
  • -
-

+ - - -

Enhancements in Vaadin @version-minor@

-

- TODO: Enhancements -

-

TOdO: Enhancements.

-

Fixes in Vaadin @version@

- -

- TODO: Ticket list -

-

- The full - details of the defects can be found at dev.vaadin.com. -

- -

Backwards incompatible - changes in Vaadin @version-minor@

-

VerticalSplitPanel and HorizontalSplitPanel position is now a float instead of an int to enable defining an exact position when using percentages.

+
-

Vaadin @version@ dependencies

+

Version @version@ built on @builddate@.

+ + +

Release Notes for Vaadin Framework @version@

+ + + +

Overview of Vaadin @version-minor@ Release

+ +

+ Vaadin is a Java application development framework for building modern web + applications that look great, perform well and make you and your users + happy. Vaadin is available under the Apache 2 license (see + license.html in the JAR). +

+ +

+ This release @version-minor@ includes a number of significant enhancements in + addition to many bug fixes. +

+ + +

Enhancements in Vaadin @version-minor@

+ +
    +
  • +

    Native scrolling support for Android and iOS (#8763)

    +
      +
    • +

      Non-native scrolling implementation used in iOS 5 because of an iOS bug (see #8792)

      +
    • +
    +
  • +
  • +

    Possibility to fire Button click events on the server-side (#8209)

    +
  • +
  • +

    Possibility to use HTML inside a Button caption (#8663)

    +
  • +
  • +

    Possibility to set "alternative text" (alt attribute) for the Embedded component (#6085)

    +
  • +
  • +

    Keyboard navigation in TabSheet (#5100)

    +
  • + +
  • +

    Max/min limits for splitter position in SplitPanel (#1744)

    +
  • +
  • +

    Extended day range in month view to six full weeks in DateField (#6718)

    +
  • +
  • +

    Uncollapseable Table columns (#7495)

    +
  • +
  • +

    Debug IDs unique to a window (#5109)

    +
  • +
+ +

+ Also note: +

+ +
    +
  • +

    A separate add-on will be released for handling broken classloaders (#8447)

    +
  • +
+ + + + + + + +

Changes in Vaadin @version@

+ +

+ This release includes the following changes: +

+ +
    +
  • #1744: SplitPanel could have setMaxSplitPosition and setMinSplitPosition methods
  • +
  • #3789: Create integration test for WebSphere Application Server 8
  • +
  • #4296: SplitPanel percentage position rounding error after splitter drag
  • +
  • #5100: TabSheet keyboard navigation
  • +
  • #5109: DebugId should be window unique, not application unique
  • +
  • #5655: Add getClientWidth() and getClientHeight() to WebBrowser
  • +
  • #6085: It should be possible to set the alternate text for embedded images
  • +
  • #6155: Memory leak in AbstractField when PropertyDataSources are used
  • +
  • #6718: PopupDateField: extend its range
  • +
  • #7002: Changing Slider orientation breaks it completely
  • +
  • #7495: Table: Make some columns uncollapsable
  • +
  • #7614: Add getComponentIndex(Component) and getComponent(int) to CssLayout
  • +
  • #7718: Table footers are visible in IE6/IE7 even though footers have been turned off (Chameleon)
  • +
  • #7772: Create build configurations for Vaadin 6.8
  • +
  • #7773: Create branch for Vaadin 6.8
  • +
  • #7816: Ensure an application that uses injection works on IBM WebSphere v8
  • +
  • #7833: Make DragAndDropWrapper capable of starting an HTML5 drag
  • +
  • #7911: Touch device identifiers to div.v-app
  • +
  • #7931: Invalid top level window size for embedded applications
  • +
  • #7975: Remove non-core classes from main source directory
  • +
  • #8203: Add setSelectedTab(TabSheet.Tab) to TabSheet API
  • +
  • #8209: Button: add public click() method
  • +
  • #8216: Warning when compiling the widgetset
  • +
  • #8307: Add Field.removeAllValidators
  • +
  • #8428: Field ROW_HEADER_FAKE_PROPERTY_ID in com.vaadin.ui.Table does not implement Serializable
  • +
  • #8523: Change the default size for the debug window
  • +
  • #8551: Notifications are displayed in parts on an Asus TF101
  • +
  • #8600: Tree.hasChildren() works incorrectly after all children were removed
  • +
  • #8637: Nightly builds are not deployed to Maven
  • +
  • #8638: Build should fail with an error if Maven deployment fails
  • +
  • #8653: TabSheet#getTab(int) unintentionally throws if index out of bounds
  • +
  • #8659: Not possible to have editable cell in a table on IPad with IOS 5.x
  • +
  • #8663: html in buttons is not possible
  • +
  • #8693: setVisibile() in InlineDateSelect doesn't work correctly
  • +
  • #8694: Provide profiling data for TestBench
  • +
  • #8699: Wrap javascript callback entry points in $entry
  • +
  • #8716: Implement native scrolling support for Panel (Android 3+ & iOS 5+)
  • +
  • #8720: Implement native scrolling support for Tabsheet (Android 3+ & iOS 5+)
  • +
  • #8721: Implement native scrolling support for Window/root (Android 3+ & iOS 5+)
  • +
  • #8722: Implement native scrolling support for sub windows (Android 3+ & iOS 5+)
  • +
  • #8723: Implement native scrolling support for Accordion (Android 3+ & iOS 5+)
  • +
  • #8724: Implement native scrolling support for Table (Android 3+ & iOS 5+)
  • +
  • #8725: Implement native scrolling support for SplitPanel (Android 3+ & iOS 5+)
  • +
  • #8739: Test using Firefox 12
  • +
  • #8763: Do some groundwork to make implementing touch scrolling in various components easier
  • +
+ +

+ The full + list of the changes can be found at dev.vaadin.com. +

+ + +

Package Contents

+ +

+ Vaadin Framework is distributed as a single JAR file. Inside the JAR you will + find: +

+ +
    +
  • Vaadin server and client side classes (/com)
  • +
  • Vaadin server and client side sources (/com)
  • +
  • The default widget set (/VAADIN/widgetsets)
  • +
  • Themes: Runo, Reindeer and Chameleon (/VAADIN/themes)
  • +
  • Release notes (/release-notes.html)
  • +
  • Licensing information (/license.html)
  • +
+ + +

Vaadin @version@ dependencies

+ +

Vaadin uses GWT @gwt-version@ for widget set compilation. GWT can be downloaded from http://code.google.com/webtoolkit/. GWT can also be automatically downloaded by the Vaadin Plug-in for Eclipse. Please note that GWT @gwt-version@ requires the validation-api-1.0.0.GA.jar and validation-api-1.0.0.GA-sources.jar files in addition to gwt-dev.jar and gwt-user.jar for widget set compilation. - -

Upgrading to Vaadin @version-minor@

-

- When upgrading from an earlier Vaadin version, you must -

    -
  • Recompile your classes using the new Vaadin JAR. Binary - compatibility is only guaranteed for maintenance releases of - Vaadin.
  • -
  • Recompile any add-ons you have created using the new Vaadin - JAR.
  • -
  • Recompile your widget set using the new Vaadin JAR and the - newly compiled add-ons.
  • -
  • If you have extracted a theme from the Vaadin JAR, you need - to update it with the theme provided in the new Vaadin JAR.
  • -
-

-

Remember also to refresh the project in your IDE to ensure that - the new version of everything is in use.

-

Using the "?debug" URL parameter you can verify that the - version of the servlet (JAR), the theme and the widgetset all match.

-

- Eclipse users should always check if there is a new version of - the Eclipse Plug-in available. The Eclipse Plug-in can be used to - update the Vaadin version in the project (Project properties » - Vaadin). -

- -

- Maven users should update the Vaadin dependency version in the - pom.xml - unless it is defined as - LATEST - . You must also ensure that the GWT dependency uses the correct - version and recompile your project and your widget set. - +

+ + +

Upgrading to Vaadin @version-minor@

+ +

+ When upgrading from an earlier Vaadin version, you must: +

+ +
    +
  • Recompile your classes using the new Vaadin JAR. Binary + compatibility is only guaranteed for maintenance releases of + Vaadin.
  • +
  • Recompile any add-ons you have created using the new Vaadin + JAR.
  • +
  • Recompile your widget set using the new Vaadin JAR and the + newly compiled add-ons.
  • +
  • If you have extracted a theme from the Vaadin JAR, you need + to update it with the theme provided in the new Vaadin JAR.
  • +
+ +

Remember also to refresh the project in your IDE to ensure that the new version + of everything is in use.

+ +

Using the "?debug" URL parameter you can verify that the + version of the servlet (JAR), the theme and the widgetset all match.

+ +

+ Eclipse users should always check if there is a new version of the Eclipse + Plug-in available. The Eclipse Plug-in can be used to update the Vaadin version in + the project (Project properties » Vaadin). +

+ +

+ Maven users should update the Vaadin dependency version in the + pom.xml unless it is defined as LATEST . You must also ensure + that the GWT dependency uses the correct version and recompile your project and + your widget set.

+

Liferay and other portal users must install the new vaadin-@version@.jar as - ROOT/WEB-INF/lib/vaadin.jar in the portal. Additionally the + ROOT/WEB-INF/lib/vaadin.jar in the portal. Additionally the contents of the VAADIN folder from the JAR must be extracted to the ROOT/html/VAADIN directory in the Liferay installation. If your portal uses custom widgets, install the latest version of Vaadin Control Panel for Liferay for easy widget set compilation. +

-

Upgrading from Vaadin 6.5 or earlier

+

Upgrading from Vaadin 6.5 or earlier

+ +

If you are upgrading from 6.5.x or earlier, notice that Vaadin @version@ uses GWT @gwt-version@. Upgrade your dependencies as necessary. See the dependencies section for more information. -

+

-

Upgrading from Vaadin 6.1 or earlier

+

Upgrading from Vaadin 6.1 or earlier

-

- The way widget sets are created was completely changed in Vaadin 6.2. - Existing projects, where custom widgets (a custom widget set) are - used, must be migrated when upgrading to Vaadin 6.2 or later. - Projects where the default widget set is used do not need migration. - See Vaadin - 6.2.0 release notes for more details. -

+

+ The way widget sets are created was completely changed in Vaadin 6.2. Existing + projects, where custom widgets (a custom widget set) are used, must be migrated + when upgrading to Vaadin 6.2 or later. Projects where the default widget set is + used do not need migration. See Vaadin + 6.2.0 release notes for more details. +

-

Notes and Limitations for Google App Engine

+

Notes and Limitations for Google App Engine

-

The following instructions and limitations apply when you run a - Vaadin application under the Google App Engine.

+

+ The following instructions and limitations apply when you run a Vaadin application + under the Google App Engine. +

-
- - + + +
  • Avoid using the session for storage, usual App Engine + limitations apply (no synchronization, i.e, unreliable).

    +
  • + +
  • + Vaadin uses memcache for mutex, the key is of the form + _vmutex<sessionid>. +

    +
  • + +
  • +

    The Vaadin WebApplicationContext class is serialized separately into + memcache and datastore; the memcache key is _vac<sessionid> and + the datastore entity kind is _vac with identifiers of the type + _vac<sessionid>.

    +
  • + +
  • +

    DO NOT update application state when serving an ApplicationResource + (e.g ClassResource.getStream()).

    +
  • + +
  • +

    + AVOID (or be very careful when) updating application state in a + TransactionListener or a HttpServletRequestListener - they are + called even when the application is not locked and won't be serialized (e.g + ApplicationResource), and changes can thus go missing (it should be + safe to update things that can be safely discarded later - i.e valid only for + the current request) +

    +
  • + +
  • +

    + The application remains locked during uploads - a progress bar is not + possible +

    +
  • + + +

    + For other known problems, see open tickets at developer site dev.vaadin.com. +

    + + +

    Supported technologies

    + +

    + Vaadin is based on Java 5 and it is also compatible with most other + operating system supporting Java 5 or newer. Vaadin is supported on the following + operating systems: +

    + +
      +
    • Windows
    • +
    • Linux
    • +
    • Mac OS X
    • +
    + +

    + Vaadin requires Java Servlet API 2.3 but also supports later versions and + should work with any Java application server that conforms to the standard. The + following application servers are supported: +

    + +
      +
    • Apache Tomcat, version 4.1-7.0
    • +
    • Oracle WebLogic® Server, version 9.2-10.3.5(11gR1)
    • +
    • IBM WebSphere® Application Server, version 6.1-8.0
    • +
    • JBoss Application Server, 3.2.8-7.0
    • +
    • Jetty, version 5.0-7.0
    • +
    • Glassfish, version 2.0-3.1
    • +
    + +

    + Vaadin supports JSR-168 and JSR-286 Portlet specifications. All portals that + implement either of the portlet specifications should work. The following + portals are supported: +

    + +
      +
    • Liferay Portal 5.2-6.0
    • +
    • GateIn Portal 3.1
    • +
    • eXo Platform 3
    • +
    • Oracle WebLogic® Portal 10gR3
    • +
    • WebSphere Portal 6.1-7.0
    • +
    + +

    + Vaadin also supports Google App Engine. +

    + +

    + Vaadin supports the following browsers: +

    + +
      +
    • Mozilla Firefox 3-11
    • +
    • Internet Explorer 6-9
    • +
    • Safari 4-5
    • +
    • Opera 10-11
    • +
    • Google Chrome 13-19
    • +
    + +

    + Vaadin supports the built-in browsers in the following mobile operating + systems: +

    + +
      +
    • iOS 4-5
    • +
    • Android 2-3
    • +
    + + +

    Vaadin on the Web

    + + +
    - - - - \ No newline at end of file + vaadin }> thinking of U and I + ↑ Back to top + + + + + + -- cgit v1.2.3 From 052feb7be25e3f18bd751877b306d8247098d7f3 Mon Sep 17 00:00:00 2001 From: Artur Signell Date: Tue, 15 May 2012 05:17:49 +0300 Subject: Fixed header height by taking padding into account (box sizing change) --- WebContent/VAADIN/themes/liferay/window/window.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'WebContent') diff --git a/WebContent/VAADIN/themes/liferay/window/window.css b/WebContent/VAADIN/themes/liferay/window/window.css index 5ac7c02175..f034d7503f 100644 --- a/WebContent/VAADIN/themes/liferay/window/window.css +++ b/WebContent/VAADIN/themes/liferay/window/window.css @@ -11,7 +11,7 @@ } .v-window-outerheader { - height: 16px; + height: 38px; margin-left: 9px; padding: 10px 40px 12px 2px; background: transparent url(top-right.png) no-repeat right top; -- cgit v1.2.3 From abdc1ee5c270658b9f361cace015ff27cc448a68 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Fri, 1 Jun 2012 12:19:05 +0000 Subject: Update supported platforms to include Firefox 12, Android 4 svn changeset:23874/svn branch:6.8 --- WebContent/release-notes.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'WebContent') diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 3f3cc30a3d..ef27d8de8c 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -406,7 +406,7 @@

      -
    • Mozilla Firefox 3-11
    • +
    • Mozilla Firefox 3-12
    • Internet Explorer 6-9
    • Safari 4-5
    • Opera 10-11
    • @@ -420,7 +420,7 @@
      • iOS 4-5
      • -
      • Android 2-3
      • +
      • Android 2-4
      -- cgit v1.2.3 From 9cffab9586b2a2e6e0ecbd540374c98ff792a27e Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Thu, 7 Jun 2012 15:13:16 +0000 Subject: Fixed non-matching header close tags, added link to classloader workaround svn changeset:23912/svn branch:6.8 --- WebContent/release-notes.html | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'WebContent') diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index ef27d8de8c..64243f50f3 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -71,7 +71,7 @@

      -

      Enhancements in Vaadin @version-minor@

      +

      Enhancements in Vaadin @version-minor@

      • @@ -94,7 +94,6 @@
      • Keyboard navigation in TabSheet (#5100)

      • -
      • Max/min limits for splitter position in SplitPanel (#1744)

      • @@ -102,20 +101,18 @@

        Extended day range in month view to six full weeks in DateField (#6718)

      • -

        Uncollapseable Table columns (#7495)

        +

        Non-collapsible Table columns (#7495)

      • Debug IDs unique to a window (#5109)

      • -
      - -

      - Also note: -

      - - @@ -123,14 +120,14 @@ -

      Changes in Vaadin @version@

      +

      Changes in Vaadin @version@

      This release includes the following changes: @@ -191,7 +188,7 @@

      -

      Package Contents

      +

      Package Contents

      Vaadin Framework is distributed as a single JAR file. Inside the JAR you will @@ -208,7 +205,7 @@

    -

    Vaadin @version@ dependencies

    +

    Vaadin @version@ dependencies

    Vaadin uses GWT @gwt-version@ for widget set compilation. GWT can be -- cgit v1.2.3 From 6940761ffbdad2624c92f3a1f99bc4040f018bf0 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Fri, 8 Jun 2012 11:02:54 +0000 Subject: Added more highlighted features to the release notes svn changeset:23918/svn branch:6.8 --- WebContent/release-notes.html | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'WebContent') diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 64243f50f3..83b41b32dd 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -91,6 +91,9 @@

  • Possibility to set "alternative text" (alt attribute) for the Embedded component (#6085)

  • +
  • +

    Possibility to query the browser window width and height on the server-side (#5655)

    +
  • Keyboard navigation in TabSheet (#5100)

  • @@ -104,7 +107,22 @@

    Non-collapsible Table columns (#7495)

  • -

    Debug IDs unique to a window (#5109)

    +

    Selecting a TabSheet tab by its position or a Tab instance (#8203)

    +
  • +
  • +

    Getting a component by its index or the index of a given component in CssLayout (#7614)

    +
  • +
  • +

    Removing all Validators of a Field at once (#8307)

    +
  • +
  • +

    Debug IDs unique to a window, not the whole application (#5109)

    +
  • +
  • +

    Larger default size for the debug window (#8523)

    +
  • +
  • +

    Compatibility with Google SuperDevMode (#8924)

  • An add-on for handling broken classloaders (#8447)

    -- cgit v1.2.3 From 398487ab5ecf9f4f144d9ce462460cae2b069ed2 Mon Sep 17 00:00:00 2001 From: Marko Grönroos Date: Fri, 8 Jun 2012 14:26:45 +0000 Subject: Updated changelog. Changed formatting of enhancements list. svn changeset:23921/svn branch:6.8 --- WebContent/release-notes.html | 51 +++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'WebContent') diff --git a/WebContent/release-notes.html b/WebContent/release-notes.html index 83b41b32dd..21f13e075e 100644 --- a/WebContent/release-notes.html +++ b/WebContent/release-notes.html @@ -75,60 +75,60 @@
    • -

      Native scrolling support for Android and iOS (#8763)

      + Native scrolling support for Android and iOS (#8763)
      • -

        Non-native scrolling implementation used in iOS 5 because of an iOS bug (see #8792)

        + Non-native scrolling implementation used in iOS 5 because of an iOS bug (see #8792)
    • -

      Possibility to fire Button click events on the server-side (#8209)

      + Possibility to fire Button click events on the server-side (#8209)
    • -

      Possibility to use HTML inside a Button caption (#8663)

      + Possibility to use HTML inside a Button caption (#8663)
    • -

      Possibility to set "alternative text" (alt attribute) for the Embedded component (#6085)

      + Possibility to set "alternative text" (alt attribute) for the Embedded component (#6085)
    • -

      Possibility to query the browser window width and height on the server-side (#5655)

      + Possibility to query the browser window width and height on the server-side (#5655)
    • -

      Keyboard navigation in TabSheet (#5100)

      + Keyboard navigation in TabSheet (#5100)
    • -

      Max/min limits for splitter position in SplitPanel (#1744)

      + Max/min limits for splitter position in SplitPanel (#1744)
    • -

      Extended day range in month view to six full weeks in DateField (#6718)

      + Extended day range in month view to six full weeks in DateField (#6718)
    • -

      Non-collapsible Table columns (#7495)

      + Non-collapsible Table columns (#7495)
    • -

      Selecting a TabSheet tab by its position or a Tab instance (#8203)

      + Selecting a TabSheet tab by its position or a Tab instance (#8203)
    • -

      Getting a component by its index or the index of a given component in CssLayout (#7614)

      + Getting a component by its index or the index of a given component in CssLayout (#7614)
    • -

      Removing all Validators of a Field at once (#8307)

      + Removing all Validators of a Field at once (#8307)
    • -

      Debug IDs unique to a window, not the whole application (#5109)

      + Debug IDs unique to a window, not the whole application (#5109)
    • -

      Larger default size for the debug window (#8523)

      + Larger default size for the debug window (#8523)
    • -

      Compatibility with Google SuperDevMode (#8924)

      + Compatibility with Google SuperDevMode (#8924)
    • -

      An add-on for handling broken classloaders (#8447)

      + An add-on for handling broken classloaders (#8447)
    • @@ -165,18 +165,26 @@
    • #7495: Table: Make some columns uncollapsable
    • #7614: Add getComponentIndex(Component) and getComponent(int) to CssLayout
    • #7718: Table footers are visible in IE6/IE7 even though footers have been turned off (Chameleon)
    • +
    • #7771: Update to GWT 2.4
    • #7772: Create build configurations for Vaadin 6.8
    • #7773: Create branch for Vaadin 6.8
    • #7816: Ensure an application that uses injection works on IBM WebSphere v8
    • #7833: Make DragAndDropWrapper capable of starting an HTML5 drag
    • +
    • #7865: "Tutorial uses deprecated ""SplitPanel"" rather than ""HorizontalSplitPanel""."
    • #7911: Touch device identifiers to div.v-app
    • #7931: Invalid top level window size for embedded applications
    • #7975: Remove non-core classes from main source directory
    • #8203: Add setSelectedTab(TabSheet.Tab) to TabSheet API
    • #8209: Button: add public click() method
    • #8216: Warning when compiling the widgetset
    • +
    • #8289: Replace @ClientWidget annotation with an annotation that uses String instead of Class
    • +
    • #8297: Static logger instances can cause memory leakage on redeploy
    • #8307: Add Field.removeAllValidators
    • +
    • #8332: Vaadin should use -webkit-overflow-scroll: touch for modern devices and also consider to use GWT:s TouchScroller helper
    • #8428: Field ROW_HEADER_FAKE_PROPERTY_ID in com.vaadin.ui.Table does not implement Serializable
    • +
    • #8447: Provide a compatibility jar file for servers that use broken classloaders
    • +
    • #8451: Error while deploying Vaadin application on Websphere Application Server 8.0
    • +
    • #8513: Remove steps from Tutorial project
    • #8523: Change the default size for the debug window
    • #8551: Notifications are displayed in parts on an Asus TF101
    • #8600: Tree.hasChildren() works incorrectly after all children were removed
    • @@ -196,7 +204,12 @@
    • #8724: Implement native scrolling support for Table (Android 3+ & iOS 5+)
    • #8725: Implement native scrolling support for SplitPanel (Android 3+ & iOS 5+)
    • #8739: Test using Firefox 12
    • -
    • #8763: Do some groundwork to make implementing touch scrolling in various components easier
    • +
    • #8763: Utilities for native touch scrolling on Android 4+ and iOS 5+
    • +
    • #8798: NPE from RequestTimer prevents showing the real error
    • +
    • #8878: VFilterSelect should implement SubPartAware to always be able to find the text box
    • +
    • #8914: Show better error message when variable change decoding fails
    • +
    • #8923: ?debug=quiet not working with / in uri fragment
    • +
    • #8924: Remove document.write from bootstrap to enable using SuperDevMode

    -- cgit v1.2.3 From 24e3409e6ff117ff954f36a9c9378690c76634f8 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Sun, 10 Jun 2012 15:10:10 +0300 Subject: Initial support for javascript components (#8888) --- WebContent/statictestfiles/jsconnector.js | 12 ++ WebContent/statictestfiles/jsextension.js | 13 ++ src/com/vaadin/annotations/LoadScripts.java | 16 ++ .../terminal/AbstractJavascriptExtension.java | 9 ++ .../terminal/gwt/client/ApplicationConnection.java | 43 ++--- .../gwt/client/JavascriptConnectorHelper.java | 179 +++++++++++++++++++++ .../terminal/gwt/client/JavascriptExtension.java | 33 ++++ src/com/vaadin/terminal/gwt/client/WidgetSet.java | 8 +- .../HasJavascriptConnectorHelper.java | 11 ++ .../gwt/client/communication/JsonEncoder.java | 2 + .../gwt/client/communication/RpcManager.java | 59 +++++-- .../client/ui/JavascriptComponentConnector.java | 60 +++++++ .../terminal/gwt/client/ui/JavascriptWidget.java | 25 +++ .../terminal/gwt/server/BootstrapHandler.java | 57 ++++++- src/com/vaadin/ui/AbstractJavascriptComponent.java | 8 + .../BasicJavascriptComponent.java | 73 +++++++++ .../features/SimpleJavascriptExtensionTest.java | 95 +++++++++++ 17 files changed, 658 insertions(+), 45 deletions(-) create mode 100644 WebContent/statictestfiles/jsconnector.js create mode 100644 WebContent/statictestfiles/jsextension.js create mode 100644 src/com/vaadin/annotations/LoadScripts.java create mode 100644 src/com/vaadin/terminal/AbstractJavascriptExtension.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptExtension.java create mode 100644 src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java create mode 100644 src/com/vaadin/ui/AbstractJavascriptComponent.java create mode 100644 tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java create mode 100644 tests/testbench/com/vaadin/tests/features/SimpleJavascriptExtensionTest.java (limited to 'WebContent') diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js new file mode 100644 index 0000000000..db8a065e86 --- /dev/null +++ b/WebContent/statictestfiles/jsconnector.js @@ -0,0 +1,12 @@ +window.com_vaadin_tests_components_javascriptcomponent_BasicJavascriptComponent_ExampleWidget = function() { + var connector = this; + + var rootElement = connector.getWidgetElement(); + rootElement.innerHTML = 'Hello world!'; + rootElement.onclick = function() { + connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavascriptComponent$ExampleClickRpc", "onClick")("message"); + } + connector.onStateChange = function() { + console.log('state change:', this.getState()); + } +} \ No newline at end of file diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js new file mode 100644 index 0000000000..df67db8927 --- /dev/null +++ b/WebContent/statictestfiles/jsextension.js @@ -0,0 +1,13 @@ +window.com_vaadin_tests_features_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { + var state = this.getState(); + var greetBack = this.getRpcProxyFunction('com.vaadin.tests.features.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); + + this.registerRpc("com.vaadin.tests.features.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { + 'greet': function(greeting) { + var response = window.prompt(state.prefix + greeting); + if (response !== null) { + greetBack(response); + } + } + }); +} \ No newline at end of file diff --git a/src/com/vaadin/annotations/LoadScripts.java b/src/com/vaadin/annotations/LoadScripts.java new file mode 100644 index 0000000000..f2b72407f7 --- /dev/null +++ b/src/com/vaadin/annotations/LoadScripts.java @@ -0,0 +1,16 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +public @interface LoadScripts { + public String[] value(); + +} diff --git a/src/com/vaadin/terminal/AbstractJavascriptExtension.java b/src/com/vaadin/terminal/AbstractJavascriptExtension.java new file mode 100644 index 0000000000..c86f69c1be --- /dev/null +++ b/src/com/vaadin/terminal/AbstractJavascriptExtension.java @@ -0,0 +1,9 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +public class AbstractJavascriptExtension extends AbstractExtension { + +} diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index 0a954f530b..93a51e6e96 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -40,6 +40,7 @@ import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage; +import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; import com.vaadin.terminal.gwt.client.communication.JsonDecoder; import com.vaadin.terminal.gwt.client.communication.JsonEncoder; import com.vaadin.terminal.gwt.client.communication.MethodInvocation; @@ -1411,12 +1412,19 @@ public class ApplicationConnection { .getConnector(connectorId); if (null != connector) { - JSONObject stateDataAndType = new JSONObject( + JSONObject stateJson = new JSONObject( states.getJavaScriptObject(connectorId)); + if (connector instanceof HasJavascriptConnectorHelper) { + ((HasJavascriptConnectorHelper) connector) + .getJavascriptConnectorHelper() + .setNativeState( + stateJson.getJavaScriptObject()); + } + SharedState state = connector.getState(); JsonDecoder.decodeValue(new Type(state.getClass() - .getName(), null), stateDataAndType, state, + .getName(), null), stateJson, state, ApplicationConnection.this); StateChangeEvent event = GWT @@ -1557,11 +1565,8 @@ public class ApplicationConnection { for (int i = 0; i < rpcLength; i++) { try { JSONArray rpcCall = (JSONArray) rpcCalls.get(i); - MethodInvocation invocation = parseMethodInvocation(rpcCall); - VConsole.log("Server to client RPC call: " - + invocation); - rpcManager.applyInvocation(invocation, - getConnectorMap()); + rpcManager.parseAndApplyInvocation(rpcCall, + ApplicationConnection.this); } catch (final Throwable e) { VConsole.error(e); } @@ -1574,26 +1579,6 @@ public class ApplicationConnection { ApplicationConfiguration.runWhenWidgetsLoaded(c); } - private MethodInvocation parseMethodInvocation(JSONArray rpcCall) { - String connectorId = ((JSONString) rpcCall.get(0)).stringValue(); - String interfaceName = ((JSONString) rpcCall.get(1)).stringValue(); - String methodName = ((JSONString) rpcCall.get(2)).stringValue(); - JSONArray parametersJson = (JSONArray) rpcCall.get(3); - - MethodInvocation methodInvocation = new MethodInvocation(connectorId, - interfaceName, methodName); - Type[] parameterTypes = rpcManager.getParameterTypes(methodInvocation); - - Object[] parameters = new Object[parametersJson.size()]; - for (int j = 0; j < parametersJson.size(); ++j) { - parameters[j] = JsonDecoder.decodeValue(parameterTypes[j], - parametersJson.get(j), null, this); - } - - methodInvocation.setParameters(parameters); - return methodInvocation; - } - // Redirect browser, null reloads current page private static native void redirect(String url) /*-{ @@ -2142,8 +2127,8 @@ public class ApplicationConnection { private ServerConnector createAndRegisterConnector(String connectorId, int connectorType) { // Create and register a new connector with the given type - ServerConnector p = widgetSet - .createConnector(connectorType, configuration); + ServerConnector p = widgetSet.createConnector(connectorType, + configuration); connectorMap.registerConnector(connectorId, p); p.doInit(connectorId, this); diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java new file mode 100644 index 0000000000..633a4bc2c6 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java @@ -0,0 +1,179 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.ArrayList; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.json.client.JSONArray; +import com.vaadin.terminal.gwt.client.communication.MethodInvocation; + +public class JavascriptConnectorHelper { + + private final ServerConnector connector; + private final JavaScriptObject nativeState = JavaScriptObject + .createObject(); + private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); + + private JavaScriptObject connectorWrapper; + private int tag; + + public JavascriptConnectorHelper(ServerConnector connector) { + this.connector = connector; + } + + public boolean init() { + ApplicationConfiguration conf = connector.getConnection() + .getConfiguration(); + ArrayList attemptedNames = new ArrayList(); + Integer tag = Integer.valueOf(this.tag); + while (tag != null) { + String serverSideClassName = conf.getServerSideClassNameForTag(tag); + String initFunctionName = serverSideClassName + .replaceAll("\\.", "_"); + if (tryInitJs(initFunctionName, getConnectorWrapper())) { + VConsole.log("Javascript connector initialized using " + + initFunctionName); + return true; + } else { + VConsole.log("No javascript function " + initFunctionName + + " found"); + attemptedNames.add(initFunctionName); + tag = conf.getParentTag(tag.intValue()); + } + } + VConsole.log("No javascript init for connector not found"); + showInitProblem(attemptedNames); + return false; + } + + protected void showInitProblem(ArrayList attemptedNames) { + // Default does nothing + } + + private static native boolean tryInitJs(String initFunctionName, + JavaScriptObject connectorWrapper) + /*-{ + if (typeof $wnd[initFunctionName] == 'function') { + $wnd[initFunctionName].apply(connectorWrapper); + return true; + } else { + return false; + } + }-*/; + + private JavaScriptObject getConnectorWrapper() { + if (connectorWrapper == null) { + connectorWrapper = createConnectorWrapper(); + } + + return connectorWrapper; + } + + protected JavaScriptObject createConnectorWrapper() { + return createConnectorWrapper(this, nativeState, rpcMap, + connector.getConnectorId()); + } + + public void fireNativeStateChange() { + fireNativeStateChange(getConnectorWrapper()); + } + + private static native void fireNativeStateChange( + JavaScriptObject connectorWrapper) + /*-{ + if (typeof connectorWrapper.onStateChange == 'function') { + connectorWrapper.onStateChange(); + } + }-*/; + + private static native JavaScriptObject createConnectorWrapper( + JavascriptConnectorHelper h, JavaScriptObject nativeState, + JavaScriptObject registeredRpc, String connectorId) + /*-{ + return { + 'getConnectorId': function() { + return connectorId; + }, + 'getState': function() { + return nativeState; + }, + 'getRpcProxyFunction': function(iface, method) { + return $entry(function() { + h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); + }); + }, + 'registerRpc': function(iface, rpcHandler) { + if (!registeredRpc[iface]) { + registeredRpc[iface] = []; + } + registeredRpc[iface].push(rpcHandler); + }, + }; + }-*/; + + private void fireRpc(String iface, String method, + JsArray arguments) { + JSONArray argumentsArray = new JSONArray(arguments); + Object[] parameters = new Object[arguments.length()]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = argumentsArray.get(i); + } + connector.getConnection().addMethodInvocationToQueue( + new MethodInvocation(connector.getConnectorId(), iface, method, + parameters), true); + } + + public void setNativeState(JavaScriptObject state) { + updateNativeState(nativeState, state); + } + + private static native void updateNativeState(JavaScriptObject state, + JavaScriptObject input) + /*-{ + // Copy all fields to existing state object + for(var key in state) { + if (state.hasOwnProperty(key)) { + delete state[key]; + } + } + + for(var key in input) { + if (input.hasOwnProperty(key)) { + state[key] = input[key]; + } + } + }-*/; + + public Object[] decodeRpcParameters(JSONArray parametersJson) { + return new Object[] { parametersJson.getJavaScriptObject() }; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public void invokeJsRpc(MethodInvocation invocation, + JSONArray parametersJson) { + invokeJsRpc(rpcMap, invocation.getInterfaceName(), + invocation.getMethodName(), + parametersJson.getJavaScriptObject()); + } + + private static native void invokeJsRpc(JavaScriptObject rpcMap, + String interfaceName, String methodName, JavaScriptObject parameters) + /*-{ + var targets = rpcMap[interfaceName]; + if (!targets) { + return; + } + for(var i = 0; i < targets.length; i++) { + var target = targets[i]; + target[methodName].apply(target, parameters); + } + }-*/; + +} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java new file mode 100644 index 0000000000..6c098a52f6 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java @@ -0,0 +1,33 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import com.vaadin.terminal.AbstractJavascriptExtension; +import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.ui.AbstractConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; + +@Connect(AbstractJavascriptExtension.class) +public class JavascriptExtension extends AbstractConnector implements + HasJavascriptConnectorHelper { + private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( + this); + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + public JavascriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index d7cc2df00d..ecbfb0ecc9 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -5,6 +5,7 @@ package com.vaadin.terminal.gwt.client; import com.google.gwt.core.client.GWT; +import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; public class WidgetSet { @@ -52,7 +53,12 @@ public class WidgetSet { /* * let the auto generated code instantiate this type */ - return widgetMap.instantiate(classType); + ServerConnector connector = widgetMap.instantiate(classType); + if (connector instanceof HasJavascriptConnectorHelper) { + ((HasJavascriptConnectorHelper) connector) + .getJavascriptConnectorHelper().setTag(tag); + } + return connector; } } diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java new file mode 100644 index 0000000000..74bc75da66 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java @@ -0,0 +1,11 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.communication; + +import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; + +public interface HasJavascriptConnectorHelper { + public JavascriptConnectorHelper getJavascriptConnectorHelper(); +} diff --git a/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java b/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java index 657f44896d..cb7dbe5e72 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java +++ b/src/com/vaadin/terminal/gwt/client/communication/JsonEncoder.java @@ -59,6 +59,8 @@ public class JsonEncoder { boolean restrictToInternalTypes, ApplicationConnection connection) { if (null == value) { return JSONNull.getInstance(); + } else if (value instanceof JSONValue) { + return (JSONValue) value; } else if (value instanceof String[]) { String[] array = (String[]) value; JSONArray jsonArray = new JSONArray(); diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java index 1d3447687d..e0ffb40125 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java +++ b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java @@ -9,8 +9,12 @@ import java.util.HashMap; import java.util.Map; import com.google.gwt.core.client.GWT; +import com.google.gwt.json.client.JSONArray; +import com.google.gwt.json.client.JSONString; +import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.ConnectorMap; import com.vaadin.terminal.gwt.client.ServerConnector; +import com.vaadin.terminal.gwt.client.VConsole; /** * Client side RPC manager that can invoke methods based on RPC calls received @@ -41,20 +45,10 @@ public class RpcManager { * * @param invocation * method to invoke - * @param connectorMap - * mapper used to find Connector for the method call and any - * connectors referenced in parameters */ public void applyInvocation(MethodInvocation invocation, - ConnectorMap connectorMap) { - ServerConnector connector = connectorMap.getConnector(invocation - .getConnectorId()); + ServerConnector connector) { String signature = getSignature(invocation); - if (connector == null) { - throw new IllegalStateException("Target connector (" - + invocation.getConnectorId() + ") not found for RCC to " - + signature); - } RpcMethod rpcMethod = getRpcMethod(signature); Collection implementations = connector @@ -82,4 +76,47 @@ public class RpcManager { return getRpcMethod(getSignature(invocation)).getParameterTypes(); } + public void parseAndApplyInvocation(JSONArray rpcCall, + ApplicationConnection connection) { + ConnectorMap connectorMap = ConnectorMap.get(connection); + + String connectorId = ((JSONString) rpcCall.get(0)).stringValue(); + String interfaceName = ((JSONString) rpcCall.get(1)).stringValue(); + String methodName = ((JSONString) rpcCall.get(2)).stringValue(); + JSONArray parametersJson = (JSONArray) rpcCall.get(3); + + ServerConnector connector = connectorMap.getConnector(connectorId); + + MethodInvocation invocation = new MethodInvocation(connectorId, + interfaceName, methodName); + if (connector instanceof HasJavascriptConnectorHelper) { + ((HasJavascriptConnectorHelper) connector) + .getJavascriptConnectorHelper().invokeJsRpc(invocation, + parametersJson); + } else { + if (connector == null) { + throw new IllegalStateException("Target connector (" + + connector + ") not found for RCC to " + + getSignature(invocation)); + } + + parseMethodParameters(invocation, parametersJson, connection); + VConsole.log("Server to client RPC call: " + invocation); + applyInvocation(invocation, connector); + } + } + + private void parseMethodParameters(MethodInvocation methodInvocation, + JSONArray parametersJson, ApplicationConnection connection) { + Type[] parameterTypes = getParameterTypes(methodInvocation); + + Object[] parameters = new Object[parametersJson.size()]; + for (int j = 0; j < parametersJson.size(); ++j) { + parameters[j] = JsonDecoder.decodeValue(parameterTypes[j], + parametersJson.get(j), null, connection); + } + + methodInvocation.setParameters(parameters); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java new file mode 100644 index 0000000000..57e65e91c6 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java @@ -0,0 +1,60 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.user.client.Element; +import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.ui.AbstractJavascriptComponent; + +@Connect(AbstractJavascriptComponent.class) +public class JavascriptComponentConnector extends AbstractComponentConnector + implements HasJavascriptConnectorHelper { + + private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( + this) { + @Override + protected void showInitProblem( + java.util.ArrayList attemptedNames) { + getWidget().showNoInitFound(attemptedNames); + } + + @Override + protected JavaScriptObject createConnectorWrapper() { + JavaScriptObject connectorWrapper = super.createConnectorWrapper(); + addGetWidgetElement(connectorWrapper, getWidget().getElement()); + return connectorWrapper; + } + }; + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + private static native void addGetWidgetElement( + JavaScriptObject connectorWrapper, Element element) + /*-{ + connectorWrapper.getWidgetElement = function() { + return element; + }; + }-*/; + + @Override + public JavascriptWidget getWidget() { + return (JavascriptWidget) super.getWidget(); + } + + public JavascriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java new file mode 100644 index 0000000000..93a4417b1c --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java @@ -0,0 +1,25 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.ArrayList; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.user.client.ui.Widget; + +public class JavascriptWidget extends Widget { + public JavascriptWidget() { + setElement(Document.get().createDivElement()); + } + + public void showNoInitFound(ArrayList attemptedNames) { + String message = "Could not initialize JavascriptConnector because no javascript init function was found. Make sure one of these functions are defined:

      "; + for (String name : attemptedNames) { + message += "
    • " + name + "
    • "; + } + message += "
    "; + + getElement().setInnerHTML(message); + } +} diff --git a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java b/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java index 8a0c700121..ae1fadd91b 100644 --- a/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java +++ b/src/com/vaadin/terminal/gwt/server/BootstrapHandler.java @@ -9,6 +9,10 @@ import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Serializable; import java.io.Writer; +import java.lang.annotation.Annotation; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; @@ -16,6 +20,7 @@ import javax.servlet.http.HttpServletResponse; import com.vaadin.Application; import com.vaadin.RootRequiresMoreInformationException; import com.vaadin.Version; +import com.vaadin.annotations.LoadScripts; import com.vaadin.external.json.JSONException; import com.vaadin.external.json.JSONObject; import com.vaadin.terminal.DeploymentConfiguration; @@ -467,15 +472,15 @@ public abstract class BootstrapHandler implements RequestHandler { page.write("\n"); page.write(""); + + "html, body {height:100%;margin:0;}\n"); // Add favicon links if (themeName != null) { String themeUri = getThemeUri(context, themeName); page.write(""); + + themeUri + "/favicon.ico\" />\n"); page.write(""); + + themeUri + "/favicon.ico\" />\n"); } Root root = context.getRoot(); @@ -484,7 +489,51 @@ public abstract class BootstrapHandler implements RequestHandler { page.write("" + AbstractApplicationServlet.safeEscapeForHtml(title) - + ""); + + "\n"); + + if (root != null) { + List loadScriptsAnnotations = getAnnotationsFor( + root.getClass(), LoadScripts.class); + Collections.reverse(loadScriptsAnnotations); + // Begin from the end as a class might requests scripts that depend + // on script loaded by a super class + for (int i = loadScriptsAnnotations.size() - 1; i >= 0; i--) { + LoadScripts loadScripts = loadScriptsAnnotations.get(i); + String[] value = loadScripts.value(); + if (value != null) { + for (String script : value) { + page.write("\n"); + } + } + } + + } + } + + private static List getAnnotationsFor( + Class type, Class annotationType) { + List list = new ArrayList(); + // Find from the class hierarchy + Class currentType = type; + while (currentType != Object.class) { + T annotation = currentType.getAnnotation(annotationType); + if (annotation != null) { + list.add(annotation); + } + currentType = currentType.getSuperclass(); + } + + // Find from an implemented interface + for (Class iface : type.getInterfaces()) { + T annotation = iface.getAnnotation(annotationType); + if (annotation != null) { + list.add(annotation); + } + } + + return list; } /** diff --git a/src/com/vaadin/ui/AbstractJavascriptComponent.java b/src/com/vaadin/ui/AbstractJavascriptComponent.java new file mode 100644 index 0000000000..458db29172 --- /dev/null +++ b/src/com/vaadin/ui/AbstractJavascriptComponent.java @@ -0,0 +1,8 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +public class AbstractJavascriptComponent extends AbstractComponent { + +} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java new file mode 100644 index 0000000000..2240fc246b --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java @@ -0,0 +1,73 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.components.javascriptcomponent; + +import java.util.Arrays; +import java.util.List; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.AbstractJavascriptComponent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsconnector.js" }) +public class BasicJavascriptComponent extends AbstractTestRoot { + + public interface ExampleClickRpc extends ServerRpc { + public void onClick(String message); + } + + public static class SpecialState extends ComponentState { + private List data; + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + } + + public static class ExampleWidget extends AbstractJavascriptComponent { + public ExampleWidget() { + registerRpc(new ExampleClickRpc() { + public void onClick(String message) { + Root.getCurrentRoot().showNotification( + "Got a click: " + message); + } + }); + getState().setData(Arrays.asList("a", "b", "c")); + } + + @Override + public SpecialState getState() { + return (SpecialState) super.getState(); + } + } + + @Override + protected void setup(WrappedRequest request) { + ExampleWidget c = new ExampleWidget(); + c.setCaption("test caption"); + c.setDescription("Some description"); + addComponent(c); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/features/SimpleJavascriptExtensionTest.java b/tests/testbench/com/vaadin/tests/features/SimpleJavascriptExtensionTest.java new file mode 100644 index 0000000000..591689b4b0 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/features/SimpleJavascriptExtensionTest.java @@ -0,0 +1,95 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.features; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.AbstractJavascriptExtension; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.communication.ClientRpc; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.communication.SharedState; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsextension.js" }) +public class SimpleJavascriptExtensionTest extends AbstractTestRoot { + + public static class SimpleJavascriptExtensionState extends SharedState { + private String prefix; + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + } + + public static interface SimpleJavascriptExtensionClientRpc extends + ClientRpc { + public void greet(String message); + } + + public static interface SimpleJavascriptExtensionServerRpc extends + ServerRpc { + public void greet(String message); + } + + public static class SimpleJavascriptExtension extends + AbstractJavascriptExtension { + + public SimpleJavascriptExtension() { + registerRpc(new SimpleJavascriptExtensionServerRpc() { + public void greet(String message) { + Root.getCurrentRoot().showNotification( + getState().getPrefix() + message); + } + }); + } + + @Override + public SimpleJavascriptExtensionState getState() { + return (SimpleJavascriptExtensionState) super.getState(); + } + + public void setPrefix(String prefix) { + getState().setPrefix(prefix); + requestRepaint(); + } + + public void greet(String message) { + getRpcProxy(SimpleJavascriptExtensionClientRpc.class) + .greet(message); + } + } + + @Override + protected void setup(WrappedRequest request) { + final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); + simpleJavascriptExtension.setPrefix("Prefix: "); + addExtension(simpleJavascriptExtension); + addComponent(new Button("Send greeting", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension.greet("Greeted by button"); + } + })); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} -- cgit v1.2.3 From 0c06e5ac6e854ff428290db0697c11ebde97adb0 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 17:23:44 +0300 Subject: Change package name in js file not changed by previous refactoring --- WebContent/statictestfiles/jsextension.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'WebContent') diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index df67db8927..bdc0460c29 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,8 +1,8 @@ -window.com_vaadin_tests_features_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { +window.com_vaadin_tests_extensions_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { var state = this.getState(); - var greetBack = this.getRpcProxyFunction('com.vaadin.tests.features.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); + var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); - this.registerRpc("com.vaadin.tests.features.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { + this.registerRpc("com.vaadin.tests.extensions.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { 'greet': function(greeting) { var response = window.prompt(state.prefix + greeting); if (response !== null) { -- cgit v1.2.3 From 755adc2731383e6e04ddfa5bee04b6ed6feaf243 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 17:42:04 +0300 Subject: Rename Javascript -> JavaScript --- WebContent/statictestfiles/jsconnector.js | 4 +- WebContent/statictestfiles/jsextension.js | 6 +- .../terminal/AbstractJavaScriptExtension.java | 21 +++ .../terminal/AbstractJavascriptExtension.java | 20 -- .../vaadin/terminal/JavaScriptCallbackHelper.java | 61 ++++++ src/com/vaadin/terminal/JavascriptRpcHelper.java | 61 ------ .../terminal/gwt/client/ApplicationConnection.java | 6 +- .../gwt/client/JavaScriptConnectorHelper.java | 205 +++++++++++++++++++++ .../terminal/gwt/client/JavaScriptExtension.java | 33 ++++ .../gwt/client/JavascriptConnectorHelper.java | 205 --------------------- .../terminal/gwt/client/JavascriptExtension.java | 33 ---- src/com/vaadin/terminal/gwt/client/WidgetSet.java | 6 +- .../HasJavaScriptConnectorHelper.java | 11 ++ .../HasJavascriptConnectorHelper.java | 11 -- .../gwt/client/communication/RpcManager.java | 4 +- .../JavaScriptManagerConnector.java | 92 +++++++++ .../javascriptmanager/JavaScriptManagerState.java | 22 +++ .../JavascriptManagerConnector.java | 92 --------- .../javascriptmanager/JavascriptManagerState.java | 22 --- .../client/ui/JavaScriptComponentConnector.java | 60 ++++++ .../terminal/gwt/client/ui/JavaScriptWidget.java | 25 +++ .../client/ui/JavascriptComponentConnector.java | 60 ------ .../terminal/gwt/client/ui/JavascriptWidget.java | 25 --- src/com/vaadin/ui/AbstractJavaScriptComponent.java | 20 ++ src/com/vaadin/ui/AbstractJavascriptComponent.java | 19 -- src/com/vaadin/ui/JavaScript.java | 16 +- src/com/vaadin/ui/JavaScriptCallback.java | 14 ++ src/com/vaadin/ui/JavascriptCallback.java | 14 -- .../BasicJavaScriptComponent.java | 73 ++++++++ .../BasicJavascriptComponent.java | 73 -------- .../tests/extensions/JavascriptManagerTest.java | 4 +- .../extensions/SimpleJavaScriptExtensionTest.java | 95 ++++++++++ .../extensions/SimpleJavascriptExtensionTest.java | 95 ---------- 33 files changed, 755 insertions(+), 753 deletions(-) create mode 100644 src/com/vaadin/terminal/AbstractJavaScriptExtension.java delete mode 100644 src/com/vaadin/terminal/AbstractJavascriptExtension.java create mode 100644 src/com/vaadin/terminal/JavaScriptCallbackHelper.java delete mode 100644 src/com/vaadin/terminal/JavascriptRpcHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java delete mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java delete mode 100644 src/com/vaadin/terminal/gwt/client/JavascriptExtension.java create mode 100644 src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java delete mode 100644 src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java create mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java delete mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java delete mode 100644 src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java delete mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java delete mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java create mode 100644 src/com/vaadin/ui/AbstractJavaScriptComponent.java delete mode 100644 src/com/vaadin/ui/AbstractJavascriptComponent.java create mode 100644 src/com/vaadin/ui/JavaScriptCallback.java delete mode 100644 src/com/vaadin/ui/JavascriptCallback.java create mode 100644 tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java delete mode 100644 tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java create mode 100644 tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java delete mode 100644 tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java (limited to 'WebContent') diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js index db8a065e86..1432c20698 100644 --- a/WebContent/statictestfiles/jsconnector.js +++ b/WebContent/statictestfiles/jsconnector.js @@ -1,10 +1,10 @@ -window.com_vaadin_tests_components_javascriptcomponent_BasicJavascriptComponent_ExampleWidget = function() { +window.com_vaadin_tests_components_javascriptcomponent_BasicJavaScriptComponent_ExampleWidget = function() { var connector = this; var rootElement = connector.getWidgetElement(); rootElement.innerHTML = 'Hello world!'; rootElement.onclick = function() { - connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavascriptComponent$ExampleClickRpc", "onClick")("message"); + connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavaScriptComponent$ExampleClickRpc", "onClick")("message"); } connector.onStateChange = function() { console.log('state change:', this.getState()); diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index bdc0460c29..be551746ca 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,8 +1,8 @@ -window.com_vaadin_tests_extensions_SimpleJavascriptExtensionTest_SimpleJavascriptExtension = function() { +window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascriptExtension = function() { var state = this.getState(); - var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavascriptExtensionTest$SimpleJavascriptExtensionServerRpc', 'greet'); + var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest$SimpleJavaScriptExtensionServerRpc', 'greet'); - this.registerRpc("com.vaadin.tests.extensions.SimpleJavascriptExtensionTest.SimpleJavascriptExtensionClientRpc", { + this.registerRpc("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionClientRpc", { 'greet': function(greeting) { var response = window.prompt(state.prefix + greeting); if (response !== null) { diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java new file mode 100644 index 0000000000..49f361f343 --- /dev/null +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -0,0 +1,21 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import com.vaadin.ui.JavaScriptCallback; + +public class AbstractJavaScriptExtension extends AbstractExtension { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + protected void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbackHelper.registerCallback(functionName, javaScriptCallback); + } + + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } +} diff --git a/src/com/vaadin/terminal/AbstractJavascriptExtension.java b/src/com/vaadin/terminal/AbstractJavascriptExtension.java deleted file mode 100644 index e741e2af1e..0000000000 --- a/src/com/vaadin/terminal/AbstractJavascriptExtension.java +++ /dev/null @@ -1,20 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import com.vaadin.ui.JavascriptCallback; - -public class AbstractJavascriptExtension extends AbstractExtension { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java new file mode 100644 index 0000000000..5ea5e56255 --- /dev/null +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -0,0 +1,61 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; +import com.vaadin.tools.ReflectTools; +import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; +import com.vaadin.ui.JavaScriptCallback; + +public class JavaScriptCallbackHelper { + + private static final Method CALL_METHOD = ReflectTools.findMethod( + JavaScriptCallbackRpc.class, "call", String.class, JSONArray.class); + private AbstractClientConnector connector; + + private Map callbacks = new HashMap(); + private JavaScriptCallbackRpc javascriptCallbackRpc; + + public JavaScriptCallbackHelper(AbstractClientConnector connector) { + this.connector = connector; + } + + public void registerCallback(String functionName, + JavaScriptCallback javaScriptCallback) { + callbacks.put(functionName, javaScriptCallback); + ensureRpc(); + } + + private void ensureRpc() { + if (javascriptCallbackRpc == null) { + javascriptCallbackRpc = new JavaScriptCallbackRpc() { + public void call(String name, JSONArray arguments) { + JavaScriptCallback callback = callbacks.get(name); + try { + callback.call(arguments); + } catch (JSONException e) { + throw new IllegalArgumentException(e); + } + } + }; + connector.registerRpc(javascriptCallbackRpc); + } + } + + public void invokeCallback(String name, Object... arguments) { + JSONArray args = new JSONArray(Arrays.asList(arguments)); + connector.addMethodInvocationToQueue( + JavaScriptCallbackRpc.class.getName(), CALL_METHOD, + new Object[] { name, args }); + connector.requestRepaint(); + } + +} diff --git a/src/com/vaadin/terminal/JavascriptRpcHelper.java b/src/com/vaadin/terminal/JavascriptRpcHelper.java deleted file mode 100644 index 937f7e3a54..0000000000 --- a/src/com/vaadin/terminal/JavascriptRpcHelper.java +++ /dev/null @@ -1,61 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; -import com.vaadin.tools.ReflectTools; -import com.vaadin.ui.JavaScript.JavascriptCallbackRpc; -import com.vaadin.ui.JavascriptCallback; - -public class JavascriptRpcHelper { - - private static final Method CALL_METHOD = ReflectTools.findMethod( - JavascriptCallbackRpc.class, "call", String.class, JSONArray.class); - private AbstractClientConnector connector; - - private Map callbacks = new HashMap(); - private JavascriptCallbackRpc javascriptCallbackRpc; - - public JavascriptRpcHelper(AbstractClientConnector connector) { - this.connector = connector; - } - - public void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - callbacks.put(functionName, javascriptCallback); - ensureRpc(); - } - - private void ensureRpc() { - if (javascriptCallbackRpc == null) { - javascriptCallbackRpc = new JavascriptCallbackRpc() { - public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); - try { - callback.call(arguments); - } catch (JSONException e) { - throw new IllegalArgumentException(e); - } - } - }; - connector.registerRpc(javascriptCallbackRpc); - } - } - - public void invokeCallback(String name, Object... arguments) { - JSONArray args = new JSONArray(Arrays.asList(arguments)); - connector.addMethodInvocationToQueue( - JavascriptCallbackRpc.class.getName(), CALL_METHOD, - new Object[] { name, args }); - connector.requestRepaint(); - } - -} diff --git a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java index c973fe44d1..1349af465d 100644 --- a/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java +++ b/src/com/vaadin/terminal/gwt/client/ApplicationConnection.java @@ -40,7 +40,7 @@ import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConfiguration.ErrorMessage; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.communication.JsonDecoder; import com.vaadin.terminal.gwt.client.communication.JsonEncoder; import com.vaadin.terminal.gwt.client.communication.MethodInvocation; @@ -1416,8 +1416,8 @@ public class ApplicationConnection { JSONObject stateJson = new JSONObject( states.getJavaScriptObject(connectorId)); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper() .setNativeState( stateJson.getJavaScriptObject()); diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java new file mode 100644 index 0000000000..2c7ca22157 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java @@ -0,0 +1,205 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.ArrayList; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.json.client.JSONArray; +import com.vaadin.terminal.gwt.client.communication.MethodInvocation; + +public class JavaScriptConnectorHelper { + + private final ServerConnector connector; + private final JavaScriptObject nativeState = JavaScriptObject + .createObject(); + private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); + + private JavaScriptObject connectorWrapper; + private int tag; + + public JavaScriptConnectorHelper(ServerConnector connector) { + this.connector = connector; + } + + public boolean init() { + ApplicationConfiguration conf = connector.getConnection() + .getConfiguration(); + ArrayList attemptedNames = new ArrayList(); + Integer tag = Integer.valueOf(this.tag); + while (tag != null) { + String serverSideClassName = conf.getServerSideClassNameForTag(tag); + String initFunctionName = serverSideClassName + .replaceAll("\\.", "_"); + if (tryInitJs(initFunctionName, getConnectorWrapper())) { + VConsole.log("JavaScript connector initialized using " + + initFunctionName); + return true; + } else { + VConsole.log("No JavaScript function " + initFunctionName + + " found"); + attemptedNames.add(initFunctionName); + tag = conf.getParentTag(tag.intValue()); + } + } + VConsole.log("No JavaScript init for connector not found"); + showInitProblem(attemptedNames); + return false; + } + + protected void showInitProblem(ArrayList attemptedNames) { + // Default does nothing + } + + private static native boolean tryInitJs(String initFunctionName, + JavaScriptObject connectorWrapper) + /*-{ + if (typeof $wnd[initFunctionName] == 'function') { + $wnd[initFunctionName].apply(connectorWrapper); + return true; + } else { + return false; + } + }-*/; + + private JavaScriptObject getConnectorWrapper() { + if (connectorWrapper == null) { + connectorWrapper = createConnectorWrapper(); + } + + return connectorWrapper; + } + + protected JavaScriptObject createConnectorWrapper() { + return createConnectorWrapper(this, nativeState, rpcMap, + connector.getConnectorId()); + } + + public void fireNativeStateChange() { + fireNativeStateChange(getConnectorWrapper()); + } + + private static native void fireNativeStateChange( + JavaScriptObject connectorWrapper) + /*-{ + if (typeof connectorWrapper.onStateChange == 'function') { + connectorWrapper.onStateChange(); + } + }-*/; + + private static native JavaScriptObject createConnectorWrapper( + JavaScriptConnectorHelper h, JavaScriptObject nativeState, + JavaScriptObject registeredRpc, String connectorId) + /*-{ + return { + 'getConnectorId': function() { + return connectorId; + }, + 'getState': function() { + return nativeState; + }, + 'getRpcProxyFunction': function(iface, method) { + return $entry(function() { + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); + }); + }, + 'getCallback': function(name) { + return $entry(function() { + var args = [name, Array.prototype.slice.call(arguments, 0)]; + var iface = "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc"; + var method = "call"; + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); + }); + }, + 'registerCallback': function(name, callback) { + //TODO maintain separate map + if (!registeredRpc[name]) { + registeredRpc[name] = []; + } + registeredRpc[name].push(callback); + }, + 'registerRpc': function(iface, rpcHandler) { + if (!registeredRpc[iface]) { + registeredRpc[iface] = []; + } + registeredRpc[iface].push(rpcHandler); + }, + }; + }-*/; + + private void fireRpc(String iface, String method, + JsArray arguments) { + JSONArray argumentsArray = new JSONArray(arguments); + Object[] parameters = new Object[arguments.length()]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = argumentsArray.get(i); + } + connector.getConnection().addMethodInvocationToQueue( + new MethodInvocation(connector.getConnectorId(), iface, method, + parameters), true); + } + + public void setNativeState(JavaScriptObject state) { + updateNativeState(nativeState, state); + } + + private static native void updateNativeState(JavaScriptObject state, + JavaScriptObject input) + /*-{ + // Copy all fields to existing state object + for(var key in state) { + if (state.hasOwnProperty(key)) { + delete state[key]; + } + } + + for(var key in input) { + if (input.hasOwnProperty(key)) { + state[key] = input[key]; + } + } + }-*/; + + public Object[] decodeRpcParameters(JSONArray parametersJson) { + return new Object[] { parametersJson.getJavaScriptObject() }; + } + + public void setTag(int tag) { + this.tag = tag; + } + + public void invokeJsRpc(MethodInvocation invocation, + JSONArray parametersJson) { + if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(invocation + .getInterfaceName()) + && "call".equals(invocation.getMethodName())) { + invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), + null, parametersJson.get(1).isArray().getJavaScriptObject()); + } else { + invokeJsRpc(rpcMap, invocation.getInterfaceName(), + invocation.getMethodName(), + parametersJson.getJavaScriptObject()); + } + } + + private static native void invokeJsRpc(JavaScriptObject rpcMap, + String interfaceName, String methodName, JavaScriptObject parameters) + /*-{ + var targets = rpcMap[interfaceName]; + if (!targets) { + return; + } + for(var i = 0; i < targets.length; i++) { + var target = targets[i]; + if (methodName === null && typeof target === 'function') { + target.apply($wnd, parameters); + } else { + target[methodName].apply(target, parameters); + } + } + }-*/; + +} diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java new file mode 100644 index 0000000000..121208d754 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -0,0 +1,33 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; + +@Connect(AbstractJavaScriptExtension.class) +public class JavaScriptExtension extends AbstractExtensionConnector implements + HasJavaScriptConnectorHelper { + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this); + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java deleted file mode 100644 index 36f7c47959..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptConnectorHelper.java +++ /dev/null @@ -1,205 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import java.util.ArrayList; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.json.client.JSONArray; -import com.vaadin.terminal.gwt.client.communication.MethodInvocation; - -public class JavascriptConnectorHelper { - - private final ServerConnector connector; - private final JavaScriptObject nativeState = JavaScriptObject - .createObject(); - private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); - - private JavaScriptObject connectorWrapper; - private int tag; - - public JavascriptConnectorHelper(ServerConnector connector) { - this.connector = connector; - } - - public boolean init() { - ApplicationConfiguration conf = connector.getConnection() - .getConfiguration(); - ArrayList attemptedNames = new ArrayList(); - Integer tag = Integer.valueOf(this.tag); - while (tag != null) { - String serverSideClassName = conf.getServerSideClassNameForTag(tag); - String initFunctionName = serverSideClassName - .replaceAll("\\.", "_"); - if (tryInitJs(initFunctionName, getConnectorWrapper())) { - VConsole.log("Javascript connector initialized using " - + initFunctionName); - return true; - } else { - VConsole.log("No javascript function " + initFunctionName - + " found"); - attemptedNames.add(initFunctionName); - tag = conf.getParentTag(tag.intValue()); - } - } - VConsole.log("No javascript init for connector not found"); - showInitProblem(attemptedNames); - return false; - } - - protected void showInitProblem(ArrayList attemptedNames) { - // Default does nothing - } - - private static native boolean tryInitJs(String initFunctionName, - JavaScriptObject connectorWrapper) - /*-{ - if (typeof $wnd[initFunctionName] == 'function') { - $wnd[initFunctionName].apply(connectorWrapper); - return true; - } else { - return false; - } - }-*/; - - private JavaScriptObject getConnectorWrapper() { - if (connectorWrapper == null) { - connectorWrapper = createConnectorWrapper(); - } - - return connectorWrapper; - } - - protected JavaScriptObject createConnectorWrapper() { - return createConnectorWrapper(this, nativeState, rpcMap, - connector.getConnectorId()); - } - - public void fireNativeStateChange() { - fireNativeStateChange(getConnectorWrapper()); - } - - private static native void fireNativeStateChange( - JavaScriptObject connectorWrapper) - /*-{ - if (typeof connectorWrapper.onStateChange == 'function') { - connectorWrapper.onStateChange(); - } - }-*/; - - private static native JavaScriptObject createConnectorWrapper( - JavascriptConnectorHelper h, JavaScriptObject nativeState, - JavaScriptObject registeredRpc, String connectorId) - /*-{ - return { - 'getConnectorId': function() { - return connectorId; - }, - 'getState': function() { - return nativeState; - }, - 'getRpcProxyFunction': function(iface, method) { - return $entry(function() { - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); - }); - }, - 'getCallback': function(name) { - return $entry(function() { - var args = [name, Array.prototype.slice.call(arguments, 0)]; - var iface = "com.vaadin.ui.JavaScript$JavascriptCallbackRpc"; - var method = "call"; - h.@com.vaadin.terminal.gwt.client.JavascriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); - }); - }, - 'registerCallback': function(name, callback) { - //TODO maintain separate map - if (!registeredRpc[name]) { - registeredRpc[name] = []; - } - registeredRpc[name].push(callback); - }, - 'registerRpc': function(iface, rpcHandler) { - if (!registeredRpc[iface]) { - registeredRpc[iface] = []; - } - registeredRpc[iface].push(rpcHandler); - }, - }; - }-*/; - - private void fireRpc(String iface, String method, - JsArray arguments) { - JSONArray argumentsArray = new JSONArray(arguments); - Object[] parameters = new Object[arguments.length()]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = argumentsArray.get(i); - } - connector.getConnection().addMethodInvocationToQueue( - new MethodInvocation(connector.getConnectorId(), iface, method, - parameters), true); - } - - public void setNativeState(JavaScriptObject state) { - updateNativeState(nativeState, state); - } - - private static native void updateNativeState(JavaScriptObject state, - JavaScriptObject input) - /*-{ - // Copy all fields to existing state object - for(var key in state) { - if (state.hasOwnProperty(key)) { - delete state[key]; - } - } - - for(var key in input) { - if (input.hasOwnProperty(key)) { - state[key] = input[key]; - } - } - }-*/; - - public Object[] decodeRpcParameters(JSONArray parametersJson) { - return new Object[] { parametersJson.getJavaScriptObject() }; - } - - public void setTag(int tag) { - this.tag = tag; - } - - public void invokeJsRpc(MethodInvocation invocation, - JSONArray parametersJson) { - if ("com.vaadin.ui.JavaScript$JavascriptCallbackRpc".equals(invocation - .getInterfaceName()) - && "call".equals(invocation.getMethodName())) { - invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), - null, parametersJson.get(1).isArray().getJavaScriptObject()); - } else { - invokeJsRpc(rpcMap, invocation.getInterfaceName(), - invocation.getMethodName(), - parametersJson.getJavaScriptObject()); - } - } - - private static native void invokeJsRpc(JavaScriptObject rpcMap, - String interfaceName, String methodName, JavaScriptObject parameters) - /*-{ - var targets = rpcMap[interfaceName]; - if (!targets) { - return; - } - for(var i = 0; i < targets.length; i++) { - var target = targets[i]; - if (methodName === null && typeof target === 'function') { - target.apply($wnd, parameters); - } else { - target[methodName].apply(target, parameters); - } - } - }-*/; - -} diff --git a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java deleted file mode 100644 index 74c3d7da45..0000000000 --- a/src/com/vaadin/terminal/gwt/client/JavascriptExtension.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client; - -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; - -@Connect(AbstractJavascriptExtension.class) -public class JavascriptExtension extends AbstractExtensionConnector implements - HasJavascriptConnectorHelper { - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this); - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/WidgetSet.java b/src/com/vaadin/terminal/gwt/client/WidgetSet.java index ecbfb0ecc9..3d7e838c62 100644 --- a/src/com/vaadin/terminal/gwt/client/WidgetSet.java +++ b/src/com/vaadin/terminal/gwt/client/WidgetSet.java @@ -5,7 +5,7 @@ package com.vaadin.terminal.gwt.client; import com.google.gwt.core.client.GWT; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.ui.UnknownComponentConnector; public class WidgetSet { @@ -54,8 +54,8 @@ public class WidgetSet { * let the auto generated code instantiate this type */ ServerConnector connector = widgetMap.instantiate(classType); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().setTag(tag); } return connector; diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java new file mode 100644 index 0000000000..a5191a5fed --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/communication/HasJavaScriptConnectorHelper.java @@ -0,0 +1,11 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.communication; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; + +public interface HasJavaScriptConnectorHelper { + public JavaScriptConnectorHelper getJavascriptConnectorHelper(); +} diff --git a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java deleted file mode 100644 index 74bc75da66..0000000000 --- a/src/com/vaadin/terminal/gwt/client/communication/HasJavascriptConnectorHelper.java +++ /dev/null @@ -1,11 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.communication; - -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; - -public interface HasJavascriptConnectorHelper { - public JavascriptConnectorHelper getJavascriptConnectorHelper(); -} diff --git a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java index e0ffb40125..07d6292ce2 100644 --- a/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java +++ b/src/com/vaadin/terminal/gwt/client/communication/RpcManager.java @@ -89,8 +89,8 @@ public class RpcManager { MethodInvocation invocation = new MethodInvocation(connectorId, interfaceName, methodName); - if (connector instanceof HasJavascriptConnectorHelper) { - ((HasJavascriptConnectorHelper) connector) + if (connector instanceof HasJavaScriptConnectorHelper) { + ((HasJavaScriptConnectorHelper) connector) .getJavascriptConnectorHelper().invokeJsRpc(invocation, parametersJson); } else { diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java new file mode 100644 index 0000000000..72bd253ecb --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerConnector.java @@ -0,0 +1,92 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; + +import java.util.HashSet; +import java.util.Set; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.core.client.JsArray; +import com.google.gwt.json.client.JSONArray; +import com.vaadin.terminal.gwt.client.communication.MethodInvocation; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; +import com.vaadin.terminal.gwt.client.ui.Connect; +import com.vaadin.ui.JavaScript; + +@Connect(JavaScript.class) +public class JavaScriptManagerConnector extends AbstractExtensionConnector { + private Set currentNames = new HashSet(); + + @Override + protected void init() { + registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() { + public void executeJavaScript(String Script) { + eval(Script); + } + }); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + + Set newNames = getState().getNames(); + + // Current names now only contains orphan callbacks + currentNames.removeAll(newNames); + + for (String name : currentNames) { + removeCallback(name); + } + + currentNames = new HashSet(newNames); + for (String name : newNames) { + addCallback(name); + } + } + + // TODO Ensure we don't overwrite anything (important) in $wnd + private native void addCallback(String name) + /*-{ + var m = this; + $wnd[name] = $entry(function() { + //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding + var args = Array.prototype.slice.call(arguments, 0); + m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); + }); + }-*/; + + // TODO only remove what we actually added + private native void removeCallback(String name) + /*-{ + delete $wnd[name]; + }-*/; + + private static native void eval(String Script) + /*-{ + if(Script) { + $wnd.eval(Script); + } + }-*/; + + public void sendRpc(String name, JsArray arguments) { + Object[] parameters = new Object[] { name, new JSONArray(arguments) }; + + /* + * Must invoke manually as the RPC interface can't be used in GWT + * because of the JSONArray parameter + */ + getConnection().addMethodInvocationToQueue( + new MethodInvocation(getConnectorId(), + "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc", + "call", parameters), true); + } + + @Override + public JavaScriptManagerState getState() { + return (JavaScriptManagerState) super.getState(); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java new file mode 100644 index 0000000000..fc246aff04 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavaScriptManagerState.java @@ -0,0 +1,22 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; + +import java.util.HashSet; +import java.util.Set; + +import com.vaadin.terminal.gwt.client.communication.SharedState; + +public class JavaScriptManagerState extends SharedState { + private Set names = new HashSet(); + + public Set getNames() { + return names; + } + + public void setNames(Set names) { + this.names = names; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java deleted file mode 100644 index 10c4847bac..0000000000 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerConnector.java +++ /dev/null @@ -1,92 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; - -import java.util.HashSet; -import java.util.Set; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.core.client.JsArray; -import com.google.gwt.json.client.JSONArray; -import com.vaadin.terminal.gwt.client.communication.MethodInvocation; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; -import com.vaadin.terminal.gwt.client.ui.Connect; -import com.vaadin.ui.JavaScript; - -@Connect(JavaScript.class) -public class JavascriptManagerConnector extends AbstractExtensionConnector { - private Set currentNames = new HashSet(); - - @Override - protected void init() { - registerRpc(ExecuteJavaScriptRpc.class, new ExecuteJavaScriptRpc() { - public void executeJavaScript(String script) { - eval(script); - } - }); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - - Set newNames = getState().getNames(); - - // Current names now only contains orphan callbacks - currentNames.removeAll(newNames); - - for (String name : currentNames) { - removeCallback(name); - } - - currentNames = new HashSet(newNames); - for (String name : newNames) { - addCallback(name); - } - } - - // TODO Ensure we don't overwrite anything (important) in $wnd - private native void addCallback(String name) - /*-{ - var m = this; - $wnd[name] = $entry(function() { - //Must make a copy because arguments is an array-like object (not instanceof Array), causing suboptimal JSON encoding - var args = Array.prototype.slice.call(arguments, 0); - m.@com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerConnector::sendRpc(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); - }); - }-*/; - - // TODO only remove what we actually added - private native void removeCallback(String name) - /*-{ - delete $wnd[name]; - }-*/; - - private static native void eval(String script) - /*-{ - if(script) { - $wnd.eval(script); - } - }-*/; - - public void sendRpc(String name, JsArray arguments) { - Object[] parameters = new Object[] { name, new JSONArray(arguments) }; - - /* - * Must invoke manually as the RPC interface can't be used in GWT - * because of the JSONArray parameter - */ - getConnection().addMethodInvocationToQueue( - new MethodInvocation(getConnectorId(), - "com.vaadin.ui.JavaScript$JavascriptCallbackRpc", - "call", parameters), true); - } - - @Override - public JavascriptManagerState getState() { - return (JavascriptManagerState) super.getState(); - } -} diff --git a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java b/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java deleted file mode 100644 index 77794ffdca..0000000000 --- a/src/com/vaadin/terminal/gwt/client/extensions/javascriptmanager/JavascriptManagerState.java +++ /dev/null @@ -1,22 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.terminal.gwt.client.extensions.javascriptmanager; - -import java.util.HashSet; -import java.util.Set; - -import com.vaadin.terminal.gwt.client.communication.SharedState; - -public class JavascriptManagerState extends SharedState { - private Set names = new HashSet(); - - public Set getNames() { - return names; - } - - public void setNames(Set names) { - this.names = names; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java new file mode 100644 index 0000000000..c8b22a4239 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -0,0 +1,60 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.core.client.JavaScriptObject; +import com.google.gwt.user.client.Element; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.ui.AbstractJavaScriptComponent; + +@Connect(AbstractJavaScriptComponent.class) +public class JavaScriptComponentConnector extends AbstractComponentConnector + implements HasJavaScriptConnectorHelper { + + private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( + this) { + @Override + protected void showInitProblem( + java.util.ArrayList attemptedNames) { + getWidget().showNoInitFound(attemptedNames); + } + + @Override + protected JavaScriptObject createConnectorWrapper() { + JavaScriptObject connectorWrapper = super.createConnectorWrapper(); + addGetWidgetElement(connectorWrapper, getWidget().getElement()); + return connectorWrapper; + } + }; + + @Override + protected void init() { + helper.init(); + } + + @Override + public void onStateChanged(StateChangeEvent stateChangeEvent) { + super.onStateChanged(stateChangeEvent); + helper.fireNativeStateChange(); + } + + private static native void addGetWidgetElement( + JavaScriptObject connectorWrapper, Element element) + /*-{ + connectorWrapper.getWidgetElement = function() { + return element; + }; + }-*/; + + @Override + public JavaScriptWidget getWidget() { + return (JavaScriptWidget) super.getWidget(); + } + + public JavaScriptConnectorHelper getJavascriptConnectorHelper() { + return helper; + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java new file mode 100644 index 0000000000..e6c3323893 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptWidget.java @@ -0,0 +1,25 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.terminal.gwt.client.ui; + +import java.util.ArrayList; + +import com.google.gwt.dom.client.Document; +import com.google.gwt.user.client.ui.Widget; + +public class JavaScriptWidget extends Widget { + public JavaScriptWidget() { + setElement(Document.get().createDivElement()); + } + + public void showNoInitFound(ArrayList attemptedNames) { + String message = "Could not initialize JavaScriptConnector because no JavaScript init function was found. Make sure one of these functions are defined:
      "; + for (String name : attemptedNames) { + message += "
    • " + name + "
    • "; + } + message += "
    "; + + getElement().setInnerHTML(message); + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java deleted file mode 100644 index 57e65e91c6..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptComponentConnector.java +++ /dev/null @@ -1,60 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import com.google.gwt.core.client.JavaScriptObject; -import com.google.gwt.user.client.Element; -import com.vaadin.terminal.gwt.client.JavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.HasJavascriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; -import com.vaadin.ui.AbstractJavascriptComponent; - -@Connect(AbstractJavascriptComponent.class) -public class JavascriptComponentConnector extends AbstractComponentConnector - implements HasJavascriptConnectorHelper { - - private final JavascriptConnectorHelper helper = new JavascriptConnectorHelper( - this) { - @Override - protected void showInitProblem( - java.util.ArrayList attemptedNames) { - getWidget().showNoInitFound(attemptedNames); - } - - @Override - protected JavaScriptObject createConnectorWrapper() { - JavaScriptObject connectorWrapper = super.createConnectorWrapper(); - addGetWidgetElement(connectorWrapper, getWidget().getElement()); - return connectorWrapper; - } - }; - - @Override - protected void init() { - helper.init(); - } - - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - - private static native void addGetWidgetElement( - JavaScriptObject connectorWrapper, Element element) - /*-{ - connectorWrapper.getWidgetElement = function() { - return element; - }; - }-*/; - - @Override - public JavascriptWidget getWidget() { - return (JavascriptWidget) super.getWidget(); - } - - public JavascriptConnectorHelper getJavascriptConnectorHelper() { - return helper; - } -} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java b/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java deleted file mode 100644 index 93a4417b1c..0000000000 --- a/src/com/vaadin/terminal/gwt/client/ui/JavascriptWidget.java +++ /dev/null @@ -1,25 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.terminal.gwt.client.ui; - -import java.util.ArrayList; - -import com.google.gwt.dom.client.Document; -import com.google.gwt.user.client.ui.Widget; - -public class JavascriptWidget extends Widget { - public JavascriptWidget() { - setElement(Document.get().createDivElement()); - } - - public void showNoInitFound(ArrayList attemptedNames) { - String message = "Could not initialize JavascriptConnector because no javascript init function was found. Make sure one of these functions are defined:
      "; - for (String name : attemptedNames) { - message += "
    • " + name + "
    • "; - } - message += "
    "; - - getElement().setInnerHTML(message); - } -} diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java new file mode 100644 index 0000000000..881ac3f9d9 --- /dev/null +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -0,0 +1,20 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.ui; + +import com.vaadin.terminal.JavaScriptCallbackHelper; + +public class AbstractJavaScriptComponent extends AbstractComponent { + private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( + this); + + protected void registerCallback(String functionName, + JavaScriptCallback javascriptCallback) { + callbackHelper.registerCallback(functionName, javascriptCallback); + } + + protected void invokeCallback(String name, Object... arguments) { + callbackHelper.invokeCallback(name, arguments); + } +} diff --git a/src/com/vaadin/ui/AbstractJavascriptComponent.java b/src/com/vaadin/ui/AbstractJavascriptComponent.java deleted file mode 100644 index 0a26c10239..0000000000 --- a/src/com/vaadin/ui/AbstractJavascriptComponent.java +++ /dev/null @@ -1,19 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.ui; - -import com.vaadin.terminal.JavascriptRpcHelper; - -public class AbstractJavascriptComponent extends AbstractComponent { - private JavascriptRpcHelper rpcHelper = new JavascriptRpcHelper(this); - - protected void registerCallback(String functionName, - JavascriptCallback javascriptCallback) { - rpcHelper.registerCallback(functionName, javascriptCallback); - } - - protected void invokeCallback(String name, Object... arguments) { - rpcHelper.invokeCallback(name, arguments); - } -} diff --git a/src/com/vaadin/ui/JavaScript.java b/src/com/vaadin/ui/JavaScript.java index dcd8540947..fb1dba2f20 100644 --- a/src/com/vaadin/ui/JavaScript.java +++ b/src/com/vaadin/ui/JavaScript.java @@ -13,21 +13,21 @@ import com.vaadin.terminal.AbstractExtension; import com.vaadin.terminal.Extension; import com.vaadin.terminal.gwt.client.communication.ServerRpc; import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.ExecuteJavaScriptRpc; -import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavascriptManagerState; +import com.vaadin.terminal.gwt.client.extensions.javascriptmanager.JavaScriptManagerState; public class JavaScript extends AbstractExtension { - private Map callbacks = new HashMap(); + private Map callbacks = new HashMap(); // Can not be defined in client package as this JSONArray is not available // in GWT - public interface JavascriptCallbackRpc extends ServerRpc { + public interface JavaScriptCallbackRpc extends ServerRpc { public void call(String name, JSONArray arguments); } public JavaScript() { - registerRpc(new JavascriptCallbackRpc() { + registerRpc(new JavaScriptCallbackRpc() { public void call(String name, JSONArray arguments) { - JavascriptCallback callback = callbacks.get(name); + JavaScriptCallback callback = callbacks.get(name); // TODO handle situation if name is not registered try { callback.call(arguments); @@ -39,11 +39,11 @@ public class JavaScript extends AbstractExtension { } @Override - public JavascriptManagerState getState() { - return (JavascriptManagerState) super.getState(); + public JavaScriptManagerState getState() { + return (JavaScriptManagerState) super.getState(); } - public void addCallback(String name, JavascriptCallback callback) { + public void addCallback(String name, JavaScriptCallback callback) { callbacks.put(name, callback); if (getState().getNames().add(name)) { requestRepaint(); diff --git a/src/com/vaadin/ui/JavaScriptCallback.java b/src/com/vaadin/ui/JavaScriptCallback.java new file mode 100644 index 0000000000..e6b16010e4 --- /dev/null +++ b/src/com/vaadin/ui/JavaScriptCallback.java @@ -0,0 +1,14 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.ui; + +import java.io.Serializable; + +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; + +public interface JavaScriptCallback extends Serializable { + public void call(JSONArray arguments) throws JSONException; +} diff --git a/src/com/vaadin/ui/JavascriptCallback.java b/src/com/vaadin/ui/JavascriptCallback.java deleted file mode 100644 index 89700b3faf..0000000000 --- a/src/com/vaadin/ui/JavascriptCallback.java +++ /dev/null @@ -1,14 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.ui; - -import java.io.Serializable; - -import com.vaadin.external.json.JSONArray; -import com.vaadin.external.json.JSONException; - -public interface JavascriptCallback extends Serializable { - public void call(JSONArray arguments) throws JSONException; -} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java new file mode 100644 index 0000000000..4de80aaf9d --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java @@ -0,0 +1,73 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ +package com.vaadin.tests.components.javascriptcomponent; + +import java.util.Arrays; +import java.util.List; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsconnector.js" }) +public class BasicJavaScriptComponent extends AbstractTestRoot { + + public interface ExampleClickRpc extends ServerRpc { + public void onClick(String message); + } + + public static class SpecialState extends ComponentState { + private List data; + + public List getData() { + return data; + } + + public void setData(List data) { + this.data = data; + } + } + + public static class ExampleWidget extends AbstractJavaScriptComponent { + public ExampleWidget() { + registerRpc(new ExampleClickRpc() { + public void onClick(String message) { + Root.getCurrentRoot().showNotification( + "Got a click: " + message); + } + }); + getState().setData(Arrays.asList("a", "b", "c")); + } + + @Override + public SpecialState getState() { + return (SpecialState) super.getState(); + } + } + + @Override + protected void setup(WrappedRequest request) { + ExampleWidget c = new ExampleWidget(); + c.setCaption("test caption"); + c.setDescription("Some description"); + addComponent(c); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java deleted file mode 100644 index 2240fc246b..0000000000 --- a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavascriptComponent.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ -package com.vaadin.tests.components.javascriptcomponent; - -import java.util.Arrays; -import java.util.List; - -import com.vaadin.annotations.LoadScripts; -import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.ComponentState; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.AbstractJavascriptComponent; -import com.vaadin.ui.Root; - -@LoadScripts({ "/statictestfiles/jsconnector.js" }) -public class BasicJavascriptComponent extends AbstractTestRoot { - - public interface ExampleClickRpc extends ServerRpc { - public void onClick(String message); - } - - public static class SpecialState extends ComponentState { - private List data; - - public List getData() { - return data; - } - - public void setData(List data) { - this.data = data; - } - } - - public static class ExampleWidget extends AbstractJavascriptComponent { - public ExampleWidget() { - registerRpc(new ExampleClickRpc() { - public void onClick(String message) { - Root.getCurrentRoot().showNotification( - "Got a click: " + message); - } - }); - getState().setData(Arrays.asList("a", "b", "c")); - } - - @Override - public SpecialState getState() { - return (SpecialState) super.getState(); - } - } - - @Override - protected void setup(WrappedRequest request) { - ExampleWidget c = new ExampleWidget(); - c.setCaption("test caption"); - c.setDescription("Some description"); - addComponent(c); - } - - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java index 0270f7ed8f..be4675eb2d 100644 --- a/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java +++ b/tests/testbench/com/vaadin/tests/extensions/JavascriptManagerTest.java @@ -11,7 +11,7 @@ import com.vaadin.terminal.WrappedRequest; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.tests.util.Log; import com.vaadin.ui.JavaScript; -import com.vaadin.ui.JavascriptCallback; +import com.vaadin.ui.JavaScriptCallback; public class JavascriptManagerTest extends AbstractTestRoot { @@ -21,7 +21,7 @@ public class JavascriptManagerTest extends AbstractTestRoot { protected void setup(WrappedRequest request) { addComponent(log); JavaScript js = JavaScript.getCurrent(); - js.addCallback("testing", new JavascriptCallback() { + js.addCallback("testing", new JavaScriptCallback() { public void call(JSONArray arguments) throws JSONException { log.log("Got " + arguments.length() + " arguments"); log.log("Argument 1 as a number: " + arguments.getInt(0)); diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java new file mode 100644 index 0000000000..983520ee93 --- /dev/null +++ b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java @@ -0,0 +1,95 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.tests.extensions; + +import com.vaadin.annotations.LoadScripts; +import com.vaadin.terminal.AbstractJavaScriptExtension; +import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.communication.ClientRpc; +import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.communication.SharedState; +import com.vaadin.tests.components.AbstractTestRoot; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.Root; + +@LoadScripts({ "/statictestfiles/jsextension.js" }) +public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { + + public static class SimpleJavaScriptExtensionState extends SharedState { + private String prefix; + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public String getPrefix() { + return prefix; + } + } + + public static interface SimpleJavaScriptExtensionClientRpc extends + ClientRpc { + public void greet(String message); + } + + public static interface SimpleJavaScriptExtensionServerRpc extends + ServerRpc { + public void greet(String message); + } + + public static class SimpleJavascriptExtension extends + AbstractJavaScriptExtension { + + public SimpleJavascriptExtension() { + registerRpc(new SimpleJavaScriptExtensionServerRpc() { + public void greet(String message) { + Root.getCurrentRoot().showNotification( + getState().getPrefix() + message); + } + }); + } + + @Override + public SimpleJavaScriptExtensionState getState() { + return (SimpleJavaScriptExtensionState) super.getState(); + } + + public void setPrefix(String prefix) { + getState().setPrefix(prefix); + requestRepaint(); + } + + public void greet(String message) { + getRpcProxy(SimpleJavaScriptExtensionClientRpc.class) + .greet(message); + } + } + + @Override + protected void setup(WrappedRequest request) { + final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); + simpleJavascriptExtension.setPrefix("Prefix: "); + addExtension(simpleJavascriptExtension); + addComponent(new Button("Send greeting", new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension.greet("Greeted by button"); + } + })); + } + + @Override + protected String getTestDescription() { + // TODO Auto-generated method stub + return null; + } + + @Override + protected Integer getTicketNumber() { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java deleted file mode 100644 index 92c134efb0..0000000000 --- a/tests/testbench/com/vaadin/tests/extensions/SimpleJavascriptExtensionTest.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -@VaadinApache2LicenseForJavaFiles@ - */ - -package com.vaadin.tests.extensions; - -import com.vaadin.annotations.LoadScripts; -import com.vaadin.terminal.AbstractJavascriptExtension; -import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.communication.ClientRpc; -import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.client.communication.SharedState; -import com.vaadin.tests.components.AbstractTestRoot; -import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; -import com.vaadin.ui.Root; - -@LoadScripts({ "/statictestfiles/jsextension.js" }) -public class SimpleJavascriptExtensionTest extends AbstractTestRoot { - - public static class SimpleJavascriptExtensionState extends SharedState { - private String prefix; - - public void setPrefix(String prefix) { - this.prefix = prefix; - } - - public String getPrefix() { - return prefix; - } - } - - public static interface SimpleJavascriptExtensionClientRpc extends - ClientRpc { - public void greet(String message); - } - - public static interface SimpleJavascriptExtensionServerRpc extends - ServerRpc { - public void greet(String message); - } - - public static class SimpleJavascriptExtension extends - AbstractJavascriptExtension { - - public SimpleJavascriptExtension() { - registerRpc(new SimpleJavascriptExtensionServerRpc() { - public void greet(String message) { - Root.getCurrentRoot().showNotification( - getState().getPrefix() + message); - } - }); - } - - @Override - public SimpleJavascriptExtensionState getState() { - return (SimpleJavascriptExtensionState) super.getState(); - } - - public void setPrefix(String prefix) { - getState().setPrefix(prefix); - requestRepaint(); - } - - public void greet(String message) { - getRpcProxy(SimpleJavascriptExtensionClientRpc.class) - .greet(message); - } - } - - @Override - protected void setup(WrappedRequest request) { - final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); - simpleJavascriptExtension.setPrefix("Prefix: "); - addExtension(simpleJavascriptExtension); - addComponent(new Button("Send greeting", new Button.ClickListener() { - public void buttonClick(ClickEvent event) { - simpleJavascriptExtension.greet("Greeted by button"); - } - })); - } - - @Override - protected String getTestDescription() { - // TODO Auto-generated method stub - return null; - } - - @Override - protected Integer getTicketNumber() { - // TODO Auto-generated method stub - return null; - } - -} -- cgit v1.2.3 From 72c0f66e2aa588acbb517e6d9b482c7a75faf9f1 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 21:18:49 +0300 Subject: Use callbacks directly as fields in connector object (#8888) --- WebContent/statictestfiles/jsconnector.js | 1 + WebContent/statictestfiles/jsextension.js | 8 +++ .../terminal/AbstractJavaScriptExtension.java | 6 ++ .../vaadin/terminal/JavaScriptCallbackHelper.java | 17 +++++ .../gwt/client/JavaScriptConnectorHelper.java | 78 ++++++++++++++-------- .../terminal/gwt/client/JavaScriptExtension.java | 12 ++-- .../gwt/client/JavaScriptExtensionState.java | 26 ++++++++ .../client/ui/JavaScriptComponentConnector.java | 12 ++-- .../gwt/client/ui/JavaScriptComponentState.java | 26 ++++++++ src/com/vaadin/ui/AbstractJavaScriptComponent.java | 6 ++ .../BasicJavaScriptComponent.java | 13 +++- .../extensions/SimpleJavaScriptExtensionTest.java | 38 ++++++++--- 12 files changed, 193 insertions(+), 50 deletions(-) create mode 100644 src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java create mode 100644 src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java (limited to 'WebContent') diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js index 1432c20698..e08c748aa6 100644 --- a/WebContent/statictestfiles/jsconnector.js +++ b/WebContent/statictestfiles/jsconnector.js @@ -5,6 +5,7 @@ window.com_vaadin_tests_components_javascriptcomponent_BasicJavaScriptComponent_ rootElement.innerHTML = 'Hello world!'; rootElement.onclick = function() { connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavaScriptComponent$ExampleClickRpc", "onClick")("message"); + connector.onclick("another message"); } connector.onStateChange = function() { console.log('state change:', this.getState()); diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index be551746ca..d824218560 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,4 +1,5 @@ window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascriptExtension = function() { + var self = this; var state = this.getState(); var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest$SimpleJavaScriptExtensionServerRpc', 'greet'); @@ -10,4 +11,11 @@ window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascrip } } }); + + this.greetToClient = function(greeting) { + var response = window.prompt(state.prefix + greeting); + if (response !== null) { + self.greetToServer(response); + } + } } \ No newline at end of file diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java index 49f361f343..22c8dd4561 100644 --- a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -4,6 +4,7 @@ package com.vaadin.terminal; +import com.vaadin.terminal.gwt.client.JavaScriptExtensionState; import com.vaadin.ui.JavaScriptCallback; public class AbstractJavaScriptExtension extends AbstractExtension { @@ -18,4 +19,9 @@ public class AbstractJavaScriptExtension extends AbstractExtension { protected void invokeCallback(String name, Object... arguments) { callbackHelper.invokeCallback(name, arguments); } + + @Override + public JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } } diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java index 5ea5e56255..c1da8b36ba 100644 --- a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -11,6 +11,7 @@ import java.util.Map; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; import com.vaadin.tools.ReflectTools; import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; import com.vaadin.ui.JavaScriptCallback; @@ -31,9 +32,19 @@ public class JavaScriptCallbackHelper { public void registerCallback(String functionName, JavaScriptCallback javaScriptCallback) { callbacks.put(functionName, javaScriptCallback); + JavaScriptConnectorState state = getConnectorState(); + if (state.getCallbackNames().add(functionName)) { + connector.requestRepaint(); + } ensureRpc(); } + private JavaScriptConnectorState getConnectorState() { + JavaScriptConnectorState state = (JavaScriptConnectorState) connector + .getState(); + return state; + } + private void ensureRpc() { if (javascriptCallbackRpc == null) { javascriptCallbackRpc = new JavaScriptCallbackRpc() { @@ -51,6 +62,12 @@ public class JavaScriptCallbackHelper { } public void invokeCallback(String name, Object... arguments) { + if (callbacks.containsKey(name)) { + throw new IllegalStateException( + "Can't call callback " + + name + + " on the client because a callback with the same name is registered on the server."); + } JSONArray args = new JSONArray(Arrays.asList(arguments)); connector.addMethodInvocationToQueue( JavaScriptCallbackRpc.class.getName(), CALL_METHOD, diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java index 2c7ca22157..d07cf0036c 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java @@ -5,14 +5,21 @@ package com.vaadin.terminal.gwt.client; import java.util.ArrayList; +import java.util.Set; import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JsArray; import com.google.gwt.json.client.JSONArray; import com.vaadin.terminal.gwt.client.communication.MethodInvocation; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; +import com.vaadin.terminal.gwt.client.communication.StateChangeEvent.StateChangeHandler; public class JavaScriptConnectorHelper { + public interface JavaScriptConnectorState { + public Set getCallbackNames(); + } + private final ServerConnector connector; private final JavaScriptObject nativeState = JavaScriptObject .createObject(); @@ -23,6 +30,18 @@ public class JavaScriptConnectorHelper { public JavaScriptConnectorHelper(ServerConnector connector) { this.connector = connector; + connector.addStateChangeHandler(new StateChangeHandler() { + public void onStateChanged(StateChangeEvent stateChangeEvent) { + JavaScriptObject wrapper = getConnectorWrapper(); + + for (String callback : getConnectorState().getCallbackNames()) { + ensureCallback(JavaScriptConnectorHelper.this, wrapper, + callback); + } + + fireNativeStateChange(wrapper); + } + }); } public boolean init() { @@ -78,10 +97,6 @@ public class JavaScriptConnectorHelper { connector.getConnectorId()); } - public void fireNativeStateChange() { - fireNativeStateChange(getConnectorWrapper()); - } - private static native void fireNativeStateChange( JavaScriptObject connectorWrapper) /*-{ @@ -106,21 +121,6 @@ public class JavaScriptConnectorHelper { h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); }); }, - 'getCallback': function(name) { - return $entry(function() { - var args = [name, Array.prototype.slice.call(arguments, 0)]; - var iface = "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc"; - var method = "call"; - h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, args); - }); - }, - 'registerCallback': function(name, callback) { - //TODO maintain separate map - if (!registeredRpc[name]) { - registeredRpc[name] = []; - } - registeredRpc[name].push(callback); - }, 'registerRpc': function(iface, rpcHandler) { if (!registeredRpc[iface]) { registeredRpc[iface] = []; @@ -142,6 +142,14 @@ public class JavaScriptConnectorHelper { parameters), true); } + private void fireCallback(String name, JsArray arguments) { + MethodInvocation invocation = new MethodInvocation( + connector.getConnectorId(), + "com.vaadin.ui.JavaScript$JavaScriptCallbackRpc", "call", + new Object[] { name, new JSONArray(arguments) }); + connector.getConnection().addMethodInvocationToQueue(invocation, true); + } + public void setNativeState(JavaScriptObject state) { updateNativeState(nativeState, state); } @@ -176,8 +184,11 @@ public class JavaScriptConnectorHelper { if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(invocation .getInterfaceName()) && "call".equals(invocation.getMethodName())) { - invokeJsRpc(rpcMap, parametersJson.get(0).isString().stringValue(), - null, parametersJson.get(1).isArray().getJavaScriptObject()); + String callbackName = parametersJson.get(0).isString() + .stringValue(); + JavaScriptObject arguments = parametersJson.get(1).isArray() + .getJavaScriptObject(); + invokeCallback(getConnectorWrapper(), callbackName, arguments); } else { invokeJsRpc(rpcMap, invocation.getInterfaceName(), invocation.getMethodName(), @@ -185,6 +196,12 @@ public class JavaScriptConnectorHelper { } } + private static native void invokeCallback(JavaScriptObject connector, + String name, JavaScriptObject arguments) + /*-{ + connector[name](arguments); + }-*/; + private static native void invokeJsRpc(JavaScriptObject rpcMap, String interfaceName, String methodName, JavaScriptObject parameters) /*-{ @@ -194,12 +211,21 @@ public class JavaScriptConnectorHelper { } for(var i = 0; i < targets.length; i++) { var target = targets[i]; - if (methodName === null && typeof target === 'function') { - target.apply($wnd, parameters); - } else { - target[methodName].apply(target, parameters); - } + target[methodName].apply(target, parameters); } }-*/; + private static native void ensureCallback(JavaScriptConnectorHelper h, + JavaScriptObject connector, String name) + /*-{ + connector[name] = $entry(function() { + var args = Array.prototype.slice.call(arguments, 0); + h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireCallback(Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(name, args); + }); + }-*/; + + private JavaScriptConnectorState getConnectorState() { + return (JavaScriptConnectorState) connector.getState(); + } + } diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java index 121208d754..47aa7eab28 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -6,7 +6,6 @@ package com.vaadin.terminal.gwt.client; import com.vaadin.terminal.AbstractJavaScriptExtension; import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; import com.vaadin.terminal.gwt.client.extensions.AbstractExtensionConnector; import com.vaadin.terminal.gwt.client.ui.Connect; @@ -21,13 +20,12 @@ public class JavaScriptExtension extends AbstractExtensionConnector implements helper.init(); } - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - public JavaScriptConnectorHelper getJavascriptConnectorHelper() { return helper; } + + @Override + public JavaScriptExtensionState getState() { + return (JavaScriptExtensionState) super.getState(); + } } diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java new file mode 100644 index 0000000000..fecf24d450 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java @@ -0,0 +1,26 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client; + +import java.util.HashSet; +import java.util.Set; + +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; +import com.vaadin.terminal.gwt.client.communication.SharedState; + +public class JavaScriptExtensionState extends SharedState implements + JavaScriptConnectorState { + + private Set callbackNames = new HashSet(); + + public Set getCallbackNames() { + return callbackNames; + } + + public void setCallbackNames(Set callbackNames) { + this.callbackNames = callbackNames; + } + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java index c8b22a4239..ecab58bb9a 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -7,7 +7,6 @@ import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.user.client.Element; import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper; import com.vaadin.terminal.gwt.client.communication.HasJavaScriptConnectorHelper; -import com.vaadin.terminal.gwt.client.communication.StateChangeEvent; import com.vaadin.ui.AbstractJavaScriptComponent; @Connect(AbstractJavaScriptComponent.class) @@ -35,12 +34,6 @@ public class JavaScriptComponentConnector extends AbstractComponentConnector helper.init(); } - @Override - public void onStateChanged(StateChangeEvent stateChangeEvent) { - super.onStateChanged(stateChangeEvent); - helper.fireNativeStateChange(); - } - private static native void addGetWidgetElement( JavaScriptObject connectorWrapper, Element element) /*-{ @@ -57,4 +50,9 @@ public class JavaScriptComponentConnector extends AbstractComponentConnector public JavaScriptConnectorHelper getJavascriptConnectorHelper() { return helper; } + + @Override + public JavaScriptComponentState getState() { + return (JavaScriptComponentState) super.getState(); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java new file mode 100644 index 0000000000..bc8ed08bba --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java @@ -0,0 +1,26 @@ +/* +@VaadinApache2LicenseForJavaFiles@ + */ + +package com.vaadin.terminal.gwt.client.ui; + +import java.util.HashSet; +import java.util.Set; + +import com.vaadin.terminal.gwt.client.ComponentState; +import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; + +public class JavaScriptComponentState extends ComponentState implements + JavaScriptConnectorState { + + private Set callbackNames = new HashSet(); + + public Set getCallbackNames() { + return callbackNames; + } + + public void setCallbackNames(Set callbackNames) { + this.callbackNames = callbackNames; + } + +} diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java index 881ac3f9d9..e5759a1efc 100644 --- a/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -4,6 +4,7 @@ package com.vaadin.ui; import com.vaadin.terminal.JavaScriptCallbackHelper; +import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; public class AbstractJavaScriptComponent extends AbstractComponent { private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( @@ -17,4 +18,9 @@ public class AbstractJavaScriptComponent extends AbstractComponent { protected void invokeCallback(String name, Object... arguments) { callbackHelper.invokeCallback(name, arguments); } + + @Override + public JavaScriptComponentState getState() { + return (JavaScriptComponentState) super.getState(); + } } diff --git a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java index 4de80aaf9d..6519e4ae74 100644 --- a/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java +++ b/tests/testbench/com/vaadin/tests/components/javascriptcomponent/BasicJavaScriptComponent.java @@ -7,11 +7,14 @@ import java.util.Arrays; import java.util.List; import com.vaadin.annotations.LoadScripts; +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; import com.vaadin.terminal.WrappedRequest; -import com.vaadin.terminal.gwt.client.ComponentState; import com.vaadin.terminal.gwt.client.communication.ServerRpc; +import com.vaadin.terminal.gwt.client.ui.JavaScriptComponentState; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.AbstractJavaScriptComponent; +import com.vaadin.ui.JavaScriptCallback; import com.vaadin.ui.Root; @LoadScripts({ "/statictestfiles/jsconnector.js" }) @@ -21,7 +24,7 @@ public class BasicJavaScriptComponent extends AbstractTestRoot { public void onClick(String message); } - public static class SpecialState extends ComponentState { + public static class SpecialState extends JavaScriptComponentState { private List data; public List getData() { @@ -41,6 +44,12 @@ public class BasicJavaScriptComponent extends AbstractTestRoot { "Got a click: " + message); } }); + registerCallback("onclick", new JavaScriptCallback() { + public void call(JSONArray arguments) throws JSONException { + Root.getCurrentRoot().showNotification( + "Got a callback: " + arguments.getString(0)); + } + }); getState().setData(Arrays.asList("a", "b", "c")); } diff --git a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java index 983520ee93..8bcf873cd5 100644 --- a/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java +++ b/tests/testbench/com/vaadin/tests/extensions/SimpleJavaScriptExtensionTest.java @@ -5,20 +5,24 @@ package com.vaadin.tests.extensions; import com.vaadin.annotations.LoadScripts; +import com.vaadin.external.json.JSONArray; +import com.vaadin.external.json.JSONException; import com.vaadin.terminal.AbstractJavaScriptExtension; import com.vaadin.terminal.WrappedRequest; +import com.vaadin.terminal.gwt.client.JavaScriptExtensionState; import com.vaadin.terminal.gwt.client.communication.ClientRpc; import com.vaadin.terminal.gwt.client.communication.ServerRpc; -import com.vaadin.terminal.gwt.client.communication.SharedState; import com.vaadin.tests.components.AbstractTestRoot; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.JavaScriptCallback; import com.vaadin.ui.Root; @LoadScripts({ "/statictestfiles/jsextension.js" }) public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { - public static class SimpleJavaScriptExtensionState extends SharedState { + public static class SimpleJavaScriptExtensionState extends + JavaScriptExtensionState { private String prefix; public void setPrefix(String prefix) { @@ -50,6 +54,12 @@ public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { getState().getPrefix() + message); } }); + registerCallback("greetToServer", new JavaScriptCallback() { + public void call(JSONArray arguments) throws JSONException { + Root.getCurrentRoot().showNotification( + getState().getPrefix() + arguments.getString(0)); + } + }); } @Override @@ -62,10 +72,14 @@ public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { requestRepaint(); } - public void greet(String message) { + public void greetRpc(String message) { getRpcProxy(SimpleJavaScriptExtensionClientRpc.class) .greet(message); } + + public void greetCallback(String message) { + invokeCallback("greetToClient", message); + } } @Override @@ -73,11 +87,19 @@ public class SimpleJavaScriptExtensionTest extends AbstractTestRoot { final SimpleJavascriptExtension simpleJavascriptExtension = new SimpleJavascriptExtension(); simpleJavascriptExtension.setPrefix("Prefix: "); addExtension(simpleJavascriptExtension); - addComponent(new Button("Send greeting", new Button.ClickListener() { - public void buttonClick(ClickEvent event) { - simpleJavascriptExtension.greet("Greeted by button"); - } - })); + addComponent(new Button("Send rpc greeting", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension.greetRpc("Rpc greeting"); + } + })); + addComponent(new Button("Send callback greeting", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + simpleJavascriptExtension + .greetCallback("Callback greeting"); + } + })); } @Override -- cgit v1.2.3 From 51ce4a2535146a3b8861bd02f655c18d9a397522 Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Thu, 14 Jun 2012 22:57:28 +0300 Subject: Implement js rpc proxy objects and wildcard rpc support (#8888) --- WebContent/statictestfiles/jsconnector.js | 2 +- WebContent/statictestfiles/jsextension.js | 9 +- .../terminal/AbstractJavaScriptExtension.java | 7 ++ .../vaadin/terminal/JavaScriptCallbackHelper.java | 22 ++++ .../gwt/client/JavaScriptConnectorHelper.java | 133 ++++++++++++++++++--- .../terminal/gwt/client/JavaScriptExtension.java | 5 - .../gwt/client/JavaScriptExtensionState.java | 10 ++ .../client/ui/JavaScriptComponentConnector.java | 5 - .../gwt/client/ui/JavaScriptComponentState.java | 11 ++ src/com/vaadin/ui/AbstractJavaScriptComponent.java | 7 ++ 10 files changed, 183 insertions(+), 28 deletions(-) (limited to 'WebContent') diff --git a/WebContent/statictestfiles/jsconnector.js b/WebContent/statictestfiles/jsconnector.js index e08c748aa6..d7f697dbf5 100644 --- a/WebContent/statictestfiles/jsconnector.js +++ b/WebContent/statictestfiles/jsconnector.js @@ -4,7 +4,7 @@ window.com_vaadin_tests_components_javascriptcomponent_BasicJavaScriptComponent_ var rootElement = connector.getWidgetElement(); rootElement.innerHTML = 'Hello world!'; rootElement.onclick = function() { - connector.getRpcProxyFunction("com.vaadin.tests.components.javascriptcomponent.BasicJavaScriptComponent$ExampleClickRpc", "onClick")("message"); + connector.getRpcProxy().onClick("message"); connector.onclick("another message"); } connector.onStateChange = function() { diff --git a/WebContent/statictestfiles/jsextension.js b/WebContent/statictestfiles/jsextension.js index d824218560..1a46300e45 100644 --- a/WebContent/statictestfiles/jsextension.js +++ b/WebContent/statictestfiles/jsextension.js @@ -1,13 +1,16 @@ window.com_vaadin_tests_extensions_SimpleJavaScriptExtensionTest_SimpleJavascriptExtension = function() { var self = this; var state = this.getState(); - var greetBack = this.getRpcProxyFunction('com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest$SimpleJavaScriptExtensionServerRpc', 'greet'); + + //var rpc = this.getRpcProxy("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionServerRpc"); + var rpc = this.getRpcProxy(); - this.registerRpc("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionClientRpc", { +// this.registerRpc("com.vaadin.tests.extensions.SimpleJavaScriptExtensionTest.SimpleJavaScriptExtensionClientRpc", { + this.registerRpc({ 'greet': function(greeting) { var response = window.prompt(state.prefix + greeting); if (response !== null) { - greetBack(response); + rpc.greet(response); } } }); diff --git a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java index 22c8dd4561..a2f8019858 100644 --- a/src/com/vaadin/terminal/AbstractJavaScriptExtension.java +++ b/src/com/vaadin/terminal/AbstractJavaScriptExtension.java @@ -11,6 +11,13 @@ public class AbstractJavaScriptExtension extends AbstractExtension { private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( this); + @Override + protected void registerRpc(T implementation, + java.lang.Class rpcInterfaceType) { + super.registerRpc(implementation, rpcInterfaceType); + callbackHelper.registerRpc(rpcInterfaceType); + } + protected void registerCallback(String functionName, JavaScriptCallback javaScriptCallback) { callbackHelper.registerCallback(functionName, javaScriptCallback); diff --git a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java index c1da8b36ba..eabbcf4925 100644 --- a/src/com/vaadin/terminal/JavaScriptCallbackHelper.java +++ b/src/com/vaadin/terminal/JavaScriptCallbackHelper.java @@ -7,7 +7,9 @@ package com.vaadin.terminal; import java.lang.reflect.Method; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import com.vaadin.external.json.JSONArray; import com.vaadin.external.json.JSONException; @@ -75,4 +77,24 @@ public class JavaScriptCallbackHelper { connector.requestRepaint(); } + public void registerRpc(Class rpcInterfaceType) { + if (rpcInterfaceType == JavaScriptCallbackRpc.class) { + // Ignore + return; + } + Map> rpcInterfaces = getConnectorState() + .getRpcInterfaces(); + String interfaceName = rpcInterfaceType.getName(); + if (!rpcInterfaces.containsKey(interfaceName)) { + Set methodNames = new HashSet(); + + for (Method method : rpcInterfaceType.getMethods()) { + methodNames.add(method.getName()); + } + + rpcInterfaces.put(interfaceName, methodNames); + connector.requestRepaint(); + } + } + } diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java index d07cf0036c..77adcd4217 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptConnectorHelper.java @@ -5,6 +5,10 @@ package com.vaadin.terminal.gwt.client; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import com.google.gwt.core.client.JavaScriptObject; @@ -18,6 +22,8 @@ public class JavaScriptConnectorHelper { public interface JavaScriptConnectorState { public Set getCallbackNames(); + + public Map> getRpcInterfaces(); } private final ServerConnector connector; @@ -25,26 +31,80 @@ public class JavaScriptConnectorHelper { .createObject(); private final JavaScriptObject rpcMap = JavaScriptObject.createObject(); + private final Map rpcObjects = new HashMap(); + private final Map> rpcMethods = new HashMap>(); + private JavaScriptObject connectorWrapper; private int tag; + private boolean inited = false; + public JavaScriptConnectorHelper(ServerConnector connector) { this.connector = connector; + + // Wildcard rpc object + rpcObjects.put("", JavaScriptObject.createObject()); + connector.addStateChangeHandler(new StateChangeHandler() { public void onStateChanged(StateChangeEvent stateChangeEvent) { JavaScriptObject wrapper = getConnectorWrapper(); + JavaScriptConnectorState state = getConnectorState(); - for (String callback : getConnectorState().getCallbackNames()) { + for (String callback : state.getCallbackNames()) { ensureCallback(JavaScriptConnectorHelper.this, wrapper, callback); } + for (Entry> entry : state + .getRpcInterfaces().entrySet()) { + String rpcName = entry.getKey(); + String jsName = getJsInterfaceName(rpcName); + if (!rpcObjects.containsKey(jsName)) { + Set methods = entry.getValue(); + rpcObjects.put(jsName, + createRpcObject(rpcName, methods)); + + // Init all methods for wildcard rpc + for (String method : methods) { + JavaScriptObject wildcardRpcObject = rpcObjects + .get(""); + Set interfaces = rpcMethods.get(method); + if (interfaces == null) { + interfaces = new HashSet(); + rpcMethods.put(method, interfaces); + attachRpcMethod(wildcardRpcObject, null, method); + } + interfaces.add(rpcName); + } + } + } + + // Init after setting up callbacks & rpc + if (!inited) { + init(); + inited = true; + } + fireNativeStateChange(wrapper); } }); } - public boolean init() { + private static String getJsInterfaceName(String rpcName) { + return rpcName.replace('$', '.'); + } + + protected JavaScriptObject createRpcObject(String iface, Set methods) { + JavaScriptObject object = JavaScriptObject.createObject(); + + for (String method : methods) { + attachRpcMethod(object, iface, method); + } + + return object; + } + + private boolean init() { ApplicationConfiguration conf = connector.getConnection() .getConfiguration(); ArrayList attemptedNames = new ArrayList(); @@ -94,7 +154,7 @@ public class JavaScriptConnectorHelper { protected JavaScriptObject createConnectorWrapper() { return createConnectorWrapper(this, nativeState, rpcMap, - connector.getConnectorId()); + connector.getConnectorId(), rpcObjects); } private static native void fireNativeStateChange( @@ -107,7 +167,8 @@ public class JavaScriptConnectorHelper { private static native JavaScriptObject createConnectorWrapper( JavaScriptConnectorHelper h, JavaScriptObject nativeState, - JavaScriptObject registeredRpc, String connectorId) + JavaScriptObject registeredRpc, String connectorId, + Map rpcObjects) /*-{ return { 'getConnectorId': function() { @@ -116,12 +177,18 @@ public class JavaScriptConnectorHelper { 'getState': function() { return nativeState; }, - 'getRpcProxyFunction': function(iface, method) { - return $entry(function() { - h.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); - }); + 'getRpcProxy': function(iface) { + if (!iface) { + iface = ''; + } + return rpcObjects.@java.util.Map::get(Ljava/lang/Object;)(iface); }, 'registerRpc': function(iface, rpcHandler) { + //registerRpc(handler) -> registerRpc('', handler); + if (!rpcHandler) { + rpcHandler = iface; + iface = ''; + } if (!registeredRpc[iface]) { registeredRpc[iface] = []; } @@ -130,8 +197,21 @@ public class JavaScriptConnectorHelper { }; }-*/; + private native void attachRpcMethod(JavaScriptObject rpc, String iface, + String method) + /*-{ + var self = this; + rpc[method] = $entry(function() { + self.@com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper::fireRpc(Ljava/lang/String;Ljava/lang/String;Lcom/google/gwt/core/client/JsArray;)(iface, method, arguments); + }); + }-*/; + private void fireRpc(String iface, String method, JsArray arguments) { + if (iface == null) { + iface = findWildcardInterface(method); + } + JSONArray argumentsArray = new JSONArray(arguments); Object[] parameters = new Object[arguments.length()]; for (int i = 0; i < parameters.length; i++) { @@ -142,6 +222,29 @@ public class JavaScriptConnectorHelper { parameters), true); } + private String findWildcardInterface(String method) { + Set interfaces = rpcMethods.get(method); + if (interfaces.size() == 1) { + return interfaces.iterator().next(); + } else { + // TODO Resolve conflicts using argument count and types + String interfaceList = ""; + for (String iface : interfaces) { + if (interfaceList.length() != 0) { + interfaceList += ", "; + } + interfaceList += getJsInterfaceName(iface); + } + + throw new IllegalStateException( + "Can not call method " + + method + + " for wildcard rpc proxy because the function is defined for multiple rpc interfaces: " + + interfaceList + + ". Retrieve a rpc proxy for a specific interface using getRpcProxy(interfaceName) to use the function."); + } + } + private void fireCallback(String name, JsArray arguments) { MethodInvocation invocation = new MethodInvocation( connector.getConnectorId(), @@ -181,18 +284,20 @@ public class JavaScriptConnectorHelper { public void invokeJsRpc(MethodInvocation invocation, JSONArray parametersJson) { - if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(invocation - .getInterfaceName()) - && "call".equals(invocation.getMethodName())) { + String iface = invocation.getInterfaceName(); + String method = invocation.getMethodName(); + if ("com.vaadin.ui.JavaScript$JavaScriptCallbackRpc".equals(iface) + && "call".equals(method)) { String callbackName = parametersJson.get(0).isString() .stringValue(); JavaScriptObject arguments = parametersJson.get(1).isArray() .getJavaScriptObject(); invokeCallback(getConnectorWrapper(), callbackName, arguments); } else { - invokeJsRpc(rpcMap, invocation.getInterfaceName(), - invocation.getMethodName(), - parametersJson.getJavaScriptObject()); + JavaScriptObject arguments = parametersJson.getJavaScriptObject(); + invokeJsRpc(rpcMap, iface, method, arguments); + // Also invoke wildcard interface + invokeJsRpc(rpcMap, "", method, arguments); } } diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java index 47aa7eab28..e3dafab9bd 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtension.java @@ -15,11 +15,6 @@ public class JavaScriptExtension extends AbstractExtensionConnector implements private final JavaScriptConnectorHelper helper = new JavaScriptConnectorHelper( this); - @Override - protected void init() { - helper.init(); - } - public JavaScriptConnectorHelper getJavascriptConnectorHelper() { return helper; } diff --git a/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java index fecf24d450..e7bfbc4bb2 100644 --- a/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java +++ b/src/com/vaadin/terminal/gwt/client/JavaScriptExtensionState.java @@ -4,7 +4,9 @@ package com.vaadin.terminal.gwt.client; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import com.vaadin.terminal.gwt.client.JavaScriptConnectorHelper.JavaScriptConnectorState; @@ -14,6 +16,7 @@ public class JavaScriptExtensionState extends SharedState implements JavaScriptConnectorState { private Set callbackNames = new HashSet(); + private Map> rpcInterfaces = new HashMap>(); public Set getCallbackNames() { return callbackNames; @@ -23,4 +26,11 @@ public class JavaScriptExtensionState extends SharedState implements this.callbackNames = callbackNames; } + public Map> getRpcInterfaces() { + return rpcInterfaces; + } + + public void setRpcInterfaces(Map> rpcInterfaces) { + this.rpcInterfaces = rpcInterfaces; + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java index ecab58bb9a..47afe95771 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentConnector.java @@ -29,11 +29,6 @@ public class JavaScriptComponentConnector extends AbstractComponentConnector } }; - @Override - protected void init() { - helper.init(); - } - private static native void addGetWidgetElement( JavaScriptObject connectorWrapper, Element element) /*-{ diff --git a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java index bc8ed08bba..6728f85ec9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java +++ b/src/com/vaadin/terminal/gwt/client/ui/JavaScriptComponentState.java @@ -4,7 +4,9 @@ package com.vaadin.terminal.gwt.client.ui; +import java.util.HashMap; import java.util.HashSet; +import java.util.Map; import java.util.Set; import com.vaadin.terminal.gwt.client.ComponentState; @@ -14,6 +16,7 @@ public class JavaScriptComponentState extends ComponentState implements JavaScriptConnectorState { private Set callbackNames = new HashSet(); + private Map> rpcInterfaces = new HashMap>(); public Set getCallbackNames() { return callbackNames; @@ -23,4 +26,12 @@ public class JavaScriptComponentState extends ComponentState implements this.callbackNames = callbackNames; } + public Map> getRpcInterfaces() { + return rpcInterfaces; + } + + public void setRpcInterfaces(Map> rpcInterfaces) { + this.rpcInterfaces = rpcInterfaces; + } + } diff --git a/src/com/vaadin/ui/AbstractJavaScriptComponent.java b/src/com/vaadin/ui/AbstractJavaScriptComponent.java index e5759a1efc..343caf4abb 100644 --- a/src/com/vaadin/ui/AbstractJavaScriptComponent.java +++ b/src/com/vaadin/ui/AbstractJavaScriptComponent.java @@ -10,6 +10,13 @@ public class AbstractJavaScriptComponent extends AbstractComponent { private JavaScriptCallbackHelper callbackHelper = new JavaScriptCallbackHelper( this); + @Override + protected void registerRpc(T implementation, + java.lang.Class rpcInterfaceType) { + super.registerRpc(implementation, rpcInterfaceType); + callbackHelper.registerRpc(rpcInterfaceType); + } + protected void registerCallback(String functionName, JavaScriptCallback javascriptCallback) { callbackHelper.registerCallback(functionName, javascriptCallback); -- cgit v1.2.3 From cee6ead8b0fe6aae4c5a25ad562dfb5a62ecf435 Mon Sep 17 00:00:00 2001 From: Johannes Dahlström Date: Fri, 15 Jun 2012 10:38:45 +0000 Subject: #8949 Make sure a drag image always has absolute position svn changeset:23944/svn branch:6.8 --- WebContent/VAADIN/themes/base/common/common.css | 9 +++-- .../draganddropwrapper/DragStartModes.java | 43 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java (limited to 'WebContent') diff --git a/WebContent/VAADIN/themes/base/common/common.css b/WebContent/VAADIN/themes/base/common/common.css index 8734aee63f..74ed21bd1a 100644 --- a/WebContent/VAADIN/themes/base/common/common.css +++ b/WebContent/VAADIN/themes/base/common/common.css @@ -224,10 +224,11 @@ div.v-app-loading { .v-drag-element { z-index: 60000; - position: absolute; - opacity: 0.5; - filter: alpha(opacity=50); - cursor: default; + /* override any other position: properties */ + position: absolute !important; + opacity: 0.5; + filter: alpha(opacity=50); + cursor: default; } .v-scrollable { diff --git a/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java new file mode 100644 index 0000000000..9b2c03917c --- /dev/null +++ b/tests/testbench/com/vaadin/tests/components/draganddropwrapper/DragStartModes.java @@ -0,0 +1,43 @@ +package com.vaadin.tests.components.draganddropwrapper; + +import com.vaadin.tests.components.TestBase; +import com.vaadin.tests.util.TestUtils; +import com.vaadin.ui.Component; +import com.vaadin.ui.DragAndDropWrapper; +import com.vaadin.ui.DragAndDropWrapper.DragStartMode; +import com.vaadin.ui.Label; + +public class DragStartModes extends TestBase { + + @Override + protected void setup() { + + TestUtils.injectCSS(getMainWindow(), + ".v-ddwrapper { background: #ACF; }"); + + addComponent(makeWrapper(DragStartMode.NONE)); + addComponent(makeWrapper(DragStartMode.COMPONENT)); + addComponent(makeWrapper(DragStartMode.WRAPPER)); + addComponent(makeWrapper(DragStartMode.HTML5)); + } + + private Component makeWrapper(DragStartMode mode) { + Label label = new Label("Drag start mode: " + mode); + DragAndDropWrapper wrapper = new DragAndDropWrapper(label); + wrapper.setHTML5DataFlavor("Text", "HTML5!"); + wrapper.setDragStartMode(mode); + wrapper.setWidth("200px"); + return wrapper; + } + + @Override + protected String getDescription() { + return "Different drag start modes should show correct drag images"; + } + + @Override + protected Integer getTicketNumber() { + return 8949; + } + +} -- cgit v1.2.3