dev-console.lzx

<!--=======================================================================-->
<!--                                                                       -->
<!-- dev-console.lzx                                                       -->
<!--                                                                       -->
<!-- dev console SOLO app                                                  -->
<!--                                                                       -->
<!--=======================================================================-->
<canvas width="100%" height="370" proxied="false" bgcolor="#858599">
 <!-- Make sure there is a copyright in the Javascript 'binary' -->
 <attribute name="copyright" type="string" value="Copyright 2001-2011 Laszlo Systems, Inc.  All Rights Reserved.  Use is subject to license terms."/>
 <switch>
    <when property="$dhtml">
    </when>
    <otherwise>
        <debug options="ignorelayout" fontsize="12" x="800" y="0" width="600" height="80"/>
    </otherwise>
  </switch>

  <attribute name="app_runtime"/>
  <attribute name="runtime_dhtml_enabled" value="false"/>
  <attribute name="runtime_mobile_enabled" value="false"/>
  <attribute name="runtime_swf9_enabled" value="false"/>
  <attribute name="runtime_swf10_enabled" value="false"/>
  <attribute name="app_debug"/>
  <attribute name="app_backtrace"/>
  <attribute name="app_console_debug"/>
  <attribute name="app_floating_window"/>
  <attribute name="app_fullpath"/>
  <attribute name="app_query"/>
  <attribute name="app_opt_url"/>
  <attribute name="app_unopt_url"/>
  <attribute name="app_url"/>
  <attribute name="app_opt_exists"/>
  <attribute name="app_lps_root"/>
  <attribute name="app_lzt"/>
  <attribute name="app_uid"/>
  <attribute name="app_lzoptions"/>
  <attribute name="app_isproxied"/>
  <attribute name="app_incremental_compile"/>
  <attribute name="app_usemastersprite"/>

  <handler name="oninit">
      
       appdata.setAttribute('initialdata', lz.Browser.getInitArg('appinfo'));

       //       lz.Browser.callJS('console.log("'+ escape(lz.Browser.getInitArg('appinfo'))+'")');
       setAttribute('app_runtime', appdata.getPointer().xpathQuery("/info/@runtime"));
       setAttribute('app_incremental_compile', appdata.getPointer().xpathQuery("/request/param[@name = 'incremental']/@value"));
       this.setupRuntimes();
       if (app_runtime == null) {
           setAttribute('app_runtime', appdata.getPointer().xpathQuery("/request/param[@name = 'runtime']/@value"));
       }
       setAttribute('app_lzoptions', appdata.getPointer().xpathQuery("/request/param[@name = 'lzoptions']/@value"));

       setAttribute('app_debug', appdata.getPointer().xpathQuery("/request/param[@name = 'debug']/@value"));
       if (app_debug == 'y') { setAttribute('app_debug', 'true'); }

       // Force incremental-compile flag to true, if debug mode is on
       if (app_debug == 'true') {
           setAttribute('app_incremental_compile', 'true');
       }

       setAttribute('app_backtrace', appdata.getPointer().xpathQuery("/request/param[@name = 'backtrace']/@value"));
       setAttribute('app_console_debug', 
                    appdata.getPointer().xpathQuery("/request/@console-remote-debug") == 'true');
       setAttribute('app_isproxied', lz.Browser.getInitArg('appproxied'));
       setAttribute('app_floating_window',
                    appdata.getPointer().xpathQuery("/request/@console-floating-window") == 'true');
       setAttribute('app_fullpath', appdata.getPointer().xpathQuery("/request/@fullpath"));
       setAttribute('app_query', appdata.getPointer().xpathQuery("/request/@query_args"));
       setAttribute('app_opt_url', appdata.getPointer().xpathQuery("/request/@opt-url"));
       setAttribute('app_unopt_url', appdata.getPointer().xpathQuery("/request/@unopt-url"));
       setAttribute('app_url', appdata.getPointer().xpathQuery("/request/@url"));
       setAttribute('app_opt_exists', appdata.getPointer().xpathQuery("/request/@opt-exists"));
       setAttribute('app_lps_root', appdata.getPointer().xpathQuery("/request/@lps"));
       setAttribute('app_lzt', null);
       // Use the url pathname as the uid to rendevouz with the app, the app will be listening on
       // a LocalConnection there.
       setAttribute('app_uid', app_fullpath);

       if ($dhtml) {
           setAttribute('lzr', $mobile ? 'mobile' : 'dhtml');
           setAttribute('app_usemastersprite',
                        appdata.getPointer().xpathQuery("/request/param[@name = 'usemastersprite']/@value") || 
                        appdata.getPointer().xpathQuery("/request/param[@name = 'lzusemastersprite']/@value"));
           canvas.width = document.body.clientWidth;
       }
       
  </handler>

  <!-- create a table listing which runtimes are enabled -->
  <method name="setupRuntimes">
    
     // default set of runtimes
     var runtimes = ['dhtml', 'mobile', 'swf9', 'swf10'];
     // server can tell us if only some are available
     var runtimes_arg = lz.Browser.getInitArg('runtimes');
     // In the case where the compiler gets an error creating the
     // canvas, the runtimes arg may be empty. In that case, we don't
     // know what runtimes are present, so show all runtimes as
     // choices to the user.
     if (runtimes_arg != null && runtimes_arg.length > 0) {
        runtimes = runtimes_arg.split(",");
     } 
     
     for (var r in runtimes) {
         if (runtimes[r] == 'dhtml')  canvas.setAttribute('runtime_dhtml_enabled', true);
         if (runtimes[r] == 'mobile')   canvas.setAttribute('runtime_mobile_enabled', true);
         if (runtimes[r] == 'swf9')   canvas.setAttribute('runtime_swf9_enabled', true);
         if (runtimes[r] == 'swf10')  canvas.setAttribute('runtime_swf10_enabled', true);
     }
   
  </method>

  <!-- info we get is of the form 
  <appdata>
    <request opt-exists="false" 
             windows="true" 
             pocketpc="false" 
             query_args="&amp;debug=true&amp;lzr=swf7" 
             unopt-url="animation.lzx" 
             opt-url="animation.lzo" 
             fullpath="/lps-dev/examples/animation/animation.lzx" 
             url="animation.lzx" 
             opt-exists="true"
             appuid="2222222"
             console-remote-debug="true"
             lps="/lps-dev">
    <param value="true" name="debug"/>
    <param value="swf7" name="lzr"/>
   </request>
   <info runtime="swf7" 
         nondebug-up-to-date="false" 
         nondebug-exists="true" 
         debug-up-to-date="true" 
         debug-exists="true" 
         encoding="" 
         debug="true" gz-size="0" size="256968"/>
