You are viewing a plain text version of this content. The canonical link for it is here.
Posted to xap-commits@incubator.apache.org by jm...@apache.org on 2007/03/26 21:03:10 UTC
svn commit: r522625 - in /incubator/xap/trunk/codebase/src/xap:
bridges/basic/ bridges/dojo/ data/ data/controller/ data/datasource/
Author: jmargaris
Date: Mon Mar 26 14:03:09 2007
New Revision: 522625
URL: http://svn.apache.org/viewvc?view=rev&rev=522625
Log:
https://issues.apache.org/jira/browse/XAP-346
provide/require fixes for better profile building, optization
of how often we call dojo.event.connect
Removed:
incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSet.js
Modified:
incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js
incubator/xap/trunk/codebase/src/xap/bridges/dojo/DojoButtonBridge.js
incubator/xap/trunk/codebase/src/xap/data/DataFramework.js
incubator/xap/trunk/codebase/src/xap/data/DataNamespaceHandler.js
incubator/xap/trunk/codebase/src/xap/data/controller/Binding.js
incubator/xap/trunk/codebase/src/xap/data/controller/BindingResolver.js
incubator/xap/trunk/codebase/src/xap/data/controller/ContextFrame.js
incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSource.js
incubator/xap/trunk/codebase/src/xap/data/datasource/ArrayDataSet.js
incubator/xap/trunk/codebase/src/xap/data/datasource/ObjectDataSource.js
incubator/xap/trunk/codebase/src/xap/data/datasource/SimpleDocumentDataSource.js
Modified: incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js (original)
+++ incubator/xap/trunk/codebase/src/xap/bridges/basic/AbstractWidgetBridge.js Mon Mar 26 14:03:09 2007
@@ -122,7 +122,7 @@
// with tagname "myTag" and specified
// class "aSpecialClass" will add the
// classes "myTagMouseOVer" and "aSpecialClassMouseOver"
- this.setStyleClassNames( new Array(0) );
+ this.setStyleClassNames( [] );
if (this.getCssStyleName()){
// This is the base style class for this tag,
// e.g. "xapRadioButton":
@@ -267,14 +267,7 @@
//declared in XML? Would be more efficient
//TODO what about bubbling? Report events
//on children as our own?
- dojo.event.connect(rootNode,"onfocus", this, "onFocus");
- dojo.event.connect(rootNode,"onblur", this, "onBlur");
- dojo.event.connect(rootNode,"ondblclick", this, "onDblClick");
- dojo.event.connect(rootNode,"onkeydown", this, "onKeyDown");
- dojo.event.connect(rootNode,"onkeyup", this, "onKeyUp");
- dojo.event.connect(rootNode,"onkeypress", this, "onKeyPress");
- dojo.event.connect(rootNode,"onmousedown", this, "onMouseDown");
- dojo.event.connect(rootNode,"onmouseup", this, "onMouseUp");
+
/* only setup mouse events if they're needed, use the IE specific ones on IE */
if ( this._wantsMouseEvents ) {
@@ -288,6 +281,8 @@
}
dojo.event.connect(rootNode, this._onEnter, this, "onMouseOver");
dojo.event.connect(rootNode, this._onLeave, this, "onMouseOut");
+ dojo.event.connect(rootNode,"onmousedown", this, "onMouseDown");
+ dojo.event.connect(rootNode,"onmouseup", this, "onMouseUp");
}
}
}
@@ -619,7 +614,7 @@
// Initialise the default name-to[gs]etter map used under attributeSet:
//TODO is this once per object? or once per class?
- this.constructor._nameToSetterMap = new Object() ;
+ this.constructor._nameToSetterMap = {} ;
var allowed = this.getAllowedAttributes() ;
for( var i = 0; i<allowed.length; i++ ){
@@ -637,8 +632,10 @@
"borderWidth","borderColor","borderStyle","margin",
"padding","color","textDecoration","fontFamily",
"fontStyle","fontWeight", "fontSize", "textAlign",
- "popup","tooltip", "focused", "disabled","visible"];
-}
+ "popup","tooltip", "focused", "disabled","visible",
+ "onFocus","onBlur","onDoubleClick","onKeyDown",
+ "onKeyUp","onKeyPress","onMouseDown","onMouseUp"];
+};
/**
@@ -680,6 +677,52 @@
}
}
+/** XML attribute set methods for onXXX start */
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnFocusAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onfocus", this, "onFocus");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnBlurAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onblur", this, "onBlur");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnDoubleClickAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"ondblclick", this, "onDblClick");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnKeyDownAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onkeydown", this, "onKeyDown");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnKeyUpAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onkeyup", this, "onKeyUp");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnKeyPressAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onkeypress", this, "onKeyPress");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseDownAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onmousedown", this, "onMouseDown");
+};
+
+xap.bridges.basic.AbstractWidgetBridge.prototype.setOnMouseUpAttribute = function(value) {
+ // connect event, discard value
+ dojo.event.connectOnce(this.getRootDomNode(),"onmouseup", this, "onMouseUp");
+};
+
+
+/** XML attribute set methods for onXXX end */
+
+
/** XML attribute set method for "x" */
xap.bridges.basic.AbstractWidgetBridge.prototype.setXAttribute = function(value){
this.getRootDomNode().style.left = value ;
@@ -891,6 +934,10 @@
/**
* When we "set" the class from an explicit class attribute,
* we're really adding it to the base class:
+ *
+ * TODO if they set the class to "a b c" and they already had "x y z"
+ * we'll end up with all 6 on the element. Is this what we want or do we want
+ * to remove x y & z?
*
**/
xap.bridges.basic.AbstractWidgetBridge.prototype.setClassAttribute = function( pClassStr ){
@@ -922,7 +969,7 @@
var classStr = pClassStr.replace(/^\s+|\s+$/,"").replace(/\s+/," ") ;
var arrClassesToRemove = classStr.split(" ") ;
var iClasses = this.getStyleClassNames() ;
- var oClasses = new Array(0) ;
+ var oClasses = [] ;
// Remove the one to remove from the list of base style states:
for( var idOrig=0; idOrig < iClasses.length; ++idOrig){
if( iClasses[idOrig] != classStr ){
Modified: incubator/xap/trunk/codebase/src/xap/bridges/dojo/DojoButtonBridge.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/bridges/dojo/DojoButtonBridge.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/bridges/dojo/DojoButtonBridge.js (original)
+++ incubator/xap/trunk/codebase/src/xap/bridges/dojo/DojoButtonBridge.js Mon Mar 26 14:03:09 2007
@@ -27,7 +27,6 @@
Xap.provide("xap.bridges.dojo.DojoButtonBridge");
Xap.require("xap.bridges.dojo.DojoWidgetBridge");
-Xap.require("dojo.widget.html.Button") ;
Xap.require("dojo.widget.Button");
Modified: incubator/xap/trunk/codebase/src/xap/data/DataFramework.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/DataFramework.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/DataFramework.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/DataFramework.js Mon Mar 26 14:03:09 2007
@@ -20,6 +20,7 @@
Xap.provide("xap.data.DataFramework");
Xap.require("xap.data.controller.Binding") ;
+Xap.require("xap.data.controller.BindingResolver") ;
Xap.require("xap.session.Container") ;
Xap.require("xap.data.controller.BindingType") ;
Xap.require("xap.resolver.ResolutionInfo");
@@ -175,6 +176,7 @@
/* Binding */
var binding = xap.data.controller.Binding.createIteratorBinding(
this._bindingResolver.getContextStack(),
+ this.getDataSourceContainer(),
select,
bindString,
this._session,
@@ -188,7 +190,7 @@
xap.data.DataFramework.prototype.bind = function( stringOrBinding){
if ( typeof stringOrBinding == "string"){
- var binding = this._bindingResolver.createBindingFromParameterString(stringOrBinding);
+ var binding = this._bindingResolver.createBindingFromParameterString(stringOrBinding, this.getDataSourceContainer(), this.getFormatterContainer());
return this.bindBinding(binding);
}
else{
Modified: incubator/xap/trunk/codebase/src/xap/data/DataNamespaceHandler.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/DataNamespaceHandler.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/DataNamespaceHandler.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/DataNamespaceHandler.js Mon Mar 26 14:03:09 2007
@@ -18,6 +18,7 @@
*/
Xap.provide("xap.data.DataNamespaceHandler");
+Xap.require("xap.data.DataFramework");
Xap.require("xap.xml.ParserFactory");
Xap.require("xap.taghandling.PluginDocumentHandler");
Xap.require("xap.data.controller.BindingResolver") ;
Modified: incubator/xap/trunk/codebase/src/xap/data/controller/Binding.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/controller/Binding.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/controller/Binding.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/controller/Binding.js Mon Mar 26 14:03:09 2007
@@ -20,7 +20,6 @@
Xap.provide("xap.data.controller.Binding");
Xap.require("xap.util.TypeUtils");
-Xap.require("xap.data.DataFramework");
Xap.require("xap.data.controller.BindingType");
Xap.require("xap.data.controller.AttributeValueLocation");
Xap.require("xap.util.ArrayHelper");
@@ -54,14 +53,18 @@
return binding;
}
+
+/**
+ *
+ **/
xap.data.controller.Binding.createIteratorBinding =
- function(contextStack, select, name, session, bindingType, defaultValue){
+ function(contextStack, dataSourceContainer, select, name, session, bindingType, defaultValue) {
var binding = new xap.data.controller.Binding();
binding._select = select;
binding._session = session;
binding._bindingType = bindingType;
if (name && name.length > 0) {
- binding._source = xap.data.DataFramework.getDataService(session).getDataSourceContainer().get(name);
+ binding._source = dataSourceContainer.get(name);
if (!binding._source) {
// Find the ancestor iterator context with the
// specified name, since there was not data source with
Modified: incubator/xap/trunk/codebase/src/xap/data/controller/BindingResolver.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/controller/BindingResolver.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/controller/BindingResolver.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/controller/BindingResolver.js Mon Mar 26 14:03:09 2007
@@ -18,11 +18,13 @@
*/
Xap.provide("xap.data.controller.BindingResolver");
+
Xap.require("xap.session.ClientSession");
-Xap.require("xap.data.DataFramework");
Xap.require("xap.data.bridge.XmlDataTokens");
Xap.require("xap.util.EscapeSyntaxParser") ;
Xap.require("xap.data.controller.ContextStack") ;
+Xap.require("xap.data.controller.Binding") ;
+
/**
* The binding resolver contains helper methods which allow creation
* of binding objects from binding declarations. This class also maintains
@@ -91,13 +93,14 @@
* @return {Binding}
* @throws EscapeSyntaxException, DataControllerException
**/
-xap.data.controller.BindingResolver.prototype.createBindingFromParameterString = function (value) {
- /*DataService*/
- var dataService = xap.data.DataFramework.getDataService(this._session);
+xap.data.controller.BindingResolver.prototype.createBindingFromParameterString = function (value, dataSourceContainer, formatterContainer) {
+
/*Formatter*/
var formatter = null;
+
/*BindingType*/
var bindType = xap.data.controller.BindingType.ONE_TIME;
+
/*String*/
var select = null;
@@ -154,7 +157,7 @@
}
if (xap.data.bridge.XmlDataTokens.FORMATTER == parameterName ) {
if (parameterValue != null) {
- formatter = dataService.getFormatterContainer().get(parameterValue);
+ formatter = formatterContainer.get(parameterValue);
}
} else {
if (xap.data.bridge.XmlDataTokens.BINDING_TYPE == parameterName ) {
@@ -202,7 +205,7 @@
curToken += curChar ;
}
/*Binding*/
- var binding = xap.data.controller.Binding.createIteratorBinding(this.getContextStack(), select, dataSource, this._session, bindType, defaultValue);
+ var binding = xap.data.controller.Binding.createIteratorBinding(this.getContextStack(), dataSourceContainer, select, dataSource, this._session, bindType, defaultValue);
if (formatter != null) {
binding.setFormatter(formatter);
}
Modified: incubator/xap/trunk/codebase/src/xap/data/controller/ContextFrame.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/controller/ContextFrame.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/controller/ContextFrame.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/controller/ContextFrame.js Mon Mar 26 14:03:09 2007
@@ -19,7 +19,6 @@
Xap.provide("xap.data.controller.ContextFrame");
-Xap.require("xap.data.datasource.AbstractDataSet");
Xap.require("xap.data.datasource.AbstractDataSource");
/**
* A context frame encapsulates the information necessary to
Modified: incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSource.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSource.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSource.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/datasource/AbstractDataSource.js Mon Mar 26 14:03:09 2007
@@ -25,6 +25,8 @@
Xap.require("xap.util.ResourceDictionary");
Xap.require("xap.util.ArrayHelper");
Xap.require("xap.data.datasource.QueryRecord") ;
+Xap.require("xap.data.datasource.ArrayDataSet") ;
+
/**
* @fileoverview
@@ -62,7 +64,7 @@
this._asynchronousDataSourceListeners = [];
/** @private */
this._dataChangeListeners = [];
-}
+};
@@ -76,7 +78,7 @@
this._postponedQueries = [];
this._asynchronousDataSourceListeners = [];
this._dataChangeListeners = [];
-}
+};
/**
@@ -282,11 +284,8 @@
xap.data.datasource.AbstractDataSource.prototype.refresh = function () {
this.fireDataChanged();
this.executeQueries(this._boundQueries);
- if (this.getSource()){
- this.executeQueries(this._postponedQueries);
- this._postponedQueries = [];
- }
-
+ this.executeQueries(this._postponedQueries);
+ this._postponedQueries = [];
};
@@ -318,7 +317,7 @@
**/
xap.data.datasource.AbstractDataSource.prototype.handleDataSetQuery = function (query, context, listener) {
var theData = this.executeQuery(query, context) ;
- var dataset = xap.data.datasource.AbstractDataSet.getDataSet(query, this, theData);
+ var dataset = new xap.data.datasource.ArrayDataSet(query, this, theData);
listener.dataSetRetrieved(query, dataset, context);
};
@@ -332,9 +331,9 @@
* @param {xap.data.controller.ContextFrame} An optional context object for nested iteration.
* @return The result of the query.
*/
-xap.data.datasource.AbstractDataSource.prototype.executeQuery =function(queryString , context){
-
-}
+xap.data.datasource.AbstractDataSource.prototype.executeQuery =function(queryString , context) {
+ // empty
+};
/**
* Subclasses should override this method to support asynchronous loading of data.
@@ -344,7 +343,9 @@
* @return The content of the XMLHttpRequest object parsed into an object suitable to the source object
* of the data source.
*/
-xap.data.datasource.AbstractDataSource.prototype.responseToDataSource = function(response){}
+xap.data.datasource.AbstractDataSource.prototype.responseToDataSource = function(response ) {
+ // empty
+};
/**
@@ -438,7 +439,8 @@
xap.data.datasource.AbstractDataSource.prototype.addPostponedQuery = function (query, context, listener, isDataSetQuery) {
var queryRecord = new xap.data.datasource.QueryRecord(query, context, listener, isDataSetQuery);
this._postponedQueries.push(queryRecord);
-}
+};
+
/**
* @private
* Runs all the queries in a given array of queries.
@@ -455,7 +457,8 @@
this.getLog().error("Error executing databound query:" + rec.getQuery(), e);
}
}
-}
+};
+
/**
* Returns the logger used to log DataSource issues.
Modified: incubator/xap/trunk/codebase/src/xap/data/datasource/ArrayDataSet.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/datasource/ArrayDataSet.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/datasource/ArrayDataSet.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/datasource/ArrayDataSet.js Mon Mar 26 14:03:09 2007
@@ -18,7 +18,7 @@
*/
Xap.provide("xap.data.datasource.ArrayDataSet");
-Xap.require("xap.data.datasource.AbstractDataSet") ;
+
/**
* @fileoverview
@@ -27,51 +27,82 @@
/**
- * Creates a new ArrayDataSet. DataSets should be created by calling the factory method
- * <code>xap.data.datasource.AbstractDataSet.getDataSet</code> rather than be
- * constructed directly.
- *
- * @class AbstractDataSet is a data set based on array backing data.
+ * Creates a new ArrayDataSet.
+ * @class ArrayDataSet is a data set based on array backing data.
*
* @constructor
* @param {String}query The query string that produced this data set.
* @param {xap.data.datasource.AbstractDataSource}source The data source this DataSet came from.
* @param dataArray An array of backing data for the data set.
*
- * @see xap.data.datasource.AbstractDataSet#getDataSet
+ *
*
*/
-xap.data.datasource.ArrayDataSet = function (query, source, dataArray) {
- xap.data.datasource.AbstractDataSet.call(this, query, source, dataArray);
-};
-
-//needed for doc even though the below handles this
-xap.data.datasource.ArrayDataSet.prototype = new xap.data.datasource.AbstractDataSet();
+xap.data.datasource.ArrayDataSet = function (query, dataSource, data) {
+ /** @private */
+ this._query = query ;
-/**
- * Returns the size of the data set.
- *
- * @return {int} The size of the data set.
- */
-xap.data.datasource.ArrayDataSet.prototype.size = function () {
- return this._data.length;
+ /** @private */
+ this._dataSource = dataSource ;
+
+
+ if (!data) {
+ /** @private */
+ this._data = [];
+ } else if (data instanceof Array) {
+ this._data = data ;
+ } else {
+ this._data = [data];
+ }
};
-/**
- * Returns the data at the specified index.
- *
- * @param {int} index The index of that data to return.
- * @return The data at the given index.
- */
+/**
+ * Returns the query string that produced this data set.
+ * @return {String} The query string that produced this data set.
+ *
+ */
+xap.data.datasource.ArrayDataSet.prototype.getQuery = function () {
+ return this._query;
+};
+
+
+/**
+ * Returns the data source that produced this data set.
+ * @return {xap.data.datasource.AbstractDataSource} The data source that
+ * produced this data set.
+ *
+ */
+xap.data.datasource.ArrayDataSet.prototype.getDataSource = function () {
+ return this._dataSource;
+};
+
+
+/**
+ * Returns the data at the specified index. This base class method returns null;
+ * subclasses should override to return the proper value.
+ *
+ * @param {int} index The index of that data to return.
+ * @return Data object
+ */
xap.data.datasource.ArrayDataSet.prototype.getData = function (index) {
- // Have to be careful here; if you were to use "!index",
- // that would do damage if the index were 0....
- if( (typeof index=="undefined") || index==null){
- return null;
- }
- else {
- return this._data[index] ;
+ return this._data[index];
+};
+
+
+
+/**
+ * Returns the size of the data set. Subclasses should override this to
+ * return the correct size.
+ *
+ * @return {int}.
+ */
+xap.data.datasource.ArrayDataSet.prototype.size = function () {
+
+ if( ! this._data ) {
+ return 0;
}
-};
\ No newline at end of file
+
+ return this._data.length;
+};
Modified: incubator/xap/trunk/codebase/src/xap/data/datasource/ObjectDataSource.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/datasource/ObjectDataSource.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/datasource/ObjectDataSource.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/datasource/ObjectDataSource.js Mon Mar 26 14:03:09 2007
@@ -19,7 +19,6 @@
Xap.provide("xap.data.datasource.ObjectDataSource");
Xap.require("xap.data.datasource.AbstractDataSource");
-Xap.require("xap.data.datasource.AbstractDataSet") ;
Xap.require("xap.xml.ParserFactory") ;
Xap.require("xap.xml.dom.Document");
Xap.require("google.xpath");
Modified: incubator/xap/trunk/codebase/src/xap/data/datasource/SimpleDocumentDataSource.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/codebase/src/xap/data/datasource/SimpleDocumentDataSource.js?view=diff&rev=522625&r1=522624&r2=522625
==============================================================================
--- incubator/xap/trunk/codebase/src/xap/data/datasource/SimpleDocumentDataSource.js (original)
+++ incubator/xap/trunk/codebase/src/xap/data/datasource/SimpleDocumentDataSource.js Mon Mar 26 14:03:09 2007
@@ -19,7 +19,6 @@
Xap.provide("xap.data.datasource.SimpleDocumentDataSource");
Xap.require("xap.data.datasource.AbstractDataSource");
-Xap.require("xap.data.datasource.AbstractDataSet") ;
Xap.require("xap.xml.ParserFactory") ;
Xap.require("xap.xml.dom.Document");
Xap.require("google.xpath");