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 mt...@apache.org on 2006/08/16 20:18:12 UTC
svn commit: r432019 [4/7] - in /incubator/xap/trunk/dist: dojo.js xapcore.js
zimbra.js
Added: incubator/xap/trunk/dist/xapcore.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/dist/xapcore.js?rev=432019&view=auto
==============================================================================
--- incubator/xap/trunk/dist/xapcore.js (added)
+++ incubator/xap/trunk/dist/xapcore.js Wed Aug 16 13:18:11 2006
@@ -0,0 +1,27691 @@
+/*
+ Copyright 2006 The Apache Software Foundation.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless readAndOuputFile by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+
+/*
+ This is a compiled version of XAP, built for deployment.
+*/
+
+dojo.provide("xap.util.Utils") ;
+
+xap.util.Utils = function(){}
+
+xap.util.Utils.importFile = function( path ) {
+ if( xap.util.Utils.s_pathCache == null ) {
+ xap.util.Utils.s_pathCache = new Object();
+ }
+ if ( xap.util.Utils.s_pathCache[path] ){
+ return;
+ }
+ xap.util.Utils.s_pathCache[path] = true;
+ var scriptElement = "<script language=\"JavaScript\" " +
+ "type=\"text/javascript\" src=\"" + path + "\"></script>";
+ document.write( scriptElement );
+}
+
+xap.util.Utils.s_pathCache = null;
+
+/**
+ * Method for debugging---less than a full object-dump, more than toString()
+**/
+xap.util.Utils.interrogate = function(obj,withFun){
+ var s="" ;
+ if (typeof obj != "object"){
+ s = "<not an object>" ;
+ } else {
+ for (var keyy in obj){
+ var valStr = ""+obj[keyy] ;
+ if (valStr.substring(0,8)=="function" && !withFun){
+ continue ;
+ }
+ s += "^"+keyy+':'+valStr ;
+ }
+ }
+ // Puts the result, with CR/LFs turned to carets, into
+ // the copyable part of a prompt box:
+ prompt("",s.replace(/[\r\n]/g,"^")) ;
+}
+
+
+
+
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+Xap = function () {}
+
+//make xap load from the xap directory
+dojo.hostenv.setModulePrefix("xap", "../xap");
+dojo.hostenv.setModulePrefix("google", "../google");
+
+
+Xap.kwCompoundRequire = function(){
+ dojo.kwCompoundRequire.apply(dojo, arguments);
+}
+
+
+Xap.provide = function(){
+ dojo.provide.apply(dojo,arguments);
+}
+
+
+
+// We use these repeatedly, why re-create them each time?
+Xap.trailingSlashRegexp = /^.*\/$/ ;
+Xap.allFullstopsRegexp = /\./g ;
+Xap.anyAsteriskRegexp = /\*/g ;
+
+Xap.ourLoadedClasses = new Object() ;
+
+Xap.require = function(){
+
+// Modules will have to go through Dojo:
+ var toLoad = arguments[0] ;
+ var notModule = (toLoad.search(Xap.anyAsteriskRegexp)==-1) ;
+//
+//
+// Don't overload, don't depend on ArrayHelper being around:
+ var alreadyLoaded = (Xap.ourLoadedClasses[toLoad])?true:false ;
+ if( alreadyLoaded ){
+ Xap._logString += "Redundant load attempt: "+toLoad ;
+ return ;
+ }
+
+ // do we need to reload this file?
+ //---is it in the "debuggables" list?--are we reloading everything?
+ var needToDebugLoad = notModule
+ && (Xap._debugAll
+ || (Xap._debugLoad && Xap._debuggables[toLoad])
+ ) ;
+
+
+ try {
+ dojo.require.apply(dojo,arguments) ;
+ if(needToDebugLoad){
+
+ Xap.addDebuggables([toLoad]) ;
+ Xap.ourLoadedClasses[toLoad] = true ;
+ }
+ } catch (ee) {
+ Xap._logString += '\n'+ee ;
+ }
+
+}
+
+Xap.addDebuggables = function(){
+ if( !Xap._debuggables ){
+ Xap._debuggables = new Object() ;
+ }
+ for (var ii=0; ii<arguments.length; ++ii ){
+ Xap._debuggables[arguments[ii]] = true ;
+ }
+}
+
+
+
+Xap._loadDebuggable = function(str){
+ var path = str.replace(Xap.allFullstopsRegexp,"/") ;
+ if ( !Xap._sourceRootDir.match(Xap.trailingSlashRegexp)){
+ Xap._sourceRootDir +="/" ;
+ }
+ path = Xap._sourceRootDir +"src/"+path +".js" ;
+ //alert(path) ;
+ xap.util.Utils.importFile(path) ;
+}
+
+Xap._loadDebuggables = function(pathHolderObj){
+ if( !pathHolderObj){
+ // Default behavior:
+ Xap._loadDebuggables(Xap._debuggables) ;
+ return ;
+ } else {
+ for (var nom in pathHolderObj){
+ Xap._loadDebuggable( nom ) ;
+ }
+ }
+}
+
+Xap.debugLoad = function(){
+ Xap._addDebuggables(arguments) ;
+ Xap._loadDebuggables() ;
+}
+
+
+
+
+
+/**
+
+/**
+ * @private
+ * Looks for nodes with the criteria we want
+**/
+Xap._findAppElements = function(){
+//Experiment Xap.require("google.xpath");
+ var currentContext = new google.ExprContext(document) ;
+// The following _should_ work, but I think google's XPath
+// is a little broken---an earlier attempt to run //*[id='anId']
+// in xap.xml.xmodify.Xmodify code didn't work, either
+// var parsedXPathExpr = google.xpathParse("//*[@appName]") ;
+ var parsedXPathExpr = google.xpathParse("//") ;
+ var targetNodes = parsedXPathExpr.evaluate( currentContext );
+ var targetNodesArray = targetNodes.nodeSetValue();
+ return targetNodesArray ;
+
+}
+
+
+Xap.scanPage = function(){
+ var allPossibleContainerNodes = Xap._findAppElements() ;
+ for (var i =0; i<allPossibleContainerNodes.length; i++){
+ var element = allPossibleContainerNodes[i] ;
+ if( !element.getAttribute ){
+ continue;
+ }
+ var thisElementsAppName = null ;
+ thisElementsAppName = element.getAttribute("appName");
+ if(!thisElementsAppName){
+ continue;
+ }
+ var src = element.getAttribute("src");
+// alert("Found xap tag with \n appName:" + thisElementsAppName + ", \n and source " + src+ "\n under element of type: "+element.nodeName);
+ var context = element.getAttribute("context");
+ var toolkit = element.getAttribute("toolkit");
+
+ var session = Xap.createSession(context, src, toolkit , element);
+ // these might be handy to keep around:
+ session.appName = thisElementsAppName ;
+ session.src = src ;
+ session.domContainer = element ;
+ if (window[thisElementsAppName]==null){
+ window[thisElementsAppName]= session;
+ }
+ else{
+ //TODO throw some error?
+ }
+ }
+}
+
+
+
+
+
+
+Xap.bootstrap = function( sourceRootDir,loadType ) {
+ // Will need this later to hold dojo configuration information:
+ if (!djConfig){
+ if (!config){
+ djConfig={} ;
+ } else {
+ djConfig = config ;
+ }
+ }
+
+
+ // debugger-friendlier loader?:
+ Xap._debugLoad = (loadType)?true:false ;
+ Xap._debugAll = (loadType && loadType == "debugAll") ;
+ if( !Xap._debuggables ){
+ Xap._debuggables = new Object() ;
+ }
+
+ Xap._logString = "" ;
+ Xap._showLog = function(){
+ prompt("",Xap._logString.replace(/\n/g,"^")) ;
+ }
+
+ Xap._sourceRootDir = sourceRootDir;
+ Xap.loadXap( sourceRootDir );
+ //Xap.loadZimbra( sourceRootDir );
+
+// We've done all the "real" loading, now let's attach code to source files
+// previously targetted for debugger-friendly (specified before we bootstrap):
+//Later: don't load automatically, wait for latest possible moment:
+// if( Xap._debugLoad ){
+// Xap._loadDebuggables() ;
+// }
+
+}
+
+Xap.createSession = function( context, startPage,toolkitType , element) {
+ Xap.require("xap.session.ClientSession");
+ var session = new xap.session.ClientSession( context,toolkitType ,element );
+ session._start( startPage );
+ return session;
+}
+
+
+
+
+Xap.loadXap = function( sourceRootDir ) {
+
+
+}
+
+
+//for some reason dojo.hostent.loadUri() doesn't work on some (one?)
+//of these files, it gives an error on this.func being undefined.
+//That's ok as we are going to ditch these files anyway
+Xap.loadZimbra = function( sourceRootDir ) {
+
+ if ( !sourceRootDir.match(Xap.trailingSlashRegexp)){
+ sourceRootDir +="/" ;
+ }
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/msgs/AjxMsg.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxCore.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxEnv.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxUtil.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxText.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxException.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxCookie.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/soap/AjxSoapException.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/soap/AjxSoapFault.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/soap/AjxSoapDoc.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/net/AjxRpcRequest.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/net/AjxRpc.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxWindowOpener.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxVector.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxStringUtils.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/debug/AjxDebug.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/debug/AjxDebugXmlDocument.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/xml/AjxXmlDoc.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/config/data/AjxConfig.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxEnv.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxImg.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/core/AjxException.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxCallback.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxTimedAction.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/events/AjxEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/events/AjxEventMgr.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/events/AjxListener.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxDateUtils.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxStringUtils.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxVector.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxSelectionManager.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/net/AjxPost.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxBuffer.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/util/AjxCache.js" );
+
+ // DWT classes
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/core/DwtImg.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/core/Dwt.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/core/DwtException.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/core/DwtDraggable.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/graphics/DwtCssStyle.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/graphics/DwtPoint.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/graphics/DwtRectangle.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/graphics/DwtUnits.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtEventManager.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtDateRangeEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtDisposeEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtUiEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtControlEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtKeyEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtMouseEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtMouseEventCapture.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtListViewActionEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtSelectionEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtHtmlEditorStateEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtTreeEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtHoverEvent.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/dnd/DwtDragEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/dnd/DwtDragSource.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/dnd/DwtDropEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/dnd/DwtDropTarget.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtHoverMgr.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtControl.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtComposite.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtShell.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtColorPicker.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtBaseDialog.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtDialog.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtLabel.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtListView.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtButton.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtMenuItem.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtMenu.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtMessageDialog.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtHtmlEditor.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtInputField.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtSash.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtToolBar.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/graphics/DwtBorder.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtToolTip.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtStickyToolTip.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtTreeItem.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtTree.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtCalendar.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtPropertyPage.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtTabView.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtWizardDialog.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtSelect.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtAddRemove.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtAlert.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtText.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtIframe.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtXFormDialog.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtPropertySheet.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtGrouper.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/widgets/DwtProgressBar.js" );
+
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/events/DwtXFormsEvent.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XFormGlobal.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XModel.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XModelItem.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XForm.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XFormItem.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/XFormChoices.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/OSelect_XFormItem.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/js/dwt/xforms/ButtonGrid.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/zimbra/examples/tree/TreeExample.js" );
+
+ //TODO this really shouldn't be here, but they rely on some zimbra stuff
+ //and are zimbra extensions
+ xap.util.Utils.importFile( sourceRootDir + "src/xap/components/zimbra/DwtSplitter.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/xap/components/zimbra/DwtSplitChild.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/xap/components/zimbra/DwtTablePanel.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/xap/components/zimbra/DwtVerticalLayoutPanel.js" );
+ xap.util.Utils.importFile( sourceRootDir + "src/xap/components/zimbra/DwtHorizontalLayoutPanel.js" );
+
+}
+
+Xap.resolveConstructor = function(aString){
+ var scoper = dj_global ;
+ var arr = aString.split(".") ;
+ for( var kk=0; kk< arr.length - 1; ++kk ){
+ scoper = scoper[arr[kk]] ;
+ }
+ return scoper[arr[arr.length-1]] ;
+}
+
+
+/**
+ * Handles common class set-up routines, assumes constructors for subclass and superclass already exist:
+**/
+Xap.setupClassAsSubclassOf = function(subclassName,superclassName,sub,sup){
+ var subclassConstructor = Xap.resolveConstructor( subclassName ) ;
+ var superclassConstructor = Xap.resolveConstructor( superclassName ) ;
+
+
+ subclassConstructor.prototype = new superclassConstructor();
+ subclassConstructor.prototype.superclass = superclassConstructor.prototype ;
+
+ // This can by default the same for all objects; can overwrite this definition in
+ // the source file, if desired...
+ subclassConstructor.prototype.toString = function(){
+ return subclassName ;
+ }
+
+ subclassConstructor.s_log = xap.util.LogFactory.getLog( subclassName ) ;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide("xap.util.LogFactory");
+Xap.provide("xap.util.LogFactory.ConsoleLog");
+ /**
+ * @constructor
+ * TODO either replace or expand this to work with some other logging
+ * framework
+ *
+ * xap.util.LogFactory provides a single static method that may be used to retrieve
+ * a named Log interface. Multiple calls to the <code>getLog()</code> method
+ * with the same argument will return the same instance of the Log.
+ *
+ * @author ikaplansky
+ */
+xap.util.LogFactory = function(){} ;
+
+//-----------------------------------------------------------------------
+// Class Variables.
+//-----------------------------------------------------------------------
+xap.util.LogFactory.s_nameToConsoleLog = new Object();
+xap.util.LogFactory.s_loggingEnabled = true;
+//-----------------------------------------------------------------------
+// Constructors.
+//-----------------------------------------------------------------------
+
+
+//-----------------------------------------------------------------------
+// Public Class Methods.
+//-----------------------------------------------------------------------
+
+
+
+
+
+/**
+ * Returns an instance of Log for use in logging.
+ * Bypasses an IE Object problem by replacing all
+ * @param name The named instance to return.
+ */
+xap.util.LogFactory.getLog = function( name ) {
+ if ( ! xap.util.LogFactory.s_nameToConsoleLog[name] ) {
+ xap.util.LogFactory.s_nameToConsoleLog[name] = new xap.util.LogFactory.ConsoleLog( name );
+ }
+ var log = xap.util.LogFactory.s_nameToConsoleLog[name];
+ return log;
+}
+
+xap.util.LogFactory.disableLogging = function() {
+ xap.util.LogFactory.s_loggingEnabled = false;
+}
+
+xap.util.LogFactory.enableLogging = function() {
+ xap.util.LogFactory.s_loggingEnabled = true;
+}
+
+//-----------------------------------------------------------------------
+// Inner Classes.
+//-----------------------------------------------------------------------
+
+
+
+xap.util.LogFactory.ConsoleLog = function( name ) {
+ this._name = name;
+ this._isDebug = true;
+}
+
+xap.util.LogFactory.ConsoleLog.s_logWindow = null;
+
+xap.util.LogFactory.ConsoleLog.prototype.isDebug = function() {
+ return this._isDebug;
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.setDebug = function( debug ) {
+ this._isDebug = debug;
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.debug = function ( message ) {
+ if ( this.isDebug() ) {
+ this.output( "Debug", message );
+ }
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.info = function( message ) {
+ this.output( "Info", message );
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.warn = function( message ) {
+ this.output( "Warn", message );
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.error = function( message ) {
+ this.outputErr( "Error", message );
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.exception = function ( message, throwable ) {
+ this.outputErr( "Exception", message );
+ if ( throwable ) {
+ this.outputErr( throwable );
+ }
+}
+
+//---------------------------------------------
+// Private Methods.
+xap.util.LogFactory.ConsoleLog.prototype.output = function( id, message ) {
+
+ if( xap.util.LogFactory.s_loggingEnabled ) {
+ var output = this.format(id, message);
+
+
+ if ( !xap.util.LogFactory.ConsoleLog.s_logWindow || xap.util.LogFactory.ConsoleLog.s_logWindow.closed ) {
+
+
+ xap.util.LogFactory.ConsoleLog.s_logWindow = window.open('', "XAPLOG");
+ if (!xap.util.LogFactory.ConsoleLog.s_logWindow || xap.util.LogFactory.ConsoleLog.s_logWindow.closed) return;
+ xap.util.LogFactory.ConsoleLog.s_logWindow.document.open();
+ xap.util.LogFactory.ConsoleLog.s_logWindow.document.writeln("<head><title>Log</title></head><body><div id=\"log\"/></body>" );
+ xap.util.LogFactory.ConsoleLog.s_logWindow.document.close();
+ }
+
+ if (!xap.util.LogFactory.ConsoleLog.s_logWindow || xap.util.LogFactory.ConsoleLog.s_logWindow.closed) return;
+
+
+ //then write to log window
+ var consoleDoc = xap.util.LogFactory.ConsoleLog.s_logWindow.document;
+ var log = consoleDoc.getElementById('log');
+ var p = consoleDoc.createElement('p');
+
+ ('Error Exception'.indexOf(id) != -1) && (p.style.color = '#BB0000');
+
+ p.appendChild(consoleDoc.createTextNode(output));
+
+ log.appendChild(p);
+
+ var opener = xap.util.LogFactory.ConsoleLog.s_logWindow.opener;
+ if (opener && opener.focus) {opener.focus();}
+
+
+ }
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.outputErr = function( id, message ) {
+ this.output( id, message );
+}
+
+xap.util.LogFactory.ConsoleLog.prototype.format = function( id, message ) {
+ var buff = "[" + id + " - " + new Date() + " (" + this._name +
+ "): " + message + "]";
+ return buff;
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ /**
+ * @fileoverview Helper class for testing is items are letters,
+ * whitespace, alphanumeric, etc.
+ *
+ * @author ikaplansky
+ */
+
+Xap.provide("xap.util.Character");
+
+
+/**
+ * There is no need to ever construct a Character object
+ * at this time, just use the static methods.
+ *
+ * @class Helper class for testing is items are letters,
+ * whitespace, alphanumeric, etc.
+ *
+ * @constructor
+ */
+
+xap.util.Character = function(){}
+
+/** @private */
+xap.util.Character._reLetter = /^[a-zA-Z]$/;
+
+
+/** @private */
+xap.util.Character._reDigit = /^\d/;
+
+/** @private */
+xap.util.Character._reLetterOrDigit = /^([a-zA-Z]|\d)$/;
+
+/** @private */
+xap.util.Character._reWhitespace = /^(\s)*$/;
+
+
+//None of these are used right now,
+//comment them back in as needed
+//Character.reAlphabetic = /^[a-zA-Z]+$/;
+//Character.reAlphanumeric = /^[a-zA-Z0-9]+$/;
+//Character.reInteger = /^\d+$/;
+//Character.reSignedInteger = /^(\+|-)?\d+$/;
+//Character.reFloat = /^((\d+(\.\d*)?)|((\d*\.)?\d+))$/;
+//Character.reSignedFloat = /^(((\+|-)?\d+(\.\d*)?)|((\+|-)?(\d*\.)?\d+))$/;
+
+
+xap.util.Character.isLetter = function ( c ) {
+ return xap.util.Character._reLetter.test( c );
+}
+
+xap.util.Character.isDigit = function ( c ) {
+ return xap.util.Character._reDigit.test( c );
+}
+
+xap.util.Character.isLetterOrDigit = function( c ) {
+ return xap.util.Character._reLetterOrDigit.test( c );
+}
+
+xap.util.Character.isWhiteSpace = function ( str ) {
+ return xap.util.Character._reWhitespace.test( str );
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+ /**
+ * This class contains useful helper methods for working with XML.
+ *
+ * @author ikaplansky
+ */
+//ExperimentXap.require("xap.util.Character");
+
+
+xap.util.XmlUtils = function(){}
+
+// We need to special-case validating tag names to include this
+xap.util.XmlUtils.INDENTATION = " ";
+
+/**
+ * Provides an indentation String for the given level of indentation.
+ *
+ * @param indentationLevel The level of indentation.
+ */
+xap.util.XmlUtils.getIndentation = function( indentationLevel ) {
+ var indentation = "";
+ for ( var i = 0; i < indentationLevel; i++ ) {
+ indentation += xap.util.XmlUtils.INDENTATION;
+ }
+ return indentation;
+}
+
+/**
+ * This method will XML-encode a string.
+ *
+ * @param s - the string to be encoded
+ * @return - the encoded string
+ * @see #xmlDecode(String)
+ */
+xap.util.XmlUtils.encode = function( s ) {
+ if ( s == null ) {
+ return "";
+ }
+
+ var buffer = new Array( s.length );
+ var c;
+ for ( var i = 0; i < s.length; i++ ) {
+ c = s.charAt( i );
+
+ if (c == '&') {
+ buffer[i] = "&";
+ } else if (c == '<') {
+ buffer[i] = "<";
+ } else if (c == '>') {
+ buffer[i] = ">";
+ } else if (c == '\'') {
+ buffer[i] = "'";
+ } else if (c == '\"') {
+ buffer[i] = """;
+ } else {
+ buffer[i] = c;
+ }
+ }
+ return buffer.join("");
+}
+
+/**
+ * This method will perform a simple XML-encoding of double quotes only.
+ * This can be useful for readability of attribute values where a strict
+ * parser is not in use.
+ *
+ * @param s - the string to be encoded
+ * @return - the encoded string
+ * @see #xmlDecode(String)
+ */
+xap.util.XmlUtils.encodeDoubleQuotes = function( s ) {
+ if ( s == null ) {
+ return "";
+ }
+ var buffer = new Array( s.length );
+ var c;
+ for (var i = 0; i < s.length; i++) {
+ c = s.charAt( i );
+ if ( c == '\"' ) {
+ buffer[i] = """;
+ } else {
+ buffer[i] = c;
+ }
+ }
+ return buffer.join("");
+}
+
+/**
+ * This method will XML-decode a string.
+ *
+ * @param s - the string to be decoded
+ * @return - the decoded string
+ * @see #xmlEncode(String)
+ */
+xap.util.XmlUtils.decode = function( str ) {
+ if ( str == null ) {
+ return "";
+ }
+
+ var buffer = new Array( str.length );
+ var s = str.toLowerCase();
+ var c;
+
+ for ( var i = 0; i < s.length; i++) {
+ c = s.charAt(i);
+
+ if (c == '&') {
+ if ( s.indexOf( "&", i ) != -1 ) {
+ buffer[i] = "&";
+ i += 4;
+ } else if ( s.indexOf( "<", i ) != -1 ) {
+ buffer[i] = "<";
+ i += 3;
+ } else if ( s.indexOf( ">", i ) != -1 ) {
+ buffer[i] = ">";
+ i += 3;
+ } else if ( s.indexOf( "'", i ) != -1) {
+ buffer[i] = "\'";
+ i += 5;
+ } else if ( s.indexOf( """, i ) != -1) {
+ buffer[i] = "\"";
+ i += 5;
+ } else {
+ buffer[i] = c;
+ }
+ } else {
+ buffer[i] = c;
+ }
+ }
+ return buffer.join("");
+}
+
+/**
+ * Checks to make sure a given string is a valud XML-1.0 tag name.
+ *
+ * @param tagName - the string to check
+ * @return - true if valid, false otherwise
+ */
+xap.util.XmlUtils.isValidXmlTagName = function( tagName ) {
+ if( tagName == null ) {
+ return false;
+ }
+ if( tagName.length == 0 ) {
+ return false;
+ }
+ var firstChar = tagName.charAt( 0 );
+ if( xap.util.Character.isLetter( firstChar ) == false && firstChar != '_'){
+ //tags can begin with only letters or underscore
+ return false;
+ }
+ if( tagName.length >= 3 ) {
+ var test = tagName.substring( 0, 3 );
+ if( test.toLowerCase() == "xml" ) {
+ // Tags cannot start with any variation of "xml"
+ return false;
+ }
+ }
+ for( var i = 1; i < tagName.length; i++ ) {
+ var c = tagName.charAt( i );
+ if( xap.util.Character.isLetterOrDigit(c) == false &&
+ c != '.' &&
+ c != '_' &&
+ c != '-') {
+ return false;
+ }
+ }
+ return true;
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+ Xap.provide( "xap.util.HttpUtils" ) ;
+
+
+
+ /**
+ * TODO either expand or replace this with another good set of utilities to deal
+ * with HTTP/network functionality. We need to be able to do things like post,
+ * set headers, etc, and we need to return the request itself rather than
+ * the content so we can check status code etc etc
+ *
+ * Creates an HTTP request that can then be sent to the server.
+ * @param url The url to the server page. This follows the rules
+ * of createFullyQualifiedUrl. If the url doesn't have a leading slash, the
+ * current application context will be used.
+ * @return, a new HttpRequest object with uri set to the provided url information. The
+ * request's "Content-Type" is set to "application/octet-stream" by default.
+ *
+ * @author ikaplansky
+ */
+
+xap.util.HttpUtils = function(){}
+
+xap.util.HttpUtils.s_log = xap.util.LogFactory.getLog( "xap.util.HttpUtils" );
+
+
+
+xap.util.HttpUtils.createHttpRequest = function() {
+ var request;
+ try {
+ if ( window.XMLHttpRequest ) {
+ request = new XMLHttpRequest();
+ } else {
+ request = new ActiveXObject("Microsoft.XMLHTTP");
+ }
+ } catch( e ) {
+ xap.util.HttpUtils.s_log( "XMLHttpRequest is not supported in this browser"
+ + e );
+ }
+ return request;
+}
+
+
+xap.util.HttpUtils.get = function( url, callback){
+ var request = xap.util.HttpUtils.createHttpRequest();
+ request.open( "GET", url, callback!=null );
+ if( callback ) {
+ request.onreadystatechange = function() {
+ if( request.readyState == 4 ) {
+ //TODO need object here? other states?
+ callback.apply( request );
+ }
+ }
+ }
+
+ request.send( null );
+ return request;
+}
+
+xap.util.HttpUtils.post = function( url, callback, content){
+ var request = xap.util.HttpUtils.createHttpRequest();
+ request.open( "POST", url, callback!=null );
+ if( callback ) {
+ request.onreadystatechange = function() {
+ if( request.readyState == 4 ) {
+ //TODO need object here? other states?
+ callback.apply( request );
+ }
+ }
+ }
+
+ request.send( content );
+ return request;
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.util.UidProvider');
+
+ /**
+ * @fileoverview xap.util.UidProvider generates a sequences of unique ids.
+ *
+ * @author ikaplansky
+ */
+
+
+/**
+ * Creates a xap.util.UidProvider with the given seed.
+ *
+ * @class xap.util.UidProvider generates a sequences of unique ids. You can use it
+ * by instantiating an instance of a xap.util.UidProvider or through the static
+ * createId method.
+ *
+ * @param {String} seed A unique-ish string.
+ */
+xap.util.UidProvider = function( seed ) {
+ this._count = 0;
+ if ( seed == null ) {
+ this._seed = xap.util.UidProvider._createSeed();
+ } else {
+ this._seed = seed;
+ }
+
+ if ( this._seed[ this._seed.length -1 ] != '-' ) {
+ this._seed = this._seed + "-";
+ }
+}
+
+
+/** @private */
+xap.util.UidProvider.XAP_ID_PREFIX = "xap:";
+
+/** @private */
+xap.util.UidProvider.s_count = 0;
+
+/** @private */
+xap.util.UidProvider._createSeed = function () {
+ return new Date().getTime();
+}
+
+/** @private */
+xap.util.UidProvider.s_seed = xap.util.UidProvider._createSeed();
+
+//-----------------------------------------------------------------------
+// Public Class Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * Returns a unique id.
+ *
+ * @type String
+ */
+xap.util.UidProvider.createId = function() {
+ return new String( xap.util.UidProvider.XAP_ID_PREFIX +
+ xap.util.UidProvider.s_seed + xap.util.UidProvider.s_count++ );
+}
+
+
+//-----------------------------------------------------------------------
+// Public Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * Returns a unique id that directly follows the last created ID.
+ * Different runs of nextId() starting with the same seed should always
+ * return the same IDs.
+ *
+ * @type String
+ */
+xap.util.UidProvider.prototype.nextId = function () {
+ return xap.util.UidProvider.XAP_ID_PREFIX + this._seed + this._count++;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.util.Hashtable');
+
+
+//TODO like many classes exception handling here needs to be
+//more thought out.
+
+/**
+ * @fileoverview A standard hashtable implementation.
+ *
+ * @author ikaplansky
+ * @author jmargaris
+ *
+ */
+
+/**
+ * Creates a new xap.util.Hashtable.
+ *
+ * @class A standard hashtable implementation. Unlike
+ * many hashtable implementations this will work for object to object
+ * mappings, not just strings to objects. Unique keys should
+ * always map properly, regardless of their toString() implementations.
+ */
+xap.util.Hashtable =function(){
+ this._hashtable = new Object();
+ this._size = 0;
+}
+
+
+/**
+ * @private
+ * A key we keep incrementing to help us assign
+ * new unique has keys to objects.
+ */
+xap.util.Hashtable.s_uniqueKey = 0;
+
+/**
+ * Clears the hashtable of all key/value pairs.
+ */
+xap.util.Hashtable.prototype.clear = function() {
+ this._hashtable = new Object();
+}
+
+/**
+ * Returns true if the given object is a key in the hashtable.
+ * @type boolean
+ */
+xap.util.Hashtable.prototype.containsKey = function( key ) {
+ if (key===null){
+ throw new xap.util.Exception( "key cannot be null in xap.util.Hashtable.containsKey()" );
+ }
+ key = this._computeKey(key);
+ return this._hashtable[key]!=null;
+}
+
+/**
+ * Returns true if the given object is a value in the hashtable.
+ * @type boolean
+ */
+xap.util.Hashtable.prototype.containsValue = function( value ) {
+ if (value==null){
+ throw new xap.util.Exception( "value cannot be null at xap.util.Hashtable.containsValue()" );
+ }
+ for ( var i in this._hashtable ) {
+ if ( this._hashtable[i] == value ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Returns the object mapped to the given key, or null
+ * if no mapping exists for that key.
+ */
+xap.util.Hashtable.prototype.get = function ( key ) {
+ if (key==null){
+ throw new xap.util.Exception( "key cannot be null at xap.util.Hashtable.get()" );
+ }
+ key = this._computeKey(key);
+ return this._hashtable[key];
+}
+
+/**
+ * Maps the given key to the given value, replacing and returning any old value.
+ * @return The old value that was mapped to the given key.
+ */
+xap.util.Hashtable.prototype.put = function( key, value ) {
+ if ( key == null ) {
+ throw new xap.util.Exception( "key cannot be null at xap.util.Hashtable.put()" );
+ }
+ if( value == null ) {
+ throw new xap.util.Exception( "value cannot be null at xap.util.Hashtable.put()" );
+ }
+ key = this._computeKey(key);
+ if( this._hashtable[key] == null ) {
+ this._size++;
+ }
+
+ var o = this._hashtable[key];
+ this._hashtable[key] = value;
+ return o;
+}
+
+/**
+ * Removes the mapping for this key.
+ * @return The object that was mapped to this key.
+ */
+xap.util.Hashtable.prototype.remove = function( key ) {
+ if (key==null){
+ throw new xap.util.Exception( "key cannot be null at xap.util.Hashtable.remove()" );
+ }
+ key = this._computeKey(key);
+ var rtn = this._hashtable[key];
+ delete( this._hashtable[key] );
+ if( rtn != null ) {
+ this._size--;
+ }
+ return rtn;
+}
+
+/**
+ * Returns the number of key/value mappings in the hashtable.
+ * @type integer
+ */
+xap.util.Hashtable.prototype.size = function() {
+ return this._size;
+}
+
+
+xap.util.Hashtable.prototype.toString = function() {
+ var result = "{";
+ for ( var i in this._hashtable) {
+ if ( this._hashtable[i] != null ) {
+ result += i + "=>" + this._hashtable[i] + "\n";
+ }
+ }
+ result += "}";
+ return result;
+}
+
+
+//TODO this is a bit messed up right now as it returns
+//the keys AFTER they have been transformed by
+//_computeKey so they may not match the keys the things
+//were added with originally. We should keep a map of
+//keys to original objects?
+/**
+ * Returns an array of all the keys in the hashtable.
+ * @type Array
+ */
+xap.util.Hashtable.prototype.keys = function() {
+ var keys = new Array(this.size());
+ var index = 0;
+ for ( var i in this._hashtable ) {
+
+ //TODO do we really need this check?
+ if ( this._hashtable[i] != null ) {
+ keys[index]=i;
+ index++;
+ }
+ }
+ return keys;
+}
+
+/**
+ * Returns an array of all the values in the hashtable.
+ * @type Array
+ */
+xap.util.Hashtable.prototype.values = function() {
+ var values = new Array(this.size());
+ var index = 0;
+ for ( var i in this._hashtable ) {
+ if ( this._hashtable[i] != null ) {
+ values[index] = this._hashtable[i];
+ index++;
+ }
+ }
+ return values;
+}
+
+/**
+ * @private
+ * Compute a hashtable key. If the thing is a number or string
+ * or has a _hashKey use that, otherwise assign a unique one.
+ * We need to do this because js objects don't have
+ * any innate sort of hashKey() function and we can't rely
+ * on toString() because that's just silly.
+ * (Most hs hashtables do rely on toString - and don't work)
+ * TODO look over this more
+ */
+xap.util.Hashtable.prototype._computeKey = function( x ){
+
+ if (typeof(x) != 'object'){
+ return x.toString();
+ }
+
+ if (x.constructor==Number || x.constructor==String){
+ return x.toString();
+ }
+
+ if (x._xapHashKey==null){
+ x._xapHashKey = xap.util.Hashtable.s_uniqueKey++;
+ }
+ return x._xapHashKey.toString();
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+Xap.provide("xap.util.Exception");
+
+/**
+ * @fileoverview Base class for non-internationalized exceptions
+ *
+ * @author ikaplansky
+ * @author jmargaris
+ */
+
+
+/**
+ * Creates a new exception with the given message and cause.
+ *
+ * @class Base class for non-internationalized exceptions
+ *
+ * @param message The message
+ * @param cause The cause of the message, typically another exception
+ */
+xap.util.Exception = function( message, cause, location ) {
+ this._message = message;
+ this._cause = cause;
+ this._location = location;
+}
+
+xap.util.Exception .prototype.getLocation = function() {
+ return this._location;
+}
+
+xap.util.Exception .prototype.getMessage = function() {
+ return this._message;
+}
+
+xap.util.Exception .prototype.getCause = function() {
+ return this._cause;
+}
+
+xap.util.Exception .prototype.toString = function() {
+ var buf = "Message:" + this._message;
+ if( this._cause != null ){
+ buf += "\nCause:" + this._cause.toString();
+ }
+ return buf;
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+Xap.provide("xap.util.EscapeSyntaxParser");
+//ExperimentXap.require("xap.util.Exception");
+
+
+//TODO docs here need help, mostly ported over unchanged.
+
+/**
+ * @fileoverview A parser for escaping/unescaping strings based on
+ * escape sequences.
+ *
+ * @author jmargaris
+ */
+
+/**
+ * Creates a new EscapeSyntaxParser.
+ *
+ * @class This class is used for escaping/unescaping strings that have single-character
+ * escape sequences in them. An escape syntax parser maps escape sequences
+ * of the form 'Xa' to 'b' where 'X' is the escape lead (typically a \),
+ * 'a' is the character being escaped and 'b' is the resulting character.
+ * <br><br>
+ * For example take the following EscapeSyntaxParser: <br><br>
+ * <code>
+ * new xap.util.EscapeSyntaxParser('\\', ['\\', '{', '}'], ['\\', '{', '}'], false);
+ * </code>
+ * <br><br>
+ * In this case '\' is the escape sequence starter. '\\' is mapped to '\',
+ * '\{' is mapped to '{', and '\}' is mapped to '}'<br><br>
+ * Now consider the following alernate parser:<br>
+ * <code>
+ * new xap.util.EscapeSyntaxParser('x', ['\\', '{', '}'], ['a', 'b', 'c'], false);
+ * </code><br><br>
+ * In this case 'x' is the escape sequence starter. 'x\' is mapped to 'a',
+ * 'x{' is mapped to 'b', and 'x}' is mapped to 'c'
+ *
+ *
+ *
+ * @param {Character} escapeLead The character that signifies an escape sequence, typically \
+ * @param {Array} escapeChars An array of characters to escape
+ * @param {Array} resolvedChars A parallel array of characters to resolve to
+ * @param {Boolean} strict If true report all unrecognized escape sequences as errors
+ */
+xap.util.EscapeSyntaxParser = function( escapeLead, escapeChars, resolvedChars, strict ){
+ this._escapeLead = escapeLead;
+ this._escapeSequenceCharacters = escapeChars;
+ this._resolvedCharacters = resolvedChars;
+ this._reportUnknownEscapeSequencesAsErrors = strict;
+
+}
+
+xap.util.EscapeSyntaxParser.UNRESOLVED_CHARACTER = new Object();
+
+
+/**
+ * Returns the resolved character at the given index in the given string.
+ * If the escapeSequenceIndex does not point to the start of an escape
+ * sequence UNRESOLVED_CHARACTER is returned, NOT the original character. This method
+ * exists for complex parsing operations such as parsing a comma separated
+ * list of parameters which may each have different escape sequences.
+ *
+ * @param s
+ * @param escapeSequenceIndex
+ * @return TODO
+ * @throws RuntimeException
+ */
+xap.util.EscapeSyntaxParser.prototype.getResolvedCharacter = function( s, index){
+ var c = s.charAt(index);
+
+ //if we don't start with the escape sequence starter we are done
+ if (c!=this._escapeLead){
+ return xap.util.EscapeSyntaxParser.UNRESOLVED_CHARACTER;
+ }
+ //if \ was the last character that's not valid
+ if (index+1>=s.length && this._reportUnknownEscapeSequencesAsErrors){
+ throw new xap.util.Exception("Invalid escape sequence: " + this._escapeLead +
+ " at index " + index + " in string: " + s);
+ }
+
+ //get the next character after the \ and check it against our list
+ //if we find it, return the corresponding resolved character
+ var keyCharacter = s.charAt(index+1);
+ for (var i = 0 ; i<this._escapeSequenceCharacters.length; i++){
+ if (keyCharacter==this._escapeSequenceCharacters[i]){
+ return this._resolvedCharacters[i];
+ }
+ }
+
+ if (this._reportUnknownEscapeSequencesAsErrors){
+ throw new xap.util.Exception("Invalid escape sequence: " + this._escapeLead + keyCharacter +
+ " at index " + index + " in string: " + s);
+ }
+
+ //if we got here it means we had \x where that is not a valid
+ //escape sequence AND we are not reporting that as error so
+ //just say we didn't need to do any resolution which should make
+ //the caller just accept the \ as a normal character
+ return xap.util.EscapeSyntaxParser.UNRESOLVED_CHARACTER;
+}
+
+ /**
+ * Given an unescaped string, convert it into an escaped one that
+ * fits this escape syntax. For example given the string
+ * "hello\there" turn it into "hello\\there".
+ * @param s The string to escape.
+ * @return A properly escaped string
+ */
+xap.util.EscapeSyntaxParser.prototype.escape = function( s ){
+ var b = new String();
+ for (var i =0; i<s.length; i++){
+ var c = s.charAt(i);
+ var neededReplace = false;
+ for (var j=0; j<this._resolvedCharacters.length; j++ ){
+ //replace character with an escape sequence
+ if (c==this._resolvedCharacters[j]){
+ b += this._escapeLead;
+ b += this._escapeSequenceCharacters[j];
+ neededReplace = true;
+ break;
+ }
+ }
+
+ //if we didn't replace the character
+ //with an escape sequence just append it directly.
+ if (!neededReplace){
+ b += c;
+ }
+ }
+ return b;
+}
+
+/**
+ * Parses the string and returns a new string with escape sequences
+ * replaced with resolved values if any resolution was needed. If not
+ * the original string is returned.
+ */
+xap.util.EscapeSyntaxParser.prototype.parse = function( s ){
+ var buffer = null;
+ for (var i =0; i<s.length; i++){
+ var c = this.getResolvedCharacter(s,i);
+
+ //if c==UNRESOLVED_CHARACTER it means no resolution was needed, so just
+ //apend on the original character
+ if (c==xap.util.EscapeSyntaxParser.UNRESOLVED_CHARACTER){
+
+ //if we are building up a resolved string append to it
+ if (buffer!=null){
+ buffer += s.charAt(i);
+ }
+ }
+
+ //if we got some value back, that is what we should use and we
+ //also need to SKIP over the next character!
+ else{
+ //if we don't have a buffer yet we need to make one now
+ //that has all the content we've skipped over so far
+ if (buffer==null){
+ buffer = s.substring(0,i);
+ }
+ buffer+=c;
+ i++;
+ }
+ }
+ return buffer==null?s:buffer;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+Xap.provide("xap.util.MessageFormat");
+Xap.require("xap.util.EscapeSyntaxParser")
+
+/**
+ * @fileoverview Provides an approximation of Java message format.
+ * @author jmargaris
+ *
+ */
+
+/**
+ * @class Provides an approximation of Java message format.
+ */
+xap.util.MessageFormat = function() {}
+
+
+/**
+ * A simple approximation of Java message format,
+ * takes a string like "aaa{0} bbb{1} ccc{2}" and plugs
+ * in arguments in that order. Currently there is no escape syntax at all. TODO
+ *
+ * @param {String} formatString The string message format.
+ * @param {Array} args An array of arguments to plug into the message format.
+ */
+xap.util.MessageFormat.format = function( formatString, args ){
+ if (!formatString){
+ return null;
+ }
+
+ //TODO escaping syntax?? And if we replace something
+ //and it has a {1} we are in trouble...
+ for (var i =0; args && i<args.length; i++){
+ var replacementString = "\\{" + i + "\\}";
+ var regEx = new RegExp(replacementString, "gm");
+
+ formatString = formatString.replace(regEx, ""+args[i]);
+ }
+ return formatString;
+}
+
+//TODO if nothing else put this in a general
+//xap.string.... method
+//along with trim() and others.
+
+
+//DOJO code that is similar
+//no escape syntax here either?
+//this lets you do something like:
+//asd {hello} asd {goodbye}
+//then pass in an object[hello]=x and object[goodby]=y and do the sub that way
+
+// dojo.string.substituteParams = function(template /*string */, hash /* object - optional or ... */) {
+// var map = (typeof hash == 'object') ? hash : dojo.lang.toArray(arguments, 1);
+//
+// return template.replace(/\%\{(\w+)\}/g, function(match, key){
+// return map[key] || dojo.raise("Substitution not found: " + key);
+// });
+//};
+//
+//
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+Xap.provide( "xap.util.ResourceDictionary" ) ;
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.util.Hashtable");
+//Experiment
+Xap.require("xap.util.MessageFormat");
+
+
+
+
+ /**
+ * xap.util.ResourceDictionary's purpose is to look up messages (i.e. debug, info) by
+ * ids. The messages should be defined in property files that are specific to
+ * given locales.
+ *
+ * @author ikaplansky
+ */
+
+
+
+xap.util.ResourceDictionary = function() {}
+
+//-------------------------------------------------------------------
+// Class Variables.
+//-------------------------------------------------------------------
+xap.util.ResourceDictionary.s_classnameToResourceObject = new xap.util.Hashtable();
+xap.util.ResourceDictionary.s_log = xap.util.LogFactory.getLog( "xap.util.ResourceDictionary" );
+
+//-------------------------------------------------------------------
+// Public Class Methods.
+//-------------------------------------------------------------------
+xap.util.ResourceDictionary.getMessage = function( msgId, className, args ) {
+ var resourceObject = xap.util.ResourceDictionary.s_classnameToResourceObject.get
+ ( className );
+ if( resourceObject == null ) {
+ try {
+//Experiment Xap.require(className);
+ var resourceObject = eval ( "new " + className + "Res();" );
+ xap.util.ResourceDictionary.s_classnameToResourceObject.put( className, resourceObject );
+ } catch ( e ){
+ xap.util.ResourceDictionary.s_log.exception( "Exception getting message:" +
+ "id=" + msgId + ",classname=" + className +
+ ", args:" + args + ", exception:" + e );
+ }
+ }
+ if( resourceObject != null ) {
+ var messagePattern = resourceObject.messages[msgId];
+ return xap.util.MessageFormat.format( messagePattern, args);
+ }
+ return "MsgId:" + msgId + ",class:" + className + ",args:" + args;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.util.XapException');
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.util.ResourceDictionary");
+
+
+
+ /**
+ * @fileoverview Base class for internationalized exceptions
+ *
+ * @author ikaplansky
+ */
+
+
+/**
+ * Creates a new exception with the given message id, args and cause.
+ *
+ * @class Base class for internationalized exceptions. These exceptions
+ * are created with a message ID rather than a text message. That ID
+ * is looked up in another resource set and the args are plugged into
+ * the message format. Currently the resource set is defined
+ * as getClassName() + "Res" but that should probably change,
+ * this scheme needs to be thought out a lot more. The ideal is that
+ * it's easy to swap in different sets of messages with a minimal
+ * amount of effort.
+ *
+ * @param msgId The ID of the message format to use
+ * @param args An array of arguments that plug into the message format.
+ * @param cause The cause of the message, typically another exception
+ * @param location Information on where the exception occured, for example
+ * classname-methodname
+ */
+
+xap.util.XapException = function( msgId, args, cause, location ) {
+ // any time when this exception is subclassed, the xap.util.XapException constructor
+ // gets called without any args to define the prototype of the subclass.
+ // we want to ignore those calls.
+ if( msgId ) {
+ this._msgId = msgId;
+ this._localizedMessage = xap.util.ResourceDictionary.getMessage( msgId,
+ this.getClassName(), args );
+ this._cause = cause;
+ this._location = location;
+ }
+}
+
+xap.util.XapException.CLASSNAME = "xap.util.XapException";
+
+//-----------------------------------------------------------------------
+// Public Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * Returns the Throwable object that was specified in the constructor
+ * of this exception as the cause. This may be null.
+ *
+ * @return The cause exception.
+ */
+xap.util.XapException.prototype.getCause = function() {
+ return this._cause;
+}
+
+xap.util.XapException.prototype.getLocation = function() {
+ return this._location;
+}
+
+/**
+ * Returns the id of the message that was used for localization.
+ * This is the value passed in the constructor.
+ *
+ * @return The message id.
+ */
+xap.util.XapException.prototype.getMessageId = function() {
+ return this._msgId;
+}
+
+xap.util.XapException.prototype.getMessage = function() {
+ return this._localizedMessage;
+}
+
+xap.util.XapException.prototype.toString = function() {
+ return this._localizedMessage;
+}
+
+xap.util.XapException.prototype.getClassName = function() {
+ return xap.util.XapException.CLASSNAME;
+}
+
+/**
+ * Converts an exception to a string. This should work for
+ * xap.util.XapException, xap.util.Exception and built-in JS exceptions
+ */
+xap.util.XapException.exceptionToString = function(exception){
+ var s = new String();
+
+ if (!exception){
+ return s;
+ }
+
+ if (exception.name && exception.message){ //should exist for browser exceptions
+ s+= "Exception: " + exception.name + " - " + exception.message + "\n";
+ }
+
+ else if (exception.getMessage){//should exist for xap exceptions
+ s+="Exception:" + exception.getMessage() + "\n";
+ }
+
+ if (exception.getLocation && exception.getLocation()){
+ s+="Occured at:" + exception.getLocation() + "\n";
+ }
+
+ if (exception.getCause && exception.getCause()){
+ s+="Caused by:\n" + xap.util.XapException.exceptionToString(exception.getCause());
+ }
+
+ //next-to-last resort just use toString
+ if (s.length==0 && exception.toString){
+ s = exception.toString();
+ }
+ // last resort: let JS sort it out:
+ if (s.length==0){
+ s = "" +exception ;
+ }
+
+ return s;
+
+
+}
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.util.XapExceptionRes');
+
+
+ /**
+ * @fileoverview Base class for internationalized exceptions
+ *
+ * @author ikaplansky
+ */
+
+
+/**
+ * Resource for XapException.
+ *
+ * @class Resource for XapException---will need to keep this around as long
+ * as XapException is around, otherwise we get errors when it's expected.
+ */
+
+xap.util.XapExceptionRes = function( ) {}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+Xap.provide( "xap.util.Profiler" ) ;
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.util.Hashtable");
+
+
+xap.util.Profiler = function (){}
+
+xap.util.Profiler._hashtable = new xap.util.Hashtable();
+
+xap.util.Profiler.s_log = xap.util.LogFactory.getLog("xap.util.Profiler");
+
+xap.util.Profiler.start = function( message ){
+ var x = xap.util.Profiler._hashtable.get(message);
+ if (!x){
+ x = new Array();
+ }
+
+ x.push(new Date());
+
+ xap.util.Profiler._hashtable.put(message, x);
+}
+
+xap.util.Profiler.end = function( message ){
+ var now = new Date();
+ var x = xap.util.Profiler._hashtable.get(message);
+
+
+ if (!x || x.length==0) return;
+ var startTime = x.pop();
+
+ var message = message + "[" + x.length + "] took " + (now.getTime()-startTime.getTime()) + "ms";
+ xap.util.Profiler.s_log.debug(message);
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.xml.dom.events.DomChangeEvent');
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.StructureChangeEvent");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.XapElement");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.Document");
+
+
+ /* @fileoverview xap.xml.dom.events.DomChangeEvent is the base class for {@link xap.xml.dom.events.AttributeChangeEvent}
+ * and {@link xap.xml.dom.events.StructureChangeEvent}.
+ *
+ * @author ikaplansky
+ */
+
+/*
+ * xap.xml.dom.events.DomChangeEvent should not be instantiated directly.
+ *
+ * @class xap.xml.dom.events.DomChangeEvent is the base class for {@link xap.xml.dom.events.AttributeChangeEvent}
+ * and {@link xap.xml.dom.events.StructureChangeEvent}.
+ *
+ * @param source The source xap.xml.dom.XapElement on which the event occurred.
+ *
+ * @author ikaplansky
+ */
+xap.xml.dom.events.DomChangeEvent = function( source ) {
+ this._sourceElement = source;
+}
+
+
+
+//-----------------------------------------------------------------------
+// Public Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * Get the Element on which the event is being triggered. For
+ * attribute changes, this will be the element on which the attribute
+ * was changed, for element additions and removals this is the parent
+ * on which the change was triggered.
+ *
+ * <br><br>
+ *
+ * This method will return null if there is no source element. This
+ * can happen when the event is generated as the result of setting
+ * a xap.xml.dom.Document root node.
+ *
+ * @return The Element that triggered the event or null if there is
+ * no element parent.
+ */
+xap.xml.dom.events.DomChangeEvent.prototype.getSourceElement = function () {
+ return this._sourceElement;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.xml.dom.events.AttributeChangeEvent');
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.DomChangeEvent");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.AttributeChangeListener");
+
+
+/**
+ * @fileoverview Event object that encapsulates attribute changes.
+ *
+ * @author ikaplansky
+ * @author jmargaris
+ */
+
+
+/**
+ * Creates an xap.xml.dom.events.AttributeChangeEvent instance.
+ *
+ * @class xap.xml.dom.events.AttributeChangeEvent objects are passed to methods on {@link
+ * xap.xml.dom.events.AttributeChangeListener}. They contain information about attribute
+ * changes.
+ *
+ * @see xap.xml.dom.events.AttributeChangeListener
+ *
+ * @param source The source xap.xml.dom.XapElement
+ * @param name The attribute name
+ * @param newValue The new value for the attribute
+ */
+xap.xml.dom.events.AttributeChangeEvent = function( source, name, newValue ) {
+ xap.xml.dom.events.DomChangeEvent.call( this, source );
+ this._attributeName = name;
+ this._oldValue = source.getAttribute( this._attributeName );
+ this._newValue = newValue;
+}
+
+xap.xml.dom.events.AttributeChangeEvent.prototype = new xap.xml.dom.events.DomChangeEvent;
+
+
+//-----------------------------------------------------------------------
+// Public Methods
+//-----------------------------------------------------------------------
+
+
+
+/**
+ * Returns the name of the attribute being changed.
+ *
+ * @return The name of the attribute being changed.
+ */
+xap.xml.dom.events.AttributeChangeEvent.prototype.getName = function() {
+ return this._attributeName;
+}
+
+/**
+ * Returns the value of the attribute before the change.
+ * This method returns null if the attribute didn't previously
+ * exist on the source element.
+ *
+ * @return The value of the attribute before the change.
+ */
+xap.xml.dom.events.AttributeChangeEvent.prototype.getOldValue = function() {
+ return this._oldValue;
+}
+
+/**
+ * Returns the new value of the attribute.
+ * This method returns null if the attribute is being removed
+ * from the source element.
+ *
+ * @return The new value of the attribute.
+ */
+xap.xml.dom.events.AttributeChangeEvent.prototype.getNewValue = function() {
+ return this._newValue;
+}
+
+/**
+ * Set the new value of the attribute. It is only valid to set
+ * the attribute value if the event is passed to you in the
+ * beforeAttributeChange() call. If the event was passed to
+ * you in the onAttributeChange() call then setting the value
+ * will cause an UnsupportedOperationException to be thrown.
+ *
+ * Calling this method in the beforeAttributeRemoval() and
+ * onAttributeRemoval() will have no effect.
+ *
+ * @param value The new value of the attribute.
+ * @exception UnsupportedOperationException if the attribute value
+ * has already been accepted by all attribute listeners.
+ */
+xap.xml.dom.events.AttributeChangeEvent.prototype.setNewValue = function( value ) {
+ if ( value == null ) {
+ // TODO - internationalize
+ throw new xap.util.Exception
+ ("Can't set the attribute value as null");
+ }
+ var elementValue = this.getSourceElement().getAttribute( this.getName() );
+ if ( elementValue != null && elementValue != this._oldValue ) {
+ // TODO - internationalize
+ throw new xap.util.Exception
+ ("You may only change the new value of attributes " +
+ "before the change has been committed (accepted by " +
+ "all registered xap.xml.dom.events.AttributeChangeListener objects)");
+ }
+ if ( this._newValue != null && this._newValue == this._oldValue ) {
+ // TODO -
+ //
+ // This may need an UnsupportedOperationException if
+ // the value has already been accepted by the listeners.
+ // This is a boundary case, it means that the new value
+ // has been set the same as the old value. IIF this
+ // call has been made after all the acceptAttributeChange()
+ // calls have been made, then it should throw an exception.
+ // However, there is no way to know since the new value
+ // and the old value are the same.
+ //
+ // Consider adding a package protected method that sets the
+ // new value as immutable.
+ }
+ this._newValue = value;
+}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.xml.dom.events.AttributeChangeListener');
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.ChangeRejectedException");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.AttributeChangeEvent");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.XapElement");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.Document");
+
+
+ /**
+ * @fileoverview A listener that is notified of XML attribute changes.
+ * @author ikaplansky
+ * @author jmargaris
+ */
+
+/**
+ * @class xap.xml.dom.events.AttributeChangeListener is notified of changes to
+ * XML element attributes. Listeners may be added to individual xap.xml.dom.XapElement objects
+ * or on the xap.xml.dom.Document as a whole. They are ordered and will be called in the
+ * order in which they were registered. Listeners registered at the xap.xml.dom.Document
+ * level will be called before listeners registered at the xap.xml.dom.XapElement level.
+ * Objects that wish to listen for attribute changes should either
+ * extend this object or implement that same method names.
+ *
+ * @see xap.xml.dom.XapElement#addAttributeChangeListener
+ * @see xap.xml.dom.XapElement#removeAttributeChangeListener
+ * @see xap.xml.dom.Document#addAttributeChangeListener
+ * @see xap.xml.dom.Document#removeAttributeChangeListener
+ */
+
+
+//-----------------------------------------------------------------------
+// Constructors.
+//-----------------------------------------------------------------------
+xap.xml.dom.events.AttributeChangeListener = function(){}
+
+
+//-----------------------------------------------------------------------
+// Public Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * This method is called after Element.setAttribute() is called, but
+ * before the value is actually changed. Listeners have the opportunity
+ * to modify the new value or reject the change. Modifying the value
+ * will NOT fire a new event. The value is modified and the new value
+ * is passed to subsequent listeners beforeAttributeChange() methods for
+ * their review. Should they decide to modify it, the final value will
+ * reflect their changes too.
+ *
+ * @param event The xap.xml.dom.events.AttributeChangeEvent representing the change.
+ * @exception xap.xml.dom.events.ChangeRejectedException Implementors may throw this
+ * if they wish to provide a reason that they rejected the change
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.ChangeRejectedException");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.AttributeChangeEvent");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.XapElement");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.Document");
+
+ * in the exception message.
+ */
+xap.xml.dom.events.AttributeChangeListener.prototype.beforeAttributeSet = function( event ) {}
+
+/**
+ * This method is called after Element.setAttribute() and after all
+ * listeners have accepted the change. The underlying value of the
+ * attribute on the Element object has already been changed.
+ * Listeners may not modify the value or reject the change.
+ *
+ * @param event The xap.xml.dom.events.AttributeChangeEvent representing the change.
+ */
+xap.xml.dom.events.AttributeChangeListener.prototype.onAttributeSet = function( event ){}
+
+
+/**
+ * This method is called after Element.removeAttribute() is called,
+ * but before the attribute is actually removed. Listeners have
+ * the opportunity to reject the removal by throwing a
+ * xap.xml.dom.events.ChangeRejectedException.
+ *
+ * @param event The xap.xml.dom.events.AttributeChangeEvent representing the change.
+ * @exception xap.xml.dom.events.ChangeRejectedException thrown to reject the remove.
+ */
+xap.xml.dom.events.AttributeChangeListener.prototype.beforeAttributeRemoved = function( event ){}
+
+/**
+ * This method is called after Element.removeAttribute() is called
+ * and after all listeners have accepted the removal. When this
+ * method is called the attribute has already been removed from
+ * the element.
+ *
+ * @param event The xap.xml.dom.events.AttributeChangeEvent representing the remove.
+ */
+xap.xml.dom.events.AttributeChangeListener.prototype.onAttributeRemoved = function( event ){}
+
+
+/*
+ * Copyright 2006 The Apache Software Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+//Let Dojo know what to expect from this file:
+Xap.provide('xap.xml.dom.events.ChangeRejectedException');
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.StructureChangeListener");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.DomChangeEvent");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.events.AttributeChangeListener");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.xml.dom.Document");
+
+// Auto-added---o.k.?
+//ExperimentXap.require("xap.util.XapException");
+
+
+ /**
+ * @fileoverview An exception indicating a DOM attribute or structure
+ * change was rejected.
+ *
+ * @author ikaplansky
+ * @author jmargaris
+ *
+ *
+ * @class This is thrown from by {@link xap.xml.dom.events.AttributeChangeListener} and {@link
+ * xap.xml.dom.events.StructureChangeListener} "before" methods. Consequently, they are thrown
+ * by many of the DOM API methods. When thrown, it signals that the operation
+ * being performed on the xap.xml.dom.Document was rejected by one of the event listeners.
+ */
+xap.xml.dom.events.ChangeRejectedException = function( msgId, args, cause, event ) {
+ xap.util.XapException.call( this, msgId, args, cause );
+ this._event = event;
+}
+xap.xml.dom.events.ChangeRejectedException.prototype = new xap.util.XapException;
+
+//-----------------------------------------------------------------------
+// Constants.
+//-----------------------------------------------------------------------
+xap.xml.dom.events.ChangeRejectedException.CLASSNAME = "xap.xml.dom.events.ChangeRejectedException";
+xap.xml.dom.events.ChangeRejectedException.CHANGE_ATTRIBUTE_TO_NULL_MSGID = "listenerChangedAttributeToNull";
+xap.xml.dom.events.ChangeRejectedException.CHANGE_CHILD_TO_NULL_MSGID = "listenerChangedChildToNull";
+xap.xml.dom.events.ChangeRejectedException.REJECTED_WITH_REASON_MSGID = "rejectedWithReason";
+xap.xml.dom.events.ChangeRejectedException.ROOT_NODE_CHANGE_DISALLOWED_MSGID = "rootNodeChangeDisallowed";
+
+
+//-----------------------------------------------------------------------
+// Public Methods.
+//-----------------------------------------------------------------------
+
+/**
+ * Returns the <code>xap.xml.dom.events.DomChangeEvent</code> that was rejected.
+ */
+xap.xml.dom.events.ChangeRejectedException.prototype.getEvent = function() {
+ return this._event;
+}
+
+xap.xml.dom.events.ChangeRejectedException.prototype.getClassName = function() {
+ return xap.xml.dom.events.ChangeRejectedException.CLASSNAME;
+}
+
+
+if(!this["dojo"]){
+ alert("\"dojo/__package__.js\" is now located at \"dojo/dojo.js\". Please update your includes accordingly");
+}
+
+// Copyright 2005 Google Inc.
+// All Rights Reserved
+//
+// Miscellania that support the ajaxslt implementation.
+//
+// Author: Steffen Meschkat <me...@google.com>
+//
+
+Xap.provide("google.misc");
+
+
+with (google){
+ // Returns the text value if a node; for nodes without children this
+ // is the nodeValue, for nodes with children this is the concatenation
+ // of the value of all children.
+ google.xmlValue = function(node) {
+ if (!node) {
+ return '';
+ }
+
+ var ret = '';
+ if (node.nodeType == DOM_TEXT_NODE ||
+ node.nodeType == DOM_CDATA_SECTION_NODE ||
+ node.nodeType == DOM_ATTRIBUTE_NODE) {
+ ret += node.nodeValue;
+
+ } else if (node.nodeType == DOM_ELEMENT_NODE ||
+ node.nodeType == DOM_DOCUMENT_NODE ||
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+ for (var i = 0; i < node.childNodes.length; ++i) {
+ ret += arguments.callee(node.childNodes[i]);
+ }
+ }
+ return ret;
+ }
+
+ // Returns the representation of a node as XML text.
+ google.xmlText =function(node) {
+ var ret = '';
+ if (node.nodeType == DOM_TEXT_NODE) {
+ ret += xmlEscapeText(node.nodeValue);
+
+ } else if (node.nodeType == DOM_ELEMENT_NODE) {
+ ret += '<' + node.nodeName;
+ for (var i = 0; i < node.attributes.length; ++i) {
+ var a = node.attributes[i];
+ if (a && a.nodeName && a.nodeValue) {
+ ret += ' ' + a.nodeName;
+ ret += '="' + xmlEscapeAttr(a.nodeValue) + '"';
+ }
+ }
+
+ if (node.childNodes.length == 0) {
+ ret += '/>';
+
+ } else {
+ ret += '>';
+ for (var i = 0; i < node.childNodes.length; ++i) {
+ ret += arguments.callee(node.childNodes[i]);
+ }
+ ret += '</' + node.nodeName + '>';
+ }
+
+ } else if (node.nodeType == DOM_DOCUMENT_NODE ||
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
+ for (var i = 0; i < node.childNodes.length; ++i) {
+ ret += arguments.callee(node.childNodes[i]);
+ }
+ }
+
+ return ret;
+ }
+
+ // Applies the given function to each element of the array.
+ google.mapExec = function(array, func) {
+ for (var i = 0; i < array.length; ++i) {
+ func(array[i]);
+ }
+ }
+
+ // Returns an array that contains the return value of the given
+ // function applied to every element of the input array.
+ google.mapExpr = function(array, func) {
+ var ret = [];
+ for (var i = 0; i < array.length; ++i) {
+ ret.push(func(array[i]));
+ }
+ return ret;
+ };
+
+ // Reverses the given array in place.
+ google.reverseInplace = function(array) {
+ for (var i = 0; i < array.length / 2; ++i) {
+ var h = array[i];
+ var ii = array.length - i - 1;
+ array[i] = array[ii];
+ array[ii] = h;
+ }
+ }
+
+ // Shallow-copies an array.
+ google.copyArray = function(dst, src) {
+ for (var i = 0; i < src.length; ++i) {
+ dst.push(src[i]);
+ }
+ }
+
+ google.assert = function(b) {
+ if (!b) {
+ throw 'assertion failed';
+ }
+ }
+
+
+ // Based on
+ // <http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/core.html#ID-1950641247>
+ google.DOM_ELEMENT_NODE = 1;
+ google.DOM_ATTRIBUTE_NODE = 2;
+ google.DOM_TEXT_NODE = 3;
+ google.DOM_CDATA_SECTION_NODE = 4;
+ google.DOM_ENTITY_REFERENCE_NODE = 5;
+ google.DOM_ENTITY_NODE = 6;
+ google.DOM_PROCESSING_INSTRUCTION_NODE = 7;
+ google.DOM_COMMENT_NODE = 8;
+ google.DOM_DOCUMENT_NODE = 9;
+ google.DOM_DOCUMENT_TYPE_NODE = 10;
+ google.DOM_DOCUMENT_FRAGMENT_NODE = 11;
+ google.DOM_NOTATION_NODE = 12;
+
+
+ google.xpathdebug = false; // trace xpath parsing
+ google.xsltdebug = false; // trace xslt processing
+
+
+ // Escape XML special markup chracters: tag delimiter < > and entity
+ // reference start delimiter &. The escaped string can be used in XML
+ // text portions (i.e. between tags).
+ google.xmlEscapeText = function(s) {
+ return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
+ }
+
+ // Escape XML special markup characters: tag delimiter < > entity
+ // reference start delimiter & and quotes ". The escaped string can be
+ // used in double quoted XML attribute value portions (i.e. in
+ // attributes within start tags).
+ google.xmlEscapeAttr = function(s) {
+ return xmlEscapeText(s).replace(/\"/g, '"');
+ }
+
+ // Escape markup in XML text, but don't touch entity references. The
+ // escaped string can be used as XML text (i.e. between tags).
+ google.xmlEscapeTags = function(s) {
+ return s.replace(/</g, '<').replace(/>/g, '>');
+ }
+
+ // An implementation of the debug log.
+
+ google.logging__ = true;
+
+ google.Log = function() {};
+
+ Log.lines = [];
+
+ Log.write = function(s) {
+ if (logging__) {
+ this.lines.push(xmlEscapeText(s));
+ this.show();
+ }
+ };
+
+ // Writes the given XML with every tag on a new line.
+ Log.writeXML = function(xml) {
+ if (logging__) {
+ var s0 = xml.replace(/</g, '\n<');
+ var s1 = xmlEscapeText(s0);
+ var s2 = s1.replace(/\s*\n(\s|\n)*/g, '<br/>');
+ this.lines.push(s2);
+ this.show();
+ }
+ }
+
+ // Writes without any escaping
+ Log.writeRaw = function(s) {
+ if (logging__) {
+ this.lines.push(s);
+ this.show();
+ }
+ }
+
+ Log.clear = function() {
+ if (logging__) {
+ var l = this.div();
+ l.innerHTML = '';
+ this.lines = [];
+ }
+ }
+
+ Log.show = function() {
+ var l = this.div();
+ l.innerHTML += this.lines.join('<br/>') + '<br/>';
+ this.lines = [];
+ l.scrollTop = l.scrollHeight;
+ }
+
+ Log.div = function() {
+ var l = document.getElementById('log');
+ if (!l) {
+ l = document.createElement('div');
+ l.id = 'log';
+ l.style.position = 'absolute';
+ l.style.right = '5px';
+ l.style.top = '5px';
+ l.style.width = '250px';
+ l.style.height = '150px';
+ l.style.overflow = 'auto';
+ l.style.backgroundColor = '#f0f0f0';
+ l.style.border = '1px solid gray';
+ l.style.fontSize = '10px';
+ l.style.padding = '5px';
+ document.body.appendChild(l);
+ }
+ return l;
+ }
+
+}
+// Copyright 2005 Google Inc.
+// All Rights Reserved
+//
+// An XML parse and a minimal DOM implementation that just supportes
+// the subset of the W3C DOM that is used in the XSLT implementation.
+//
+// References:
+//
+// [DOM] W3C DOM Level 3 Core Specification
+// <http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/>.
+//
+//
+// Author: Steffen Meschkat <me...@google.com>
+
+Xap.provide("google.dom");
+//ExperimentXap.require("google.misc");
+
+
+
+// Our W3C DOM Node implementation. Note we call it google.XNode because we
+// can't define the identifier Node. We do this mostly for Opera,
+// where we can't reuse the HTML DOM for parsing our own XML, and for
+// Safari, where it is too expensive to have the template processor
+// operate on native DOM nodes.
+google.XNode = function(type, name, value, owner) {
+ this.attributes = [];
+ this.childNodes = [];
+
+ google.XNode.init.call(this, type, name, value, owner);
+}
+
+
+with (google){
+ // Don't call as method, use apply() or call().
+ XNode.init = function(type, name, value, owner) {
+ this.nodeType = type - 0;
+ this.nodeName = '' + name;
+ this.nodeValue = '' + value;
+ this.ownerDocument = owner;
+
+ this.firstChild = null;
+ this.lastChild = null;
+ this.nextSibling = null;
+ this.previousSibling = null;
+ this.parentNode = null;
+ }
+
+
+ XNode.unused_ = [];
+
+ XNode.recycle = function(node) {
+ if (!node) {
+ return;
+ }
+
+ if (node.constructor == google.XDocument) {
+ XNode.recycle(node.documentElement);
+ return;
+ }
+
+ if (node.constructor != this) {
+ return;
+ }
+
+ XNode.unused_.push(node);
+ for (var a = 0; a < node.attributes.length; ++a) {
+ XNode.recycle(node.attributes[a]);
+ }
+ for (var c = 0; c < node.childNodes.length; ++c) {
+ XNode.recycle(node.childNodes[c]);
+ }
+ node.attributes.length = 0;
+ node.childNodes.length = 0;
+ XNode.init.call(node, 0, '', '', null);
+ }
+
+
+
+ XNode.create = function(type, name, value, owner) {
+ if (XNode.unused_.length > 0) {
+ var node = XNode.unused_.pop();
+ XNode.init.call(node, type, name, value, owner);
+ return node;
+ } else {
+ return new XNode(type, name, value, owner);
+ }
+ }
+
+ XNode.prototype.appendChild = function(node) {
+ // firstChild
+ if (this.childNodes.length == 0) {
+ this.firstChild = node;
+ }
+
+ // previousSibling
+ node.previousSibling = this.lastChild;
+
+ // nextSibling
+ node.nextSibling = null;
+ if (this.lastChild) {
+ this.lastChild.nextSibling = node;
+ }
+
+ // parentNode
+ node.parentNode = this;
+
+ // lastChild
+ this.lastChild = node;
+
+ // childNodes
+ this.childNodes.push(node);
+ }
+
+
+
+
+ XNode.prototype.replaceChild = function(newNode, oldNode) {
+ if (oldNode == newNode) {
+ return;
+ }
+
+ for (var i = 0; i < this.childNodes.length; ++i) {
+ if (this.childNodes[i] == oldNode) {
+ this.childNodes[i] = newNode;
+
+ var p = oldNode.parentNode;
+ oldNode.parentNode = null;
+ newNode.parentNode = p;
+
+ p = oldNode.previousSibling;
+ oldNode.previousSibling = null;
+ newNode.previousSibling = p;
+ if (newNode.previousSibling) {
+ newNode.previousSibling.nextSibling = newNode;
+ }
+
+ p = oldNode.nextSibling;
+ oldNode.nextSibling = null;
+ newNode.nextSibling = p;
+ if (newNode.nextSibling) {
+ newNode.nextSibling.previousSibling = newNode;
+ }
+
+ if (this.firstChild == oldNode) {
+ this.firstChild = newNode;
+ }
+
+ if (this.lastChild == oldNode) {
+ this.lastChild = newNode;
+ }
+
+ break;
+ }
+ }
+ }
+
+ XNode.prototype.insertBefore = function(newNode, oldNode) {
+ if (oldNode == newNode) {
+ return;
+ }
+
+ if (oldNode.parentNode != this) {
+ return;
+ }
+
+ if (newNode.parentNode) {
+ newNode.parentNode.removeChild(newNode);
+ }
+
+ var newChildren = [];
+ for (var i = 0; i < this.childNodes.length; ++i) {
+ var c = this.childNodes[i];
+ if (c == oldNode) {
+ newChildren.push(newNode);
+
+ newNode.parentNode = this;
+
+ newNode.previousSibling = oldNode.previousSibling;
+ oldNode.previousSibling = newNode;
+ if (newNode.previousSibling) {
+ newNode.previousSibling.nextSibling = newNode;
+ }
+
+ newNode.nextSibling = oldNode;
+
+ if (this.firstChild == oldNode) {
+ this.firstChild = newNode;
+ }
+ }
+ newChildren.push(c);
+ }
+ this.childNodes = newChildren;
+ }
+
[... 24922 lines stripped ...]