[Laszlo-checkins] r11428 - openlaszlo/trunk/WEB-INF/lps/lfc/services

bargull@openlaszlo.org bargull at openlaszlo.org
Sun Oct 12 13:17:08 PDT 2008


Author: bargull
Date: 2008-10-12 13:17:04 -0700 (Sun, 12 Oct 2008)
New Revision: 11428

Modified:
   openlaszlo/trunk/WEB-INF/lps/lfc/services/LzBrowser.lzs
   openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs
Log:
Change 20081012-bargull-MHG by bargull at dell--p4--2-53 on 2008-10-12 14:09:27
    in /home/Admin/src/svn/openlaszlo/trunk
    for http://svn.openlaszlo.org/openlaszlo/trunk

Summary: services updates (part 4)

New Features: LPP-7050

Bugs Fixed:

Technical Reviewer: promanik
QA Reviewer: (pending)
Doc Reviewer: (pending)

Documentation:

Release Notes:

Details:
- add typing information
- make service classes "public final"
- add service schema (all Lz*Service classes have a static const field Lz*, which is published as lz.* in the lz-namespace)
- reindent lines if necessary

    

Tests:



Modified: openlaszlo/trunk/WEB-INF/lps/lfc/services/LzBrowser.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/services/LzBrowser.lzs	2008-10-12 15:12:23 UTC (rev 11427)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/services/LzBrowser.lzs	2008-10-12 20:17:04 UTC (rev 11428)
@@ -7,13 +7,13 @@
  * @subtopic Services
  * @access public
  */
- 
+
 /**
  * <p><code>lz.Browser</code> is the single instance of the class
  * <code>lz.BrowserService</code>.</p>
  *
  * <p>Interface to the browser via the runtime kernel</p>
- * <p>The <classname>lz.Browser</classname> service provides access to the browser and player environment. 
+ * <p>The <classname>lz.Browser</classname> service provides access to the browser and player environment.
  * It includes methods to load URLs in the browser, and check the version of the player. For example:</p>
  * <example title="Using lz.Browser to launch another browser">
  * <![CDATA[<canvas height="140" debug="true">
@@ -30,314 +30,309 @@
  *
  * @shortdesc Provides access to the browser and player environment
  */
