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/23 17:54:06 UTC
svn commit: r434102 [2/2] - /incubator/xap/trunk/dist/zimbra.js
Modified: incubator/xap/trunk/dist/zimbra.js
URL: http://svn.apache.org/viewvc/incubator/xap/trunk/dist/zimbra.js?rev=434102&r1=434101&r2=434102&view=diff
==============================================================================
--- incubator/xap/trunk/dist/zimbra.js (original)
+++ incubator/xap/trunk/dist/zimbra.js Wed Aug 23 10:54:06 2006
@@ -1,4 +1,4 @@
-/** auto include file:./zimbra/js/msgs/AjxMsg.js **/
+/** auto include file:./xap/peter/src/zimbra/js/msgs/AjxMsg.js **/
function launch() {
// DBG = new AjxDebug( AjxDebug.NONE, null, false );
}
@@ -338,7 +338,227 @@
/* Global ELEMENT declarations */
function ExMsg() {}
-/** auto include file:./zimbra/js/core/AjxEnv.js **/
+/** auto include file:./xap/peter/src/zimbra/js/core/AjxCore.js **/
+/*
+* ***** BEGIN LICENSE BLOCK *****
+* Version: MPL 1.1
+*
+* The contents of this file are subject to the Mozilla Public
+* License Version 1.1 ("License"); you may not use this file except in
+* compliance with the License. You may obtain a copy of the License at
+* http://www.zimbra.com/license
+*
+* Software distributed under the License is distributed on an "AS IS"
+* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+* the License for the specific language governing rights and limitations
+* under the License.
+*
+* The Original Code is: Zimbra AJAX Toolkit.
+*
+* The Initial Developer of the Original Code is Zimbra, Inc.
+* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
+* All Rights Reserved.
+*
+* Contributor(s):
+*
+* ***** END LICENSE BLOCK *****
+*/
+
+
+function AjxCore() {}
+
+AjxCore._objectIds = [null];
+
+
+AjxCore.assignId =
+function(anObject) {
+ var myId = AjxCore._objectIds.length;
+ AjxCore._objectIds[myId]= anObject;
+ return myId;
+};
+
+AjxCore.unassignId =
+function(anId) {
+ AjxCore._objectIds[anId]= null;
+};
+
+AjxCore.objectWithId =
+function(anId) {
+ return AjxCore._objectIds[anId];
+};
+
+/**
+ * Adds a listener to an element, for the given event name.
+ */
+AjxCore.addListener =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
+ listenerStruct.list[listenerStruct.list.length] = action;
+};
+
+/**
+ * sets a one time event handler for the given eventName.
+ */
+AjxCore.setEventHandler =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
+ listenerStruct.single = action;
+};
+
+/**
+ * removes a listener for a given event
+ */
+AjxCore.removeListener =
+function(eventSource, eventName, action) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
+
+ if (listenerStruct) {
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++) {
+ if (listenerList[i] == action)
+ listenerList[i] = null;
+ }
+ }
+};
+
+/**
+ * removes all listeners for a given eventName, and source
+ */
+AjxCore.removeAllListeners =
+function(eventSource, eventName) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
+
+ if (listenerStruct) {
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++)
+ listenerList[i] = null;
+ }
+ AjxCore.unassignId(listenerStruct.id);
+};
+
+/**
+ * notifies listeners of the event. This only needs to be called if
+ * the event is not a standard DOM event. Those types of event callbacks
+ * will be triggered by their event handlers
+ */
+AjxCore.notifyListeners =
+function(eventSource, eventName, arg1) {
+ eventSource = AjxCore._getEventSource(eventSource);
+ var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName)
+ if (listenerStruct)
+ eventSource[eventName](arg1);
+};
+
+AjxCore._getEventSource =
+function(eventSource) {
+ if (typeof(eventSource) == 'string')
+ eventSource = document.getElementById(eventSource);
+ return eventSource;
+};
+
+AjxCore.getListenerStruct =
+function (eventSource, eventName) {
+ return AjxCore._getListenerStruct(eventSource, eventName);
+};
+
+/**
+ * gets the existing struct for the eventSource, or creates a new one.
+ */
+AjxCore._getListenerStruct =
+function(eventSource, eventName, create) {
+ var listenerStruct = null;
+ if (eventSource[eventName]) {
+ var id = eventSource[eventName]._lsListenerStructId;
+ listenerStruct = AjxCore.objectWithId(id);
+ } else if (create) {
+ listenerStruct = AjxCore._setupListener(eventSource, eventName);
+ }
+
+ return listenerStruct;
+};
+
+/**
+ * Creates a listener struct
+ */
+AjxCore._setupListener =
+function(eventSource, eventName, id) {
+ var listenerStruct = new Object();
+ listenerStruct.list = new Array();
+ listenerStruct.single = null;
+ var id = listenerStruct.id = AjxCore.assignId(listenerStruct);
+ var handler = AjxCore._createListenerClosure(id);
+ eventSource[eventName] = handler;
+ eventSource[eventName]._lsListenerStructId = id;
+
+ return listenerStruct;
+};
+
+AjxCore._createListenerClosure =
+function(id) {
+ var closure = function(arg1) {
+ var listenerStruct = AjxCore.objectWithId(id);
+ var listenerList = listenerStruct.list;
+ for (var i = 0; i < listenerList.length; i++) {
+ var callback = listenerList[i];
+ if (callback) {
+ if (typeof(callback) == 'string') {
+ eval(callback);
+ } else {
+ // handle AjxListener callbacks as well as simple functions
+ if (callback.handleEvent) {
+ callback.handleEvent(arg1, this);
+ } else {
+ callback(arg1, this);
+ }
+ }
+ }
+ }
+ if (listenerStruct.single) {
+ var callback = listenerStruct.single;
+ if (typeof(callback) == 'string') {
+ eval(callback);
+ } else {
+ return callback.handleEvent
+ ? callback.handleEvent(arg1, this)
+ : callback(arg1, this);
+ }
+ }
+ }
+ return closure;
+};
+
+/**
+ * Convenience method for adding onload listeners
+ */
+AjxCore.addOnloadListener =
+function(action) {
+ if (window.onload && (!window.onload._lsListenerStructId)) {
+ var priorListener = window.onload;
+ window.onload = null;
+ AjxCore.addListener(window, "onload", priorListener);
+ }
+
+ AjxCore.addListener(window, "onload", action);
+};
+
+/**
+ * Convenience method for adding onunload listeners
+ */
+AjxCore.addOnunloadListener =
+function(action) {
+ if (window.onunload && (!window.onunload._lsListenerStructId)) {
+ var priorListener = window.onunload;
+ window.onunload = null;
+ AjxCore.addListener(window, "onunload", priorListener);
+ }
+
+ AjxCore.addListener(window, "onunload", action);
+};
+/** auto include file:./xap/peter/src/zimbra/js/core/AjxEnv.js **/
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
@@ -557,7 +777,7 @@
};
}
}
-/** auto include file:./zimbra/js/util/AjxUtil.js **/
+/** auto include file:./xap/peter/src/zimbra/js/util/AjxUtil.js **/
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
@@ -847,6 +1067,7 @@
* Convert an XML node to the equivalent JS. Traverses the node's
* children recursively.
* <p>
+
* NOTE: This method has not been extensively tested and likely needs
* work.
*
@@ -982,6 +1203,7 @@
* you want to modify properties of an object and want to keep those values
* separate from the values in the original object. You can then iterate
* over the proxy's properties and use the <code>hasOwnProperty</code>
+
* method to determine if the property is a new value in the proxy.
* <p>
* <strong>Note:</strong>
@@ -1031,7 +1253,7 @@
newList.push(list[i]);
return newList;
};
-/** auto include file:./zimbra/js/core/AjxCore.js **/
+/** auto include file:./xap/peter/src/zimbra/js/util/AjxText.js **/
/*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
@@ -1058,2100 +1280,1496 @@
*/
-function AjxCore() {}
-
-AjxCore._objectIds = [null];
+// NOTE: The API for the classes in this file are inspired by the Java text
+// formatting classes but the implementation was NOT copied or ported
+// from the Java sources.
+//
+// Format class
+//
-AjxCore.assignId =
-function(anObject) {
- var myId = AjxCore._objectIds.length;
- AjxCore._objectIds[myId]= anObject;
- return myId;
-};
+/**
+ * Base class for all formats. To format an object, instantiate the
+ * format of your choice and call the <code>format</code> method which
+ * returns the formatted string.
+ */
+function AjxFormat(pattern) {
+ this._pattern = pattern;
+ this._segments = [];
+}
-AjxCore.unassignId =
-function(anId) {
- AjxCore._objectIds[anId]= null;
+/** Returns string representation of this object. */
+AjxFormat.prototype.toString = function() {
+ var s = [];
+ s.push("pattern=\"",this._pattern,'"');
+ if (this._segments.length > 0) {
+ s.push(", segments={ ");
+ for (var i = 0; i < this._segments.length; i++) {
+ if (i > 0) { s.push(", "); }
+ s.push(String(this._segments[i]));
+ }
+ s.push(" }");
+ }
+ return s.join("");
};
-AjxCore.objectWithId =
-function(anId) {
- return AjxCore._objectIds[anId];
-};
+// Data
-/**
- * Adds a listener to an element, for the given event name.
- */
-AjxCore.addListener =
-function(eventSource, eventName, action) {
- eventSource = AjxCore._getEventSource(eventSource);
- var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
- listenerStruct.list[listenerStruct.list.length] = action;
-};
+AjxFormat.prototype._pattern;
+AjxFormat.prototype._segments;
-/**
- * sets a one time event handler for the given eventName.
- */
-AjxCore.setEventHandler =
-function(eventSource, eventName, action) {
- eventSource = AjxCore._getEventSource(eventSource);
- var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName, true);
- listenerStruct.single = action;
-};
+// Public methods
-/**
- * removes a listener for a given event
+/**
+ * This method does <em>not</em> need to be overridden unless
+ * the subclass doesn't use format segments and takes complete
+ * responsibility for formatting.
*/
-AjxCore.removeListener =
-function(eventSource, eventName, action) {
- eventSource = AjxCore._getEventSource(eventSource);
- var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
-
- if (listenerStruct) {
- var listenerList = listenerStruct.list;
- for (var i = 0; i < listenerList.length; i++) {
- if (listenerList[i] == action)
- listenerList[i] = null;
- }
+AjxFormat.prototype.format = function(object) {
+ var s = [];
+ for (var i = 0; i < this._segments.length; i++) {
+ s.push(this._segments[i].format(object));
}
+ return s.join("");
};
-/**
- * removes all listeners for a given eventName, and source
- */
-AjxCore.removeAllListeners =
-function(eventSource, eventName) {
- eventSource = AjxCore._getEventSource(eventSource);
- var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName);
+/**
+ * Parses the given string according to this format's pattern and returns
+ * an object.
+ * <p>
- if (listenerStruct) {
- var listenerList = listenerStruct.list;
- for (var i = 0; i < listenerList.length; i++)
- listenerList[i] = null;
+ * <strong>Note:</strong>
+ * The default implementation of this method assumes that the sub-class
+ * has implemented the <code>_createParseObject</code> method.
+ */
+AjxFormat.prototype.parse = function(s) {
+ var object = this._createParseObject();
+ var index = 0;
+ for (var i = 0; i < this._segments.length; i++) {
+ var segment = this._segments[i];
+ index = segment.parse(object, s, index);
}
- AjxCore.unassignId(listenerStruct.id);
+ // REVISIT: Should this return null instead?
+ if (index < s.length) {
+ throw new AjxFormat.ParsingException(this, null, "input too long"); // I18n
+ }
+ return object;
};
-/**
- * notifies listeners of the event. This only needs to be called if
- * the event is not a standard DOM event. Those types of event callbacks
- * will be triggered by their event handlers
+/**
+ * Returns an array of segments that comprise this format.
+ * <p>
+ * <strong>Note:</strong>
+ * This method is specific to this implementation and does not follow
+ * the format classes found in the <code>java.text</code> package.
*/
-AjxCore.notifyListeners =
-function(eventSource, eventName, arg1) {
- eventSource = AjxCore._getEventSource(eventSource);
- var listenerStruct = AjxCore._getListenerStruct(eventSource, eventName)
- if (listenerStruct)
- eventSource[eventName](arg1);
+AjxFormat.prototype.getSegments = function() {
+ return this._segments;
};
-AjxCore._getEventSource =
-function(eventSource) {
- if (typeof(eventSource) == 'string')
- eventSource = document.getElementById(eventSource);
- return eventSource;
+/** Returns a string pattern for this format. */
+AjxFormat.prototype.toPattern = function() {
+ return this._pattern;
};
-AjxCore.getListenerStruct =
-function (eventSource, eventName) {
- return AjxCore._getListenerStruct(eventSource, eventName);
+/** Returns a copy of this format. */
+AjxFormat.prototype.clone = function() {
+ return new this.constructor(this._pattern);
};
-/**
- * gets the existing struct for the eventSource, or creates a new one.
- */
-AjxCore._getListenerStruct =
-function(eventSource, eventName, create) {
- var listenerStruct = null;
- if (eventSource[eventName]) {
- var id = eventSource[eventName]._lsListenerStructId;
- listenerStruct = AjxCore.objectWithId(id);
- } else if (create) {
- listenerStruct = AjxCore._setupListener(eventSource, eventName);
- }
+// Protected methods
- return listenerStruct;
-};
-
/**
- * Creates a listener struct
- */
-AjxCore._setupListener =
-function(eventSource, eventName, id) {
- var listenerStruct = new Object();
- listenerStruct.list = new Array();
- listenerStruct.single = null;
- var id = listenerStruct.id = AjxCore.assignId(listenerStruct);
- var handler = AjxCore._createListenerClosure(id);
- eventSource[eventName] = handler;
- eventSource[eventName]._lsListenerStructId = id;
+ * Creates the object that is initialized by parsing
+ * <p>
- return listenerStruct;
+ * <strong>Note:</strong>
+ * This must be implemented by sub-classes.
+ */
+AjxFormat.prototype._createParseObject = function(s) {
+ throw new AjxFormat.ParsingException(this, null, "not implemented"); // I18n
};
-AjxCore._createListenerClosure =
-function(id) {
- var closure = function(arg1) {
- var listenerStruct = AjxCore.objectWithId(id);
- var listenerList = listenerStruct.list;
- for (var i = 0; i < listenerList.length; i++) {
- var callback = listenerList[i];
- if (callback) {
- if (typeof(callback) == 'string') {
- eval(callback);
- } else {
- // handle AjxListener callbacks as well as simple functions
- if (callback.handleEvent) {
- callback.handleEvent(arg1, this);
- } else {
- callback(arg1, this);
- }
- }
- }
- }
- if (listenerStruct.single) {
- var callback = listenerStruct.single;
- if (typeof(callback) == 'string') {
- eval(callback);
- } else {
- return callback.handleEvent
- ? callback.handleEvent(arg1, this)
- : callback(arg1, this);
- }
- }
- }
- return closure;
-};
+// Protected static methods
-/**
- * Convenience method for adding onload listeners
- */
-AjxCore.addOnloadListener =
-function(action) {
- if (window.onload && (!window.onload._lsListenerStructId)) {
- var priorListener = window.onload;
- window.onload = null;
- AjxCore.addListener(window, "onload", priorListener);
+AjxFormat._zeroPad = function(s, length, zeroChar, rightSide) {
+ s = typeof s == "string" ? s : String(s);
+
+ if (s.length >= length) return s;
+
+ zeroChar = zeroChar || '0';
+
+ var a = [];
+ for (var i = s.length; i < length; i++) {
+ a.push(zeroChar);
}
+ a[rightSide ? "unshift" : "push"](s);
- AjxCore.addListener(window, "onload", action);
+ return a.join("");
};
-/**
- * Convenience method for adding onunload listeners
- */
-AjxCore.addOnunloadListener =
-function(action) {
- if (window.onunload && (!window.onunload._lsListenerStructId)) {
- var priorListener = window.onunload;
- window.onunload = null;
- AjxCore.addListener(window, "onunload", priorListener);
- }
+//
+// Format exception base class
+//
- AjxCore.addListener(window, "onunload", action);
+AjxFormat.FormatException = function(format, message) {
+ this._format = format;
+ this._message = message;
+};
+AjxFormat.FormatException.prototype.toString = function() {
+ return this._message;
};
-/** auto include file:./zimbra/js/soap/AjxSoapFault.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+// Data
-/* Represents a SOAP Fault
-*
-* Public attributes:
-*
-* - faultCode: The SOAP fault code
-* - reason: Reason string
-* - errorCode: server error code
-*/
-function AjxSoapFault(faultEl) {
- if (arguments.length == 0) return;
- var prefix = faultEl.prefix;
- var codeStr = prefix + ":Code";
- var reasonStr = prefix + ":Reason";
- var detailStr = prefix + ":Detail"
- // We will assume a correctly formatted Fault element
- for (var i = 0; i < faultEl.childNodes.length; i++) {
- var childNode = faultEl.childNodes[i];
- if (childNode.nodeName == codeStr) {
- var faultCode = childNode.firstChild.firstChild.nodeValue;
- if (faultCode == (prefix + ":VersionMismatch"))
- this.faultCode = AjxSoapFault.VERSION_MISMATCH;
- else if (faultCode == (prefix + ":MustUnderstand"))
- this.faultCode = AjxSoapFault.MUST_UNDERSTAND;
- else if (faultCode == (prefix + ":DataEncodingUnknown"))
- this.faultCode = AjxSoapFault.DATA_ENCODING_UNKNOWN;
- else if (faultCode == (prefix + ":Sender"))
- this.faultCode = AjxSoapFault.SENDER;
- else if (faultCode == (prefix + ":Receiver"))
- this.faultCode = AjxSoapFault.RECEIVER;
- else
- this.faultCode = AjxSoapFault.UNKNOWN;
- } else if (childNode.nodeName == reasonStr) {
- this.reason = childNode.firstChild.firstChild.nodeValue;
- } else if (childNode.nodeName == detailStr) {
- this.errorCode = childNode.firstChild.firstChild.firstChild.nodeValue;
- }
- }
-}
-
-AjxSoapFault.prototype.toString =
-function() {
- return "AjxSoapFault";
-}
-
-AjxSoapFault.SENDER = -1;
-AjxSoapFault.RECEIVER = -2;
-AjxSoapFault.VERSION_MISMATCH = -3;
-AjxSoapFault.MUST_UNDERSTAND = -4;
-AjxSoapFault.DATA_ENCODING_UNKNOWN = -5;
-AjxSoapFault.UNKNOWN = -6;
-/** auto include file:./zimbra/js/util/AjxCookie.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+AjxFormat.FormatException.prototype._format;
+AjxFormat.FormatException.prototype._message;
+//
+// Formatting exception class
+//
-function AjxCookie() {
-}
+AjxFormat.FormattingException = function(format, segment, message) {
+ AjxFormat.FormatException.call(this, format, message);
+ this._segment = segment;
+};
+AjxFormat.FormattingException.prototype = new AjxFormat.FormatException;
+AjxFormat.FormattingException.prototype.constructor = AjxFormat.FormattingException;
-AjxCookie.prototype.toString =
-function() {
- return "AjxCookie";
-}
+// Data
-AjxCookie.getCookie =
-function(doc, name) {
- var arg = name + "=";
- var alen = arg.length;
- var clen = doc.cookie.length;
- var cookie = doc.cookie;
- var i = 0;
- while (i < clen) {
- var j = i + alen;
- if (cookie.substring(i, j) == arg) {
- var endstr = cookie.indexOf (";", j);
- if (endstr == -1)
- endstr = cookie.length;
- return unescape(cookie.substring(j, endstr));
- }
- i = cookie.indexOf(" ", i) + 1;
- if (i == 0)
- break;
- }
- return null;
-}
+AjxFormat.FormattingException.prototype._segment;
-AjxCookie.setCookie =
-function(doc, name, value, expires, path, domain, secure) {
- doc.cookie = name + "=" + escape (value) +
- ((expires) ? "; expires=" + expires.toGMTString() : "") +
- ((path) ? "; path=" + path : "") +
- ((domain) ? "; domain=" + domain : "") +
- ((secure) ? "; secure" : "");
-}
+//
+// Parsing exception class
+//
-AjxCookie.deleteCookie =
-function (doc, name, path, domain) {
- doc.cookie = name + "=" +
- ((path) ? "; path=" + path : "") +
- ((domain) ? "; domain=" + domain : "") + "; expires=Fri, 31 Dec 1999 23:59:59 GMT";
-}
-/** auto include file:./zimbra/js/debug/AjxDebug.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+AjxFormat.ParsingException = function(format, segment, message) {
+ AjxFormat.FormatException.call(this, format, message);
+ this._segment = segment;
+};
+AjxFormat.ParsingException.prototype = new AjxFormat.FormatException;
+AjxFormat.ParsingException.prototype.constructor = AjxFormat.ParsingException;
+// Data
-/**
-* Creates a new debug window. The document inside is not kept open. All the
- output goes into a single <div> element.
-* @constructor
-* @class
-* This class pops up a debug window and provides functions to send output there
-* in various ways. The output is continuously appended to the bottom of the
-* window. The document is left unopened so that the browser doesn't think it's
-* continuously loading and keep its little icon flailing forever. Also, the DOM
-* tree can't be manipulated on an open document. All the output is added to the
-* window by appending it the DOM tree. Another method of appending output is to
-* open the document and use document.write(), but then the document is left open.
-* <p>
-* Any client that uses this class can turn off debugging by changing the first
-* argument to the constructor to AjxDebug.NONE.
-*
-* @author Conrad Damon
-* @author Ross Dargahi
-* @param level debug level for the current debugger (no window will be displayed for a level of NONE)
-* @param name the name of the window. Defaults to "debug_" prepended to the calling window's URL.
-* @param showTime a boolean that toggles the display of timestamps before debug messages
-*/
-function AjxDebug(level, name, showTime) {
- this._dbgName = "AjxDebugWin_" + location.hostname.replace(/\./g,'_');
- this._level = level;
- this._showTime = showTime;
- this._enabled = (this._level != AjxDebug.NONE);
- this._showTiming = false;
- this._startTimePt = this._lastTimePt = 0;
- this._dbgWindowInited = false;
+AjxFormat.ParsingException.prototype._segment;
- this._msgQueue = new Array();
- AjxDebug._CONTENT_FRAME_ID = AjxDebug._CONTENT_FRAME_ID;
- this._isPrevWinOpen = false;
- if (!this._enabled) return;
+//
+// Segment class
+//
- this._openDebugWindow();
+AjxFormat.Segment = function(format, s) {
+ this._parent = format;
+ this._s = s;
};
+AjxFormat.Segment.prototype.toString = function() {
+ return "segment: \""+this._s+'"';
+};
-AjxDebug.NONE = "DBG0"; // no debugging (window will not come up)
-AjxDebug.DBG1 = "DBG1"; // minimal debugging
-AjxDebug.DBG2 = "DBG2"; // moderate debugging
-AjxDebug.DBG3 = "DBG3"; // anything goes
-AjxDebug.PERF = "PERF"; // performance timings
-
-// map from number to debug level
-AjxDebug.DBG = new Object();
-AjxDebug.DBG[-1] = AjxDebug.PERF;
-AjxDebug.DBG[0] = AjxDebug.NONE;
-AjxDebug.DBG[1] = AjxDebug.DBG1;
-AjxDebug.DBG[2] = AjxDebug.DBG2;
-AjxDebug.DBG[3] = AjxDebug.DBG3;
-
-// map from debug level to number
-AjxDebug.GBD = {};
-AjxDebug.GBD[AjxDebug.PERF] = -1;
-AjxDebug.GBD[AjxDebug.NONE] = 0;
-AjxDebug.GBD[AjxDebug.DBG1] = 1;
-AjxDebug.GBD[AjxDebug.DBG2] = 2;
-AjxDebug.GBD[AjxDebug.DBG3] = 3;
-
-AjxDebug.MAX_OUT = 25000; // max length capable of outputting
+// Data
-AjxDebug._LINK_FRAME_ID = "AjxDebug_LF";
-AjxDebug._CONTENT_FRAME_ID = "AjxDebug_CF";
-AjxDebug._BUTTON_FRAME_ID = "AjxDebug_BF";
+AjxFormat.Segment.prototype._parent;
+AjxFormat.Segment.prototype._s;
-AjxDebug._id = 0;
-AjxDebug._openErrors = 0;
+// Public methods
-AjxDebug.prototype.toString =
-function() {
- return "AjxDebug";
-}
+AjxFormat.Segment.prototype.format = function(o) {
+ return this._s;
+};
/**
-* Set debug level. May open or close the debug window if moving to or from level NONE.
-*
-* @param level debug level for the current debugger
-*/
-AjxDebug.prototype.setDebugLevel =
-function(level) {
- if (level == this._level) return;
-
- this._level = level;
- if (level == AjxDebug.NONE) {
- this._enabled = false;
- this._debugWindow.close();
- this._debugWindow = null;
- } else {
- this._enabled = true;
- if (this._debugWindow == null || this._debugWindow.closed)
- this._openDebugWindow();
- }
+ * Parses the string at the given index, initializes the parse object
+ * (as appropriate), and returns the new index within the string for
+ * the next parsing step.
+ * <p>
+ * <strong>Note:</strong>
+ * This method must be implemented by sub-classes.
+ *
+ * @param o [object] The parse object to be initialized.
+ * @param s [string] The input string to be parsed.
+ * @param index [number] The index within the string to start parsing.
+ */
+AjxFormat.Segment.prototype.parse = function(o, s, i) {
+ throw new AjxFormat.ParsingException(this._parent, this, "not implemented"); // I18n
};
-AjxDebug.prototype.getDebugLevel =
-function(level) {
- return this._level;
-};
+// Protected static methods
-AjxDebug.prototype.isShowTiming =
-function() {
- return this._showTiming;
+AjxFormat.Segment._parseLiteral = function(literal, s, index) {
+ if (s.length - index < literal.length) {
+ throw new AjxFormat.ParsingException(this._parent, this, "input too short"); // I18n
+ }
+ for (var i = 0; i < literal.length; i++) {
+ if (literal.charAt(i) != s.charAt(index + i)) {
+ throw new AjxFormat.ParsingException(this._parent, this, "input doesn't match"); // I18n
+ }
+ }
+ return index + literal.length;
};
-
-/**
-* Turn the display of timing statements on/off. Timing starts over any time it's turned on.
-*
-* @param on whether to display timing statements
-*/
-AjxDebug.prototype.showTiming =
-function(on, level, msg) {
- this._showTiming = on;
-
- if (on) {
- this._startTimePt = this._lastTimePt = 0;
-
- var a = [];
- for (var i = 1; i < arguments.length; i++)
- a.push(arguments[i]);
-
- var args = this._handleArgs(a);
- if (args) {
- var msgLevel = AjxDebug.DBG1;
- if (String(level).match(/^DBG|PERF/))
- msgLevel = level;
-
- this.println(msgLevel, " ----- " + args[0] + " ----- ");
+AjxFormat.Segment._parseLiterals = function(literals, s, index) {
+ for (var i = 0; i < literals.length; i++) {
+ try {
+ var literal = literals[i];
+ return AjxFormat.Segment._parseLiteral(literal, s, index);
+ }
+ catch (e) {
+ // ignore. keep trying to find a match
}
}
- this._startTimePt = this._lastTimePt = new Date().getTime();
+ return -1;
};
/**
-* Prints a debug message. Any HTML will be rendered, and a line break is added.
-*
-* @param level debug level for the current debugger
-* @param msg the text to display
-*/
-AjxDebug.prototype.println =
-function(level, msg, linkName) {
- if (this.isDisabled() || this._debugWindow.closed) return;
- var args = this._handleArgs(arguments, linkName);
- if (!args) return;
-
- msg = args.join("");
- /*** DEBUG ***
- if (String(level).match(/^DBG|PERF/)) {
- msg = level + ": " + msg;
+ * Parses an integer at the offset of the given string and calls a
+ * method on the specified object.
+ *
+ * @param o [object] The target object.
+ * @param f [function] The method to call on the target object.
+ * @param adjust [number] The numeric adjustment to make on the
+ * value before calling the object method.
+ * @param s [string] The string to parse.
+ * @param index [number] The index within the string to start parsing.
+ * @param fixedlen [number] If specified, specifies the required number
+ * of digits to be parsed.
+ */
+AjxFormat.Segment._parseInt = function(o, f, adjust, s, index, fixedlen) {
+ var len = fixedlen || s.length - index;
+ var head = index;
+ for (var i = 0; i < len; i++) {
+ if (!s.charAt(index++).match(/\d/)) {
+ index--;
+ break;
+ }
}
- /*** DEBUG ***/
- this._add(this._timestamp() + msg + "<br>", null, null, null, linkName);
+ var tail = index;
+ if (head == tail) {
+ throw new AjxFormat.ParsingException(this._parent, this, "number not present"); // I18n
+ }
+ if (fixedlen && tail - head != fixedlen) {
+ throw new AjxFormat.ParsingException(this._parent, this, "number too short"); // I18n
+ }
+ var value = parseInt(s.substring(head, tail), 10);
+ if (f) {
+ var target = o || window;
+ f.call(target, value + adjust);
+ }
+ return tail;
};
-AjxDebug.prototype.isDisabled =
-function () {
- return !this._enabled;
-};
+//
+// Date format class
+//
/**
-* Prints an object into a table, with a column for properties and a column for values. Above the table is a header with the object
-* class and the CSS class (if any). The properties are sorted (numerically if they're all numbers). Creating and appending table
-* elements worked in Mozilla but not IE. Using the insert* methods works for both. Properties that are function
-* definitions are skipped.
-*
-* @param level debug level for the current debugger
-* @param obj the object to be printed
-* @param showFuncs whether to show props that are functions
-*/
-AjxDebug.prototype.dumpObj =
-function(level, obj, showFuncs, linkName) {
- if (this.isDisabled() || this._debugWindow.closed)return;
- var args = this._handleArgs(arguments, linkName);
- if (!args) return;
- obj = args[0];
- if (!obj) return;
- this._showFuncs = args[1];
+ * The AjxDateFormat class formats Date objects according to a specified
+ * pattern. The patterns are defined the same as the SimpleDateFormat
+ * class in the Java libraries. <strong>Note:</strong> <em>Only the
+ * Gregorian Calendar is supported at this time.</em> Supporting other
+ * calendars would require a lot more information downloaded to the
+ * client. Limiting dates to the Gregorian calendar is a trade-off.
+ * <p>
- AjxDebug._visited = new AjxVector();
- this._add(null, obj);
- this._showFuncs = null;
+ * <strong>Note:</strong>
+ * The date format differs from the Java patterns a few ways: the pattern
+ * "EEEEE" (5 'E's) denotes a <em>short</em> weekday and the pattern "MMMMM"
+ * (5 'M's) denotes a <em>short</em> month name. This matches the extended
+ * pattern found in the Common Locale Data Repository (CLDR) found at:
+ * http://www.unicode.org/cldr/.
+ */
+function AjxDateFormat(pattern) {
+ AjxFormat.call(this, pattern);
+ if (typeof pattern == "number") {
+ switch (pattern) {
+ case AjxDateFormat.SHORT: pattern = I18nMsg.formatDateShort; break;
+ case AjxDateFormat.MEDIUM: pattern = I18nMsg.formatDateMedium; break;
+ case AjxDateFormat.LONG: pattern = I18nMsg.formatDateLong; break;
+ case AjxDateFormat.FULL: pattern = I18nMsg.formatDateFull; break;
+ }
+ }
+ for (var i = 0; i < pattern.length; i++) {
+ // literal
+ var c = pattern.charAt(i);
+ if (c == "'") {
+ var head = i + 1;
+ for (i++ ; i < pattern.length; i++) {
+ var c = pattern.charAt(i);
+ if (c == "'") {
+ if (i + 1 < pattern.length && pattern.charAt(i + 1) == "'") {
+ pattern = pattern.substr(0, i) + pattern.substr(i + 1);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ if (i == pattern.length) {
+ // TODO: i18n
+ throw new FormatException(this, "unterminated string literal");
+ }
+ var tail = i;
+ var segment = new AjxFormat.TextSegment(this, pattern.substring(head, tail));
+ this._segments.push(segment);
+ continue;
+ }
+
+ // non-meta chars
+ var head = i;
+ while(i < pattern.length) {
+ c = pattern.charAt(i);
+ if (AjxDateFormat._META_CHARS.indexOf(c) != -1 || c == "'") {
+ break;
+ }
+ i++;
+ }
+ var tail = i;
+ if (head != tail) {
+ var segment = new AjxFormat.TextSegment(this, pattern.substring(head, tail));
+ this._segments.push(segment);
+ i--;
+ continue;
+ }
+
+ // meta char
+ var head = i;
+ while(++i < pattern.length) {
+ if (pattern.charAt(i) != c) {
+ break;
+ }
+ }
+ var tail = i--;
+ var count = tail - head;
+ var field = pattern.substr(head, count);
+ var segment = null;
+ switch (c) {
+ case 'G': segment = new AjxDateFormat.EraSegment(this, field); break;
+ case 'y': segment = new AjxDateFormat.YearSegment(this, field); break;
+ case 'M': segment = new AjxDateFormat.MonthSegment(this, field); break;
+ case 'w': segment = new AjxDateFormat.WeekSegment(this, field); break;
+ case 'W': segment = new AjxDateFormat.WeekSegment(this, field); break;
+ case 'D': segment = new AjxDateFormat.DaySegment(this, field); break;
+ case 'd': segment = new AjxDateFormat.DaySegment(this, field); break;
+ case 'F': segment = new AjxDateFormat.WeekdaySegment(this, field); break;
+ case 'E': segment = new AjxDateFormat.WeekdaySegment(this, field); break;
+ case 'a': segment = new AjxDateFormat.AmPmSegment(this, field); break;
+ case 'H': segment = new AjxDateFormat.HourSegment(this, field); break;
+ case 'k': segment = new AjxDateFormat.HourSegment(this, field); break;
+ case 'K': segment = new AjxDateFormat.HourSegment(this, field); break;
+ case 'h': segment = new AjxDateFormat.HourSegment(this, field); break;
+ case 'm': segment = new AjxDateFormat.MinuteSegment(this, field); break;
+ case 's': segment = new AjxDateFormat.SecondSegment(this, field); break;
+ case 'S': segment = new AjxDateFormat.SecondSegment(this, field); break;
+ case 'z': segment = new AjxDateFormat.TimezoneSegment(this, field); break;
+ case 'Z': segment = new AjxDateFormat.TimezoneSegment(this, field); break;
+ }
+ if (segment != null) {
+ segment._index = this._segments.length;
+ this._segments.push(segment);
+ }
+ }
+}
+AjxDateFormat.prototype = new AjxFormat;
+AjxDateFormat.prototype.constructor = AjxDateFormat;
+
+AjxDateFormat.prototype.toString = function() {
+ return "[AjxDateFormat: "+AjxFormat.prototype.toString.call(this)+"]";
};
-/**
-* Dumps a bunch of text into a <textarea>, so that it is wrapped and scrollable. HTML will not be rendered.
-*
-* @param level debug level for the current debugger
-* @param text the text to output as is
-*/
-AjxDebug.prototype.printRaw =
-function(level, text, linkName) {
- if (this.isDisabled() || this._debugWindow.closed) return;
- var args = this._handleArgs(arguments, linkName);
- if (!args) return;
- text = args[0];
-
- this._add(null, text, false, true);
-};
+// Constants
-/**
-* Pretty-prints a chunk of XML, doing color highlighting for different types of nodes.
+AjxDateFormat.SHORT = 0;
+AjxDateFormat.MEDIUM = 1;
+AjxDateFormat.LONG = 2;
+AjxDateFormat.FULL = 3;
+AjxDateFormat.DEFAULT = AjxDateFormat.MEDIUM;
-* @param level debug level for the current debugger
-* @param text some XML
-*/
-AjxDebug.prototype.printXML =
-function(level, text, linkName) {
- if (this.isDisabled() || this._debugWindow.closed) return;
- var args = this._handleArgs(arguments, linkName);
- if (!args) return;
- text = args[0];
- if (!text) return;
-
- // skip generating pretty xml if theres too much data
- if (AjxEnv.isSafari || text.length > AjxDebug.MAX_OUT) {
- this.printRaw(text);
- return;
- }
- this._add(null, text, true, false);
-};
+AjxDateFormat._META_CHARS = "GyMwWDdFEaHkKhmsSzZ";
-/**
-* Reveals white space in text by replacing it with tags.
-*
-* @param level debug level for the current debugger
-* @param text the text to be displayed
-*/
-AjxDebug.prototype.display =
-function(level, text) {
- if (this.isDisabled() || this._debugWindow.closed) return;
- var args = this._handleArgs(arguments);
- if (!args) return;
- text = args[0];
+AjxDateFormat._dateFormats = [
+ I18nMsg.formatDateShort, I18nMsg.formatDateMedium,
+ I18nMsg.formatDateLong, I18nMsg.formatDateFull
+];
+AjxDateFormat._timeFormats = [
+ I18nMsg.formatTimeShort, I18nMsg.formatTimeMedium,
+ I18nMsg.formatTimeLong, I18nMsg.formatTimeFull
+];
- text = text.replace(/\r?\n/g, '[crlf]');
- text = text.replace(/ /g, '[space]');
- text = text.replace(/\t/g, '[tab]');
- this.printRaw(level, text);
-};
+AjxDateFormat._DATE_FORMATTERS = {};
+AjxDateFormat._TIME_FORMATTERS = {};
+AjxDateFormat._DATETIME_FORMATTERS = {};
-AjxDebug.prototype.timePt =
-function(level, msg) {
- if (!this._showTiming || !this._enabled || this._debugWindow.closed) return;
-
- var args = this._handleArgs(arguments);
- if (!args) return;
- var msg = args[0];
-
- var now = new Date().getTime();
- var elapsed = now - this._startTimePt;
- var interval = now - this._lastTimePt;
- this._lastTimePt = now;
- var text = "[" + elapsed + " / " + interval + "]";
- if (msg)
- text += " " + msg;
- html = "<div>" + text + "</div>";
- extraType = typeof(text);
+// Static methods
- var myMsg = new DebugMessage(html);
-
- // Add the message to our stack
- this._addMessage(myMsg);
- return interval;
+AjxDateFormat.getDateInstance = function(style) {
+ // lazily create formatters
+ style = style != null ? style : AjxDateFormat.DEFAULT;
+ if (!AjxDateFormat._DATE_FORMATTERS[style]) {
+ AjxDateFormat._DATE_FORMATTERS[style] = new AjxDateFormat(AjxDateFormat._dateFormats[style]);
+ }
+ return AjxDateFormat._DATE_FORMATTERS[style];
};
-
-// Private methods
-
-AjxDebug.prototype._getHtmlForObject =
-function(anObj, isXml, isRaw) {
- var html = new Array();
- var idx = 0;
-
- if (AjxUtil.isUndefined(anObj)) {
- html[idx++] = "<span>Undefined</span>";
- } else if (AjxUtil.isNull(anObj)) {
- html[idx++] = "<span>NULL</span>";
- } else if (AjxUtil.isBoolean(anObj)) {
- html[idx++] = "<span>" + anObj + "</span>";
- } else if (AjxUtil.isNumber(anObj)) {
- html[idx++] = "<span>" + anObj +"</span>";
- } else {
- if (isRaw) {
- html[idx++] = this._timestamp();
- html[idx++] = "<textarea rows='25' style='width:100%' readonly='true'>";
- html[idx++] = anObj;
- html[idx++] = "</textarea>";
- html[idx++] = "<p></p>";
- } else if (isXml) {
- var xmldoc = new AjxDebugXmlDocument;
- var doc = xmldoc.create();
- doc.loadXML(anObj);
- html[idx++] = "<div style='border-width:2px; border-style:inset; width:100%; height:300px; overflow:auto'>";
- html[idx++] = this._createXmlTree(doc, 0);
- html[idx++] = "</div>";
- } else {
- html[idx++] = "<div style='border-width:2px; border-style:inset; width:100%; height:300px; overflow:auto'>";
- html[idx++] = "<pre>";
- html[idx++] = this._dump(anObj, true);
- html[idx++] = "</div>";
- html[idx++] = "</pre>";
- }
+AjxDateFormat.getTimeInstance = function(style) {
+ // lazily create formatters
+ style = style != null ? style : AjxDateFormat.DEFAULT;
+ if (!AjxDateFormat._TIME_FORMATTERS[style]) {
+ AjxDateFormat._TIME_FORMATTERS[style] = new AjxDateFormat(AjxDateFormat._timeFormats[style]);
}
- return html.join("");
+ return AjxDateFormat._TIME_FORMATTERS[style];
};
-// Pretty-prints a Javascript object
-AjxDebug.prototype._dump =
-function(obj, recurse) {
-
- var indentLevel = 0;
- var showBraces = false;
- var stopRecursion = false;
- if (arguments.length > 2) {
- indentLevel = arguments[2];
- showBraces = arguments[3];
- stopRecursion = arguments[4];
+AjxDateFormat.getDateTimeInstance = function(dateStyle, timeStyle) {
+ // lazily create formatters
+ dateStyle = dateStyle != null ? dateStyle : AjxDateFormat.DEFAULT;
+ timeStyle = timeStyle != null ? timeStyle : AjxDateFormat.DEFAULT;
+ var style = dateStyle * 10 + timeStyle;
+ if (!AjxDateFormat._DATETIME_FORMATTERS[style]) {
+ var pattern = I18nMsg.formatDateTime;
+ var params = [ AjxDateFormat._dateFormats[dateStyle], AjxDateFormat._timeFormats[timeStyle] ];
+
+ var dateTimePattern = AjxMessageFormat.format(pattern, params);
+ AjxDateFormat._DATETIME_FORMATTERS[style] = new AjxDateFormat(dateTimePattern);
}
+ return AjxDateFormat._DATETIME_FORMATTERS[style];
+};
- if (AjxUtil.isObject(obj)) {
- if (obj.toString() == "ZmAppCtxt"){
- return "[ZmAppCtxt]";
- }
- if (AjxDebug._visited.contains(obj))
- return "[visited object]";
- else
- AjxDebug._visited.add(obj);
- }
+AjxDateFormat.format = function(pattern, date) {
+ return new AjxDateFormat(pattern).format(date);
+};
+AjxDateFormat.parse = function(pattern, dateStr) {
+ return new AjxDateFormat(pattern).parse(dateStr);
+};
- var indent = AjxStringUtil.repeat(" ", indentLevel);
- var text = "";
-
- if (AjxUtil.isUndefined(obj)) {
- text += "[undefined]";
- } else if (AjxUtil.isNull(obj)) {
- text += "[null]";
- } else if (AjxUtil.isBoolean(obj)) {
- text += obj ? "true" : "false";
- } else if (AjxUtil.isString(obj)) {
- // obj = obj.replace(/\r/g, "\\r");
- // obj = obj.replace(/\n/g, "\\n");
- // obj = obj.replace(/\t/g, "\\t");
- text += '"' + AjxDebug._escapeForHTML(obj) + '"';
- } else if (AjxUtil.isNumber(obj)) {
- text += obj;
- } else if (AjxUtil.isObject(obj)) {
- var isArray = AjxUtil.isArray(obj);
- if (stopRecursion) {
- text += isArray ? "[Array]" : obj.toString();
- } else {
- stopRecursion = !recurse;
- var keys = new Array();
- for (var i in obj)
- keys.push(i);
+// Public methods
- isArray ? keys.sort(function(a,b) {return a - b;}) : keys.sort();
-
+/**
+ * Parses the given string and returns a date. If the string cannot be
+ * parsed as a date, <code>null</code> is returned.
+ */
+AjxDateFormat.prototype.parse = function(s) {
+ var object = null;
+ try {
+ object = AjxFormat.prototype.parse.call(this, s);
+ }
+ catch (e) {
+ // do nothing
+ }
+ return object;
+};
- if (showBraces)
- text += isArray ? "[" : "{";
- for (var i = 0; i < keys.length; i++) {
- var key = keys[i];
- var nextObj = obj[key];
- var value = null;
- // 5/31/05 EMC:
- // For dumping events, and dom elements, though I may not want to
- // traverse the node, I do want to know what the attribute is.
- if (nextObj == window || nextObj == document || (!AjxEnv.isIE && nextObj instanceof Node)){
- value = nextObj.toString();
- }
- if ((typeof(nextObj) == "function")){
- if (this._showFuncs) {
- value = "[function]";
- } else {
- continue;
- }
- }
+// Protected methods
- if (i > 0) text += ",";
- text += "\n" + indent;
- if (value != null) {
- text += key + ": " + value;
- } else {
- text += key + ": " + this._dump(nextObj, recurse, indentLevel + 2, true, stopRecursion);
- }
- }
- if (i > 0)
- text += "\n" + AjxStringUtil.repeat(" ", indentLevel - 1);
- if (showBraces)
- text += isArray ? "]" : "}";
- }
- }
- return text;
+AjxDateFormat.prototype._createParseObject = function() {
+ return new Date(0, 0, 1, 0, 0, 0, 0);
};
-// If the first arg is a debug level, check it and then strip it.
-AjxDebug.prototype._handleArgs =
-function(args, linkNameSpecified) {
- if (this._level == AjxDebug.NONE) return;
-
- var levelSpecified = false;
- var curLevel = AjxDebug.GBD[this._level];
- var msgLevel = AjxDebug.GBD[AjxDebug.DBG1];
- if (typeof args[0] == "string" && String(args[0]).match(/^DBG|PERF/)) {
- msgLevel = AjxDebug.GBD[args[0]];
- levelSpecified = true;
- }
- if (msgLevel > curLevel) return;
-
- // NOTE: Can't just slice the items we want because args is not an Array
- var array = new Array(args.length);
- var len = (linkNameSpecified) ? args.length - 1 : args.length;
- for (var i = 0; i < len; i++) {
- array[i] = args[i];
- }
- if (levelSpecified) { array.shift(); }
- return array;
+//
+// Text segment class
+//
+
+AjxFormat.TextSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
};
+AjxFormat.TextSegment.prototype = new AjxFormat.Segment;
+AjxFormat.TextSegment.prototype.constructor = AjxFormat.TextSegment;
-AjxDebug.prototype._getCookieVal =
-function (cookieName) {
- var myRE = cookieName + "=([^;]+)";
- var myVals = document.cookie.match(new RegExp(myRE));
- var val = null;
- // Return the last value defined (if found)
- if (myVals && (myVals.length > 0)) {
- var valStr = myVals[myVals.length-1];
- if (valStr == "true") {
- val = true;
- } else if (valStr == "false") {
- val = false;
- } else {
- val = valStr;
- }
- }
- return val;
+AjxFormat.TextSegment.prototype.toString = function() {
+ return "text: \""+this._s+'"';
};
-AjxDebug.prototype._openDebugWindow =
-function() {
- this._enabled = true;
- // check if there is a debug window already open
- this._isPrevWinOpen = this._getCookieVal("AjxDebugWinOpen");
- if (!this._isPrevWinOpen) {
- this._debugWindow = AjxWindowOpener.openBlank(this._dbgName, "width=600,height=400,resizable=yes,scrollbars=yes", this._initWindow, this);
- } else {
- this._debugWindow = window.open("" , this._dbgName, "width=600,height=400,resizable=yes,scrollbars=yes");
- this._initWindow();
- }
+// Public methods
+
+AjxFormat.TextSegment.prototype.parse = function(o, s, index) {
+ return AjxFormat.Segment._parseLiteral(this._s, s, index);
};
+//
+// Date segment class
+//
-AjxDebug.prototype._initWindow =
-function() {
- if (this._debugWindow == null) {
- this._enabled = false;
- return;
- }
-
- try {
- this._document = this._debugWindow.document;
- this._document.title = "Debug";
+AjxDateFormat.DateSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
+}
+AjxDateFormat.DateSegment.prototype = new AjxFormat.Segment;
+AjxDateFormat.DateSegment.prototype.constructor = AjxDateFormat.DateSegment;
- if (!this._isPrevWinOpen) {
- this._document.write([
- "<html>",
- "<head>",
- "<script>",
- "function blank() {return [",
- "'<html><head><style type=\"text/css\">',",
- "'P, TD, DIV, SPAN, SELECT, INPUT, TEXTAREA, BUTTON {',",
- "'font-family: Tahoma, Arial, Helvetica, sans-serif;',",
- "'font-size:11px;}',",
- "'.Link {cursor: pointer;color:blue;text-decoration:underline;white-space:nowrap;width:100%;}',",
- "'.Mark {color:white; background-color:black; width:100%;font-size:14px;font-weight:bold;}',",
- "'.MarkLink {cursor: pointer;color:white;background-color:black;text-decoration:underline;font-weight:bold;white-space:nowrap;width:100%;}',",
- "'.Run {color:black; background-color:red;width:100%;font-size:18px;font-weight:bold;}',",
- "'.RunLink {cursor: pointer;color:black;background-color:red;text-decoration:underline;font-weight:bold;white-space:nowrap;width:100%;}',",
- "'</style></head><body></body></html>'].join(\"\");}",
- "</script>",
- "</head>",
- "<frameset cols='125, *'>",
- "<frameset rows='*,40'>",
- "<frame name='", AjxDebug._LINK_FRAME_ID, "' id='", AjxDebug._LINK_FRAME_ID, "' src='javascript:parent.parent.blank();'>",
- "<frame name='", AjxDebug._BUTTON_FRAME_ID, "' id='", AjxDebug._BUTTON_FRAME_ID, "' src='javascript:parent.parent.blank();'>",
- "</frameset>",
- "<frame name='", AjxDebug._CONTENT_FRAME_ID, "' id='", AjxDebug._CONTENT_FRAME_ID, "' src='javascript:parent.blank();'>",
- "</frameset>",
- "</html>"].join(""));
- var ta = new AjxTimedAction(this, AjxDebug.prototype._finishInitWindow);
- AjxTimedAction.scheduleAction(ta, 250);
- } else {
- this._contentFrame = this._document.getElementById(AjxDebug._CONTENT_FRAME_ID);
- this._linkFrame = this._document.getElementById(AjxDebug._LINK_FRAME_ID);
- this._createLinkNContent(this, "RunLink", "NEW RUN", "Run", "NEW RUN");
-
- // Firefox allows us to attach an event listener, and runs it even
- // though the window with the code is gone ... odd, but nice. IE,
- // though will not run the handler, so we make sure, even if we're
- // coming back to the window, to attach the onunload handler. In general
- // reattach all handlers for IE
- if (AjxEnv.isIE) {
- this._debugWindow.attachEvent('onunload', AjxDebug.unloadHandler);
- this._markBtn.onclick = AjxDebug._mark;
- this._clearBtn.onclick = AjxDebug._clear;
- }
-
- this._dbgWindowInited = true;
- // show any messages that have been queued up, while the window loaded.
- this._showMessages();
- }
- } catch (ex) {
- AjxDebug.deleteWindowCookie();
- this._debugWindow.close();
+// Protected methods
- // If we've exceeded a certain # of errors, just close window and bail.
- if (AjxDebug._openErrors < 5) {
- AjxDebug._openErrors++;
- this._openDebugWindow();
+AjxDateFormat.DateSegment.prototype._getFixedLength = function() {
+ var fixedlen;
+ if (this._index + 1 < this._parent._segments.length) {
+ var nextSegment = this._parent._segments[this._index + 1];
+ if (!(nextSegment instanceof AjxFormat.TextSegment)) {
+ fixedlen = this._s.length;
}
}
+ return fixedlen;
};
-AjxDebug.prototype._finishInitWindow =
-function() {
- this._contentFrame = this._document.getElementById(AjxDebug._CONTENT_FRAME_ID);
- this._linkFrame = this._document.getElementById(AjxDebug._LINK_FRAME_ID);
-
- // Create the mark and clear buttons
- var buttonFrame = this._document.getElementById(AjxDebug._BUTTON_FRAME_ID);
- var buttonFrameDoc = buttonFrame.contentWindow.document;
- var buttonFrameBody = buttonFrameDoc.body;
-
- var markBtn = this._markBtn = buttonFrameDoc.createElement("button");
- markBtn.innerHTML = "Mark";
- markBtn._dbg = this;
- markBtn.onclick = AjxDebug._mark;
+//
+// Date era segment class
+//
- var clearBtn = this._markBtn = buttonFrameDoc.createElement("button");
- clearBtn._contentFrameId = AjxDebug._CONTENT_FRAME_ID;
- clearBtn._linkFrameId = AjxDebug._LINK_FRAME_ID;
- clearBtn.innerHTML = "Clear";
- clearBtn._dbg = this;
- clearBtn.onclick = AjxDebug._clear;
-
- buttonFrameBody.appendChild(markBtn);
- buttonFrameBody.appendChild(buttonFrameDoc.createTextNode(" "));
- buttonFrameBody.appendChild(clearBtn);
+AjxDateFormat.EraSegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
+};
+AjxDateFormat.EraSegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.EraSegment.prototype.constructor = AjxDateFormat.EraSegment;
+AjxDateFormat.EraSegment.prototype.toString = function() {
+ return "dateEra: \""+this._s+'"';
+};
- // If we're not using a div
- // Set a cookie telling ourselves that a debug window is already open
- document.cookie = "AjxDebugWinOpen=true";
-
- // setup an onunload method
- if (!AjxEnv.isIE) {
- this._debugWindow.onunload = AjxDebug.unloadHandler;
- window.addEventListener('unload', AjxDebug.myWindowUnloadHandler, true);
- } else {
- this._debugWindow.attachEvent('onunload', AjxDebug.unloadHandler);
- window.attachEvent = AjxDebug.myWindowUnloadHandler;
- }
+// Public methods
- this._dbgWindowInited = true;
- this._showMessages();
+AjxDateFormat.EraSegment.prototype.format = function(date) {
+ // TODO: Only support current era at the moment...
+ return I18nMsg.eraAD;
};
+//
+// Date year segment class
+//
-/**
-* Scrolls to the bottom of the window. How it does that depends on the browser.
-*
-* @private
-*/
-AjxDebug.prototype._scrollToBottom =
-function() {
- if (AjxEnv.isIE) {
- this._contentFrame.contentWindow.document.body.scrollIntoView(false);
- this._linkFrame.contentWindow.document.body.scrollIntoView(false);
- } else {
- this._contentFrame.contentWindow.scrollTo(0, this._contentFrame.contentWindow.document.body.offsetHeight);
- this._linkFrame.contentWindow.scrollTo(0, this._linkFrame.contentWindow.document.body.offsetHeight);
- }
+AjxDateFormat.YearSegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
};
+AjxDateFormat.YearSegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.YearSegment.prototype.constructor = AjxDateFormat.YearSegment;
-/**
-* Returns a timestamp string, if we are showing them.
-* @private
-*/
-AjxDebug.prototype._timestamp =
-function() {
- return this._showTime
- ? AjxDateFormat.getTimeInstance().format(new Date()) + ": "
- : "";
+AjxDateFormat.YearSegment.prototype.toString = function() {
+ return "dateYear: \""+this._s+'"';
};
-AjxDebug.prototype.setShowTimestamps =
-function(show) {
- this._showTime = show;
-};
+// Public methods
-// this function takes an xml node and returns an html string that displays that node
-// the indent argument is used to describe what depth the node is at so that
-// the html code can create a nice indention
-AjxDebug.prototype._createXmlTree =
-function (node, indent) {
+AjxDateFormat.YearSegment.prototype.format = function(date) {
+ var year = String(date.getFullYear());
+ return this._s.length < 4 ? year.substr(year.length - 2) : AjxFormat._zeroPad(year, this._s.length);
+};
- if (node == null)
- return "";
- var str = "";
-
- switch (node.nodeType) {
- case 1: // Element
- str += "<div style='color: blue; padding-left: 16px;'><<span style='color: DarkRed;'>" + node.nodeName + "</span>";
-
- var attrs = node.attributes;
- for (var i = 0; i < attrs.length; i++)
- str += this._createXmlAttribute(attrs[i]);
-
- if (!node.hasChildNodes())
- return str + "/></div>";
-
- str += "><br />";
-
- var cs = node.childNodes;
- for (var i = 0; i < cs.length; i++)
- str += this._createXmlTree(cs[i], indent + 3);
-
- str += "</<span style='color: DarkRed;'>" + node.nodeName + "</span>></div>";
- break;
-
- case 9: // Document
- var cs = node.childNodes;
- for (var i = 0; i < cs.length; i++)
- str += this._createXmlTree(cs[i], indent);
- break;
-
- case 3: // Text
- if (!/^\s*$/.test(node.nodeValue)) {
- var val = node.nodeValue.replace(/</g, "<").replace(/>/g, ">");
- str += "<span style='color: WindowText; padding-left: 16px;'>" + val + "</span><br />";
- }
- break;
-
- case 7: // ProcessInstruction
- str += "<?" + node.nodeName;
-
- var attrs = node.attributes;
- for (var i = 0; i < attrs.length; i++)
- str += this._createXmlAttribute(attrs[i]);
-
- str+= "?><br />"
- break;
-
- case 4: // CDATA
- str = "<div style=''><![CDATA[<span style='color: WindowText; font-family: \"Courier New\"; white-space: pre; display: block; border-left: 1px solid Gray; padding-left: 16px;'>" +
- node.nodeValue +
- "</span>]" + "]></div>";
- break;
-
- case 8: // Comment
- str = "<div style='color: blue; padding-left: 16px;'><!--<span style='white-space: pre; font-family: \"Courier New\"; color: Gray; display: block;'>" +
- node.nodeValue +
- "</span>--></div>";
- break;
-
- case 10:
- str = "<div style='color: blue; padding-left: 16px'><!DOCTYPE " + node.name;
- if (node.publicId) {
- str += " PUBLIC \"" + node.publicId + "\"";
- if (node.systemId)
- str += " \"" + node.systemId + "\"";
- }
- else if (node.systemId) {
- str += " SYSTEM \"" + node.systemId + "\"";
- }
- str += "></div>";
-
- // TODO: Handle custom DOCTYPE declarations (ELEMENT, ATTRIBUTE, ENTITY)
-
- break;
-
- default:
- //alert(node.nodeType + "\n" + node.nodeValue);
- this._inspect(node);
+AjxDateFormat.YearSegment.prototype.parse = function(date, s, index) {
+ var fixedlen = this._getFixedLength();
+ var nindex = AjxFormat.Segment._parseInt(date, date.setFullYear, 0, s, index, fixedlen);
+ // adjust 2-digit years
+ if (nindex - index == 2) {
+ if (!AjxDateFormat._2digitStartYear) {
+ AjxDateFormat._2digitStartYear = parseInt(AjxMsg.dateParsing2DigitStartYear);
+ }
+ var syear = AjxDateFormat._2digitStartYear;
+ var pyear = parseInt(s.substr(index,2));
+ var century = (Math.floor(syear / 100) + (pyear < (syear % 100) ? 1 : 0)) * 100;
+ var year = century + pyear;
+ date.setFullYear(year);
}
-
- return str;
+ return nindex;
};
-AjxDebug.prototype._createXmlAttribute =
-function(a) {
- return " <span style='color: red'>" + a.nodeName + "</span><span style='color: blue'>=\"" + a.nodeValue + "\"</span>";
+//
+// Date month segment class
+//
+
+AjxDateFormat.MonthSegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
};
+AjxDateFormat.MonthSegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.MonthSegment.prototype.constructor = AjxDateFormat.MonthSegment;
-AjxDebug.prototype._inspect =
-function(obj) {
- var str = "";
- for (var k in obj)
- str += "obj." + k + " = " + obj[k] + "\n";
- window.alert(str);
+AjxDateFormat.MonthSegment.prototype.toString = function() {
+ return "dateMonth: \""+this._s+'"';
};
-AjxDebug.prototype._add =
-function (aMsg, extraInfo, isXml, isRaw, linkName){
- var extraType = typeof(extraInfo);
+// Constants
- if (AjxUtil.isSpecified(extraInfo))
- extraInfo = this._getHtmlForObject(extraInfo, isXml, isRaw);
+AjxDateFormat.MonthSegment.MONTHS = {};
+AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.SHORT] = [
+ AjxMsg.monthJanShort, AjxMsg.monthFebShort, AjxMsg.monthMarShort,
+ AjxMsg.monthAprShort, AjxMsg.monthMayShort, AjxMsg.monthJunShort,
+ AjxMsg.monthJulShort, AjxMsg.monthAugShort, AjxMsg.monthSepShort,
+ AjxMsg.monthOctShort, AjxMsg.monthNovShort, AjxMsg.monthDecShort
+];
+AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.MEDIUM] = [
+ I18nMsg.monthJanMedium, I18nMsg.monthFebMedium, I18nMsg.monthMarMedium,
+ I18nMsg.monthAprMedium, I18nMsg.monthMayMedium, I18nMsg.monthJunMedium,
+ I18nMsg.monthJulMedium, I18nMsg.monthAugMedium, I18nMsg.monthSepMedium,
+ I18nMsg.monthOctMedium, I18nMsg.monthNovMedium, I18nMsg.monthDecMedium
+];
+AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.LONG] = [
+ I18nMsg.monthJanLong, I18nMsg.monthFebLong, I18nMsg.monthMarLong,
+ I18nMsg.monthAprLong, I18nMsg.monthMayLong, I18nMsg.monthJunLong,
+ I18nMsg.monthJulLong, I18nMsg.monthAugLong, I18nMsg.monthSepLong,
+ I18nMsg.monthOctLong, I18nMsg.monthNovLong, I18nMsg.monthDecLong
+];
- // Add the message to our stack
- this._addMessage(new DebugMessage(aMsg, null, null, null, extraInfo, linkName));
+// Public methods
+AjxDateFormat.MonthSegment.prototype.format = function(date) {
+ var month = date.getMonth();
+ switch (this._s.length) {
+ case 1: return String(month + 1);
+ case 2: return AjxFormat._zeroPad(month + 1, 2);
+ case 3: return AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.MEDIUM][month];
+ case 5: return AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.SHORT][month];
+ }
+ return AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.LONG][month];
};
-AjxDebug.prototype._addMessage =
-function (aMsg) {
- this._msgQueue[this._msgQueue.length] = aMsg;
- this._showMessages();
+AjxDateFormat.MonthSegment.prototype.parse = function(date, s, index) {
+ var months;
+ switch (this._s.length) {
+ case 3:
+ months = AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.SHORT];
+ case 4:
+ months = months || AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.MEDIUM];
+ case 5: {
+ months = months || AjxDateFormat.MonthSegment.MONTHS[AjxDateFormat.LONG];
+ var nindex = AjxFormat.Segment._parseLiterals(months, s, index);
+ if (nindex != -1) {
+ return nindex;
+ }
+ throw new AjxFormat.ParsingException(this._parent, this, "no match"); // I18n
+ }
+ }
+ var fixedlen = this._getFixedLength();
+ return AjxFormat.Segment._parseInt(date, date.setMonth, -1, s, index, fixedlen);
};
-donola=false;
-AjxDebug.prototype._showMessages =
-function () {
- if (!this._dbgWindowInited) {
- // For now, don't show the messages-- assuming that this case only
- // happens at startup, and many messages will be written
- return;
- }
+//
+// Date week segment class
+//
+
+AjxDateFormat.WeekSegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
+};
+AjxDateFormat.WeekSegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.WeekSegment.prototype.constructor = AjxDateFormat.WeekSegment;
+
+AjxDateFormat.WeekSegment.prototype.toString = function() {
+ return "weekMonth: \""+this._s+'"';
+};
+
+// Public methods
+
+AjxDateFormat.WeekSegment.prototype.format = function(date) {
+ var year = date.getYear();
+ var month = date.getMonth();
+ var day = date.getDate();
- if (this._msgQueue.length > 0) {
- var msg;
- var contentDiv;
- var linkDiv;
- var contentFrameDoc = this._contentFrame.contentWindow.document;
- var linkFrameDoc = this._linkFrame.contentWindow.document;
-
- for (var i = 0 ; i < this._msgQueue.length ; ++i ) {
- var now = new Date();
- msg = this._msgQueue[i];
- contentDiv = contentFrameDoc.createElement('div');
- contentDiv.innerHTML = [msg.message, msg.eHtml].join("");
- if (msg.linkName) {
- linkDiv = linkFrameDoc.createElement('div');
- linkDiv._targetId = contentDiv.id = [AjxDebug._getNextId(), now.getMilliseconds()].join("");
- linkDiv._dbg = this;
- linkDiv.className = "Link";
- linkDiv.onclick = AjxDebug._linkClicked;
- linkDiv.innerHTML = msg.linkName + " - [" + AjxDebug._getTimeStamp(now) + "]";;
- linkFrameDoc.body.appendChild(linkDiv);
- //linkFrameDoc.body.appendChild(linkFrameDoc.createElement("br"));
- }
- contentFrameDoc.body.appendChild(contentDiv);
+ var ofYear = /w/.test(this._s);
+ var date2 = new Date(year, ofYear ? 0 : month, 1);
+
+ var week = 0;
+ while (true) {
+ week++;
+ if (date2.getMonth() > month || (date2.getMonth() == month && date2.getDate() >= day)) {
+ break;
}
+ date2.setDate(date2.getDate() + 7);
}
- this._msgQueue.length = 0;
- this._scrollToBottom();
+ return AjxFormat._zeroPad(week, this._s.length);
};
-AjxDebug._linkClicked =
-function() {
- var el = this._dbg._contentFrame.contentWindow.document.getElementById(this._targetId);
- var y = 0;
- while (el) {
- y += el.offsetTop;
- el = el.offsetParent;
+//
+// Date day segment class
+//
+
+AjxDateFormat.DaySegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
+};
+AjxDateFormat.DaySegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.DaySegment.prototype.constructor = AjxDateFormat.DaySegment;
+
+AjxDateFormat.DaySegment.prototype.toString = function() {
+ return "dateDay: \""+this._s+'"';
+};
+
+// Public methods
+
+AjxDateFormat.DaySegment.prototype.format = function(date) {
+ var month = date.getMonth();
+ var day = date.getDate();
+ if (/D/.test(this._s) && month > 0) {
+ var year = date.getYear();
+ do {
+ // set date to first day of month and then go back one day
+ var date2 = new Date(year, month, 1);
+ date2.setDate(0);
+
+ day += date2.getDate();
+ month--;
+ } while (month > 0);
}
-
- this._dbg._contentFrame.contentWindow.scrollTo(0, y);
+ return AjxFormat._zeroPad(day, this._s.length);
};
-AjxDebug._getNextId =
-function() {
- return "AjxDebug_" + AjxDebug._id++;
+AjxDateFormat.DaySegment.prototype.parse = function(date, s, index) {
+ if (/D/.test(this._s)) {
+ date.setMonth(0);
+ }
+ var fixedlen = this._getFixedLength();
+ return AjxFormat.Segment._parseInt(date, date.setDate, 0, s, index, fixedlen);
};
-AjxDebug.prototype._parseHtmlFragment =
-function (htmlStr) {
- var div = this._contentFrame.contentWindow.document.createElement('div');
- div.innerHTML = htmlStr;
- return div;
+//
+// Date weekday segment class
+//
+
+AjxDateFormat.WeekdaySegment = function(format, s) {
+ AjxDateFormat.DateSegment.call(this, format, s);
};
+AjxDateFormat.WeekdaySegment.prototype = new AjxDateFormat.DateSegment;
+AjxDateFormat.WeekdaySegment.prototype.constructor = AjxDateFormat.WeekdaySegment;
+AjxDateFormat.DaySegment.prototype.toString = function() {
+ return "dateDay: \""+this._s+'"';
+};
-// Static methods
+// Constants
-AjxDebug._mark =
-function() {
- this._dbg._createLinkNContent(this._dbg, "MarkLink", "MARK", "Mark", "MARK");
+AjxDateFormat.WeekdaySegment.WEEKDAYS = {};
+// NOTE: The short names aren't available in Java so we have to define them.
+AjxDateFormat.WeekdaySegment.WEEKDAYS[AjxDateFormat.SHORT] = [
+ AjxMsg.weekdaySunShort, AjxMsg.weekdayMonShort, AjxMsg.weekdayTueShort,
+ AjxMsg.weekdayWedShort, AjxMsg.weekdayThuShort, AjxMsg.weekdayFriShort,
+ AjxMsg.weekdaySatShort
+];
+AjxDateFormat.WeekdaySegment.WEEKDAYS[AjxDateFormat.MEDIUM] = [
+ I18nMsg.weekdaySunMedium, I18nMsg.weekdayMonMedium, I18nMsg.weekdayTueMedium,
+ I18nMsg.weekdayWedMedium, I18nMsg.weekdayThuMedium, I18nMsg.weekdayFriMedium,
+ I18nMsg.weekdaySatMedium
+];
+AjxDateFormat.WeekdaySegment.WEEKDAYS[AjxDateFormat.LONG] = [
+ I18nMsg.weekdaySunLong, I18nMsg.weekdayMonLong, I18nMsg.weekdayTueLong,
+ I18nMsg.weekdayWedLong, I18nMsg.weekdayThuLong, I18nMsg.weekdayFriLong,
+ I18nMsg.weekdaySatLong
+];
+
+// Public methods
+
+AjxDateFormat.WeekdaySegment.prototype.format = function(date) {
+ var weekday = date.getDay();
+ if (/E/.test(this._s)) {
+ var style;
+ switch (this._s.length) {
+ case 4: style = AjxDateFormat.LONG; break;
+ case 5: style = AjxDateFormat.SHORT; break;
+ default: style = AjxDateFormat.MEDIUM;
+ }
+ return AjxDateFormat.WeekdaySegment.WEEKDAYS[style][weekday];
+ }
+ return AjxFormat._zeroPad(weekday, this._s.length);
};
-AjxDebug.prototype._createLinkNContent =
-function(ajxDbgObj, linkClass, linkLabel, contentClass, contentLabel) {
- var now = new Date();
- var timeStamp = [" - [", AjxDebug._getTimeStamp(now), "]"].join("");
- var linkFrameDoc = ajxDbgObj._linkFrame.contentWindow.document;
- var div = linkFrameDoc.createElement("div");
- div.className = linkClass;
- div.innerHTML = linkLabel + timeStamp;
- var id = "Lnk_" + now.getMilliseconds();
- div._targetId = id;
- div._dbg = ajxDbgObj;
- div.onclick = AjxDebug._linkClicked
- linkFrameDoc.body.appendChild(div);
- //linkFrameDoc.body.appendChild(linkFrameDoc.createElement("br"));
-
- var contentFrameDoc = ajxDbgObj._contentFrame.contentWindow.document;
- div = contentFrameDoc.createElement("div");
- div.className = contentClass;
- div.id = id;
- div.innerHTML = contentLabel + timeStamp;
- div._dbg = ajxDbgObj;
- contentFrameDoc.body.appendChild(contentFrameDoc.createElement("p"));
- contentFrameDoc.body.appendChild(div);
- contentFrameDoc.body.appendChild(contentFrameDoc.createElement("p"));
+//
+// Time segment class
+//
+
+AjxDateFormat.TimeSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
};
+AjxDateFormat.TimeSegment.prototype = new AjxFormat.Segment;
+AjxDateFormat.TimeSegment.prototype.constructor = AjxDateFormat.TimeSegment;
-AjxDebug._clear =
-function() {
- this._dbg._contentFrame.contentWindow.document.body.innerHTML = "";
- this._dbg._linkFrame.contentWindow.document.body.innerHTML = "";
+//
+// Time hour segment class
+//
+
+AjxDateFormat.HourSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
};
+AjxDateFormat.HourSegment.prototype = new AjxDateFormat.TimeSegment;
+AjxDateFormat.HourSegment.prototype.constructor = AjxDateFormat.HourSegment;
-AjxDebug.myWindowUnloadHandler =
-function() {
- if (AjxEnv.isNav) {
- DBG._debugWindow.onunload = null;
- } else {
- DBG._debugWindow.detachEvent('onunload', AjxDebug.unloadHandler);
- }
+AjxDateFormat.HourSegment.prototype.toString = function() {
+ return "timeHour: \""+this._s+'"';
};
-AjxDebug.unloadHandler =
-function() {
- try {
- window.AjxDebug.deleteWindowCookie();
- } catch (ex) {
- // do nothing. This might be caused by the unload handler
- // firing while the window is changing domains.
+// Public methods
+
+AjxDateFormat.HourSegment.prototype.format = function(date) {
+ var hours = date.getHours();
+ if (hours > 12 && /[hK]/.test(this._s)) {
+ hours -= 12;
+ }
+ /***
+ // NOTE: This is commented out to match the Java formatter output
+ // but from the comments for these meta-chars, it doesn't
+ // seem right.
+ if (/[Hk]/.test(this._s)) {
+ hours--;
}
+ /***/
+ return AjxFormat._zeroPad(hours, this._s.length);
};
-AjxDebug.deleteWindowCookie =
-function() {
- var expiredDate = new Date('Fri, 31 Dec 1999 23:59:59 GMT'); // I18n???
- document.cookie = "AjxDebugWinOpen=false;expires=" + expiredDate.toGMTString();
+//
+// Time minute segment class
+//
+
+AjxDateFormat.MinuteSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
};
+AjxDateFormat.MinuteSegment.prototype = new AjxDateFormat.TimeSegment;
+AjxDateFormat.MinuteSegment.prototype.constructor = AjxDateFormat.MinuteSegment;
-AjxDebug._escapeForHTML =
-function(str){
- if (typeof(str) != 'string') return str;
- var s = str;
- s = s.replace(/\&/g, '&');
- s = s.replace(/\</g, '<');
- s = s.replace(/\>/g, '>');
- s = s.replace(/\"/g, '"');
- s = s.replace(/\xA0/g, ' ');
- return s;
+AjxDateFormat.MinuteSegment.prototype.toString = function() {
+ return "timeMinute: \""+this._s+'"';
};
-AjxDebug._getTimeStamp =
-function(date) {
- date = (date) ? date : new Date();
- return AjxStringUtil.htmlEncode([AjxDateUtil.getTimeStr(date, "%H:%m:%s"), ".", date.getMilliseconds()].join(""), true);
+// Public methods
+
+AjxDateFormat.MinuteSegment.prototype.format = function(date) {
+ var minutes = date.getMinutes();
+ return AjxFormat._zeroPad(minutes, this._s.length);
};
-/**
- * Simple wrapper for log messages
- */
-DebugMessage = function(aMsg, aType, aCategory, aTime, extraHtml, linkName) {
- this.message = (AjxUtil.isSpecified(aMsg)) ? aMsg : '';
- this.type = aType ? aType : null;
- this.category = aCategory ? aCategory : '';
- this.time = aTime ? aTime : (new Date().getTime());
- this.eHtml = extraHtml ? extraHtml : '';
- this.linkName = linkName;
+//
+// Time second segment class
+//
+
+AjxDateFormat.SecondSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
};
-/** auto include file:./zimbra/js/soap/AjxSoapException.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+AjxDateFormat.SecondSegment.prototype = new AjxDateFormat.TimeSegment;
+AjxDateFormat.SecondSegment.prototype.constructor = AjxDateFormat.SecondSegment;
+AjxDateFormat.SecondSegment.prototype.toString = function() {
+ return "timeSecond: \""+this._s+'"';
+};
-function AjxSoapException(msg, code, method, detail) {
- AjxException.call(this, msg, code, method, detail);
-}
+// Public methods
-AjxSoapException.prototype.toString =
-function() {
- return "AjxSoapException";
-}
+AjxDateFormat.SecondSegment.prototype.format = function(date) {
+ var minutes = /s/.test(this._s) ? date.getSeconds() : date.getMilliseconds();
+ return AjxFormat._zeroPad(minutes, this._s.length);
+};
-AjxSoapException.prototype = new AjxException;
-AjxSoapException.prototype.constructor = AjxSoapException;
+//
+// Time am/pm segment class
+//
-AjxSoapException.INTERNAL_ERROR = "INTERNAL_ERROR";
-AjxSoapException.INVALID_PDU = "INVALID_PDU";
-AjxSoapException.ELEMENT_EXISTS = "ELEMENT_EXISTS";
-/** auto include file:./zimbra/js/util/AjxCallback.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+AjxDateFormat.AmPmSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
+};
+AjxDateFormat.AmPmSegment.prototype = new AjxDateFormat.TimeSegment;
+AjxDateFormat.AmPmSegment.prototype.constructor = AjxDateFormat.AmPmSegment;
+AjxDateFormat.AmPmSegment.prototype.toString = function() {
+ return "timeAmPm: \""+this._s+'"';
+};
-/**
-* Creates a callback which consists of at least a function reference, and possibly also
-* an object to call it from.
-* @constructor
-* @class
-* This class represents a callback function which can be called standalone, or from a
-* given object. What the callback takes as arguments and what it returns are left to the
-* client.
-*
-* @author Conrad Damon
-* @param obj [Object] the object to call the function from
-* @param func [function] the callback function
-* @param args [primitive or Array] default arguments
-*/
-function AjxCallback(obj, func, args) {
- if (arguments.length == 0) return;
+// Public methods
- this.obj = obj;
- this.func = func;
- this.args = args;
-}
+AjxDateFormat.AmPmSegment.prototype.format = function(date) {
+ var hours = date.getHours();
+ return hours < 12 ? I18nMsg.periodAm : I18nMsg.periodPm;
+};
-AjxCallback.prototype.toString =
-function() {
- return "AjxCallback";
-}
+//
+// Time timezone segment class
+//
-/**
-* Runs the callback function, from within the object if there is one. The
-* called function passed arguments are the concatenation of the argument
-* array passed to this object's constructor and the argument array passed
-* to the <code>run</code> method. Whatever the called function returns is
-* returned to the caller.
-*
-* @param arg1 The first argument which will be appended to the argument
-* array passed to this object's constructor. Any number of
-* arguments may be passed to the <code>run</code> method.
-*/
-AjxCallback.prototype.run =
-function(/* arg1 ... argN */) {
- // combine original args with new ones
- var args = [];
+AjxDateFormat.TimezoneSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
+};
+AjxDateFormat.TimezoneSegment.prototype = new AjxDateFormat.TimeSegment;
+AjxDateFormat.TimezoneSegment.prototype.constructor = AjxDateFormat.TimezoneSegment;
- // sometimes we want to pass a null or false argument, so simply
- // checking for if (this.args) won't do.
- if (typeof this.args != "undefined") {
- if (this.args instanceof Array)
- // NOTE: We must NOT use this.args directly if this method's
- // params are gonna be pushed onto the array because it
- // will change the original args!
- args = arguments.length > 0 ? args.concat(this.args) : this.args;
- else
- args.push(this.args);
- }
+AjxDateFormat.TimezoneSegment.prototype.toString = function() {
+ return "timeTimezone: \""+this._s+'"';
+};
- for (var i = 0; i < arguments.length; ++i)
- args.push(arguments[i]);
+// Public methods
- // invoke function
- return this.func.apply(this.obj || window, args);
+AjxDateFormat.TimezoneSegment.prototype.format = function(date) {
+ var clientId = date.timezone || AjxTimezone.DEFAULT;
+ if (/Z/.test(this._s)) {
+ return AjxTimezone.getShortName(clientId);
+ }
+ return this._s.length < 4 ? AjxTimezone.getMediumName(clientId) : AjxTimezone.getLongName(clientId);
};
-/**
- * The following function is what an AjxCallback should be *all* about. It
- * returns a plain function that will call your supplied "func" in the context
- * of "obj" and pass to it, in this order, any additional arguments that you
- * pass to simpleClosure and the arguments that were passed to it at the call
- * time.
- *
- * An example should do:
- *
- * div.onclick = AjxCallback.simpleClosure(this.handler, this, "some data");
- * ...
- * this.handler = function(data, event) {
- * // event will be passed for DOM2 compliant browsers
- * // and data is "some data"
- * };
- *
- * [this is one of the most useful functions I ever wrote :D -mihai@zimbra.com]
- */
-AjxCallback.simpleClosure = function(func, obj) {
- var args = [];
- for (var i = 2; i < arguments.length; ++i)
- args.push(arguments[i]);
- return function() {
- var args2 = [];
- for (var i = 0; i < arguments.length; ++i)
- args2.push(arguments[i]);
- func.apply(obj || this, args.concat(args2));
- };
-};
-/** auto include file:./zimbra/js/util/AjxSelectionManager.js **/
-/*
-* ***** BEGIN LICENSE BLOCK *****
-* Version: MPL 1.1
-*
-* The contents of this file are subject to the Mozilla Public
-* License Version 1.1 ("License"); you may not use this file except in
-* compliance with the License. You may obtain a copy of the License at
-* http://www.zimbra.com/license
-*
-* Software distributed under the License is distributed on an "AS IS"
-* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
-* the License for the specific language governing rights and limitations
-* under the License.
-*
-* The Original Code is: Zimbra AJAX Toolkit.
-*
-* The Initial Developer of the Original Code is Zimbra, Inc.
-* Portions created by Zimbra are Copyright (C) 2005 Zimbra, Inc.
-* All Rights Reserved.
-*
-* Contributor(s):
-*
-* ***** END LICENSE BLOCK *****
-*/
+//
+// Message format class
+//
+function AjxMessageFormat(pattern) {
+ AjxFormat.call(this, pattern);
+ for (var i = 0; i < pattern.length; i++) {
+ // literal
+ var c = pattern.charAt(i);
+ if (c == "'") {
+ if (i + 1 < pattern.length && pattern.charAt(i + 1) == "'") {
+ var segment = new AjxFormat.TextSegment(this, "'");
+ this._segments.push(segment);
+ i++;
+ continue;
+ }
+ var head = i + 1;
+ for (i++ ; i < pattern.length; i++) {
+ var c = pattern.charAt(i);
+ if (c == "'") {
+ if (i + 1 < pattern.length && pattern.charAt(i + 1) == "'") {
+ pattern = pattern.substr(0, i) + pattern.substr(i + 1);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ if (i == pattern.length) {
+ // TODO: i18n
+ throw new AjxFormat.FormatException(this, "unterminated string literal");
+ }
+ var tail = i;
+ var segment = new AjxFormat.TextSegment(this, pattern.substring(head, tail));
+ this._segments.push(segment);
+ continue;
+ }
+
+ // non-meta chars
+ var head = i;
+ while(i < pattern.length) {
+ c = pattern.charAt(i);
+ if (c == '{' || c == "'") {
+ break;
+ }
+ i++;
+ }
+ var tail = i;
+ if (head != tail) {
+ var segment = new AjxFormat.TextSegment(this, pattern.substring(head, tail));
+ this._segments.push(segment);
+ i--;
+ continue;
+ }
+
+ // meta char
+ var head = i + 1;
+ while(++i < pattern.length) {
+ if (pattern.charAt(i) == '}') {
+ break;
+ }
+ }
+ var tail = i;
+ var count = tail - head;
+ var field = pattern.substr(head, count);
+ var segment = new AjxMessageFormat.MessageSegment(this, field);
+ if (segment != null) {
+ this._segments.push(segment);
+ }
+ }
+}
+AjxMessageFormat.prototype = new AjxFormat;
+AjxMessageFormat.prototype.constructor = AjxMessageFormat;
-/**
- * This requires an "owner" which is the object that owns the full set of items, implmenting:
- * getItemCount() to return the number of items
- * getItem(index) to return the item at a given index.
- *
- * And optionally implementing
- * itemSelectionChanged(item, index, isSelected) which is called
- * for each item that is selected or deselected
- * selectionChanged() which is called after a batch of items have
- * been selected or deselected with select()
- *
- */
-
-AjxSelectionManager = function(anOwner) {
- this._owner = anOwner;
+AjxMessageFormat.prototype.toString = function() {
+ return "[AjxMessageFormat: "+AjxFormat.prototype.toString.call(this)+"]";
};
-// -----------------------------------------------------------
-// Constants
-// -----------------------------------------------------------
+// Static methods
-// Actions for select()
-AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS = 0;
-AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS = 1;
-AjxSelectionManager.SELECT_TO_ANCHOR = 2;
-AjxSelectionManager.DESELECT_ALL = 3;
-AjxSelectionManager.SELECT_ALL = 4;
+AjxMessageFormat.format = function(pattern, params) {
+ return new AjxMessageFormat(pattern).format(params);
+};
-// -----------------------------------------------------------
-// API Methods
-// -----------------------------------------------------------
+// Public methods
-/**
- * returns an AjxVector
- */
-AjxSelectionManager.prototype.getItems = function() {
- if (this._selectedItems == null) {
- this._selectedItems = this._createItemsCollection();
+AjxMessageFormat.prototype.format = function(params) {
+ if (!(params instanceof Array)) {
+ params = [ params ];
}
- return this._selectedItems;
+ return AjxFormat.prototype.format.call(this, params);
};
-/**
- * returns the number of selected items
- */
-AjxSelectionManager.prototype.getLength = function() {
- return this.getItems().length;
-};
-
-/**
- * returns the anchor, unless nothing is selected
- */
-AjxSelectionManager.prototype.getAnchor = function() {
- if (this._anchor == null) {
- var items = this.getItems();
- if (items.length > 0) {
- this._anchor = items[0];
- }
- }
- return this._anchor;
-};
-
-/**
- * The cursor probably changes when the users navigates with
- * the keyboard. This returns the item that is currently the cursor,
- * and null if nothing is selected.
- */
-AjxSelectionManager.prototype.getCursor = function() {
- if (this._cursor == null) {
- this._cursor = this.getAnchor();
- }
- return this._cursor;
-};
-
-
-/**
- * Returns true if the given item is selected.
- */
-AjxSelectionManager.prototype.isSelected = function(item) {
- return this.getItems().binarySearch(item) != -1;
-};
-
-AjxSelectionManager.prototype.selectOneItem = function(item) {
- this.select(item, AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS);
-};
-
-AjxSelectionManager.prototype.toggleItem = function(item) {
- this.select(item, AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS);
-};
-
-AjxSelectionManager.prototype.selectFromAnchorToItem = function(item) {
- this.select(item, AjxSelectionManager.SELECT_TO_ANCHOR);
-};
-
-AjxSelectionManager.prototype.deselectAll = function() {
- this.select(null, AjxSelectionManager.DESELECT_ALL);
-};
-
-AjxSelectionManager.prototype.selectAll = function() {
- this.select(null, AjxSelectionManager.SELECT_ALL);
-};
-
-
-/**
- * This method will notify the owner of any changes by calling
- * itemSelectionChanged() (if the owner defines it) for each item whose
- * selection changes and also by calling selectionChanged() (if the
- * owner defines it) once at the end, if anything changed selection.
- *
- */
-AjxSelectionManager.prototype.select = function(item, action) {
-
- // Update the anchor and cursor, if necessary
- this._setAnchorAndCursor(item, action);
-
- // save off the old set of selected items
- var oldItems = this._selectedItems;
- var oldItemsCount = (oldItems == null) ? 0 : oldItems.length;
-
- // create a fresh set of selected items
- this._selectedItems = null;
- this._selectedItems = this._createItemsCollection();
-
- // Now update the selection
- var itemCount = this._owner.getItemCount();
- var needsSort = false;
- var selectionChanged = false;
- var selecting = false;
- for (var i = 0; i < itemCount; ++i) {
- var testItem = this._owner.getItem(i);
- var oldSelectionExists = this._isItemOldSelection(testItem, oldItems);
- var newSelectionExists = oldSelectionExists;
-
- switch (action) {
- case AjxSelectionManager.SELECT_TO_ANCHOR:
- if (this._anchor == null) {
- // If we have no anchor, let it be the first item
- // in the list
- this._anchor = testItem;
- }
- var atEdge = (testItem == this._anchor || testItem == item);
- var changed = false;
- // mark the beginning of the selection for the iteration
- if (!selecting && atEdge) {
- selecting = true;
- changed = true;
- }
- newSelectionExists = selecting;
- // mark the end of the selection if we're there
- if ((!changed || this._anchor == item)
- && selecting && atEdge) {
- selecting = false;
- }
+//
+// AjxMessageFormat.MessageSegment class
+//
- break;
- case AjxSelectionManager.SELECT_ONE_CLEAR_OTHERS:
- newSelectionExists = (testItem == item);
- break;
- case AjxSelectionManager.TOGGLE_ONE_LEAVE_OTHERS:
- if (testItem == item) {
- newSelectionExists = !oldSelectionExists ;
+AjxMessageFormat.MessageSegment = function(format, s) {
+ AjxFormat.Segment.call(this, format, s);
+ var parts = s.split(',');
+ this._index = Number(parts[0]);
+ this._type = parts[1] || "string";
+ this._style = parts[2];
+ switch (this._type) {
+ case "number": {
+ switch (this._style) {
+ case "integer": this._formatter = AjxNumberFormat.getIntegerInstance(); break;
+ case "currency": this._formatter = AjxNumberFormat.getCurrencyInstance(); break;
+ case "percent": this._formatter = AjxNumberFormat.getPercentInstance(); break;
+ default: this._formatter = this._style == null ? AjxNumberFormat.getInstance() : new AjxNumberFormat(this._style);
}
break;
- case AjxSelectionManager.DESELECT_ALL:
- newSelectionExists = false;
- break;
- case AjxSelectionManager.SELECT_ALL:
- newSelectionExists = true;
- break;
- }
-
- if (newSelectionExists) {
- this._selectedItems.add(testItem);
- needsSort = (this._selectedItems.length > 1);
}
-
- if ( newSelectionExists != oldSelectionExists) {
- // Something changed so notify the owner.
- if (this._owner.itemSelectionChanged != null) {
- this._owner.itemSelectionChanged(testItem,
- i, newSelectionExists);
+ case "date": case "time": {
+ var func = this._type == "date" ? AjxDateFormat.getDateInstance : AjxDateFormat.getTimeInstance;
+ switch (this._style) {
+ case "short": this._formatter = func(AjxDateFormat.SHORT); break;
+ case "medium": this._formatter = func(AjxDateFormat.MEDIUM); break;
+ case "long": this._formatter = func(AjxDateFormat.LONG); break;
+ case "full": this._formatter = func(AjxDateFormat.FULL); break;
+ default: this._formatter = this._style == null ? func(AjxDateFormat.DEFAULT) : new AjxDateFormat(this._style);
}
- selectionChanged = true;
+ break;
}
+ case "choice": /*TODO*/ break;
}
- selectionChanged = selectionChanged || (oldItemsCount !=
- this._selectedItems.length);
-
- if (needsSort) this._selectedItems.sort();
- if (selectionChanged && this._owner.selectionChanged != null) {
- this._owner.selectionChanged(item);
- }
};
+AjxMessageFormat.MessageSegment.prototype = new AjxFormat.Segment;
+AjxMessageFormat.MessageSegment.prototype.constructor = AjxMessageFormat.MessageSegment;
-/**
- * Remove an item from the selection managers selected items
- * collection if it exists.
- */
-AjxSelectionManager.prototype.removeItem = function(item) {
- if (this._selectedItems) {
- var index = this._selectedItems.binarySearch(item);
- if (index > -1) this._selectedItems.removeAt(index);
- }
+AjxMessageFormat.MessageSegment.prototype.toString = function() {
+ var a = [ "message: \"", this._s, "\", index: ", this.index ];
+ if (this._type) a.push(", type: ", this._type);
+ if (this._style) a.push(", style: ", this._style);
+ if (this._formatter) a.push(", formatter: ", this._formatter.toString());
+ return a.join("");
};
-// -----------------------------------------------------------
-// Internal Methods
-// -----------------------------------------------------------
-
-/**
- * Creates an array suitable for use as the sorted list of selected
- * items and returns it.
- */
-AjxSelectionManager.prototype._createItemsCollection = function() {
[... 44216 lines stripped ...]