</appdata>

  -->


  <dataset name="appdata"/>

  <method name="deploySOLO">
    
     var path = escape(app_fullpath.substring(app_lps_root.length));
     if (app_runtime == 'dhtml' || app_runtime == 'mobile') {
        var url = app_lps_root + "/lps/admin/solo-dhtml-deploy.jsp?runtime="+app_runtime+"&appurl="+path;
     } else {
        var url = app_lps_root + "/lps/admin/solo-deploy.jsp?runtime="+app_runtime+"&appurl="+path;
     }

     this.loadURL(url, '_blank');
     
  </method>

  <!-- generates an exploded widget file to tmp working dir, and redirects to it's config.xml '-->
  <method name="runWidget">
    
     var path = escape(app_fullpath.substring(app_lps_root.length));
     if (app_runtime == 'dhtml' || app_runtime == 'mobile') {
        var url = app_lps_root + "/lps/admin/solo-dhtml-deploy.jsp?runtime="+app_runtime+"&appurl="+path+"&whatpage=emulator";
     } else {
        var url = app_lps_root + "/lps/admin/solo-deploy.jsp?runtime="+app_runtime+"&appurl="+path+"&whatpage=emulator";
     }

     this.loadURL(url, '_blank');
     
  </method>



   <method name="debugApp">
     cb_debug.setValue(true); 
     canvas.reloadApp();
   </method>

   <method name="viewSource">
         setAttribute('app_lzt', 'source');
     canvas.reloadApp();
   </method>

   <method name="viewWrapper">
         setAttribute('app_lzt', 'deployment');
     canvas.reloadApp();
   </method>

   <method name="viewDocs">
     var url = app_lps_root + "/index.html";
     this.loadURL(url);
   </method>
   
   <method name="viewDev">
     var url = "http://www.openlaszlo.org/community";
     this.loadURL(url);
   </method>
   
   <method name="viewForums">
     var url = "http://forum.openlaszlo.org/";
     this.loadURL(url);
   </method>

   <method name="loadURL" args="url, target='_top'">
     lz.Browser.loadURL(url, target);
   </method>
   
  <resource name="footer_logo" src="../assets/logo_laszlo_footer.gif"/>

  <view name="main" width="${parent.width}">
      <view name="logo" resource="footer_logo" bgcolor="0x4c4c4c" height="${canvas.app_console_debug ? 370 : 71}"/>
      <view name="controls" x="70">
        <view name="firstrow" y="4">
            <text fontsize="11" x="8" y="7"><b>Compile Options:</b></text>
            <view x="125" width="${parent.compilecontrols.width + 5}" height="32" bgcolor="black">
                <view x="1" y="1" width="${parent.width - 2}" height="30" bgcolor="#7a7a8c"/>
            </view>
            <view x="125" name="compilecontrols">
                <radiogroup id="rg_runtime" layout="class: simplelayout; axis: x; spacing:12" x="10" y="9">
                    <radiobutton id="rb8" value="'mobile'" enabled="${canvas.runtime_mobile_enabled}" selected="${canvas.app_runtime == 'mobile'}">mobile</radiobutton>
                    <radiobutton id="rb10" value="'swf10'" enabled="${canvas.runtime_swf10_enabled}" selected="${canvas.app_runtime == 'swf10'}">swf10</radiobutton>
                    <radiobutton id="rbdhtml" value="'dhtml'" enabled="${canvas.runtime_dhtml_enabled}" selected="${canvas.app_runtime == 'dhtml'}">HTML5</radiobutton>
                </radiogroup>
                <view x="$once{rg_runtime.x + rg_runtime.width + 14}">
                    <view height="14" width="1" bgcolor="black" y="9"/>
                    <checkbox id="cb_debug" value="${canvas.app_debug == 'true'}" x="16" y="8">Debug</checkbox>
                    <checkbox id="cb_backtrace" value="${canvas.app_backtrace == 'true'}" x="82" y="8">Backtrace</checkbox>
                    <checkbox id="cb_proxied" value="${canvas.app_isproxied == 'true'}" x="168" y="8">Proxied</checkbox>
                    <checkbox id="cb_incremental" value="${canvas.app_incremental_compile == 'true'}" x="240" y="8">Incremental</checkbox>
                    <switch>
                        <when runtime="dhtml">
                            <checkbox id="cb_usemastersprite" value="${canvas.app_usemastersprite == 'true'}" x="335" y="8">Use master sprite</checkbox>
                        </when>
                    </switch>
                    <button onclick="canvas.gotoApp()" x="${(canvas.app_runtime == 'dhtml' || canvas.app_runtime == 'mobile') ? 465 : 370}" y="3">Compile</button>
                    <handler name="onvalue" reference="cb_backtrace">
                    if (cb_backtrace.value) {
                        cb_debug.setAttribute('value', true);
                    }
                    </handler>
                    <handler name="onvalue" reference="cb_debug">
                    if (cb_debug.value == false) {
                        cb_backtrace.setAttribute('value', false);
                    }
                    </handler>
                </view>
            </view>
            <view x="${parent.compilecontrols.width + parent.compilecontrols.x + 32}">
                <button onclick="canvas.viewSource()" y="3">View Source</button>
            </view>
        </view>

        <view bgcolor="black" width="${canvas.width - 70}" height="1" y="39"/>
          
        <view width="${parent.firstrow.width}" y="43" layout="axis: x; spacing: 5">
          <text fontsize="11" x="8" y="4"><b>Deploy:</b></text>
          <button onclick="canvas.viewWrapper()">Server</button>
          <button onclick="canvas.deploySOLO()">Widget (SOLO)</button>
          <button onclick="canvas.runWidget()">Widget Emulator</button>

          <view fgcolor="0x15159b" y="3" options="ignorelayout" align="right" layout="axis: x; spacing: 3">
            <text onclick="canvas.viewDocs()"><u>Documentation</u></text>
            <text onclick="canvas.viewDev()"><u>Developer Community</u></text>
            <text onclick="canvas.viewForums()"><u>Developer Forums</u></text>
          </view>
          
        </view>

          <!--
            <view datapath="appdata:/" >
            <simplelayout/>
            <text resize='true'  datapath="request/@url"/>
            <text resize='true'  datapath="request/@fullpath"/>
            <text resize='true'  datapath="info/@runtime"/>
            </view>

          <view name="blank2" width="200"/>

          -->

          <checkbox y="10" x="${parent.firstrow.width + 20}" id="cb_remotedebug" visible="${! (canvas.app_runtime == 'dhtml' ||  canvas.app_runtime == 'mobile')  }" value="${canvas.app_console_debug}">Console Remote Debug</checkbox>


          <!-- <checkbox id="cb_popup" value="${app_floating_window}">in separate window</checkbox> -->




 <switch>
    <when runtime="dhtml">
    </when>
    <otherwise>
        <state name="consoledebugstate" applied="${canvas.app_console_debug}">
            <view y="90" layout="axis:x;spacing:4">

            <!-- enter expression to be sent to app under debug -->

            <text resize="true" text="${'Evaluate in '+canvas.app_url}"/>
            <edittext doesenter="true" id="expr2" width="300">
                <method name="doEnterDown">
                canvas.remoteEval(expr2.text);
                </method>
            </edittext>
            <button enabled="false" bgcolor="white" id="app_eval_btn" onclick="canvas.remoteEval(expr2.text)">Eval</button>
            <button onclick="app_eval_btn.setAttribute('enabled', true);                              canvas.sendConsoleAlive()">Connect To App</button>
            <button onclick="console.clear();">Clear</button>
            </view>

            <window title="console" id="console" width="1000" y="120" height="200" resizable="true">
            <method name="write" args="objects">
                
                var n = arguments.length
                // Pass each value to __write individually so they can be
                // 'presented' as objects if applicable
                for (var i = 0; i < n; i++) {
                var v = arguments[i];
                var s = ((i == (n-1)) ? '\n' : ' ');
                this.output.addText(lz.Browser.xmlEscape(v)+s);
                sbar.page(sbar.scrollmax);
                }
                
            </method>

            <method name="clear">
                
                this.output.setAttribute('text', '');
                
            </method>
            <method name="writeRaw" args="str">
                
                // Funky thing that Henry discovered you have to do to make newlines
                // why wouldn't <br/> work?
                this.output.addText(str.split('\n').join('&#32;\n'));
                sbar.page(sbar.scrollmax);
                
            </method>
            <text name="output" multiline="true" resize="true" selectable="true" width="${parent.width}">
         
             <handler name="ontextlink" args="oid:String">
                canvas.displayObjectByID(oid);
             </handler>

            </text>
            <scrollbar name="sbar" id="sb"/>
            </window>
        </state>
    </otherwise>
  </switch>

      </view>
  </view>


  <method name="gotoApp">              
    // reload the page with the .lzx path
    var p = app_fullpath.substring(0,app_fullpath.length -4)+".lzx";
    setAttribute('app_fullpath', p);
    this.reloadApp();
  </method>
  
  <method name="reloadApp">
    
    var qruntime = rg_runtime.value;
    var qdebug = cb_debug.value;
    var qbacktrace = cb_backtrace.value;
    var consoledebug = cb_remotedebug.value;
    var qproxied = cb_proxied.value;
    var qinc = cb_incremental.value;

    // parse original app query string, override with user settings
    // for debug, runtime, etc
    var params = new LzParam();
    
    var lzoptions = {};
    var qitems = LzParam.parseQueryString(app_query);
    var rawlzoptstring = qitems['lzoptions'];
    var querylzoptions = null;
    if (rawlzoptstring != null) {
        querylzoptions = LzKernelUtils.parselzoptions(rawlzoptstring);
        for ( var optname in querylzoptions) {
            // scrub old name from query arg
            var tname = lz.Browser.oldOptionName(optname);
            if (tname == null) {
                tname = optname;
            }
            delete qitems[tname];
            // we're not supporting multiple values for options right now, just take first value
            lzoptions[optname] = querylzoptions[optname][0];
        }
    }

    // remove old-style option from query args, and add new lzoptions-style arg value
    lzoptions['debug'] = qdebug;
    delete qitems['debug'];

    // remove old-style option from query args, and add new lzoptions-style arg value
    lzoptions['backtrace'] = qbacktrace;
    delete qitems['backtrace'];

    // remove old-style option from query args, and add new lzoptions-style arg value
    lzoptions['proxied'] = qproxied;
    delete qitems['lzproxied'];

    lzoptions['incremental'] = qinc;

    // remove old-style option from query args, and add new lzoptions-style arg value
    delete qitems['lzr']; 
    lzoptions['runtime'] = qruntime; 


    if ($dhtml) {
        lzoptions['usemastersprite'] = cb_usemastersprite.value;
    }
    if (qruntime != 'dhtml' && qruntime != 'mobile' ) {
        delete lzoptions['usemastersprite'];
    }

    /*
    // code to instruct server to pop up debug console in own window (doesn't work in Firefox)
    if (cb_popup.value) {
       qitems['lzconsolewindow'] = true;
    }
    */

    // and lzconsoledebug = true
    if (consoledebug) {
        qitems['lzconsoledebug'] = true;
        lzoptions['debug'] = true;
    } else {
        delete qitems.lzconsoledebug;
        delete lzoptions.remotedebug;
    }

    // can be {swf,source,deployment}
    if (app_lzt != null) {
        qitems['lzt'] = app_lzt;
    }

    if (lzoptions.debug + '' == 'false') {
        delete lzoptions['debug'];
    } else {
        lzoptions.debug = 'true';
    }

    if (lzoptions.backtrace + '' == 'false') {
        delete lzoptions['backtrace'];
    } else {
        lzoptions.backtrace = 'true';
    }

    // create lzoptions arg
    var lzoptval = "";
    var seen = {};
    var nargs = 0;
    for ( var opt in lzoptions) {
        // work aorund bugs in Safari
        if (opt == '') continue;
        if (opt.indexOf('#38;') != -1) {
            var i = opt.indexOf('#38;');
            opt = opt.substring(i + 4, opt.length);
        }
        if (seen[opt]) continue;
        if ((nargs++) > 0) {
            lzoptval += ",";
        }
        lzoptval += opt+"("+ lzoptions[opt] + ")";
        seen[opt] = true;
    }
    qitems['lzoptions'] = lzoptval


    //Debug.write( 'qitems', qitems);
    // Copy values to LzParam object
    seen = {};
    for ( var key in qitems) {
        // work aorund bugs in Safari
        if (key == '') continue;
        if (key.indexOf('#38;') != -1) {
            var i = key.indexOf('#38;');
            key = key.substring(i + 4, key.length);
        }
        if (seen[key]) continue;
        //alert('params ' + key + ' ' + qitems[key]);
        params.setValue(key, qitems[key]);
        seen[key] = true;
    }

    //alert('params ' + params.toString());

    var url = app_fullpath+"?"+params.serialize("=", "&", true);

    //Debug.write('this.loadURL("'+url+'")');
    this.loadURL(url);

    
  </method>

  <method name="displayObjectByID" args="uid">
    
    // Not very abstract, but it works for now
    receivingLC.send(appListenerName, "displayObj", uid);
    
  </method>


  <method name="showLogMessage" args="msg">
      
      console.writeRaw(lz.Browser.xmlEscape(msg)+"<br>");
      
  </method>


  <method name="showWarning" args="filename,lineNumber,msg">
      
       console.writeRaw(msg);
       
  </method>

  <method name="sendConsoleAlive">
                    
      // sets up the LocalConnection
     if (receivingLC == null) {
      var rcl = new remoteConnectionListener();
      canvas.setAttribute('consoleListenerName', "lc_consoledebug"+app_uid);
      canvas.setAttribute('appListenerName', "lc_appdebug"+app_uid);
      canvas.setAttribute('receivingLC', rcl.setupConnection());
      receivingLC.send(appListenerName, "consoleAlive", true);
     } else {
      console.writeRaw('<font color="#FF0000">Connection is already open to app.</font><br/>');
     }
    
  </method>

  <method name="remoteEval" args="expr">
    
    receivingLC.send(appListenerName, "evalExpr", expr);
    
  </method>

  <!-- pointer to the LocalConnection we receive commands on -->
  <attribute name="receivingLC"/>

  <!-- console listens on this name for messages from app -->
  <attribute name="consolelistenerName"/>

  <!-- app listens on this name for messages from console -->
  <attribute name="appListenerName"/>

 <switch>
    <when runtime="swf10">
      <!-- create an object to handle our LocalConnection listener requests -->
      <script when="immediate">
        public class remoteConnectionListener {
            #passthrough (toplevel:true) {
                import flash.net.LocalConnection;
                import flash.events.StatusEvent;
                import flash.events.SecurityErrorEvent;
            }#

            // display a debug string (with optionally clickable object id) in the console output window.
            // N.B. must be public to allow LocalConnection to dispatch to this method
            public function debugResult(msg,oid) {
                if (oid != null) {
                    var link = console.output.makeTextLink(msg, oid);
                    console.writeRaw('<font color="#0000FF">' + link +"</font>");


                } else {
                    console.writeRaw(msg);
                }
            }

            // N.B. must be public to allow LocalConnection to dispatch to this method
            public  function debugWarning(filename,lineNumber,msg) {
                canvas.showWarning(filename,lineNumber,msg);
            }

            var lc:flash.net.LocalConnection;

            private function onConnStatus(event:StatusEvent):void
            {
                switch (event.level) {
                  case "status":
                    trace("LocalConnection.send() succeeded");
                    break;
                  case "error":
                    trace("LocalConnection.send() failed", event);
                    break;
                }
            }

            private function onConnError(event:SecurityErrorEvent):void
            {
                trace("LocalConnection.send() failed", event);
            }



            // returns the LocalConnection which talks to the app 
            public function setupConnection() {
                var conn = new flash.net.LocalConnection();
                this.lc = conn;
                conn.addEventListener(StatusEvent.STATUS, onConnStatus);
                conn.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onConnError);


                // receives remote app debug message
                // display warnings
                conn.client = this;
                conn.connect(canvas.consoleListenerName);
                return conn;
            }
        }
        
        </script>
     </when>
</switch>



</canvas>
<!-- * X_LZ_COPYRIGHT_BEGIN ***************************************************
* Copyright 2001-2011 Laszlo Systems, Inc.  All Rights Reserved.              *
* Use is subject to license terms.                                            *
* X_LZ_COPYRIGHT_END ****************************************************** -->
<!-- @LZX_VERSION@                                                         -->

Cross References

Resources

Name Source Image
footer_logo ../assets/logo_laszlo_footer.gif

Named Instances