diff --git a/AppKit/CPMenu/CPMenu.j b/AppKit/CPMenu/CPMenu.j index 8e3b321ee..940664f7a 100644 --- a/AppKit/CPMenu/CPMenu.j +++ b/AppKit/CPMenu/CPMenu.j @@ -648,6 +648,9 @@ var _CPMenuBarVisible = NO, while ([highlightedItem submenu] && [highlightedItem action] === @selector(submenuAction:)) highlightedItem = [[highlightedItem submenu] highlightedItem]; + // FIXME: It is theoretically not necessarily to check isEnabled here since + // highlightedItem is always enabled. Do there exist edge cases: disabling on closing a menu, + // etc.? Requires further investigation and tests. if (highlightedItem && [highlightedItem isEnabled]) [CPApp sendAction:[highlightedItem action] to:[highlightedItem target] from:highlightedItem]; } diff --git a/AppKit/CPMenu/_CPMenuManager.j b/AppKit/CPMenu/_CPMenuManager.j index 253812f71..85ddee116 100644 --- a/AppKit/CPMenu/_CPMenuManager.j +++ b/AppKit/CPMenu/_CPMenuManager.j @@ -113,11 +113,21 @@ var SharedMenuManager = nil; // Find which menu window the mouse is currently on top of var activeMenuContainer = [self menuContainerForPoint:globalLocation], - menuLocation = [activeMenuContainer convertGlobalToBase:globalLocation], - activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound, - activeMenu = activeMenuContainer ? [activeMenuContainer menu] : nil, - activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil, - mouseOverMenuView = activeMenuContainer ? [activeItem view] : nil; + activeMenu = [activeMenuContainer menu], + menuLocation = [activeMenuContainer convertGlobalToBase:globalLocation]; + + // Find out the item the mouse is currently on top of + var activeItemIndex = activeMenuContainer ? [activeMenuContainer itemIndexAtPoint:menuLocation] : CPNotFound, + activeItem = activeItemIndex !== CPNotFound ? [activeMenu itemAtIndex:activeItemIndex] : nil; + + // If the item isn't enabled its as if we clicked on nothing. + if (![activeItem isEnabled]) + { + activeItemIndex = CPNotFound; + activeItem = nil; + } + + var mouseOverMenuView = [activeItem view]; if (type === CPPeriodic) { diff --git a/Foundation/CPException.j b/Foundation/CPException.j index 69c34b579..9537496d2 100755 --- a/Foundation/CPException.j +++ b/Foundation/CPException.j @@ -92,7 +92,7 @@ if (input == nil) if (self) { name = aName; - reason = aReason; + message = aReason; userInfo = aUserInfo; } @@ -112,7 +112,7 @@ if (input == nil) */ - (CPString)reason { - return reason; + return message; } /*! @@ -128,7 +128,7 @@ if (input == nil) */ - (CPString)description { - return reason; + return message; } /*! @@ -145,7 +145,7 @@ if (input == nil) - (id)copy { - return [[self class] exceptionWithName:name reason:reason userInfo:userInfo]; + return [[self class] exceptionWithName:name reason:message userInfo:userInfo]; } @end @@ -168,7 +168,7 @@ var CPExceptionNameKey = "CPExceptionNameKey", if (self) { name = [aCoder decodeObjectForKey:CPExceptionNameKey]; - reason = [aCoder decodeObjectForKey:CPExceptionReasonKey]; + message = [aCoder decodeObjectForKey:CPExceptionReasonKey]; userInfo = [aCoder decodeObjectForKey:CPExceptionUserInfoKey]; } @@ -182,13 +182,16 @@ var CPExceptionNameKey = "CPExceptionNameKey", - (void)encodeWithCoder:(CPCoder)aCoder { [aCoder encodeObject:name forKey:CPExceptionNameKey]; - [aCoder encodeObject:reason forKey:CPExceptionReasonKey]; + [aCoder encodeObject:message forKey:CPExceptionReasonKey]; [aCoder encodeObject:userInfo forKey:CPExceptionUserInfoKey]; } @end -objj_exception.prototype.isa = CPException; +// toll-free bridge Error to CPException +// [CPException alloc] uses an objj_exception, which is a subclass of Error +Error.prototype.isa = CPException; + [CPException initialize]; function _CPRaiseInvalidAbstractInvocation(anObject, aSelector) diff --git a/Jakefile b/Jakefile index 5e2781b63..1f5f22be4 100644 --- a/Jakefile +++ b/Jakefile @@ -48,7 +48,7 @@ task ("install", ["CommonJS"], function() { // FIXME: require("narwhal/tusk/install").install({}, $COMMONJS); // Doesn't work due to some weird this.print business. - OS.system("sudo tusk install --force " + $BUILD_CJS_OBJECTIVE_J + " " + $BUILD_CJS_CAPPUCCINO); + OS.system(["sudo", "tusk", "install", "--force", $BUILD_CJS_OBJECTIVE_J, $BUILD_CJS_CAPPUCCINO]); }); // Documentation @@ -61,7 +61,7 @@ task ("documentation", function() { if (executableExists("doxygen")) { - if (OS.system("doxygen " + FILE.join("Tools", "Documentation", "Cappuccino.doxygen"))) + if (OS.system(["doxygen", FILE.join("Tools", "Documentation", "Cappuccino.doxygen")])) OS.exit(1); //rake abort if ($? != 0) rm_rf($DOCUMENTATION_BUILD); @@ -95,7 +95,7 @@ filedir ($STARTER_DOWNLOAD_APPLICATION, ["CommonJS"], function() rm_rf($STARTER_DOWNLOAD_APPLICATION); FILE.mkdirs($STARTER_DOWNLOAD); - if (OS.system("capp gen " + $STARTER_DOWNLOAD_APPLICATION + " -t Application --noconfig")) + if (OS.system(["capp", "gen", $STARTER_DOWNLOAD_APPLICATION, "-t", "Application", "--noconfig"])) // FIXME: uncomment this: we get conversion errors //OS.exit(1); // rake abort if ($? != 0) {} @@ -161,13 +161,14 @@ task ("deploy", ["downloads"], function() // Testing -task ("test", ["build"], function() +task("test", ["build", "test-only"]); + +task("test-only", function() { var tests = new FileList('Tests/**/*Test.j'); var cmd = ["ojtest"].concat(tests.items()); - var cmdString = cmd.map(OS.enquote).join(" "); - var code = OS.system(cmdString); + var code = OS.system(cmd); if (code !== 0) OS.exit(code); }); @@ -198,8 +199,7 @@ function pushPackage(path, remote) ["git", "push", "origin", "master"] ]; - var cmdString = cmds.map(function(cmd) - { + var cmdString = cmds.map(function(cmd) { return cmd.map(OS.enquote).join(" "); }).join(" && "); diff --git a/Objective-J/Jakefile b/Objective-J/Jakefile index 06eb01c7c..fad6a97f3 100644 --- a/Objective-J/Jakefile +++ b/Objective-J/Jakefile @@ -28,20 +28,32 @@ require("../common.jake"); $BUILD_OBJECTIVE_J = FILE.join($BUILD_CONFIGURATION_DIR, "Objective-J"); -Files = new FileList("Runtime/constants.js", "Runtime/utilities.js", "Runtime/json2.js", "Runtime/runtime.js", "Runtime/dictionary.js", "Runtime/plist.js", "Runtime/file.js", "Runtime/exception.js", "Runtime/preprocess.js", "Runtime/evaluate.js", "Runtime/bootstrap.js"); +var OBJECTIVE_J_FILES = new FileList( + "Runtime/constants.js", + "Runtime/utilities.js", + "Runtime/json2.js", + "Runtime/runtime.js", + "Runtime/dictionary.js", + "Runtime/plist.js", + "Runtime/file.js", + "Runtime/exception.js", + "Runtime/preprocess.js", + "Runtime/evaluate.js", + "Runtime/bootstrap.js" +); if ($CONFIGURATION === "Debug") - Files.include("Runtime/debug.js"); + OBJECTIVE_J_FILES.include("Runtime/debug.js"); $BUILD_BROWSER_FILE = FILE.join($BUILD_OBJECTIVE_J, "Objective-J.js"); $BUILD_CJS_FILE = FILE.join($BUILD_OBJECTIVE_J, "CommonJS.environment", "Objective-J.js"); -filedir ($BUILD_BROWSER_FILE, Files, function(aTask) +filedir($BUILD_BROWSER_FILE, OBJECTIVE_J_FILES, function(aTask) { build_product(aTask.name(), environmentFlags("ObjJ") + " -DPLATFORM_USERAGENT"); }); -filedir ($BUILD_CJS_FILE, Files, function(aTask) +filedir($BUILD_CJS_FILE, OBJECTIVE_J_FILES, function(aTask) { flags = environmentFlags("CommonJS", "ObjJ"); flags += ' -DRHINO' @@ -52,7 +64,7 @@ filedir ($BUILD_CJS_FILE, Files, function(aTask) $LICENSE = FILE.join("CommonJS", "lib", "objective-j", "jake", "LICENSES", "LGPL-v2.1"); $BUILD_LICENSE = FILE.join($BUILD_OBJECTIVE_J, "LICENSE"); -filedir ($BUILD_LICENSE, [$LICENSE], function() +filedir($BUILD_LICENSE, [$LICENSE], function() { FILE.copy($LICENSE, $BUILD_LICENSE); }); @@ -83,7 +95,7 @@ new FileList("CommonJS/**/*").forEach(function(aFilename) $BUILD_CJS_OBJECTIVE_J_FRAMEWORK = FILE.join($BUILD_CJS_OBJECTIVE_J, "Frameworks", "Objective-J"); -filedir ($BUILD_CJS_OBJECTIVE_J_FRAMEWORK, function() +filedir($BUILD_CJS_OBJECTIVE_J_FRAMEWORK, function() { cp_r($BUILD_OBJECTIVE_J, $BUILD_CJS_OBJECTIVE_J_FRAMEWORK); }); @@ -92,24 +104,45 @@ CLOBBER.include($BUILD_OBJECTIVE_J); function environmentFlags() { - return "-DENVIRONMENTS=\"[" + Array.prototype.map.apply(arguments, [function(anEnvironment) - { + return "-DENVIRONMENTS=\"[" + Array.prototype.map.apply(arguments, [function(anEnvironment) { return "\\\"" + anEnvironment + "\\\""; }]).join(", ") + "]\""; } function build_product(path, flags) { - OS.system("cat Runtime/header.txt > " + OS.enquote(path)); - OS.system("cat " + - Files.filter(function(aName) - { - return !!aName.match(/\.js$/); - }).map(function(aName) - { - return OS.enquote(aName); - }).join(' ') + " | gcc " + flags + " -E -x c -P - >> " + OS.enquote(path)); + var sources = OBJECTIVE_J_FILES.filter(function(aName) { return !!aName.match(/\.js$/); }); + + var productOut = FILE.open(path, "w", { charset : "UTF-8" }); + + FILE.open("Runtime/header.txt", "r", { charset : "UTF-8" }) + .copy(productOut) + .close(); + + var preprocessor = OS.popen("gcc " + flags + " -E -x c -P -"); + + sources.forEach(function(source) { + FILE.open(source, "r", { charset : "UTF-8" }) + .copy(preprocessor.stdin) + .close(); + }); + + preprocessor.stdin.close(); + preprocessor.stdout.copy(productOut); + + productOut.close(); + + var code = preprocessor.wait(); + + // this is equivalent to the above, but less cross platform: + //OS.system(["cp", "Runtime/header.txt", path]); + //var code = OS.system("cat " + sources.map(OS.enquote).join(' ') + " | gcc " + flags + " -E -x c -P - >> " + OS.enquote(path)); + + if (code !== 0) { + FILE.remove(path); + OS.exit(1); + } // rake abort if ($? != 0) } -task ("build", [$BUILD_BROWSER_FILE, $BUILD_CJS_FILE, $BUILD_LICENSE, $BUILD_CJS_OBJECTIVE_J_FRAMEWORK]); +task("build", [$BUILD_BROWSER_FILE, $BUILD_CJS_FILE, $BUILD_LICENSE, $BUILD_CJS_OBJECTIVE_J_FRAMEWORK]); diff --git a/Objective-J/Runtime/exception.js b/Objective-J/Runtime/exception.js index ef0f1b3d5..cc0aca5db 100644 --- a/Objective-J/Runtime/exception.js +++ b/Objective-J/Runtime/exception.js @@ -25,15 +25,18 @@ var OBJJ_EXCEPTION_OUTPUT_STREAM = NULL; function objj_exception(aName, aReason, aUserInfo) { this.name = aName; - this.reason = aReason; + this.message = aReason; this.userInfo = aUserInfo; this.__address = _objj_generateObjectHash(); + + // add rhinoException to get better stack traces + if (typeof Packages !== "undefined" && Packages && Packages.org) + this.rhinoException = Packages.org.mozilla.javascript.JavaScriptException(this, null, 0); } -objj_exception.prototype.toString = function() -{ - return this.reason; -} +// make objj_exception a subclass of Error +// later we toll-free bridge Error to CPException +objj_exception.prototype = new Error(); function objj_exception_throw(anException) { diff --git a/Rakefile b/Rakefile index bf202c35f..ebd27ab18 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,13 @@ #!/usr/bin/env ruby -print(' +puts <<-eos Building with rake is no longer supported, use "jake" instead. The commands are all the same (e.g. rake install -> jake install). - If you do not have jake, you can run sudo ./bootstrap.sh to install it and its dependencies. + If you do not have jake, you can run sudo ./bootstrap.sh to install jake and it's dependencies. + + PLEASE remove your Build folder ($CAPP_BUILD if it's set) when switching from rake to jake. +eos - PLEASE remove your Build folder when switching from rake to jake. -'); exit(1); diff --git a/Tests/Foundation/CPIndexSetTest.j b/Tests/Foundation/CPIndexSetTest.j index b4d05ae9d..d5bd5d117 100644 --- a/Tests/Foundation/CPIndexSetTest.j +++ b/Tests/Foundation/CPIndexSetTest.j @@ -283,7 +283,7 @@ function descriptionWithoutEntity(aString) [self assert:[_set lastIndex] equals:19]; [self assert:[[CPIndexSet indexSet] lastIndex] equals:CPNotFound]; } - +/* - (void)testAddSpeed { var startTime = [CPDate date]; @@ -296,7 +296,7 @@ function descriptionWithoutEntity(aString) print([startTime timeIntervalSinceNow]); //[self assertTrue: ABS([startTime timeIntervalSinceNow]) < 2]; } - +*/ - (void)testIndexGreaterThanIndex { [self assert:[_set indexGreaterThanIndex:5] equals:10]; diff --git a/common.jake b/common.jake index fdf280550..2cd240707 100644 --- a/common.jake +++ b/common.jake @@ -113,6 +113,9 @@ function partial_require(path, exports) // FIXME: is there a better way to do this??? OS.system = function(aCommand) { + if (Array.isArray(aCommand)) + aCommand = aCommand.map(OS.enquote).join(" "); + return system("PATH=" + OS.enquote(bin) + ":$PATH " + aCommand); }