Remove DataBinding.js, introduce EventDelegator.js
EventDelegator will forward all relevant events from Text and DropDown
to AutoSuggest.js (ClientModelListener) which will also handle data
synchronization and the logic itself.
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/AutoSuggest.java b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/AutoSuggest.java
index 669e3fb..60c2f20 100644
--- a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/AutoSuggest.java
+++ b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/AutoSuggest.java
@@ -19,7 +19,7 @@
import org.eclipse.rap.addons.autosuggest.internal.Model;
import org.eclipse.rap.addons.autosuggest.internal.ModelListener;
import org.eclipse.rap.addons.autosuggest.internal.resources.AutoSuggestScript;
-import org.eclipse.rap.addons.autosuggest.internal.resources.DataBindingScript;
+import org.eclipse.rap.addons.autosuggest.internal.resources.EventDelegatorScript;
import org.eclipse.rap.addons.dropdown.DropDown;
import org.eclipse.rap.clientscripting.ClientListener;
import org.eclipse.rap.clientscripting.Script;
@@ -150,9 +150,8 @@
protected void attachClientListeners() {
int[] dropDownEventTypes = new int[] { SWT.Show, SWT.Hide, SWT.Selection, SWT.DefaultSelection };
- attachClientListenerToDropDown( DataBindingScript.getInstance(), dropDownEventTypes );
- attachClientListenerToText( DataBindingScript.getInstance(), SWT.Modify, SWT.Verify );
- attachClientListenerToModel( DataBindingScript.getInstance(), "change" );
+ attachClientListenerToDropDown( EventDelegatorScript.getInstance(), dropDownEventTypes );
+ attachClientListenerToText( EventDelegatorScript.getInstance(), SWT.Modify, SWT.Verify );
attachClientListenerToModel( AutoSuggestScript.getInstance(), "change", "accept" );
}
@@ -179,6 +178,7 @@
for( String type : types ) {
model.addListener( type, clientModelListener );
}
+ model.set( "autoSuggestListenerId", clientModelListener.getId() );
}
private void connectClientObjects() {
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/ClientModelListener.java b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/ClientModelListener.java
index 84529b7..f34a44d 100644
--- a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/ClientModelListener.java
+++ b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/ClientModelListener.java
@@ -29,6 +29,10 @@
public void handleEvent( JsonObject argument ) { }
+ public String getId() {
+ return getRemoteId();
+ }
+
void addTo( Model model, String eventType ) {
final ClientListenerBinding binding = addTo( model.getId(), eventType );
if( binding != null ) {
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/AutoSuggest.js b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/AutoSuggest.js
index 288a7f1..4ee5315 100644
--- a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/AutoSuggest.js
+++ b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/AutoSuggest.js
@@ -14,22 +14,51 @@
///////////////////
// Event Delegation
+var MODEL_KEY = "org.eclipse.rap.addons.autosuggest#Model";
+
function handleEvent( event ) {
+ if( event.widget ) {
+ var model = rap.getObject( event.widget.getData( MODEL_KEY ) );
+ if( event.widget.classname === "rwt.dropdown.DropDown" ) {
+ handleDropDownEvent( model, event );
+ } else {
+ handleTextEvent( model, event );
+ }
+ } else {
+ handleModelEvent( event.source, event );
+ }
+}
+
+function handleModelEvent( model, event ) {
+ var textWidget;
+ try {
+ textWidget = rap.getObject( model.get( "textWidgetId" ) );
+ } catch( ex ) {
+ // When Text is disposed, AutoSuggest may perform a set operation before it is also disposed
+ return;
+ }
+ var dropDown = rap.getObject( model.get( "dropDownWidgetId" ) );
if( event.type === "accept" ) {
- onAcceptSuggestion.apply( event.source, [ event ] );
+ onAcceptSuggestion.apply( model, [ event ] );
} else {
switch( event.property ) {
case "dataSourceId":
- onChangeDataSourceId.apply( event.source, [ event ] );
+ onChangeDataSourceId.apply( model, [ event ] );
break;
case "suggestions":
- onChangeSuggestions.apply( event.source, [ event ] );
+ onChangeSuggestions.apply( model, [ event ] );
break;
case "userText":
- onChangeUserText.apply( event.source, [ event ] );
+ onChangeUserText.apply( model, [ event ] );
+ break;
+ case "suggestionsVisible":
+ syncModelSuggestionsVisible.apply( model, [ dropDown, event ] );
break;
case "currentSuggestions":
- onChangeCurrentSuggestions.apply( event.source, [ event ] );
+ onChangeCurrentSuggestions.apply( model, [ event ] );
+ break;
+ case "currentSuggestionTexts":
+ syncModelCurrentSuggestionTexts.apply( model, [ dropDown, event ] );
break;
case "selectedSuggestionIndex":
onChangeSelectedSuggestionIndex.apply( event.source, [ event ] );
@@ -37,10 +66,84 @@
case "replacementText":
onChangeReplacementText.apply( event.source, [ event ] );
break;
+ case "text":
+ syncModelText.apply( model, [ textWidget, event ] );
+ break;
+ case "textSelection":
+ syncModelTextSelection.apply( model, [ textWidget, event ] );
+ break;
}
}
}
+function handleDropDownEvent( model, event ) {
+ switch( event.type ) {
+ case SWT.Show:
+ case SWT.Hide:
+ syncDropDownVisible.apply( model, [ event.widget, event ] );
+ break;
+ case SWT.Selection:
+ syncDropDownSelection.apply( model, [ event.widget, event ] );
+ break;
+ case SWT.DefaultSelection:
+ forwardDropDownDefaultSelection.apply( model, [ event.widget, event ] );
+ break;
+ }
+}
+
+function handleTextEvent( model, event ) {
+ var userAction = getUserAction( event );
+ switch( event.type ) {
+ case SWT.Modify:
+ syncTextText.apply( model, [ event.widget, event, userAction ] );
+ break;
+ }
+ setUserAction( event );
+}
+
+////////////////////////////////
+// Synchronize Model <-> Widgets
+
+function syncTextText( textWidget, event, userAction ) {
+ var text = textWidget.getText();
+ this.set( "text", text, { "action" : "sync" } );
+ if( userAction ) {
+ this.set( "userText", text, { "action" : userAction } );
+ }
+}
+
+function syncDropDownVisible( dropDown, event ) {
+ this.set( "suggestionsVisible", dropDown.getVisible(), { "action" : "sync" } );
+}
+
+function syncModelSuggestionsVisible( dropDown, event ) {
+ if( event.options.action !== "sync" ) {
+ dropDown.setVisible( event.value );
+ }
+}
+
+function syncDropDownSelection( dropDown, event ) {
+ this.set( "selectedSuggestionIndex", event.index, { "action" : "sync" } );
+}
+
+function forwardDropDownDefaultSelection( dropDown, event ) {
+ this.notify( "accept", { type : "accept", "source" : this } );
+}
+
+function syncModelCurrentSuggestionTexts( dropDown, event ) {
+ dropDown.setItems( this.get( "currentSuggestionTexts" ) );
+}
+
+function syncModelText( textWidget, event ) {
+ if( event.options.action !== "sync" ) {
+ textWidget.setText( event.value );
+ }
+}
+
+function syncModelTextSelection( textWidget, event ) {
+ textWidget.setSelection( event.value );
+}
+
//////////////////
// Event Handling
@@ -96,6 +199,7 @@
this.set( "textSelection", [ 0, text.length ] );
}
} else {
+ // TODO : not always working?
this.set( "textSelection", [ userText.length, text.length ] );
}
}
@@ -288,3 +392,17 @@
return result;
}
}
+
+function setUserAction( event ) {
+ if( event.type === SWT.Verify ) {
+ // See Bug 404896 - [ClientScripting] Verify event keyCode is always zero when replacing txt
+ var action = ( event.text !== "" /* && event.keyCode !== 0 */ ) ? "typing" : "deleting";
+ event.widget.setData( "userAction", action );
+ }
+}
+
+function getUserAction( event ) {
+ var action = event.widget.getData( "userAction" );
+ event.widget.setData( "userAction", null );
+ return action;
+}
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBinding.js b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBinding.js
deleted file mode 100644
index 42e84ee..0000000
--- a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBinding.js
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2013 EclipseSource.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * EclipseSource - initial API and implementation
- ******************************************************************************/
-
-//@ sourceURL=DataBinding.js
-
-///////////////////
-// Event Delegation
-
-var MODEL_KEY = "org.eclipse.rap.addons.autosuggest#Model";
-
-function handleEvent( event ) {
- if( event.widget ) {
- var model = rap.getObject( event.widget.getData( MODEL_KEY ) );
- if( event.widget.classname === "rwt.dropdown.DropDown" ) {
- handleDropDownEvent( model, event );
- } else {
- handleTextEvent( model, event );
- }
- } else {
- handleModelEvent.apply( this, arguments );
- }
-}
-
-function handleDropDownEvent( model, event ) {
- switch( event.type ) {
- case SWT.Show:
- case SWT.Hide:
- onDropDownChangeVisible( model, event );
- break;
- case SWT.Selection:
- onDropDownSelection( model, event );
- break;
- case SWT.DefaultSelection:
- onDropDownDefaultSelection( model, event );
- break;
- }
-}
-
-function handleTextEvent( model, event ) {
- var userAction = getUserAction( event );
- switch( event.type ) {
- case SWT.Modify:
- onTextModify( model, event, userAction );
- break;
- }
- setUserAction( event );
-}
-
-function handleModelEvent( event ) {
- var model = event.source;
- var textWidget;
- try {
- textWidget = rap.getObject( model.get( "textWidgetId" ) );
- } catch( ex ) {
- // When Text is disposed, AutoSuggest may perform a set operation before it is disposed as well
- return;
- }
- var dropDown = rap.getObject( model.get( "dropDownWidgetId" ) );
- switch( event.property ) {
- case "text":
- onModelChangeText( textWidget, model, event );
- break;
- case "textSelection":
- onModelChangeTextSelection( textWidget, model, event );
- break;
- case "currentSuggestionTexts":
- onModelChangeCurrentSuggestionTexts( dropDown, model, event );
- break;
- case "suggestionsVisible":
- onModelChangeSuggestionsVisible( dropDown, model, event );
- break;
- }
-}
-
-function setUserAction( event ) {
- if( event.type === SWT.Verify ) {
- // See Bug 404896 - [ClientScripting] Verify event keyCode is always zero when replacing txt
- var action = ( event.text !== "" /* && event.keyCode !== 0 */ ) ? "typing" : "deleting";
- event.widget.setData( "userAction", action );
- }
-}
-
-function getUserAction( event ) {
- var action = event.widget.getData( "userAction" );
- event.widget.setData( "userAction", null );
- return action;
-}
-
-/////////////////
-// Event Handling
-
-function onTextModify( model, event, userAction ) {
- var text = event.widget.getText();
- model.set( "text", text, { "action" : "sync" } );
- if( userAction ) {
- model.set( "userText", text, { "action" : userAction } );
- }
-}
-
-function onDropDownChangeVisible( model, event ) {
- model.set( "suggestionsVisible", event.widget.getVisible(), { "action" : "sync" } );
-}
-
-function onDropDownSelection( model, event ) {
- model.set( "selectedSuggestionIndex", event.index, { "action" : "sync" } );
-}
-
-function onDropDownDefaultSelection( model, event ) {
- model.notify( "accept", { type : "accept", "source" : model } );
-}
-
-function onModelChangeCurrentSuggestionTexts( dropDown, model, event ) {
- dropDown.setItems( model.get( "currentSuggestionTexts" ) );
-}
-
-function onModelChangeSuggestionsVisible( dropDown, model, event ) {
- if( event.options.action !== "sync" ) {
- dropDown.setVisible( event.value );
- }
-}
-
-function onModelChangeText( textWidget, model, event ) {
- if( event.options.action !== "sync" ) {
- textWidget.setText( event.value );
- }
-}
-
-function onModelChangeTextSelection( textWidget, model, event ) {
- textWidget.setSelection( event.value );
-}
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegator.js b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegator.js
new file mode 100644
index 0000000..ca52007
--- /dev/null
+++ b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegator.js
@@ -0,0 +1,24 @@
+/*******************************************************************************
+ * Copyright (c) 2013 EclipseSource.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * EclipseSource - initial API and implementation
+ ******************************************************************************/
+
+//@ sourceURL=DataBinding.js
+
+///////////////////
+// Event Delegation
+
+var MODEL_KEY = "org.eclipse.rap.addons.autosuggest#Model";
+
+function handleEvent( event ) {
+ var model = rap.getObject( event.widget.getData( MODEL_KEY ) );
+ var autoSuggestListener
+ = rwt.remote.ObjectRegistry.getObject( model.get( "autoSuggestListenerId" ) );
+ autoSuggestListener.call( event );
+}
diff --git a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBindingScript.java b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegatorScript.java
similarity index 78%
rename from bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBindingScript.java
rename to bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegatorScript.java
index f92a20d..7267335 100644
--- a/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/DataBindingScript.java
+++ b/bundles/org.eclipse.rap.addons.autosuggest/src/org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegatorScript.java
@@ -14,18 +14,18 @@
import org.eclipse.rap.rwt.SingletonUtil;
-public class DataBindingScript extends Script {
+public class EventDelegatorScript extends Script {
- public static DataBindingScript getInstance() {
- return SingletonUtil.getSessionInstance( DataBindingScript.class );
+ public static EventDelegatorScript getInstance() {
+ return SingletonUtil.getSessionInstance( EventDelegatorScript.class );
}
- private DataBindingScript() {
+ private EventDelegatorScript() {
super( getText() );
}
private static String getText() {
- String path = "org/eclipse/rap/addons/autosuggest/internal/resources/DataBinding.js";
+ String path = "org/eclipse/rap/addons/autosuggest/internal/resources/EventDelegator.js";
return ResourceLoaderUtil.readTextContent( path );
}