-class LzBrowserService {
-  /** The browser service.  Also available as the global
-   * <code>lz.Browser</code>.
-   *
-   * @type LzBrowserService
-   * @keywords readonly
-   * @devnote this should be a public getter to enforce readonly
-   */
-  static var LzBrowser:LzBrowserService;
+public final class LzBrowserService {
+    /**
+     * The browser service.  Also available as the global
+     * <code>lz.Browser</code>.
+     *
+     * @type LzBrowserService
+     * @keywords readonly
+     * @devnote this should be a public getter to enforce readonly
+     */
+    public static const LzBrowser:LzBrowserService;
 
-  /** @access private
-   * @devnote AS3 does not allow private constructors, so we need the
-   * error
-   */
-  function LzBrowserService() {
-    //    if (LzBrowserService.LzBrowser) {
-    //      throw new Error("There can be only one LzBrowser");
-    //    }
-  }
+    /**
+     * @access private
+     * @devnote AS3 does not allow private constructors, so we need the
+     * error
+     */
+    function LzBrowserService() {
+      super();
+      //    if (LzBrowserService.LzBrowser) {
+      //      throw new Error("There can be only one LzBrowser");
+      //    }
+    }
 
-  // Create the singleton
-  LzBrowserService.LzBrowser = new LzBrowserService();
+    // Create the singleton
+    LzBrowserService.LzBrowser = new LzBrowserService();
 
-  /**
-   * Loads a URL in the browser, optionally in a target
-   *
-   * @param String url: URL to load
-   * @param String target: Optionally specifies a named frame to display the contents of the URL.
-   * The document specified by URL is loaded into the current browser frame by default.
-   */
-  function loadURL ( url, target=null, features=null )
-    { LzBrowserKernel.loadURL (url, target, features);}
+    /**
+     * Loads a URL in the browser, optionally in a target
+     *
+     * @param String url: URL to load
+     * @param String target: Optionally specifies a named frame to display the contents of the URL.
+     * The document specified by URL is loaded into the current browser frame by default.
+     */
+    function loadURL (url:String, target:String = null, features:String = null) :void {
+        LzBrowserKernel.loadURL(url, target, features);
+    }
 
-  /**
-   * Runs Javascript in the browser using a javascript: url, optionally in a
-   * target window.  Note that Flash limits the javascript string to a maximum of 508 characters.  See callJS() for a higher-performance alternative.
-   *
-   * @param String js: Javascript string to execute
-   * @param String target: Optionally specifies a named frame to display the contents of the URL.
-   * By default, the javascript specified in 'js' is executed in the current
-   * browser frame .
-   */
-  function loadJS ( js, target=null )
-    { LzBrowserKernel.loadJS.apply (null, arguments);}
+    /**
+     * Runs Javascript in the browser using a javascript: url, optionally in a
+     * target window.  Note that Flash limits the javascript string to a maximum of 508 characters.
+     * See callJS() for a higher-performance alternative.
+     *
+     * @param String js: Javascript string to execute
+     * @param String target: Optionally specifies a named frame to display the contents of the URL.
+     * By default, the javascript specified in 'js' is executed in the current
+     * browser frame .
+     */
+    function loadJS (js:String, target:String = null) :void {
+        LzBrowserKernel.loadJS.apply(null, arguments);
+    }
 
-  /**
-   * Runs a Javascript method in the browser, optionally returning the result.  Note that this feature requires the application to be embedded by the embed-compressed.js library. 
-   *
-   * @param String methodname: Browser javascript method name to execute
-   * @param Function callback: Optional callback function to receive the return value of the javascript call
-   * @param * arguments to call the method with
-   */
-  function callJS ( methodname, callback=null, args=null )
-    { LzBrowserKernel.callJS.apply (null, arguments);}
+    /**
+     * Runs a Javascript method in the browser, optionally returning the result.  Note that this feature
+     * requires the application to be embedded by the embed-compressed.js library.
+     *
+     * @param String methodname: Browser javascript method name to execute
+     * @param Function callback: Optional callback function to receive the return value of the javascript call
+     * @param * arguments to call the method with
+     */
+    function callJS (methodname:String, callback:Function = null, args:* = null) :void {
+        LzBrowserKernel.callJS.apply(null, arguments);
+    }
 
-  /**
-   * Returns version information about the browser
-   */
-  function getVersion () :String
-    { return LzBrowserKernel.getVersion ();}
-    
-  /**
-   * Returns information about the operating system
-   */
-  function getOS () :String
-    { return LzBrowserKernel.getOS ();}
-    
-  /**
-   * Returns the URL from which the application was loaded.
-   * @return String: the URL the swf was loaded from
-   *
-   */
-  function getLoadURL ()
-    { return LzBrowserKernel.getLoadURL ();}
+    /**
+     * Returns version information about the browser
+     */
+    function getVersion () :String {
+        return LzBrowserKernel.getVersion();
+    }
 
-  /**
-   * This function returns the value of a key in the request string that
-   * requested the the lzx app. This can be used to communicate server to an lzx
-   * app without forcing the app to make a request
-   *
-   * @param String name: The name of the key whose value to return
-   *
-   * @return String: The value for a key that appears in the request to the lps
-   * server
-   */
-  function getInitArg (name)
-    { return LzBrowserKernel.getInitArg (name);}
+    /**
+     * Returns information about the operating system
+     */
+    function getOS () :String {
+        return LzBrowserKernel.getOS();
+    }
 
-  /**
-   * This function returns the id the app was started with
-   * 
-   * @return String: The id the app was started with
-   */
-  function getAppID ()
-    { return LzBrowserKernel.getAppID();}
+    /**
+     * Returns the URL from which the application was loaded.
+     * @return String: the URL the swf was loaded from
+     *
+     */
+    function getLoadURL () :String {
+        return LzBrowserKernel.getLoadURL();
+    }
 
-  /**
-   * Turns the flash context menu on or off
-   * @keywords flashspecific private
-   * @param Boolean truefalse: boolean value - true for on, false for off.
-   */
-  function showMenu (truefalse)
-    { LzBrowserKernel.showMenu (truefalse);}
+    /**
+     * This function returns the value of a key in the request string that
+     * requested the the lzx app. This can be used to communicate server to an lzx
+     * app without forcing the app to make a request
+     *
+     * @param String name: The name of the key whose value to return
+     *
+     * @return String: The value for a key that appears in the request to the lps
+     * server
+     */
+    function getInitArg (name:String) :String {
+        return LzBrowserKernel.getInitArg(name);
+    }
 
-  /**
-   * Sets the system clipboard to the specified string
-   * @keywords flashspecific
-   *
-   * @param String str: String to set the system clipboard to
-   */
-  function setClipboard (str)
-    { LzBrowserKernel.setClipboard (str);}
+    /**
+     * This function returns the id the app was started with
+     *
+     * @return String: The id the app was started with
+     */
+    function getAppID () :String {
+        return LzBrowserKernel.getAppID();
+    }
 
-  /**
-   * Determines if the a screen reader is active and the Flash player is focused
-   * @keywords flashspecific
-   *
-   * @return: True if a screen reader is active and the Flash player is focused
-   */
-  function isAAActive ()
-    { return LzBrowserKernel.isAAActive ();}
+    /**
+     * Turns the flash context menu on or off
+     * @keywords flashspecific private
+     * @param Boolean truefalse: boolean value - true for on, false for off.
+     */
+    function showMenu (truefalse:Boolean) :void {
+        LzBrowserKernel.showMenu(truefalse);
+    }
 
-  /**
-   * Updates accessibility data
-   * @keywords flashspecific
-   * @access private
-   */
-  function updateAccessibility ()
-    { LzBrowserKernel.updateAccessibility ();}
+    /**
+     * Sets the system clipboard to the specified string
+     * @keywords flashspecific
+     *
+     * @param String str: String to set the system clipboard to
+     */
+    function setClipboard (str:String) :void {
+        LzBrowserKernel.setClipboard (str);
+    }
 
-  /**
+    /**
+     * Determines if the a screen reader is active and the Flash player is focused
+     * @keywords flashspecific
+     *
+     * @return: True if a screen reader is active and the Flash player is focused
+     */
+    function isAAActive () :Boolean {
+        return LzBrowserKernel.isAAActive();
+    }
+
+    /**
+     * Updates accessibility data
+     * @keywords flashspecific
+     * @access private
+     */
+    function updateAccessibility () :void  {
+        LzBrowserKernel.updateAccessibility();
+    }
+
+    /**
     * Loads a proxy policy file
     * @keywords flashspecific
     * @access private
     */
-  function loadProxyPolicy (url) {
-    LzBrowserKernel.loadProxyPolicy(url);
-  }
-
-  /** @access private */
-  var postToLps = true;
-  /** @access private */
-  var parsedloadurl = false;
-  /** @access private */
-  var defaultPortNums = { http: 80, https: 443 };
-
-  /**
-   * Returns the base URL the lzx was loaded from
-   * @keywords private
-   */
-  function getBaseURL (secure=null, port=null) {
-    var url = this.getLoadURLAsLzURL();
-
-    if (secure) {
-      url.protocol = "https";
+    function loadProxyPolicy (url:String) :void {
+        LzBrowserKernel.loadProxyPolicy(url);
     }
 
-    if (port) {
-      url.port = port;
-    }
+    /** @access private */
+    var postToLps :Boolean = true;
+    /** @access private */
+    var parsedloadurl :LzURL = null;
+    /** @access private */
+    var defaultPortNums :Object = { http: 80, https: 443 };
 
-    if (secure && port == null) {
-      url.port = this.defaultPortNums[url.protocol];
-    }
-    //Debug.write('port', port);
-    //Debug.write('secure', secure);
-    //Debug.write('url.port', url.port);
+    /**
+     * Returns the base URL the lzx was loaded from
+     * @keywords private
+     */
+    function getBaseURL (secure:* = null, port:* = null) :LzURL {
+        var url:LzURL = this.getLoadURLAsLzURL();
 
-    url.query = null;
+        if (secure) {
+            url.protocol = "https";
+        }
 
-    //Debug.write('base url' + url.toString());
-    return url;
-  }
+        if (port) {
+            url.port = port;
+        } else if (secure && port == null) {
+            url.port = this.defaultPortNums[url.protocol];
+        }
 
-  /**
-   * Returns the loadUrl as a new LzURL
-   *
-   * @return LzURL: the URL the application was loaded from, as an LzURL
-   */
-  function getLoadURLAsLzURL (){
-    if ( !this.parsedloadurl ){
-      this.parsedloadurl = new LzURL( this.getLoadURL() );
+        url.query = null;
+
+        //Debug.write('base url' + url.toString());
+        return url;
     }
-    return this.parsedloadurl.dupe();
-  }
 
-  /**
-   * Converts relative URLs to absolute by prepending the load URL
-   * @keywords private
-   * @param String url: URL to convert
-   * @param Boolean secure: true if relative http is really https
-   * @return String: an absolute URL
-   */
-  function toAbsoluteURL (url, secure) {
-    // If it begins with "/@WEBAPP@/", server will handle URL.
-    // or If it begins with "file:", server will handle URL.
-    // or do we have an absolute url?
-    if ( url.indexOf("://") > -1  ||
-         url.indexOf("/@WEBAPP@/") == 0 ||
-         url.indexOf("file:") == 0 ){
-
-      return url;
+    /**
+     * Returns the loadUrl as a new LzURL
+     *
+     * @return LzURL: the URL the application was loaded from, as an LzURL
+     */
+    function getLoadURLAsLzURL () :LzURL {
+        if (! this.parsedloadurl) {
+            this.parsedloadurl = new LzURL( this.getLoadURL() );
+        }
+        return this.parsedloadurl.dupe();
     }
 
+    /**
+     * Converts relative URLs to absolute by prepending the load URL
+     * @keywords private
+     * @param String url: URL to convert
+     * @param Boolean secure: true if relative http is really https
+     * @return String: an absolute URL
+     */
+    function toAbsoluteURL (url:String, secure:Boolean) :String {
+        // If it begins with "/@WEBAPP@/", server will handle URL.
+        // or If it begins with "file:", server will handle URL.
+        // or do we have an absolute url?
+        if (url.indexOf("://") > -1 ||
+             url.indexOf("/@WEBAPP@/") == 0 ||
+             url.indexOf("file:") == 0) {
+            return url;
+        }
 
-    //do we have a protocol?
-    var returl = "";
-    var u = this.getLoadURLAsLzURL();
-    //Debug.write('load url', u.toString());
-    //for LzURL: protocol,host, port, path, file, query
+        var u = this.getLoadURLAsLzURL();
+        u.query = null;
 
-    /* Description: lz.Browser.toAbsoluteURL('http:/zot/foo.bar') =>
-       http://127.0.0.1:8080/lps-dev-bug/examples//zot/foo.bar
-       I would have hoped for:
-       http://127.0.0.1:8080/zot/foo.bar
-    */
+        /* Description: lz.Browser.toAbsoluteURL('http:/zot/foo.bar') =>
+           http://127.0.0.1:8080/lps-dev-bug/examples//zot/foo.bar
+           I would have hoped for:
+           http://127.0.0.1:8080/zot/foo.bar
+        */
 
-    //no colons unless you specify protocol
-    if ( url.indexOf(":") > -1 ){
-      /* http:foo.lzx
-         http:/foo.lzx
-      */
-      var colon = url.indexOf(":");
-      var loadUrlIsSecure = (u.protocol == 'https');
-      u.protocol = url.substring( 0 , colon );
-      if (secure || loadUrlIsSecure) {
-        if (u.protocol == 'http') {
-          u.protocol = 'https'
+        //do we have a protocol?
+        //no colons unless you specify protocol
+        if (url.indexOf(":") > -1) {
+            /* http:foo.lzx
+               http:/foo.lzx
+            */
+            var colon:int = url.indexOf(":");
+            var loadUrlIsSecure:Boolean = (u.protocol == 'https');
+            u.protocol = url.substring( 0, colon );
+            if (secure || loadUrlIsSecure) {
+                if (u.protocol == 'http') {
+                    u.protocol = 'https';
+                }
             }
-      }
-      var path = url.substring(colon+1, url.length);
-      // is URL of the form http:/zot/foo.bar?
-      if (path.charAt(0) == '/') {
-        u.path = url.substring( colon + 1 );
-        u.file = null;
-      } else {
-        u.file = url.substring( colon + 1 );
-      }
-      u.query = null
+            var path:String = url.substring(colon + 1, url.length);
+            // is URL of the form http:/zot/foo.bar?
+            if (path.charAt(0) == '/') {
+                u.path = url.substring( colon + 1 );
+                u.file = null;
+            } else {
+                u.file = url.substring( colon + 1 );
+            }
         } else {
-      if ( url.charAt( 0 ) == '/' ){
-        //this is the root of the host
-        u.path = url;
-        //although this is really both the path and the file,
-        //it's expedient to handle it this way, since this
-        //method just returns a string
-        u.file = null;
-      } else {
-        //no protocol -- totally relative
-        u.file = url;
-      }
-      u.query = null
+            if (url.charAt( 0 ) == '/') {
+                //this is the root of the host
+                u.path = url;
+                //although this is really both the path and the file,
+                //it's expedient to handle it this way, since this
+                //method just returns a string
+                u.file = null;
+            } else {
+                //no protocol -- totally relative
+                u.file = url;
+            }
         }
-    //Debug.write( "changed: " + url );
-    //Debug.write( " to: " + u.toString() );
-    return u.toString();
+        //Debug.write( "changed: " + url );
+        //Debug.write( " to: " + u.toString() );
+        return u.toString();
+    }
 
-    /*
-      if ( url.indexOf("http") != 0 ) {
-      var u = new LzURL( this.getLoadURL() );
-      if ( url.indexOf("/") == 0 ) u.path = null;
-      u.file = null;
-      u.query = null;
-      url = u.toString() + url;
-      Debug.write("Converting toAbsoluteURL: " + url + " to " + u.toString() + url)
-      }
-      return url;
-    */
-  }
+    /**
+     * Escape special characters in message: &amp; and &lt;.
+     * @param String str: The string to escape
+     */
+    function xmlEscape (str:String) :String {
+        return LzDataElement.__LZXMLescape( str );
+    }
 
-  /**
-   * Escape special characters in message: &amp; and &lt;.
-   * @param String str: The string to escape
-   */
-  function xmlEscape (str) {
-    return LzDataElement.__LZXMLescape( str );
-  }
+    /**
+     * Escape a string using URL encoding.
+     * @param String str: The string to escape
+     * @return String: An URL escaped string
+     */
+    function urlEscape (str:String) :String {
+        return escape( str );
+    }
 
-  /**
-   * Escape a string using URL encoding.
-   * @param String str: The string to escape
-   * @return String: An URL escaped string
-   */
-  function urlEscape (str) {
-    return escape( str );
-  }
+    /**
+     * Escape a string using URL encoding.
+     * @param String str: The string to unescape
+     * @return String: An URL decoded string
+     */
+    function urlUnescape (str:String) :String {
+        return unescape( str.split('+').join(' ') );
+    }
 
-  /**
-   * Escape a string using URL encoding.
-   * @param String str: The string to unescape
-   * @return String: An URL decoded string
-   */
-  function urlUnescape (str) {
-    return unescape( str.split('+').join(' ') );
-  }
+    /** @access private */
+    function usePost () :Boolean {
+        return this.postToLps && this.supportsPost();
+    }
 
-  /** @access private */
-  function usePost (){
-    return this.postToLps && this.supportsPost();
-  }
+    /** @access private */
+    function supportsPost () :Boolean {
+        return true;
+    }
 
-  /** @access private */
-  function supportsPost (){
-    return true;
-  }
-
-    /**   @access public
-     *   @param Object params a hash table of key-value pairs
+    /**
+     * @access public
+     * @param Object params a hash table of key-value pairs
      * The params arg has keys that have the following meaning:
      * <ul>
      * <li>url: url, including query args</li>
@@ -348,42 +343,40 @@
      * <li>proxyurl: the url of the proxy server host. Should be just a path, must not contain a query string.</li>
      * <li>nsprefix: boolean, if true preserve namespace prefixes in data response</li>
      * <li>timeout: milliseconds for timeout</li>
-     * <li> cacheable: boolean, cache on server</li>
-     * <li> ccache: boolean, cache at client</li>
-     * <li> sendheaders: boolean, server sends back HTTP headers with data response</li>
-     * <li> secure: boolean, will be used when converting relative to absolute url, to make it https</li>
-     * <li> trimwhitespace: boolean</li>
+     * <li>cacheable: boolean, cache on server</li>
+     * <li>ccache: boolean, cache at client</li>
+     * <li>sendheaders: boolean, server sends back HTTP headers with data response</li>
+     * <li>secure: boolean, will be used when converting relative to absolute url, to make it https</li>
+     * <li>trimwhitespace: boolean</li>
      *</ul>
      */
-    public function makeProxiedURL (params:Object):String {
+    public function makeProxiedURL (params:Object) :String {
         var headers:Object = params.headers;
         var postbody:String = params.postbody;
         var proxyurl:String = params.proxyurl;
-        var secure:Boolean = params.secure;
+        var custom_args:Object = params.serverproxyargs;
 
-        var custom_args = params.serverproxyargs;
+        var qargs:Object; // the query args which accompany the proxy request
 
-        var qargs = null; // the query args which accompany the proxy request
-
         // If developer supplied their own custom proxy args, use them
         if (custom_args) {
             qargs = {
-            url: this.toAbsoluteURL(params.url, params.secure),                
+                url: this.toAbsoluteURL(params.url, params.secure),
                 lzt: params.service,
                 reqtype: params.httpmethod.toUpperCase()
             };
-            for (var opt in custom_args) {
+            for (var opt:String in custom_args) {
                 qargs[opt] = custom_args[opt];
             }
         } else {
             // Standard LPS proxy server control args
             qargs = {
+                url: this.toAbsoluteURL(params.url, params.secure),
                 lzt: params.service,
                 reqtype: params.httpmethod.toUpperCase(),
                 sendheaders: params.sendheaders,
                 trimwhitespace: params.trimwhitespace,
                 nsprefix: params.trimwhitespace,
-                url: this.toAbsoluteURL(params.url, params.secure),
                 timeout: params.timeout,
                 cache: params.cacheable,
                 ccache: params.ccache
@@ -394,29 +387,27 @@
         if (postbody != null) {
             qargs.lzpostbody = postbody;
         }
-            
+
         // Set HTTP headers
-        var hname;
-        var headerString = "";
         if (headers != null) {
-            for (hname in headers) {
-                headerString += (hname + ": " + headers[hname]+"\n");
+            var headerString:String = "";
+            for (var hname:String in headers) {
+                headerString += (hname + ": " + headers[hname] + "\n");
             }
+            if (headerString != "") {
+                qargs['headers'] = headerString;
+            }
         }
 
-        if (headerString != "") {
-            qargs['headers'] = headerString;
-        }
-
         // break the browser cache by creating an arg with a unique value
-        if (!params.ccache) {
+        if (! params.ccache) {
             qargs.__lzbc__ = (new Date()).getTime();
         }
 
         // append query args onto url
-        var sep = "?";
-        for (var key in qargs) {
-            var val = qargs[key];
+        var sep:String = "?";
+        for (var key:String in qargs) {
+            var val:* = qargs[key];
             if (typeof(val) == "string") {
                 val = encodeURIComponent(val);
                 if ($dhtml) {
@@ -431,8 +422,6 @@
         return proxyurl;
     }
 
-
-
 } // End of LzBrowserService
 lz.BrowserService = LzBrowserService;  // publish
 
@@ -446,11 +435,11 @@
  */
 lz.Browser = LzBrowserService.LzBrowser;
 
-if ($dhtml){
+if ($dhtml) {
 } else {
   lz.embed = new LzInheritedHash();
   // proxy object for browser Lz
-  lz.embed.setCanvasAttribute  = function (name, value, hist) {
+  lz.embed.setCanvasAttribute = function (name, value, hist) {
     lz.Browser.callJS('lz.embed.setCanvasAttribute', false, name, value, hist);
   }
   lz.embed.callMethod = function (js) {

Modified: openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs
===================================================================
--- openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs	2008-10-12 15:12:23 UTC (rev 11427)
+++ openlaszlo/trunk/WEB-INF/lps/lfc/services/LzKeys.lzs	2008-10-12 20:17:04 UTC (rev 11428)
@@ -15,9 +15,9 @@
   *
   * lz.Keys is a service that provides key handling messages. Objects can also
   * register callbacks to be sent when specific key combinitions are down.
-  * 
+  *
   * <p>Here is a simple example:</p>
-  * 
+  *
   * <example title="lz.Keys">
   * <programlisting>&lt;canvas height="140" debug="true"&gt;
   *   &lt;handler name="onkeydown" reference="lz.Keys" args="k"&gt;
@@ -32,218 +32,173 @@
   *   &lt;handler name="oninit"&gt;
   *     del = new LzDelegate(this, "pressA");
   *     lz.Keys.callOnKeyCombo(del, ["A"]);
-  *   &lt;/handler&gt; 
+  *   &lt;/handler&gt;
   * &lt;/canvas&gt;</programlisting></example>
   *
   * @shortdesc Keyboard input service.
   */
-public class LzKeysService extends LzEventable {
+public final class LzKeysService extends LzEventable {
+
+    /**
+     * The key service.  Also available as the global
+     * <code>lz.Keys</code>.
+     *
+     * @type LzKeysService
+     * @keywords readonly
+     * @devnote this should be a public getter to enforce readonly
+     */
+    public static const LzKeys:LzKeysService;
+
     /** @access private */
     function LzKeysService() {
         super();
+        //    if (LzKeysService.LzKeys) {
+        //      throw new Error("There can be only one LzKeys");
+        //    }
         if ($swf9) {
         } else {
             LzKeyboardKernel.setCallback(this, '__keyEvent');
         }
 
+        if ($dhtml) {
+            // Need to explicitly register this.  Make sure lz.embed.mousewheel is there for
+            // lztest
+            if (lz.embed['mousewheel']) {
+                lz.embed.mousewheel.setCallback(this, '__mousewheelEvent');
+            }
+        }
+    }
 
-        // add additional codes
-        this.keyCodes['add'] = 107;
-        // Backspace doesn't work in the Authoring tool player...
-        this.keyCodes['delete'] = 46;
-        this.keyCodes['0']  = 48 ;
-        this.keyCodes['1']  = 49 ;
-        this.keyCodes['2']  = 50 ;
-        this.keyCodes['3']  = 51 ;
-        this.keyCodes['4']  = 52 ;
-        this.keyCodes['5']  = 53 ;
-        this.keyCodes['6']  = 54 ;
-        this.keyCodes['7']  = 55 ;
-        this.keyCodes['8']  = 56 ;
-        this.keyCodes['9']  = 57 ;
+    // Create the singleton
+    LzKeysService.LzKeys = new LzKeysService();
 
-        this.keyCodes[')']  = 48 ;
-        this.keyCodes['!']  = 49 ;
-        this.keyCodes['@']  = 50 ;
-        this.keyCodes['#']  = 51 ;
-        this.keyCodes['$']  = 52 ;
-        this.keyCodes['%']  = 53 ;
-        this.keyCodes['^']  = 54 ;
-        this.keyCodes['&']  = 55 ;
-        this.keyCodes['*']  = 56 ;
-        this.keyCodes['(']  = 57 ;
-
-        this.keyCodes[';']  = 186 ;
-        this.keyCodes[':']  = 186 ;
-        this.keyCodes['=']  = 187 ;
-        this.keyCodes['+']  = 187 ;
-
-        this.keyCodes['<']  = 188 ;
-        this.keyCodes[',']  = 188 ;
-        this.keyCodes['-']  = 189 ;
-        this.keyCodes['_']  = 189; 
-        this.keyCodes['>']  = 190 ;
-        this.keyCodes['.']  = 190 ;
-        this.keyCodes['/']  = 191 ;
-        this.keyCodes['?']  = 191 ;
-
-        this.keyCodes['`']  = 192 ;
-        this.keyCodes['~']  = 192 ;
-        this.keyCodes['[']  = 219 ;
-        this.keyCodes['{']  = 219 ;
-        this.keyCodes['\\']  = 220 ;
-        this.keyCodes['|']  =  220; 
-        this.keyCodes[']']  = 221 ;
-        this.keyCodes['}']  = 221 ;
-        this.keyCodes['\"']  = 222 ;
-        this.keyCodes['\'']  = 222 ;
-
-        this.keyCodes['IME']  = 229 ;
-    }
-        
     /**
-     * A hash where each of the keys that is currently 
+     * A hash where each of the keys that is currently
      * down on the keyboard is set to true.
      * @type Object
      * @access private
      */
-    var downKeysHash = {};
+    var downKeysHash :Object = {};
 
     /**
      * An array of currently pressed key codes.
      * @type Array
      * @access private
      */
-    var downKeysArray = [];
+    var downKeysArray :Array = [];
 
     /**
-     * An object used by callOnKeyCombo() to track kep combinations  
+     * An object used by callOnKeyCombo() to track key combinations
      * @type Object
      * @access private
      */
-    var keycombos = {};
+    var keycombos :Object = {};
 
     /**
-     * Sent when a key is pressed; sent with keycode 
+     * Sent when a key is pressed; sent with keycode
      * for key that was pressed.
      * @lzxtype event
      * @access public
      */
-    var onkeydown = LzDeclaredEvent;
+    var onkeydown :LzDeclaredEventClass = LzDeclaredEvent;
     /**
      * Sent whenever a key goes up; sent with keycode
      * for key that was let go.
      * @lzxtype event
      * @access public
      */
-    var onkeyup = LzDeclaredEvent;
+    var onkeyup :LzDeclaredEventClass = LzDeclaredEvent;
     /**
-     * Sent when the mouse wheel changes state.  Sent with a positive or 
-     * negative number depending on the direction and amount the wheel moved. 
+     * Sent when the mouse wheel changes state.  Sent with a positive or
+     * negative number depending on the direction and amount the wheel moved.
      * @lzxtype event
      * @access public
      */
-    var onmousewheeldelta = LzDeclaredEvent;
+    var onmousewheeldelta :LzDeclaredEventClass = LzDeclaredEvent;
 
     /** For mapping key names (control, shift, alt) back to character codes
       * @access private */
-    var codemap = {shift: 16, control: 17, alt: 18};
+    const codemap :Object = {shift: 16, control: 17, alt: 18};
 
     /** @access private */
-    function __keyEvent ( delta, k, type ){
+    function __keyEvent (delta:Object, k:Number, type:String) :void {
         //for each key change, send the corresponding event
-        for (var key in delta) {
-            var down = delta[key];
-            if (this.codemap[key] != null) k = this.codemap[key];
+        var cm:Object = this.codemap;
+        for (var key:String in delta) {
+            var down:Boolean = delta[key];
+            if (cm[key] != null) k = cm[key];
             if (down) {
                 this.gotKeyDown(k);
             } else {
                 this.gotKeyUp(k);
-            }    
+            }
         }
-    }    
+    }
 
     /**
-     * Called whenever a key is pressed with the Flash keycode corresponding to 
+     * Called whenever a key is pressed with the Flash keycode corresponding to
      * the down key.
-     * 
+     *
      * @access private
      * @param Number kC: The Flash keycode for the key that is down.
      * @param String info: if "extra" then ignore if you already got one
      */
-    function gotKeyDown ( kC, info = null ){
-        if ( this.downKeysArray.length > 0 ){
-            var badkeys = null;
+    function gotKeyDown (kC:Number, info:String = null) :void {
+        var dkhash:Object = this.downKeysHash;
+        var dkeys:Array = this.downKeysArray;
 
-            for ( var i = this.downKeysArray.length-1 ; i >=0; i-- ){
-                var dkC = this.downKeysArray[ i ];
-                if (  dkC == kC ) continue;
-            }
-        }
-        var firstkeydown = !this.downKeysHash[ kC ];
+        var firstkeydown:Boolean = !dkhash[ kC ];
         if (firstkeydown) {
-            this.downKeysHash[ kC ] = true;
-            this.downKeysArray.push (  kC );
-        } 
+            dkhash[ kC ] = true;
+            dkeys.push( kC );
+            dkeys.sort();
+        }
         // send key down event first, so inputtext will get key event
         // before a command that may change the focus
         if (firstkeydown || info != "extra") {
-            // won'tdown || info != "extra") {
             // won't send repeated key events in player XXX ?
 
             // check for IME
-            if (this.downKeysHash[229] != true) {
+            if (dkhash[229] != true) {
                 if (this.onkeydown.ready) this.onkeydown.sendEvent( kC );
             }
         }
-
-        if ( firstkeydown ){
-            var cp = this.keycombos;
-            var dkeys = this.downKeysArray;
-            dkeys.sort();
-            for ( var i = 0 ; i < dkeys.length && cp != null ; i++ ){
-                cp  = cp[ dkeys[ i ] ];
+        if (firstkeydown) {
+            var cp:Object = this.keycombos;
+            for (var i:int = 0; i < dkeys.length && cp != null; i++) {
+                cp = cp[ dkeys[ i ] ];
             }
 
             if (cp != null && 'delegates' in cp) {
-                for ( var i = 0 ; i < cp.delegates.length ; i++ ){
-                    cp.delegates[ i ].execute( this.downKeysArray );
+                var del:Array = cp.delegates;
+                for (var i:int = 0; i < del.length; i++) {
+                    del[ i ].execute( dkeys );
                 }
             }
         }
-
-        /*if ( Selection.getFocus() != null ){
-          passKeyPress( kC );
-          }*/
-            
     }
 
     /**
-     * Called whenever the a key is released with the Flash keycode 
+     * Called whenever the a key is released with the Flash keycode
      * corresponding to the up key.
-     * 
+     *
      * @access private
      * @param Number kC: The Flash keycode for the key that was released.
      */
-    function gotKeyUp ( kC ){
-
-        if (!this.downKeysHash[ kC ]) {
-            // Debug.write("derived keyDown", kC);
-        }
-    
-        if ( this.downKeysHash[229] != true && !this.downKeysHash[ kC ]) {
+    function gotKeyUp (kC:Number) :void {
+        var dkhash:Object = this.downKeysHash;
+        if (dkhash[229] != true && !dkhash[ kC ]) {
             // in FP5 some keys don't get a keydown event, but do get a keyup
             this.gotKeyDown( kC );
         }
 
-        delete this.downKeysHash[ kC ];
+        delete dkhash[ kC ];
 
-        this.downKeysArray = [];
-        for ( var k in this.downKeysHash ){
-            this.downKeysArray.push( k );
+        var dkeys:Array = this.downKeysArray = [];
+        for (var k:String in dkhash) {
+            dkeys.push( k );
         }
         if (this.onkeyup.ready) this.onkeyup.sendEvent( kC );
-
     }
 
     /**
@@ -251,15 +206,16 @@
      * @param k: The name of the key to check for downness or an array of
      * key names, e.g. ['shift', 'tab']
      */
-    function isKeyDown ( k ){
+    function isKeyDown (k:*) :Boolean {
         if (typeof(k) == "string") {
             return (this.downKeysHash[ this.keyCodes[ k.toLowerCase() ] ] == true);
         } else {
             // an array of keys was passed
-            var down = true;
-            for (var i=0; i < k.length; i++) {
-                down = down && (this.downKeysHash[this.keyCodes[k[i].toLowerCase()]]
-                                == true);
+            var down:Boolean = true;
+            var dkhash:Object = this.downKeysHash;
+            var kc:Object = this.keyCodes;
+            for (var i:int = 0; i < k.length; i++) {
+                down = down && (dkhash[ kc[ k[i].toLowerCase() ] ] == true);
             }
             return down;
         }
@@ -267,7 +223,7 @@
 
     /**
      * Instructs the service to call the given delegate whenever the
-     * given key combination is pressed.  
+     * given key combination is pressed.
      * The names for recognized special keys are (case-insensitive):
      * <ul>
      * <li>numbpad0 </li>
@@ -362,52 +318,53 @@
      * @param LzDelegate d: The delegate to be called when the keycombo is down.
      * @param Array kCArr: Array of strings indicating which keys constitute the
      * keycombo. This array may be in any order.
+     * @devnote TODO: [20081012 anba] (LPP-7037) change param d to LzDelegatable
      */
-    function callOnKeyCombo ( d , kCArr ){
-
-        var kcSorted = [];
-        for (var i = 0; i < kCArr.length; i++ ){
-            kcSorted.push( this.keyCodes[ kCArr[ i ].toLowerCase() ] );
+    function callOnKeyCombo (d:*, kCArr:Array) :void {
+        var kc:Object = this.keyCodes;
+        var kcSorted:Array = [];
+        for (var i:int = 0; i < kCArr.length; i++) {
+            kcSorted.push( kc[ kCArr[ i ].toLowerCase() ] );
         }
-    
         kcSorted.sort();
-    
-        var cp = this.keycombos;
-        for ( var i = 0 ; i < kcSorted.length; i++ ){
 
-            if ( cp[ kcSorted[ i ] ] == null ){
-                cp[ kcSorted[ i ] ] = {};
-                cp[ kcSorted[ i ] ].delegates = [ ];
+        var cp:Object = this.keycombos;
+        for (var i:int = 0; i < kcSorted.length; i++) {
+            var cpnext:Object = cp[ kcSorted[ i ] ];
+            if (cpnext == null) {
+                cp[ kcSorted[ i ] ] = cpnext = {delegates: []};
             }
-            cp  = cp[ kcSorted[ i ] ];
+            cp = cpnext;
         }
         cp.delegates.push( d );
     }
-                        
+
     /**
-     * Removes the request to call the delegate on the keycombo. 
-     * @param LzDelegate d: The delegate that was to be called when the 
+     * Removes the request to call the delegate on the keycombo.
+     * @param LzDelegate d: The delegate that was to be called when the
      * keycombo was down.
-     * @param Array kCArr: An array of strings indicating which keys 
+     * @param Array kCArr: An array of strings indicating which keys
      * constituted the keycombo.
+     * @devnote TODO: [20081012 anba] (LPP-7037) change param d to LzDelegatable
      */
-    function removeKeyComboCall ( d , kCArr ){
-        var kcSorted = [];
-        for (var i = 0; i < kCArr.length; i++ ){
-            kcSorted.push( this.keyCodes[ kCArr[ i ].toLowerCase() ] );
+    function removeKeyComboCall (d:*, kCArr:Array) :* {
+        var kc:Object = this.keyCodes;
+        var kcSorted:Array = [];
+        for (var i:int = 0; i < kCArr.length; i++) {
+            kcSorted.push( kc[ kCArr[ i ].toLowerCase() ] );
         }
         kcSorted.sort();
 
-        var cp = this.keycombos;
-        for ( var i = 0 ; i < kcSorted.length; i++ ){
-            if ( cp[ kcSorted[ i ] ] == null ){
+        var cp:Object = this.keycombos;
+        for (var i:int = 0; i < kcSorted.length; i++) {
+            cp = cp[ kcSorted[ i ] ];
+            if (cp == null) {
                 return false; //error
             }
-            cp  = cp[ kcSorted[ i ] ];
         }
-        for ( var i = cp.delegates.length-1 ; i >=0; i-- ){
-            if ( cp.delegates[ i ] == d ){
-                cp.delegates.splice( i , 1 );
+        for (var i:int = cp.delegates.length - 1; i >= 0; i--) {
+            if (cp.delegates[ i ] == d) {
+                cp.delegates.splice( i, 1 );
             }
         }
     }
@@ -415,7 +372,7 @@
     /**
      * @access private
      */
-    function enableEnter ( onroff ){
+    function enableEnter (onroff:Boolean) :void {
         //Debug.write("enableEnter: "+onroff);
         // SWF-specific
         if ($debug) Debug.write('lz.Keys.enableEnter not yet defined');
@@ -425,122 +382,93 @@
     }
 
     /**
-      * The amount the mouse wheel last moved.  Use the 
+      * The amount the mouse wheel last moved.  Use the
       * onmousewheeldelta event to learn when this value changes.
       * @type Number
       * @lzxtype Number
       * @lzxdefault 0
       * @keywords readonly
       */
-    var mousewheeldelta = 0;
+    var mousewheeldelta :Number = 0;
 
     /** @access private */
-    function __mousewheelEvent(d) {
-        //Debug.write('__mousewheelEvent', d);
+    function __mousewheelEvent (d:Number) :void {
         this.mousewheeldelta = d;
         if (this.onmousewheeldelta.ready) this.onmousewheeldelta.sendEvent(d);
     }
 
+    /** Called when the last focusable element is reached
+      * @access private
+      */
+    function gotLastFocus (ignore:*) :void {
+        LzKeyboardKernel.gotLastFocus();
+    }
+
     /**
      * A hash that maps key names to key codes.
      * @type Object
      * @access private
      */
-    var keyCodes = {
-    a : 65 ,
-    b : 66 ,
-    c : 67 ,
-    d : 68 ,
-    e : 69 ,
-    f : 70 ,
-    g : 71 ,
-    h : 72 ,
-    i : 73 ,
-    j : 74 ,
-    k : 75 ,
-    l : 76 ,
-    m : 77 ,
-    n : 78 ,
-    o : 79 ,
-    p : 80 ,
-    q : 81 ,
-    r : 82 ,
-    s : 83 ,
-    t : 84 ,
-    u : 85 ,
-    v : 86 ,
-    w : 87 ,
-    x : 88 ,
-    y : 89 ,
-    z : 90 ,
-    numbpad0 : 96 ,
-    numbpad1 : 97 ,
-    numbpad2 : 98 ,
-    numbpad3 : 99 ,
-    numbpad4 : 100 ,
-    numbpad5 : 101 ,
-    numbpad6 : 102 ,
-    numbpad7 : 103 ,
-    numbpad8 : 104 ,
-    numbpad9 : 105 ,
-    multiply : 106 ,
-    enter : 13 ,
-    subtract : 109 ,
-    decimal : 110 ,
-    divide : 111 ,
-    f1 : 112 ,
-    f2 : 113 ,
-    f3 : 114 ,
-    f4 : 115 ,
-    f5 : 116 ,
-    f6 : 117 ,
-    f7 : 118 ,
-    f8 : 119 ,
-    f9 : 120 ,
-    f10 : 121 ,
-    f11 : 122 ,
-    f12 : 123 ,
-    backspace : 8 ,
-    tab : 9 ,
-    clear : 12 ,
-    enter : 13 ,
-    shift : 16 ,
-    control : 17 ,
-    alt : 18 ,
-    capslock : 20 ,
-    esc : 27 ,
-    spacebar : 32 ,
-    pageup : 33 ,
-    pagedown : 34 ,
-    end : 35 ,
-    home : 36 ,
-    leftarrow : 37 ,
-    uparrow : 38 ,
-    rightarrow : 39 ,
-    downarrow : 40 ,
-    insert : 45 ,
-    help : 47 ,
-    numlock : 144
-    }
+    const keyCodes :Object = {
+    /* numerical keys and non-alphanum keys */
+    '0' : 48, ')' : 48,    ';'  : 186, ':'  : 186,
+    '1' : 49, '!' : 49,    '='  : 187, '+'  : 187,
+    '2' : 50, '@' : 50,    '<'  : 188, ','  : 188,
+    '3' : 51, '#' : 51,    '-'  : 189, '_'  : 189,
+    '4' : 52, '$' : 52,    '>'  : 190, '.'  : 190,
+    '5' : 53, '%' : 53,    '/'  : 191, '?'  : 191,
+    '6' : 54, '^' : 54,    '`'  : 192, '~'  : 192,
+    '7' : 55, '&' : 55,    '['  : 219, '{'  : 219,
+    '8' : 56, '*' : 56,    '\\' : 220, '|'  : 220,
+    '9' : 57, '(' : 57,    ']'  : 221, '}'  : 221,
+                           '\"' : 222, '\'' : 222,
+    /* alphabetical keys */
+    a : 65, b : 66, c : 67, d : 68, e : 69, f : 70, g : 71,
+    h : 72, i : 73, j : 74, k : 75, l : 76, m : 77, n : 78,
+    o : 79, p : 80, q : 81, r : 82, s : 83, t : 84, u : 85,
+    v : 86, w : 87, x : 88, y : 89, z : 90,
 
-    /** Called when the last focusable element is reached
-      * @access private 
-      */
-    function gotLastFocus(ignore) {
-        LzKeyboardKernel.gotLastFocus();
+    /* numpad keys */
+    numbpad0 : 96,  numbpad1 : 97,  numbpad2 : 98,  numbpad3 : 99,  numbpad4 : 100,
+    numbpad5 : 101, numbpad6 : 102, numbpad7 : 103, numbpad8 : 104, numbpad9 : 105,
+    multiply : 106, 'add'    : 107, subtract : 109, decimal  : 110, divide   : 111,
+
+    /* function keys */
+    f1 : 112, f2 : 113, f3 : 114, f4  : 115, f5  : 116, f6  : 117,
+    f7 : 118, f8 : 119, f9 : 120, f10 : 121, f11 : 122, f12 : 123,
+
+    /* special keys */
+    backspace : 8,
+    tab : 9,
+    clear : 12,
+    enter : 13,
+    shift : 16,
+    control : 17,
+    alt : 18,
+    'pause' : 19, 'break' : 19,
+    capslock : 20,
+    esc : 27,
+    spacebar : 32,
+    pageup : 33,
+    pagedown : 34,
+    end : 35,
+    home : 36,
+    leftarrow : 37,
+    uparrow : 38,
+    rightarrow : 39,
+    downarrow : 40,
+    insert : 45,
+    'delete' : 46,
+    help : 47,
+    numlock : 144,
+    screenlock : 145,
+    'IME' : 229
     }
+
 }
 lz.KeysService = LzKeysService;  // publish
 
 /**
-  * lz.Keys is a shortcut for <a href="LzKeysService.html">LzKeysService</a>.
+  * lz.Keys is a shortcut for <a href="LzKeysService.html">LzKeysService.LzKeys</a>.
   */
-lz.Keys = new LzKeysService();
-
-if ($dhtml) {
-    // Need to explicitly register this.  Make sure lz.embed.mousewheel is there for 
-    // lztest
-    if (lz.embed['mousewheel']) {
-        lz.embed.mousewheel.setCallback(lz.Keys, '__mousewheelEvent');
-    }
-}
+lz.Keys = LzKeysService.LzKeys;



More information about the Laszlo-checkins mailing list