| /******************************************************************************* |
| * Copyright (c) 2012, 2013 EclipseSource and others. |
| * 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 |
| ******************************************************************************/ |
| |
| (function() { |
| |
| rwt.qx.Class.createNamespace( "org.eclipse.rap.clientscripting", {} ); |
| |
| var ObjectRegistry = rwt.remote.ObjectRegistry; |
| |
| org.eclipse.rap.clientscripting.ClientScriptingUtil = { |
| |
| _wrapperHelper : function(){}, |
| |
| _getterMapping : { |
| "rwt.widgets.Text" : { |
| "getText" : function( widget ) { return function() { return widget.getValue(); }; }, |
| "getSelection" : function( widget ) { return function() { return widget.getSelection(); }; }, |
| "getEditable" : function( widget ) { return function() { return !widget.getReadOnly(); }; } |
| }, |
| "rwt.widgets.List" : { |
| "getSelection" : function( widget ) { |
| return function() { |
| var items = widget.getSelectedItems(); |
| var result = []; |
| for( var i = 0; i < items.length; i++ ) { |
| result[ i ] = rwt.util.Encoding.unescape( items[ i ].getLabel() ); |
| } |
| return result; |
| }; |
| } |
| } |
| }, |
| |
| _eventTypeMapping : { |
| "*" : { |
| "KeyDown" : "keypress", |
| "KeyUp" : "keyup", |
| "MouseDown" : "mousedown", |
| "MouseUp" : "mouseup", |
| "MouseMove" : "mousemove", |
| "MouseEnter" : "mouseover", |
| "MouseExit" : "mouseout", |
| "MouseDoubleClick" : "dblclick", |
| "Paint" : "paint", |
| "FocusIn" : "focus", |
| "FocusOut" : "blur", |
| "Show" : "appear", |
| "Hide" : "disappear" |
| }, |
| "rwt.widgets.List" : { |
| "Selection" : "changeSelection", |
| "DefaultSelection" : "dblclick" |
| }, |
| "rwt.widgets.Text" : { |
| "Verify" : "input", // TODO [tb] : does currently not react on programatic changes |
| "Modify" : "changeValue" |
| } |
| }, |
| |
| isPublicObject : function( obj ) { |
| return ObjectRegistry.getEntry( ObjectRegistry.getId( obj ) ).handler.isPublic === true; |
| }, |
| |
| getNativeEventSource : function( source, eventType ) { |
| var SWT = org.eclipse.rap.clientscripting.SWT; |
| var result; |
| if( source.classname === "rwt.widgets.List" && eventType === "Selection" ) { |
| result = source.getManager(); |
| } else { |
| result = source; |
| } |
| return result; |
| }, |
| |
| getNativeEventType : function( source, eventType ) { |
| var map = this._eventTypeMapping; |
| var result; |
| if( map[ source.classname ] && map[ source.classname ][ eventType ] ) { |
| result = map[ source.classname ][ eventType ]; |
| } else { |
| result = map[ "*" ][ eventType ]; |
| } |
| return result; |
| }, |
| |
| wrapAsProto : function( object ) { |
| this._wrapperHelper.prototype = object; |
| var result = new this._wrapperHelper(); |
| this._wrapperHelper.prototype = null; |
| return result; |
| }, |
| |
| disposeObject : function( object ) { |
| for( var key in object ) { |
| if( object.hasOwnProperty( key ) ) { |
| object[ key ] = null; |
| } |
| } |
| }, |
| |
| postProcessEvent : function( event, wrappedEvent, originalEvent ) { |
| var SWT = org.eclipse.rap.clientscripting.SWT; |
| switch( event.type ) { |
| case SWT.Verify: |
| this._postProcessVerifyEvent( event, wrappedEvent, originalEvent ); |
| break; |
| case SWT.KeyDown: |
| case SWT.KeyUp: |
| this._postProcessKeyEvent( event, wrappedEvent, originalEvent ); |
| break; |
| } |
| }, |
| |
| attachSetter : function( proxy, source ) { |
| var id = ObjectRegistry.getId( source ); |
| var handler = id ? ObjectRegistry.getEntry( id ).handler : null; |
| if( handler ) { |
| var properties = handler.properties; |
| for( var i = 0; i < properties.length; i++ ) { |
| var property = properties[ i ]; |
| proxy[ "set" + rwt.util.Strings.toFirstUp( property ) ] = |
| this._createSetter( id, property ); |
| } |
| } |
| }, |
| |
| attachGetter : function( proxy, source ) { |
| if( source.classname ) { |
| var getterMap = this._getterMapping[ source.classname ]; |
| for( var key in getterMap ) { |
| proxy[ key ] = getterMap[ key ]( source ); |
| } |
| } |
| }, |
| |
| attachUserData : function( proxy, source ) { |
| var setter = this._setUserData; |
| var getter = this._getUserData; |
| proxy.setData = function( property, value ) { |
| setter( source, arguments ); |
| }; |
| proxy.getData = function( property ) { |
| return getter( source, arguments ); |
| }; |
| }, |
| |
| attachControlMethods : function( proxy, source ) { |
| var id = ObjectRegistry.getId( source ); |
| var ClientScriptingUtil = org.eclipse.rap.clientscripting.ClientScriptingUtil; |
| proxy.redraw = function() { |
| ClientScriptingUtil._initGC( source ); |
| }; |
| proxy.forceFocus = function() { |
| var result = false; |
| if( source.getEnabled() && ClientScriptingUtil._isVisible( source ) ) { |
| rwt.widgets.Display.getCurrent().setFocusControl( id ); |
| result = true; |
| } |
| return result; |
| }; |
| }, |
| |
| addDisposeListener : function( widget, listener ) { |
| var orgDestroy = widget.destroy; |
| widget.destroy = function() { |
| listener( this ); |
| orgDestroy.call( widget ); |
| }; |
| }, |
| |
| initEvent : function( event, type, target, originalEvent ) { |
| var SWT = org.eclipse.rap.clientscripting.SWT; |
| event.widget = org.eclipse.rap.clientscripting.WidgetProxy.getInstance( target ); |
| event.type = type; |
| switch( type ) { |
| case SWT.KeyDown: |
| case SWT.KeyUp: |
| this._initKeyEvent( event, originalEvent ); |
| break; |
| case SWT.MouseDown: |
| case SWT.MouseUp: |
| case SWT.MouseMove: |
| case SWT.MouseEnter: |
| case SWT.MouseExit: |
| case SWT.MouseDoubleClick: |
| this._initMouseEvent( event, originalEvent ); |
| break; |
| case SWT.Verify: |
| this._initVerifyEvent( event, originalEvent ); |
| break; |
| case SWT.Paint: |
| this._initPaintEvent( event, target ); |
| break; |
| } |
| }, |
| |
| _createSetter : function( id, property ) { |
| var setProperty = this._setProperty; |
| var result = function( value ) { |
| setProperty( id, property, value ); |
| }; |
| return result; |
| }, |
| |
| _setProperty : function( id, property, value ) { |
| var props = {}; |
| props[ property ] = value; |
| rwt.remote.MessageProcessor.processOperation( { |
| "target" : id, |
| "action" : "set", |
| "properties" : props |
| } ); |
| }, |
| |
| _setUserData : function( source, args ) { |
| if( args.length !== 2 ) { |
| var msg = "Wrong number of arguments in SetData: Expected 2, found " + args.length; |
| throw new Error( msg ); |
| } |
| var property = args[ 0 ]; |
| var value = args[ 1 ]; |
| var USERDATA_KEY = org.eclipse.rap.clientscripting.WidgetProxy._USERDATA_KEY; |
| var data = rwt.remote.HandlerUtil.getServerData( source ); |
| data[ property ] = value; |
| }, |
| |
| _getUserData : function( source, args ) { |
| if( args.length !== 1 ) { |
| var msg = "Wrong number of arguments in SetData: Expected 1, found " + args.length; |
| throw new Error( msg ); |
| } |
| var property = args[ 0 ]; |
| var result = null; |
| var data = rwt.remote.HandlerUtil.getServerData( source ); |
| if( typeof data[ property ] !== "undefined" ) { |
| result = data[ property ]; |
| } |
| return result; |
| }, |
| |
| _initKeyEvent : function( event, originalEvent ) { |
| var charCode = originalEvent.getCharCode(); |
| var SWT = org.eclipse.rap.clientscripting.SWT; |
| if( charCode !== 0 ) { |
| event.character = String.fromCharCode( charCode ); |
| // TODO [tb] : keyCode will be off when character is not a-z |
| event.keyCode = event.character.toLowerCase().charCodeAt( 0 ); |
| } else { |
| var keyCode = this._getLastKeyCode(); |
| switch( keyCode ) { |
| case 16: |
| event.keyCode = SWT.SHIFT; |
| break; |
| case 17: |
| event.keyCode = SWT.CTRL; |
| break; |
| case 18: |
| event.keyCode = SWT.ALT; |
| break; |
| case 224: |
| event.keyCode = SWT.COMMAND; |
| break; |
| default: |
| event.keyCode = keyCode; |
| break; |
| } |
| } |
| this._setStateMask( event, originalEvent ); |
| }, |
| |
| _initMouseEvent : function( event, originalEvent ) { |
| var target = originalEvent.getTarget()._getTargetNode(); |
| var offset = rwt.html.Location.get( target, "scroll" ); |
| event.x = originalEvent.getPageX() - offset.left; |
| event.y = originalEvent.getPageY() - offset.top; |
| if( originalEvent.isLeftButtonPressed() ) { |
| event.button = 1; |
| } else if( originalEvent.isRightButtonPressed() ) { |
| event.button = 3; |
| } if( originalEvent.isMiddleButtonPressed() ) { |
| event.button = 2; |
| } |
| this._setStateMask( event, originalEvent ); |
| }, |
| |
| _initPaintEvent : function( event, target ) { |
| var gc = this._getGCFor( target ); |
| event.gc = gc.getNativeContext(); |
| }, |
| |
| _getGCFor : function( widget ) { |
| var gc = widget.getUserData( org.eclipse.rap.clientscripting.WidgetProxy._GC_KEY ); |
| if( gc == null ) { |
| gc = this._findExistingGC( widget ); |
| if( gc == null ) { |
| gc = new rwt.widgets.GC( widget ); |
| } |
| widget.setUserData( org.eclipse.rap.clientscripting.WidgetProxy._GC_KEY, gc ); |
| } |
| return gc; |
| }, |
| |
| _initGC : function( widget ) { |
| var gc = this._getGCFor( widget ); |
| var width = widget.getInnerWidth(); |
| var height = widget.getInnerHeight(); |
| var fillStyle = widget.getBackgroundColor(); |
| var strokeStyle = widget.getTextColor(); |
| var font = [[]]; |
| if( widget.getFont() ) { |
| font[ 0 ] = widget.getFont().getFamily(); |
| font[ 1 ] = widget.getFont().getSize(); |
| font[ 2 ] = widget.getFont().getBold(); |
| font[ 3 ] = widget.getFont().getItalic(); |
| } |
| gc.init( |
| width, |
| height, |
| font, |
| rwt.util.Colors.stringToRgb( fillStyle ? fillStyle : "#000000" ), |
| rwt.util.Colors.stringToRgb( strokeStyle ? strokeStyle : "#000000" ) |
| ); |
| }, |
| |
| _findExistingGC : function( widget ) { |
| var children = widget._getTargetNode().childNodes; |
| var result = null; |
| for( var i = 0; i < children.length && result == null; i++ ) { |
| if( children[ i ].rwtObject instanceof rwt.widgets.GC ) { |
| result = children[ i ].rwtObject; |
| } |
| } |
| return result; |
| }, |
| |
| _isVisible : function( widget ) { |
| var result = true; |
| var current = widget; |
| while( current && result ) { |
| result = current.getVisibility(); |
| current = current.getParent(); |
| } |
| return result; |
| }, |
| |
| _initVerifyEvent : function( event, originalEvent ) { |
| var text = originalEvent.getTarget(); |
| if( text.classname === "rwt.widgets.Text" ) { |
| var keyCode = this._getLastKeyCode(); |
| var newValue = text.getComputedValue(); |
| var oldValue = text.getValue(); |
| var oldSelection = text.getSelection(); |
| var diff = this._getDiff( newValue, oldValue, oldSelection, keyCode ); |
| if( diff[ 0 ].length === 1 |
| && diff[ 1 ] === diff[ 2 ] |
| && diff[ 0 ] === originalEvent.getData() |
| ) { |
| event.keyCode = keyCode; |
| event.character = diff[ 0 ]; |
| } |
| event.text = diff[ 0 ]; |
| event.start = diff[ 1 ]; |
| event.end = diff[ 2 ]; |
| } |
| }, |
| |
| _postProcessVerifyEvent : function( event, wrappedEvent, originalEvent ) { |
| var widget = originalEvent.getTarget(); |
| if( wrappedEvent.doit !== false ) { |
| if( event.text !== wrappedEvent.text && event.text !== "" ) { |
| // insert replacement text |
| originalEvent.preventDefault(); |
| var currentText = widget.getValue(); |
| var textLeft = currentText.slice( 0, event.start ); |
| var textRight = currentText.slice( event.end, currentText.length ); |
| var carret = textLeft.length + wrappedEvent.text.length; |
| widget.setValue( textLeft + wrappedEvent.text + textRight ); |
| widget.setSelection( [ carret, carret ] ); |
| } |
| } else { |
| // undo any change |
| originalEvent.preventDefault(); |
| widget._renderValue(); |
| widget._renderSelection(); |
| } |
| }, |
| |
| _postProcessKeyEvent : function( event, wrappedEvent, originalEvent ) { |
| if( wrappedEvent.doit === false ) { |
| originalEvent.preventDefault(); |
| } |
| }, |
| |
| _setStateMask : function( event, originalEvent ) { |
| var SWT = org.eclipse.rap.clientscripting.SWT; |
| event.stateMask |= originalEvent.isShiftPressed() ? SWT.SHIFT : 0; |
| event.stateMask |= originalEvent.isCtrlPressed() ? SWT.CTRL : 0; |
| event.stateMask |= originalEvent.isAltPressed() ? SWT.ALT : 0; |
| event.stateMask |= originalEvent.isMetaPressed() ? SWT.COMMAND : 0; |
| }, |
| |
| _getLastKeyCode : function() { |
| // NOTE : While this is a private field, this mechanism must be integrated with |
| // KeyEventSupport anyway to support the doit flag better. |
| return rwt.remote.KeyEventSupport.getInstance()._currentKeyCode; |
| }, |
| |
| _getDiff : function( newValue, oldValue, oldSel, keyCode ) { |
| var start; |
| var end; |
| var text; |
| if( newValue.length >= oldValue.length || oldSel[ 0 ] !== oldSel[ 1 ] ) { |
| start = oldSel[ 0 ]; |
| end = oldSel[ 1 ]; |
| text = newValue.slice( start, newValue.length - ( oldValue.length - oldSel[ 1 ] ) ); |
| } else { |
| text = ""; |
| if( oldSel[ 0 ] === oldSel[ 1 ] |
| && keyCode === 8 // backspace |
| && ( oldValue.length - 1 ) === newValue.length |
| ) { |
| start = oldSel[ 0 ] - 1; |
| end = oldSel[ 0 ]; |
| } else { |
| start = oldSel[ 0 ]; |
| end = start + oldValue.length - newValue.length; |
| } |
| } |
| return [ text, start, end ]; |
| } |
| |
| }; |
| |
| }()); |