Author: shane.bryzak(a)jboss.com
Date: 2009-06-15 23:33:21 -0400 (Mon, 15 Jun 2009)
New Revision: 11161
Added:
sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Label.js
sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Panel.js
Modified:
sandbox/trunk/modules/xwidgets/examples/helloworld/index.html
sandbox/trunk/modules/xwidgets/examples/helloworld/test.xw
sandbox/trunk/modules/xwidgets/src/main/javascript/xw.Panel.js
sandbox/trunk/modules/xwidgets/src/main/javascript/xw.js
Log:
support for magical asynchronous, dynamic loading of components
Modified: sandbox/trunk/modules/xwidgets/examples/helloworld/index.html
===================================================================
--- sandbox/trunk/modules/xwidgets/examples/helloworld/index.html 2009-06-15 23:54:27 UTC
(rev 11160)
+++ sandbox/trunk/modules/xwidgets/examples/helloworld/index.html 2009-06-16 03:33:21 UTC
(rev 11161)
@@ -5,10 +5,12 @@
<div id="container"></div>
<script src="../../src/main/javascript/xw.js"></script>
- <script src="../../src/main/javascript/xw.Panel.js"></script>
- <script src="../../src/main/javascript/xw.Label.js"></script>
- <script type="text/javascript">
+ <script type="text/javascript">
+ // Can't set the resource base to another path
+ // because of browser security restrictions
+ //xw.setResourceBase("../../src/main/javascript");
+
xw.openView("test.xw", "container");
</script>
</body>
Modified: sandbox/trunk/modules/xwidgets/examples/helloworld/test.xw
===================================================================
--- sandbox/trunk/modules/xwidgets/examples/helloworld/test.xw 2009-06-15 23:54:27 UTC
(rev 11160)
+++ sandbox/trunk/modules/xwidgets/examples/helloworld/test.xw 2009-06-16 03:33:21 UTC
(rev 11161)
@@ -2,7 +2,5 @@
<view
xmlns="http://jboss.com/products/xwidgets">
<panel>
<label value="Hello World!"/>
-
-
</panel>
</view>
\ No newline at end of file
Added: sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Label.js
===================================================================
--- sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Label.js
(rev 0)
+++ sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Label.js 2009-06-16 03:33:21 UTC
(rev 11161)
@@ -0,0 +1,23 @@
+Package("xw.controls");
+
+xw.controls.Label = function()
+{
+ this.value = "";
+ this.parent = null;
+ this.control = null;
+
+ xw.controls.Label.prototype.setParent = function(parent)
+ {
+ this.parent = parent;
+ }
+
+ xw.controls.Label.prototype.paint = function()
+ {
+ if (this.control == null)
+ {
+ this.control = document.createTextNode(this.value);
+ this.control.widget = this;
+ this.parent.control.appendChild(this.control);
+ }
+ }
+}
Added: sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Panel.js
===================================================================
--- sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Panel.js
(rev 0)
+++ sandbox/trunk/modules/xwidgets/examples/helloworld/xw.Panel.js 2009-06-16 03:33:21 UTC
(rev 11161)
@@ -0,0 +1,29 @@
+Package("xw.controls");
+
+xw.controls.Panel = function()
+{
+ this.width = 200;
+ this.height = 100;
+ this.parent = null;
+ this.control = null;
+
+ xw.controls.Panel.prototype.setParent = function(parent)
+ {
+ this.parent = parent;
+ }
+
+ xw.controls.Panel.prototype.paint = function()
+ {
+ if (this.control == null)
+ {
+ this.control = document.createElement("div");
+ this.control.widget = this;
+ this.parent.control.appendChild(this.control);
+
+ this.control.style.width = "400";
+ this.control.style.height = "200";
+
+ this.control.style.border = "1px solid black";
+ }
+ }
+}
Modified: sandbox/trunk/modules/xwidgets/src/main/javascript/xw.Panel.js
===================================================================
--- sandbox/trunk/modules/xwidgets/src/main/javascript/xw.Panel.js 2009-06-15 23:54:27 UTC
(rev 11160)
+++ sandbox/trunk/modules/xwidgets/src/main/javascript/xw.Panel.js 2009-06-16 03:33:21 UTC
(rev 11161)
@@ -20,8 +20,8 @@
this.control.widget = this;
this.parent.control.appendChild(this.control);
- this.control.style.width = "100%";
- this.control.style.height = "100%";
+ this.control.style.width = "400";
+ this.control.style.height = "200";
this.control.style.border = "1px solid black";
}
Modified: sandbox/trunk/modules/xwidgets/src/main/javascript/xw.js
===================================================================
--- sandbox/trunk/modules/xwidgets/src/main/javascript/xw.js 2009-06-15 23:54:27 UTC (rev
11160)
+++ sandbox/trunk/modules/xwidgets/src/main/javascript/xw.js 2009-06-16 03:33:21 UTC (rev
11161)
@@ -28,41 +28,157 @@
return false;
}
+xw.Sys.createHttpRequest = function(mimeType)
+{
+ if (window.XMLHttpRequest)
+ {
+ var req = new XMLHttpRequest();
+ if (mimeType != null && req.overrideMimeType)
req.overrideMimeType(mimeType);
+ return req;
+ }
+ else
+ {
+ return new ActiveXObject("Microsoft.XMLHTTP");
+ }
+}
+
/**
- * View Loader - loads view definitions from a URL
+ * Asynchronously loads the javascript source from the specified url
*/
-xw.ViewLoader = {};
-xw.ViewLoader.load = function(viewName, callback)
+xw.Sys.loadSource = function(url, callback)
{
- if (window.XMLHttpRequest)
+ var req = xw.Sys.createHttpRequest("text/plain");
+ req.onreadystatechange = function() {
+ if (req.readyState == 4)
+ {
+ if (req.status == 200 || req.status == 0)
+ {
+ var e = document.createElement("script");
+ e.language = "javascript";
+ e.text = req.responseText;
+ e.type = "text/javascript";
+ document.getElementsByTagName("head")[0].appendChild(e);
+ if (callback) callback();
+ }
+ }
+ else
+ {
+ //alert("There was an error processing your request. Error code: " +
req.status);
+ }
+ };
+
+ req.open("GET", url, true);
+ req.send(null);
+}
+
+xw.Sys.isUndefined = function(value)
+{
+ return value == null && value !== null;
+}
+
+xw.Sys.arrayContains = function(arrayVal, value)
+{
+ for (var i = 0; i < arrayVal.length; i++)
{
- asyncReq = new XMLHttpRequest();
- if (asyncReq.overrideMimeType)
- asyncReq.overrideMimeType("text/xml");
+ if (arrayVal[i] == value) return true;
+ }
+ return false;
+}
+
+xw.Sys.capitalize = function(value)
+{
+ return value.substring(0, 1).toUpperCase() + value.substring(1, value.length);
+}
+
+/**
+ * Control manager
+ */
+xw.ControlManager = {};
+xw.ControlManager.controls = new Array();
+xw.ControlManager.pendingControls = new Array();
+xw.ControlManager.initControl = function(controlName)
+{
+ if (xw.Sys.isUndefined(xw.controls) ||
+ xw.Sys.isUndefined(eval("xw.controls." + controlName)))
+ {
+ var url = xw.getResourceBase() + "xw." + xw.Sys.capitalize(controlName) +
".js";
+ var callback = function() { xw.ControlManager.processPendingControls(); };
+ xw.Sys.loadSource(url, callback);
+ }
+}
+
+xw.ControlManager.processPendingControls = function()
+{
+ if (xw.ControlManager.pendingControls.length > 0)
+ {
+ var controlName = xw.ControlManager.pendingControls.shift();
+ xw.ControlManager.initControl(controlName);
}
else
{
- asyncReq = new ActiveXObject("Microsoft.XMLHTTP");
+ xw.ViewManager.signalControlsLoaded();
+ }
+}
+
+xw.ControlManager.loadControls = function(controls)
+{
+ for (var i = 0; i < controls.length; i++)
+ {
+ if (!xw.ControlManager.isControlLoaded(controls[i]))
+ {
+ xw.ControlManager.pendingControls.push(controls[i]);
+ }
}
+
+ xw.ControlManager.processPendingControls();
+}
+xw.ControlManager.isControlLoaded = function(controlName)
+{
+ for (var i = 0; i < xw.ControlManager.controls.length; i++)
+ {
+ if (xw.ControlManager.controls[i] == controlName) return true;
+ }
+ return false;
+}
- asyncReq.onreadystatechange = function() { callback(asyncReq) };
- asyncReq.open("GET", viewName, true);
- asyncReq.send(null);
- return asyncReq;
+/**
+ * View Loader - loads view definitions from a URL
+ */
+xw.ViewLoader = {};
+xw.ViewLoader.load = function(viewName, callback)
+{
+ var req = xw.Sys.createHttpRequest("text/xml");
+ req.onreadystatechange = function() { callback(req) };
+ req.open("GET", viewName, true);
+ req.send(null);
+ return req;
}
/**
* View manager - responsible for caching views
*/
xw.ViewManager = {};
-xw.ViewManager.views = {};
+xw.ViewManager.pendingViews = new Array();
xw.ViewManager.loadViewCallback = function(req, container)
{
if (req.readyState == 4)
{
if (req.status == 200 || req.status == 0)
{
- xw.renderView(req.responseXML.documentElement, container);
+ var viewRoot = req.responseXML.documentElement;
+ if (viewRoot.tagName == "view")
+ {
+ // create the view and push it into the pendingViews array
+ var view = new xw.View(viewRoot, container);
+ xw.ViewManager.pendingViews.push(view);
+ // next we want to load all of the controls
+ var controls = view.getDependencies();
+ xw.ControlManager.loadControls(controls);
+ }
+ else
+ {
+ alert("Invalid view definition - document root is not 'view'
element");
+ }
}
else
{
@@ -71,6 +187,16 @@
}
}
+xw.ViewManager.signalControlsLoaded = function()
+{
+ if (xw.ViewManager.pendingViews.length > 0)
+ {
+ var view = xw.ViewManager.pendingViews.shift();
+ view.render();
+ }
+
+}
+
xw.ViewManager.openView = function(viewName, container)
{
var callback = function(req) {
@@ -102,9 +228,35 @@
xw.View.prototype.render = function()
{
- this.element =
this.renderChildren(this.viewRoot.childNodes, this);
}
+
+ xw.View.prototype.getDependencies = function()
+ {
+ var controls = new Array();
+ this.parseControls(this.viewRoot.childNodes, controls);
+ return controls;
+ }
+
+ xw.View.prototype.parseControls = function(elements, controls)
+ {
+ for (var i = 0; i < elements.length; i++)
+ {
+ var element = elements.item(i);
+ if (element instanceof Element)
+ {
+ if (!xw.Sys.arrayContains(controls, element.tagName))
+ {
+ controls[controls.length] = element.tagName;
+ }
+ var children = element.childNodes;
+ if (children.length > 0)
+ {
+ this.parseControls(children, controls);
+ }
+ }
+ }
+ }
xw.View.prototype.renderChildren = function(children, parentControl)
{
@@ -123,6 +275,7 @@
var controlName = tag.substring(0,1).toUpperCase() +
tag.substring(1, tag.length);
+ // TODO fix
var control = eval("new xw.controls." + controlName + "()");
control.setParent(parent);
@@ -149,22 +302,23 @@
}
/**
- * General methods
+ ******* General methods *******
*/
+
+/**
+ * Opens a view in the specified container - this call is asynchronous
+ */
xw.openView = function(viewName, container)
{
xw.ViewManager.openView(viewName, container);
}
-xw.renderView = function(viewRoot, container)
-{
- if (viewRoot.tagName == "view")
- {
- var view = new xw.View(viewRoot, container);
- view.render();
- }
- else
- {
- alert("Invalid view definition - document root is not 'view'
element");
- }
+xw.setResourceBase = function(resourceBase)
+{
+ xw.resourceBase = resourceBase;
+}
+
+xw.getResourceBase = function()
+{
+ return xw.Sys.isUndefined(xw.resourceBase) ? "" : xw.resourceBase +
"/";
}
\ No newline at end of file