dev-console.lzx
<canvas width="100%" height="370" proxied="false" bgcolor="#858599">
<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>
<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>
<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>
<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>
<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>
<switch>
<when runtime="dhtml">
</when>
<otherwise>
<state name="consoledebugstate" applied="${canvas.app_console_debug}">
<view y="90" layout="axis:x;spacing:4">
<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(' \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>
<attribute name="receivingLC"/>
<attribute name="consolelistenerName"/>
<attribute name="appListenerName"/>
<switch>
<when runtime="swf10">
<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>
Cross References
Resources
Named Instances