-import "CPCustomView.j"
import "_CPCibCustomObject.j"
+import "_CPCibCustomView.j"
import "_CPCibKeyedUnarchiver.j"
import "_CPCibObjectData.j"
import "_CPCibWindowTemplate.j"
diff --git a/AppKit/Cib/CPCustomView.j b/AppKit/Cib/_CPCibCustomView.j
similarity index 100%
rename from AppKit/Cib/CPCustomView.j
rename to AppKit/Cib/_CPCibCustomView.j
diff --git a/Foundation/CPString.j b/Foundation/CPString.j
index 691a9ee1b..d98b64a42 100644
--- a/Foundation/CPString.j
+++ b/Foundation/CPString.j
@@ -128,14 +128,15 @@ var CPStringHashes = new objj_dictionary();
{
if (!format)
[CPException raise:CPInvalidArgumentException
- reason:"stringWithString: the format can't be 'nil'"];
+ reason:"initWithFormat: the format can't be 'nil'"];
self = sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
return self;
}
/*
- Creates a new string using C printf-style formatting. First argument should be a constant format string, like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
+ Creates a new string using C printf-style formatting. First argument should be a constant format string,
+ like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
@param format the format to be used, printf-style
@return the initialized CPString
*/
@@ -143,7 +144,7 @@ var CPStringHashes = new objj_dictionary();
{
if (!format)
[CPException raise:CPInvalidArgumentException
- reason:"stringWithString: the format can't be 'nil'"];
+ reason:"initWithFormat: the format can't be 'nil'"];
return sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
}
@@ -174,6 +175,21 @@ var CPStringHashes = new objj_dictionary();
}
// Combining strings
+
+/*
+ Returns a string made by appending to the reciever a string constructed from a given format
+ string and the floowing arguments
+ @param format the format string in printf-style.
+ @return the initialized CPString
+*/
+- (CPString)stringByAppendingFormat:(CPString)format, ...
+{
+ if (!format)
+ [CPException raise:CPInvalidArgumentException reason:"initWithFormat: the format can't be 'nil'"];
+
+ return self + sprintf.apply(this, Array.prototype.slice.call(arguments, 2));
+}
+
/*
Creates a new CPString from the concatenation of the receiver and the specified string.
@param aString the string to append to the receiver
@@ -214,6 +230,7 @@ var CPStringHashes = new objj_dictionary();
if (difference) string += substring.substr(difference + substring.length);
}
+//Dividing Strings
/*
Tokenizes the receiver string using the specified
delimiter. For example, if the receiver is:
@@ -261,6 +278,7 @@ var CPStringHashes = new objj_dictionary();
}
// Finding characters and substrings
+
/*
Finds the range of characters in the receiver where the specified string exists. If the string
does not exist in the receiver, the range length will be 0.
@@ -269,9 +287,7 @@ var CPStringHashes = new objj_dictionary();
*/
- (CPRange)rangeOfString:(CPString)aString
{
- var location = indexOf(aString);
-
- return CPMakeRange(location, location == CPNotFound ? 0 : aString.length);
+ return [self rangeOfString:aString options:0];
}
/*
@@ -279,13 +295,13 @@ var CPStringHashes = new objj_dictionary();
where the specified string exists. The search
is subject to the options specified in the
specified mask which can be a combination of:
-
-CPCaseInsensitiveSearch
-CPLiteralSearch
-CPBackwardsSearch
-CPAnchoredSearch
-CPNumericSearch
-
+
+ CPCaseInsensitiveSearch
+ CPLiteralSearch
+ CPBackwardsSearch
+ CPAnchoredSearch
+ CPNumericSearch
+
@param aString the string to search for
@param aMask the options to use in the search
@return the range of characters in the receiver. If the string was not found,
@@ -293,23 +309,78 @@ CPNumericSearch
*/
- (CPRange)rangeOfString:(CPString)aString options:(int)aMask
{
- var string = self,
+ return [self rangeOfString:aString options:aMask range:nil];
+}
+
+/*
+ Finds the range of characters in the receiver
+ where the specified string exists in the given range
+ of the receiver.The search is subject to the options specified in the
+ specified mask which can be a combination of:
+
+ CPCaseInsensitiveSearch
+ CPLiteralSearch
+ CPBackwardsSearch
+ CPAnchoredSearch
+ CPNumericSearch
+
+ @param aString the string to search for
+ @param aMask the options to use in the search
+ @param aRange the range of the receiver in which to search for
+ @return the range of characters in the receiver. If the string was not found,
+ the length of the range will be 0.
+*/
+- (CPRange)rangeOfString:(CPString)aString options:(int)aMask range:(CPrange)aRange
+{
+ var string = (aRange == nil) ? self : [self substringWithRange:aRange],
location = CPNotFound;
-
+
if (aMask & CPCaseInsensitiveSearch)
{
string = string.toLowerCase();
aString = aString.toLowerCase();
}
-
- if (CPBackwardsSearch) location = lastIndexOf(aString, aMask & CPAnchoredSearch ? length - aString.length : 0);
- else if (aMask & CPAnchoredSearch) location = substr(0, aString.length).indexOf(aString) != CPNotFound ? 0 : CPNotFound;
- else location = indexOf(aString);
-
+
+ if (aMask & CPBackwardsSearch)
+ location = string.lastIndexOf(aString, aMask & CPAnchoredSearch ? length - aString.length : 0);
+ else if (aMask & CPAnchoredSearch)
+ location = string.substr(0, aString.length).indexOf(aString) != CPNotFound ? 0 : CPNotFound;
+ else
+ location = string.indexOf(aString);
+
return CPMakeRange(location, location == CPNotFound ? 0 : aString.length);
}
+//Replacing Substrings
+
+/*
+ Returns a new string in which all occurrences of a target string in the reciever are replaced by
+ another given string.
+ @param target The string to replace.
+ @param replacement the string with which to replace the target
+*/
+
+- (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement
+{
+ return self.replace(new RegExp(target, "g"), replacement);
+}
+
+/*
+- (CPString)stringByReplacingOccurrencesOfString:(CPString)target withString:(CPString)replacement options:(int)options range:(CPRange)searchRange
+{
+ //TODO :Vijay implement the method
+
+}
+
+- (CPString)stringByReplacingCharactersInRange:(CPRange)range withString:(CPString)replacement
+{
+ //TODO :Vijay implement the method
+}
+*/
+
+
// Identifying and comparing strings
+
/*
Compares the receiver to the specified string.
@param aString the string with which to compare
@@ -433,7 +504,18 @@ CPNumericSearch
*/
- (double)doubleValue
{
- return eval(self);
+ return parseFloat(self, 10);
+}
+/*
+ Returns YES on encountering one of "Y", "y", "T", "t", or
+ a digit 1-9. Returns NO otherwise. This method skips the initial
+ whitespace characters, +,- followed by Zeroes.
+*/
+
+- (BOOL)boolValue
+{
+ var replaceRegExp = new RegExp("^\\s*[\\+,\\-]*0*");
+ return RegExp("^[Y,y,t,T,1-9]").test(self.replace(replaceRegExp, ''));
}
/*
@@ -441,7 +523,7 @@ CPNumericSearch
*/
- (float)floatValue
{
- return eval(self);
+ return parseFloat(self, 10);
}
/*
@@ -449,12 +531,12 @@ CPNumericSearch
*/
- (int)intValue
{
- return parseInt(self);
+ return parseInt(self, 10);
}
/*
Returns an the path components of this string. This
- method assumes that the string's contents is a '/'
+ method assumes that the string's content is a '/'
separated file system path.
*/
- (CPArray)pathComponents
@@ -472,6 +554,11 @@ CPNumericSearch
return substr(lastIndexOf('.') + 1);
}
+/*
+ Returns the last component of this string.
+ This method assumes that the string's content is a '/'
+ separated file system path.
+*/
- (CPString)lastPathComponent
{
var components = [self pathComponents];
@@ -484,8 +571,8 @@ CPNumericSearch
*/
- (CPString)stringByDeletingLastPathComponent
{
- // FIMXE: this is wrong: a/a/ returns a/a/.
- return substr(0, lastIndexOf('/')+1);
+ // FIXME: this is wrong: a/a/ returns a/a/.
+ return substr(0, lastIndexOf('/') + 1);
}
- (CPString)stringByStandardizingPath
@@ -509,11 +596,11 @@ String.prototype.isa = CPString;
var sprintfFormatRegex = new RegExp("([^%]+|%[\\+\\-\\ \\#0]*[0-9\\*]*(.[0-9\\*]+)?[hlL]?[cdieEfgGosuxXpn%])", "g");
var sprintfTagRegex = new RegExp("(%)([\\+\\-\\ \\#0]*)([0-9\\*]*)((.[0-9\\*]+)?)([hlL]?)([cdieEfgGosuxXpn%])");
-/**
+/*
Creates a new string using C printf-style formatting. First argument should be a constant format string, like ' "float val = %f" ', remaining arguments should be the variables to print the values of, comma-separated.
@param format the format to be used, printf-style
@return the initialized CPString
- */
+*/
function sprintf(format)
{
var format = arguments[0],
diff --git a/Objective-J/plist.js b/Objective-J/plist.js
index d03ede527..59f0f8515 100644
--- a/Objective-J/plist.js
+++ b/Objective-J/plist.js
@@ -340,7 +340,7 @@ function CPPropertyListCreateFromXMLData(XMLNodeOrData)
if (XMLNode.string)
{
#if RHINO
- XMLNode = DOCUMENT_ELEMENT(Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+ XMLNode = DOCUMENT_ELEMENT(_documentBuilder.parse(
new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(XMLNode.string))));
#else
if (window.ActiveXObject)
diff --git a/Tests/Foundation/CPStringTest.j b/Tests/Foundation/CPStringTest.j
new file mode 100644
index 000000000..289663cdc
--- /dev/null
+++ b/Tests/Foundation/CPStringTest.j
@@ -0,0 +1,72 @@
+import
+
+@implementation CPStringTest : OJTestCase
+
+
+- (void)testStringByReplacingOccurrencesOfStringWithString
+{
+ var expectedString = @"hello world. A new world!";
+ var dummyString = @"hello woold. A new woold!";
+ var actualString = [dummyString stringByReplacingOccurrencesOfString:@"woold" withString:@"world"];
+ [self assertTrue:(expectedString === actualString)
+ message:"stringByAppendingFormat: expected:" + expectedString + " actual:" + actualString];
+
+
+
+}
+- (void)testStringByAppendingFormat
+{
+ var format = @"%d X %d = %d";
+ var expectedString = "2 X 3 = 6";
+ var dummyString = @"";
+ var actualString = [dummyString stringByAppendingFormat:format ,2 ,3 ,6];
+ [self assertTrue:(expectedString === actualString)
+ message:"stringByAppendingFormat: expected:" + expectedString + " actual:" + actualString];
+
+}
+- (void) testBoolValue
+{
+ var testString = @" 090";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" YES";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" true";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" True";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" tTR";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" +98";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" -98";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" +08";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" -98";
+ [self assertTrue:[testString boolValue] message:"boolValue for the string " + testString + " should return true"];
+
+ testString = @" NO";
+ [self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
+
+ testString = @" -N00";
+ [self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
+
+ testString = @" 00";
+ [self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
+
+ testString = @" -00";
+ [self assertFalse:[testString boolValue] message:"boolValue for the string " + testString + " should return false"];
+
+}
+
+
+
+@end
diff --git a/Tools/Utilities/bridge.js b/Tools/Utilities/bridge.js
index bf55fb76f..9c3540c51 100644
--- a/Tools/Utilities/bridge.js
+++ b/Tools/Utilities/bridge.js
@@ -107,11 +107,11 @@ if (typeof readFile == "undefined") {
var f = new Packages.java.io.File(path);
if (!f.canRead()) {
- //alert("can't read: " + f.path)
+ alert("can't read: " + f.path)
return "";
}
- //alert("reading: " + f.getAbsolutePath());
+ alert("reading: " + f.getAbsolutePath());
var fis = new Packages.java.io.FileInputStream(f);
@@ -119,12 +119,11 @@ if (typeof readFile == "undefined") {
fis.read(b);
fis.close();
-
- //return String(new Packages.java.lang.String(b));
+
if (characterCoding)
- return new Packages.java.lang.String(b, characterCoding);
+ return String(new Packages.java.lang.String(b, characterCoding));
else
- return new Packages.java.lang.String(b);
+ return String(new Packages.java.lang.String(b));
}
}
else {
@@ -283,9 +282,25 @@ if (typeof Packages != "undefined") {
}
};
- var xhr_builder = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder();
- xhr_builder.setErrorHandler(function(exception, methodName) {
- //print("xml error!");
+ var _documentBuilderFactory = Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance();
+ // setValidating to false doesn't seem to prevent it from downloading the DTD, but lets do it anyway
+ _documentBuilderFactory.setValidating(false);
+
+ _documentBuilder = _documentBuilderFactory.newDocumentBuilder();
+ // prevent the Java XML parser from downloading the plist DTD from Apple every time we parse a plist
+ _documentBuilder.setEntityResolver(new Packages.org.xml.sax.EntityResolver({
+ resolveEntity: function(publicId, systemId) {
+ //Packages.java.lang.System.out.println("publicId=" + publicId + " systemId=" + systemId);
+
+ // TODO: return a local copy of the DTD?
+ if (String(systemId) == "http://www.apple.com/DTDs/PropertyList-1.0.dtd")
+ return new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(""));
+
+ return null;
+ }
+ }));
+ // throw an exception on error
+ _documentBuilder.setErrorHandler(function(exception, methodName) {
throw exception;
});
@@ -372,7 +387,7 @@ if (typeof Packages != "undefined") {
}
parseXMLString = function(string) {
- return (Packages.javax.xml.parsers.DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(
+ return (_documentBuilder.parse(
new Packages.org.xml.sax.InputSource(
new Packages.java.io.StringReader(string))).getDocumentElement());
}
@@ -435,23 +450,23 @@ XMLHttpRequest.prototype.send = function(body) {
try {
this.responseText = readFile(this.url);
- alert("xhr: " + this.url);
+ alert("xhr response: " + this.url + " (length="+this.responseText.length+")");
} catch (e) {
- alert("read exception: " + this.url);
+ alert("xhr exception: " + this.url);
this.responseText = "";
this.responseXML = null;
}
if (this.responseText.length > 0) {
try {
- this.responseXML = xhr_builder.parse(new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(this.responseText)));
+ this.responseXML = _documentBuilder.parse(new Packages.org.xml.sax.InputSource(new Packages.java.io.StringReader(this.responseText)));
} catch (e) {
this.responseXML = null;
}
this.status = 200;
}
else {
- alert("empty file: " + this.url);
+ alert("xhr empty: " + this.url);
this.status = 404;
}
diff --git a/Tools/nib2cib/NSCustomView.j b/Tools/nib2cib/NSCustomView.j
index 6a1362497..b6bc5c598 100644
--- a/Tools/nib2cib/NSCustomView.j
+++ b/Tools/nib2cib/NSCustomView.j
@@ -20,7 +20,7 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-import
+import
import "NSView.j"